SROP 64位-smallest(2017429ctf.ichunqiu)

概述

360春秋杯”国际网络安全挑战赛

Challenge - smallest (pwn 300) - 429 ichunqiu ctf 2017

http://2017429ctf.ichunqiu.com/competition/index

 

64位SROP很好的练习题。

程序分析

millionsky@ubuntu-16:~/tmp/smallest$ objdump -d smallest

 

smallest:     文件格式 elf64-x86-64

 

 

Disassembly of section .text:

 

00000000004000b0 <.text>:

  4000b0:       48 31 c0                xor    %rax,%rax

  4000b3:       ba 00 04 00 00          mov    $0x400,%edx

  4000b8:       48 89 e6                mov    %rsp,%rsi

  4000bb:       48 89 c7                mov    %rax,%rdi

  4000be:       0f 05                   syscall

  4000c0:       c3                      retq   

漏洞利用

3.1 关键点

1. 可以通过发送字节的数量控制read的返回值控制RAX

这里可以利用的系统调用为:

#define __NR_write 1

#define __NR_rt_sigreturn 15

 

2. 如何进行SROP

问题:sigreturn在64位syscall号为15,Signal Frame的大小位0xF8,明显比15要大,如何传输SignalFrame?

 

方案:两次read,第一次传输SignalFrame,第二次设置rax为15

 第一次read时传输的数据格式为

    Return Address or SYS_read

    PlaceHolder for syscall

    SignalFrame

 第二次read时传输的数据格式为(总共15个字节)

    syscall_addr

    7个字节的填充

Syscall gadget

 程序本身有,如果没有,vsyscall中有

3. SROP中RSP的设置

RSP必须设置为一个可写的地址。

栈中的某些数据是指向栈的指针,泄露这些数据可以得到栈的值或一个可写的地址。

l 通过argv[0]和envp获取栈所在的页

int main(int argc, char *argv[], char *envp[])

argv[0]是一个栈地址,指向的是程序的名称;

envp中保存的都是环境变量的地址,都位于栈中;

addr = leak() & 0xfffffffffffffff000

l 通过附加向量的AT_RANDOM/AT_PLATFORM获取RSP的值

附加向量中的AT_RANDOM指示栈中16字节随机数的地址。在栈中位于附加向量的后面,环境字符串的前面。可以通过这个地址计算栈中数据的地址。

AT_PLATFORM位于AT_RANDOM后面,同样可以计算RSP的值。

l SROP指向mprotect系统调用,将.text变为可写的

这样也可以得到一个可写的地址;

特别是EFL头中有程序的入口,通过它可以再次跳转到read gadget。

4. 如何泄露栈中的数据

通过read控制RAX的值为1(SYS_write),进而调用write系统调用。

3.2 思路1

1. Sigreturn

Read返回值控制EAX,设置为sigreturn的系统调用号0x0f

栈溢出,发送Signal Frame,执行sigreturn系统调用;

Sigreturn设置RSP指向ELF header中的entry point

2. Mprotect

sigreturn执行mprotect系统调用,将text段设置为RWX

3. read gadget

通过Entry point再次执行read gadget

4. Shellcode

read读取shellcode放入栈中,执行shellcode

3.3 思路2

1. Write泄露envp,获取栈地址

2. Sigreturn设置RSP为获取的地址,RIP设置为read gadget

3. Read gadget发送Signal Frame和/bin/sh

4. Sigreturn执行execve系统调用

3.4 思路3

1. Write泄露auxv AT_RANDOM/AT_PLATFORM,获取栈地址

2. Read gadget发送Signal Frame和/bin/sh

3. Sigreturn执行execve系统调用

EXP1

1. Sigreturn&mprotect&设置RSP

Sigreturn设置RSP指向ELF header中的entry point

RIP: 400c0(sys_read(pg)执行完毕)

+1

Return addr
addr_of_sys_read(1)

 

+2

PlaceHolder

 'A' * 8

+3

Signal Frame

 

+4

 '\n'

 

 

RIP: 400c0(sys_read(1)执行完毕)
发送了0x0f个字节,即sys_sigreturn

+2

Return addr
addr_of_syscall

sigreturn

+3

Signal Frame

前7个字节被覆盖为6个\x11和1个\n

+4

 '\n'

 

 

2. 通过Entry point再次执行read gadget

RIP: 400c0(sys_sigreturn&mprotect执行完毕)
  RSP=elf_hdr_addr+0x18

N+0
0x400018

Return addr
addr_of_sys_read(2)

 

N+1

 

 

 

3. 传输并执行shellcode

RIP: 400c0(sys_read(2)执行完毕)

N+1
0x40020

Return addr
shellcode_addr

 0x400028

N+1
0x40028

 shellcode

 

 

0x0a

 

EXP2

代码来自http://anciety.cn/2017/04/21/2017429ctf-smallest-writeup/

见附件

 

1. 泄露argv[0]

RIP: 400c0(sys_read(pg)执行完毕)

+0

Return addr

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值