前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >unexploitable Writeup[pwnable.tw]

unexploitable Writeup[pwnable.tw]

作者头像
WeaponX
发布2018-09-20 10:40:20
1.3K0
发布2018-09-20 10:40:20
举报
文章被收录于专栏:BinarySecBinarySecBinarySec

0x00 unexploitable

最近在刷pwnable.tw(类似pwnable.kr,不过是中国台湾的)的题,看到了一个unexploitable的题目。根据题目描述:

The original challenge is on pwnable.kr and it is solvable. This time we fix the vulnerability and now we promise that the service is unexploitable.

下载下来后丢到ida看到确实没什么变化,除了pwnable.kr那个题中最重要的一点syscall没有给。

.text:0000000000400544 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:0000000000400544                 public main
.text:0000000000400544 main            proc near               ; DATA XREF: _start+1Do
.text:0000000000400544
.text:0000000000400544 buf             = byte ptr -10h
.text:0000000000400544
.text:0000000000400544                 push    rbp
.text:0000000000400545                 mov     rbp, rsp
.text:0000000000400548                 sub     rsp, 10h
.text:000000000040054C                 mov     edi, 3          ; seconds
.text:0000000000400551                 mov     eax, 0
.text:0000000000400556                 call    _sleep
.text:000000000040055B                 lea     rax, [rbp+buf]
.text:000000000040055F                 mov     edx, 100h       ; nbytes
.text:0000000000400564                 mov     rsi, rax        ; buf
.text:0000000000400567                 mov     edi, 0          ; fd
.text:000000000040056C                 mov     eax, 0
.text:0000000000400571                 call    _read
.text:0000000000400576                 leave
.text:0000000000400577                 retn
.text:0000000000400577 main            endp

0x01 思路

在pwnable.kr上这个题目用ROP和SROP均可以完成,不过有个重要个前提有syscall。这个题目删除了这个gadget,导致题目的难度上升了一个档次。pwnable.kr的writeup在http://weaponx.site/2017/02/28/unexploitable-Writeup-pwnable-kr/

题目给出了libc,看来是让我们用内存泄漏来计算出system/execve等地址来执行system("/bin/sh")。通常内存泄漏最终需要调用类似puts\write等打印函数,然而程序中并没有这些函数。只能通过syscallsyscall_id来调用需要的函数,但是又回到的最初没有syscall的情况。

所以只能寻求一个更有创造性的方法。

0x02 寻找syscall

在libc中搜索\x0f\x0fsyscall的机器码。可以看到在read函数中就有两个gadget。

gdb-peda$ find "\x0f\x05"
...
libc.so.6 : 0x7ffff7b0467e (<read+14>:  syscall)
libc.so.6 : 0x7ffff7b0469b (<read+43>:  syscall)
...
gdb-peda$ print read
$1 = {<text variable, no debug info>} 0x7ffff7b04670 <read>

可以发现read函数中的syscall的距离函数入口的偏移量只有14和43,根据ASLR的原理。可以通过修改GOT表中read函数的LSB(last significant bit,最低有效位)为0x7e或者0x9b就得到了syscall

0x03 how to exploit

第一段payload完成溢出,并调用read将第二段payload写入bss段中,然后利用pop rbp;retleave;ret将栈迁移到bss段上。

第二段payload完成修改GOT表中read的LSB,变为syscall。利用syscall调用write泄漏sleep的地址,计算出/bin/sh\x00的地址pop rdi;ret的地址和system的地址。最后将栈迁移到第三段payload上。

第三段payload,将/bin/sh\x00放入rdi寄存器中,完成system("/bin/sh\x00")

0x04 syscall to system

通过syscall来调用函数必须要将syscall_id放入rax寄存器中,但是经过搜索并没有设置rax相关的gadgets。必须利用函数的返回值来设置raxread函数的返回值是读入字符的个数,所以可以通过调用read函数来设置rax的值。

通过写LSB得到syscallrax的值为1,即可通过syscall调用write来泄漏内存,此时可以通过泄漏内存的字节数来控制raxsleep的返回值是0,所以可以通过调用sleep来将rax置0调用read

所以既可以通过偏移计算system的地址,也可以通过syscallsyscall_id = 59来调用execve

写出exploit后Boom shakalaka!

[+] [sleep base] => [0x7fb74adbe680]
[+] [system] => [0x7fb74ad14102]
[+] [pop rdi ret] => [0x7fb74ad38390]
FINAL!!!
[*] Switching to interactive mode
$ cat /home/unexploitable/flag
FLAG{********************************}
$
[*] Interrupted
[*] Closed connection to chall.pwnable.tw port 10403

0x05 exploit

因为主办方不让公开高分的题目,所以exploit提交到主办方的writeup系统中了,https://pwnable.tw/writeup/20/927

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-03-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 unexploitable
  • 0x01 思路
  • 0x02 寻找syscall
  • 0x03 how to exploit
  • 0x04 syscall to system
  • 0x05 exploit
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档