<<基本ROP_ropemporium pivot + ret2csu

代码:https://github.com/Finsenty54/attack-code/tree/master/ROPemporium

命令

objdump -T libpivot32.so 查看所有符号
rabin2 -E ./libpivot.so 也可以查看
 -E              globally exportable symbols
objdump -j .text -d ./ret2csu
objdump -x ret2csu
gef➤  search-pattern 0x4004d0 查询含有0x4004d0 的地址

知识点

https://ctf-wiki.org/pwn/linux/stackoverflow/stack-intro/#_4

需要注意的是,32 位和 64 位程序有以下简单的区别

x86
函数参数在函数返回地址的上方
x64
System V AMD64 ABI (Linux、FreeBSD、macOS 等采用) 中前六个整型或指针参数依次保存在 RDI, RSI, RDX, RCX, R8 和 R9 寄存器中,如果还有更多的参数的话才会保存在栈上。
内存地址不能大于 0x00007FFFFFFFFFFF,6 个字节长度,否则会抛出异常。

pivot

stack pivot
To “stack pivot” just means to move the stack pointer elsewhere.

用命令可以发现
10 0x0000077d 0x0000077d GLOBAL FUNC 43 foothold_function
18 0x00000974 0x00000974 GLOBAL FUNC 164 ret2win
偏移量为1F7

stack smash
EBP-0X28
可以写入0x38
40+4 溢出到返回地址

0x080487b4 ff7508 push dword [arg_8h]
第一次写入的地方是指针,我看错了,以为直接写入arg_8h处,这里放第二段较长的ROP链

大体思路:先调用一次foothold,将got表项的内容加载进寄存器,而不是表项地址,加上ret2win的偏移,调用

ret2rsu

在 64 位程序中,函数的前 6 个参数是通过寄存器传递的,但是大多数时候,我们很难找到每一个寄存器对应的 gadgets。

参数

ret2win 的三个参数放在
│ ; arg uint32_t arg1 @ rdi
│ ; arg uint32_t arg2 @ rsi
│ ; arg uint32_t arg3 @ rdx

查看__libc_csu_init代码

objdump -j .text -d ./ret2csu

0000000000400640 <__libc_csu_init>:
  400640:    41 57                    push   %r15
  400642:    41 56                    push   %r14
  400644:    49 89 d7                 mov    %rdx,%r15
  400647:    41 55                    push   %r13
  400649:    41 54                    push   %r12
  40064b:    4c 8d 25 9e 07 20 00     lea    0x20079e(%rip),%r12        # 600df0 <__frame_dummy_init_array_entry>
  400652:    55                       push   %rbp
  400653:    48 8d 2d 9e 07 20 00     lea    0x20079e(%rip),%rbp        # 600df8 <__do_global_dtors_aux_fini_array_entry>
  40065a:    53                       push   %rbx
  40065b:    41 89 fd                 mov    %edi,%r13d
  40065e:    49 89 f6                 mov    %rsi,%r14
  400661:    4c 29 e5                 sub    %r12,%rbp
  400664:    48 83 ec 08              sub    $0x8,%rsp
  400668:    48 c1 fd 03              sar    $0x3,%rbp
  40066c:    e8 5f fe ff ff           callq  4004d0 <_init>
  400671:    48 85 ed                 test   %rbp,%rbp
  400674:    74 20                    je     400696 <__libc_csu_init+0x56>
  400676:    31 db                    xor    %ebx,%ebx
  400678:    0f 1f 84 00 00 00 00     nopl   0x0(%rax,%rax,1)
  40067f:    00 
  400680:    4c 89 fa                 mov    %r15,%rdx
  400683:    4c 89 f6                 mov    %r14,%rsi
  400686:    44 89 ef                 mov    %r13d,%edi
  400689:    41 ff 14 dc              callq  *(%r12,%rbx,8)
  40068d:    48 83 c3 01              add    $0x1,%rbx
  400691:    48 39 dd                 cmp    %rbx,%rbp
  400694:    75 ea                    jne    400680 <__libc_csu_init+0x40>
  400696:    48 83 c4 08              add    $0x8,%rsp
  40069a:    5b                       pop    %rbx
  40069b:    5d                       pop    %rbp
  40069c:    41 5c                    pop    %r12
  40069e:    41 5d                    pop    %r13
  4006a0:    41 5e                    pop    %r14
  4006a2:    41 5f                    pop    %r15
  4006a4:    c3                       retq   
  4006a5:    90                       nop
  4006a6:    66 2e 0f 1f 84 00 00     nopw   %cs:0x0(%rax,%rax,1)
  4006ad:    00 00 00 

直接用ROPgadget搜有些代码搜不到的

使用

要使用ret2csu
就需要绕过call
这是[ ]指针,需要解引用,即调用函数

objdump -x ret2csu

 10 .init         00000017  00000000004004d0  00000000004004d0  000004d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .plt          00000030  00000000004004f0  00000000004004f0  000004f0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .text         00000192  0000000000400520  0000000000400520  00000520  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .fini         00000009  00000000004006b4  00000000004006b4  000006b4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

可以看到一共有四块代码
选择.init

┌─[zentreisender@parrotos]─[~/Documents/ret2csu]
└──╼ $objdump -j .init -d ./ret2csu 

./ret2csu:     file format elf64-x86-64


Disassembly of section .init:

00000000004004d0 <_init>:
  4004d0:    48 83 ec 08              sub    $0x8,%rsp
  4004d4:    48 8b 05 1d 0b 20 00     mov    0x200b1d(%rip),%rax        # 600ff8 <__gmon_start__>
  4004db:    48 85 c0                 test   %rax,%rax
  4004de:    74 02                    je     4004e2 <_init+0x12>
  4004e0:    ff d0                    callq  *%rax
  4004e2:    48 83 c4 08              add    $0x8,%rsp
  4004e6:    c3                       retq   

gdb-ref
gef➤ search-pattern 0x4004d0

  0x600e38 - 0x600e44  →   "\xd0\x04\x40[...]" 

同时rbx=0 rbp=1

csu代码片段使用了两次