Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2017-0261 — CVE-2017-8570 Exp及利用样本分析 | Kitploit
Tools/GitHubGitHub/erfze/cve-2017-0261
Vulnerability AnalysisExploitationMalware AnalysisPapers & ResearchLearning & EducationBinary Exploitation
GitHuberfze/cve-2017-0261

CVE-2017-0261

CVE-2017-8570 Exp及利用样本分析

View Repository
106 years agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2017-0261 and Exploit Sample Analysis

0x01 Vulnerability Description

  • Cause: When opening an Office document, FLTLDR.EXE is used to render an embedded EPS file containing the vulnerability. The file is written in PostScript language and can be exploited by an attacker through a "save-restore" operation, essentially a UAF vulnerability. The vulnerability can be exploited when a user opens a file containing a malformed graphic image, or when a user inserts a malformed graphic image into an Office file.

  • Affected versions: Microsoft Office 2010 Service Pack 2, Microsoft Office 2013 Service Pack 1, Microsoft Office 2016

  • POC: kcufId's Github

0x02 POC Analysis

The author searched online for a long time and did not find an Office installation package containing EPSIMP32.FLT. Fortunately, Master kcufId provided a LoadEps.exe to load EPS files. Thanks to Master kcufId.

LoadEps.exe first loads EPSIMP32.FLT:

Image 1 Loading EPSIMP32.FLT

Then calls ImportGr to start loading the EPS file:

Image 2 ImportGr

Directly press F7 to follow here, and then you can successfully break at the breakpoint set within EPSIMP32.FLT.


Before getting into the main topic, let's first lay out the PostScript object structure.

// PostScript Object
struct PostScript object
{
    dword    type;
    dword    attr;
    dword    value1;
    dword    value2;    // if array, point to userdict where store the array object
}ps_obj;

The corresponding values for different type are as follows:

0x0       	nulltype
0x3       	integertype
0x5       	realtype
0x8       	booleantype
0x10      	operatortype
0x20      	marktype
0x40      	savetype
0x300     	nametype
0x500     	stringtype
0x900     	filetype
0x30000   	arraytype          
0x0B0000 	packedarraytype
0x70000 	packedarraytype
0x110000  	dicttype
0x210000  	gstatetype

Taking strings as an example, we elaborate on their storage structure. By setting a breakpoint on the forall function, you can further examine how it handles strings (for how to locate the forall function, refer to https://paper.seebug.org/368/).

Image 3 String Storage Structure

Image 1 corresponds to ps_obj, and its value2 field points to the corresponding item in the index list (Image 2); the index item points to a structure of size 0x30. At offset 0x24 of this structure is a pointer to a pointer to a structure of size 0x28 (Image 5), and at offset 0x2C is the string size (Image 3); in the structure of Image 5, offset 0x4 stores the address of the corresponding item in the index list for this structure (i.e., 0x01DB5E94 from Image 4), offset 0x20 points to the final storage location of the string (Image 6), and offset 0x24 is the actual memory size occupied — string size + 1.

Structure of size 0x30:

+0x0  dword   
+0x4  dword
+0x8  dword
+0xc  dword
+0x10 dword
+0x14 dword
+0x18 dword
+0x1c dword
+0x20 dword
+0x24 dword   pp_struct      // pointer to pointer to structure of size 0x28
+0x28 dword 
+0x2c dword   size           // actual string size

Structure of size 0x28 (for arrays, this structure has size 0x2C, and offset 0x28 points to array elements, each being ps_obj):

+0x0  dword
+0x4  dword					// stores the address of the corresponding item in the index list for this structure
+0x8  dword
+0xc  dword
+0x10 dword
+0x14 dword
+0x18 dword
+0x1c dword
+0x20 dword  ptr_object 	// points to the final storage location of the string
+0x24 dword  size      		// actual memory size occupied, actual string size + 1

First trigger of the vulnerability:

Image 4 First Trigger

First, the VM state is saved in variable l62. Then, for each character in variable l63, the processing procedure l61—>>l59—>>l56 is called; l62 restore restores the previous state. As a result, the memory space allocated by l63 after the /l62 save def statement is freed, becoming a dangling pointer.

Image 5 l95-l99

Variables l95-l99 determine the subsequent flow, and their values are all 0 (i.e., 32-bit):

Image 6 exch_proc

Second trigger of the vulnerability: first, memory space of size 0x27 (actually occupying 0x28) is allocated to store l63:

Image 7 l63

Then l62 restore restores the previous state, causing the memory space allocated by l63 to be freed, becoming a dangling pointer; next, l100 is executed, and the memory space previously occupied by l63 is used to store the 0x28 structure of the l102 (i.e., l136) string (this explains why l63 allocates memory of size 0x27):

Image 8 l102

Retrieve the values at offsets 0x4, 0x20, and 0x24 of this structure respectively:

Image 9 Retrieve Values

Finally, modify the content of the l136 string (the image only shows part of the modifications):

Image 10 Constructed String

These modifications are carefully constructed and will be used during the third trigger of the vulnerability.

Third trigger of the vulnerability: allocate an array containing 0x37 elements, then execute l62 restore when looping to the 0x34th element:

Image 11 Third Trigger Flow

After executing restore, the 0x30 structure of the array is overwritten with the content of the l193 string:

Image 12 Overwrite Content

Thus, the object executed in the last (0x36) forall process becomes the 0x30 structure in the image above, and retrieving its 0x36th element leads to the carefully constructed string from the second vulnerability trigger:

Image 13 Retrieve Array Element

The retrieved array element is an array of size 4, and the first element of that array is a string with a starting address of 0 and a size of 0x7FFFFFFF:

Image 14 Array Element Content

This array is stored in variable l159, and its first element — the string with start address 0 and size 0x7FFFFFFF — is stored in variable l201. After that, any address's value can be obtained via variable l201.

Obtain kernel32.dll base address:

Image 15 Get Base Address-1

Download Tool