1
- #include < vector>
2
- #include < tuple>
1
+ #include < algorithm>
3
2
#include < fstream>
4
- #include " Windows.h"
5
- #include < psapi.h>
3
+ #include < tuple>
6
4
#include < vector>
7
5
6
+ #include < Windows.h>
7
+ #include < DbgHelp.h>
8
+ #include < winnt.h>
9
+
8
10
using namespace std ;
9
11
10
12
namespace {
@@ -13,26 +15,9 @@ namespace {
13
15
constexpr DWORD invocation_interval_ms = 15 * 1000 ;
14
16
constexpr size_t stack_size = 0x10000 ;
15
17
16
- struct VersionToOffset {
17
- WORD file_version[4 ];
18
- uint32_t relative_offset;
19
- };
20
-
21
- /*
22
- * See https://changewindows.org/ for a detailed Windows 10 release history,
23
- * including updates to milestone releases. A new build of the "mshtml.dll"
24
- * file has not been included with every update.
25
- */
26
-
27
- vector<VersionToOffset> mshtml_gadget_offset_map = {
28
- // Windows 10 Creators Update (Build v10.0.15063.138 as of Apr 11, 2017)
29
- { 11 , 0 , 15063 , 138 , 0x00585068 },
30
- // Windows 10 Creators Update (Build v10.0.15063.0 as of Mar 20, 2017)
31
- { 11 , 0 , 15063 , 0 , 0x00585098 },
32
- // Windows 10 Anniversary Update (Build v10.0.14393.953 as of Mar 14, 2017)
33
- { 11 , 0 , 14393 , 953 , 0x003CBD4D },
34
- // The default ROP gadget offset (for Windows v8.1?)
35
- { 0 , 0 , 0 , 0 , 0x006D55DD }
18
+ vector<vector<uint8_t >> rop_gadget_candidates = {
19
+ { 0x59 , 0x5C , 0xC3 }, // pop ecx; pop esp; ret
20
+ { 0x58 , 0x5C , 0xC3 } // pop eax; pop esp; ret
36
21
};
37
22
38
23
struct SetupConfiguration {
@@ -78,9 +63,8 @@ Workspace& allocate_workspace() {
78
63
}
79
64
80
65
MyTuple allocate_pic (const string& filename) {
81
-
82
66
fstream file_stream{ filename, fstream::in | fstream::ate | fstream::binary };
83
- if (!file_stream) throw runtime_error (" [-] Couldn't open " + filename);
67
+ if (!file_stream) throw runtime_error (" [-] Couldn't open \" " + filename + " \" . " );
84
68
auto pic_size = static_cast <size_t >(file_stream.tellg ());
85
69
file_stream.seekg (0 , fstream::beg);
86
70
auto pic = VirtualAllocEx (GetCurrentProcess (), nullptr , pic_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
@@ -93,92 +77,70 @@ MyTuple allocate_pic(const string& filename) {
93
77
return MyTuple (pic, pic_size);
94
78
}
95
79
96
- uint32_t get_mshtml_gadget_relative_offset (const char *mshtml_filename) {
97
- DWORD version_handle;
98
- auto version_info_size = GetFileVersionInfoSizeA (mshtml_filename, &version_handle);
99
- if (version_info_size == 0 ) throw runtime_error (" [-] Couldn't GetFileVersionInfoSize: " + GetLastError ());
100
-
101
- vector<char > version_data (version_info_size);
102
- auto result = GetFileVersionInfoA (mshtml_filename, version_handle, version_info_size, &version_data[0 ]);
103
- if (!result) {
104
- throw runtime_error (" [-] Couldn't GetFileVersionInfo: " + GetLastError ());
105
- }
106
-
107
- LPBYTE version_info_buffer;
108
- UINT version_info_buffer_size;
109
- result = VerQueryValueA (&version_data[0 ], " \\ " , reinterpret_cast <VOID FAR* FAR*>(&version_info_buffer), &version_info_buffer_size);
110
- if (!result) {
111
- throw runtime_error (" [-] Couldn't VerQueryValue: " + GetLastError ());
112
- }
113
-
114
- auto *version_info = reinterpret_cast <VS_FIXEDFILEINFO *>(version_info_buffer);
115
- WORD unpacked_file_version_words[4 ] = {
116
- (version_info->dwFileVersionMS >> 16 ) & 0xffff ,
117
- (version_info->dwFileVersionMS >> 0 ) & 0xffff ,
118
- (version_info->dwFileVersionLS >> 16 ) & 0xffff ,
119
- (version_info->dwFileVersionLS >> 0 ) & 0xffff };
120
- auto unpacked_file_version = *reinterpret_cast <DWORDLONG *>(unpacked_file_version_words);
121
-
122
- printf (" [ ] Found %s version %d.%d.%d.%d.\n " ,
123
- mshtml_filename,
124
- unpacked_file_version_words[0 ],
125
- unpacked_file_version_words[1 ],
126
- unpacked_file_version_words[2 ],
127
- unpacked_file_version_words[3 ]);
128
-
129
- uint32_t relative_offset = 0 ;
130
- auto using_default = false ;
131
- auto entry_num = 0 ;
132
- while (relative_offset == 0 ) {
133
- auto * version_entry = &mshtml_gadget_offset_map[entry_num];
134
- if (*reinterpret_cast <DWORDLONG *>(version_entry->file_version ) == unpacked_file_version
135
- || *reinterpret_cast <DWORDLONG *>(version_entry->file_version ) == 0 )
136
- relative_offset = version_entry->relative_offset ;
137
- using_default = *reinterpret_cast <DWORDLONG *>(version_entry->file_version ) == 0 ;
138
- ++entry_num;
139
- }
80
+ void * get_system_dll_gadget (const string& system_dll_filename) {
81
+ printf (" [ ] Loading \" %s\" system DLL.\n " , system_dll_filename.c_str ());
82
+ auto dll_base = reinterpret_cast <uint8_t *>(LoadLibraryA (system_dll_filename.c_str ()));
83
+ if (!dll_base) throw runtime_error (" [-] Couldn't LoadLibrary: " + GetLastError ());
84
+
85
+ printf (" [+] Loaded \" %s\" at 0x%p.\n " , system_dll_filename.c_str (), dll_base);
86
+
87
+ auto pe_header = ImageNtHeader (dll_base);
88
+ if (!pe_header) throw runtime_error (" [-] Couldn't ImageNtHeader: " + GetLastError ());
89
+
90
+ auto filtered_section_headers = vector<PIMAGE_SECTION_HEADER>();
91
+ auto section_header = reinterpret_cast <PIMAGE_SECTION_HEADER>(pe_header + 1 );
92
+ for (int i = 0 ; i < pe_header->FileHeader .NumberOfSections ; ++i)
93
+ {
94
+ if (section_header->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
95
+ filtered_section_headers.push_back (section_header);
96
+ printf (" [ ] Found executable section \" %s\" at 0x%p.\n " , section_header->Name , dll_base + section_header->VirtualAddress );
97
+ }
98
+ section_header++;
99
+ };
140
100
141
- if (using_default) {
142
- printf (" [*] WARNING: Unrecognized version, so using default relative offset.\n " );
101
+ for (auto section_header : filtered_section_headers)
102
+ {
103
+ for (auto rop_gadget : rop_gadget_candidates)
104
+ {
105
+ auto section_base = dll_base + section_header->VirtualAddress ;
106
+ vector<uint8_t > section_content (section_base, section_base + section_header->Misc .VirtualSize );
107
+ auto search_result = search (begin (section_content), end (section_content), begin (rop_gadget), end (rop_gadget));
108
+ if (search_result == end (section_content))
109
+ continue ;
110
+
111
+ auto rop_gadget_offset = section_base + (search_result - begin (section_content));
112
+ printf (" [+] Found ROP gadget in section \" %s\" at 0x%p.\n " , section_header->Name , rop_gadget_offset);
113
+ return rop_gadget_offset;
114
+ }
143
115
}
144
- printf (" [ ] %s ROP gadget is at relative offset 0x%p.\n " , mshtml_filename, reinterpret_cast <void *>(relative_offset));
145
116
146
- return relative_offset;
117
+ printf (" [-] Didn't find ROP gadget in \" %s\" .\n " , system_dll_filename.c_str ());
118
+ return 0 ;
147
119
}
148
120
149
- void * get_mshtml_gadget () {
150
- auto mshtml_filename = " mshtml.dll" ;
151
- printf (" [ ] Loading %s.\n " , mshtml_filename);
152
- auto mshtml_gadget_offset = get_mshtml_gadget_relative_offset (mshtml_filename);
153
- auto mshtml_base = reinterpret_cast <uint8_t *>(LoadLibraryA (mshtml_filename));
154
- if (!mshtml_base) throw runtime_error (" [-] Couldn't LoadLibrary: " + GetLastError ());
155
-
156
- printf (" [+] Loaded %s into memory at 0x%p.\n " , mshtml_filename, mshtml_base);
157
- return mshtml_base + mshtml_gadget_offset;
158
- }
159
-
160
- void * get_gadget (bool use_mshtml, const string& gadget_pic_path) {
121
+ void * get_gadget (bool use_system_dll, const string& gadget_system_dll_filename, const string& gadget_pic_path) {
161
122
void * memory;
162
- if (use_mshtml) {
163
- memory = get_mshtml_gadget ();
164
- } else {
165
- printf (" [ ] Allocating memory for %s.\n " , gadget_pic_path.c_str ());
123
+ if (use_system_dll) {
124
+ memory = get_system_dll_gadget (gadget_system_dll_filename);
125
+ }
126
+ if (!use_system_dll || !memory) {
127
+ printf (" [ ] Allocating executable memory for \" %s\" .\n " , gadget_pic_path.c_str ());
166
128
size_t size;
167
129
tie (memory, size) = allocate_pic (gadget_pic_path);
168
- printf (" [ ] Allocated %u bytes for gadget PIC.\n " , size);
130
+ printf (" [+ ] Allocated %u bytes for gadget PIC.\n " , size);
169
131
}
170
132
return memory;
171
133
}
172
134
173
- void launch (const string& setup_pic_path, const string& gadget_pic_path) {
174
- printf (" [ ] Allocating executable memory for %s .\n " , setup_pic_path.c_str ());
135
+ void launch (const string& setup_pic_path, const string& gadget_system_dll_filename, const string& gadget_pic_path) {
136
+ printf (" [ ] Allocating executable memory for \" %s \" .\n " , setup_pic_path.c_str ());
175
137
void * setup_memory; size_t setup_size;
176
138
tie (setup_memory, setup_size) = allocate_pic (setup_pic_path);
177
139
printf (" [+] Allocated %d bytes for PIC.\n " , setup_size);
178
140
179
- auto use_mshtml { true };
141
+ auto use_system_dll { true };
180
142
printf (" [ ] Configuring ROP gadget.\n " );
181
- auto gadget_memory = get_gadget (use_mshtml , gadget_pic_path);
143
+ auto gadget_memory = get_gadget (use_system_dll, gadget_system_dll_filename , gadget_pic_path);
182
144
printf (" [+] ROP gadget configured.\n " );
183
145
184
146
printf (" [ ] Allocating read/write memory for config, stack, and trampoline.\n " );
@@ -225,7 +187,7 @@ void launch(const string& setup_pic_path, const string& gadget_pic_path) {
225
187
226
188
int main () {
227
189
try {
228
- launch (" setup.pic" , " gadget.pic" );
190
+ launch (" setup.pic" , " mshtml.dll " , " gadget.pic" );
229
191
} catch (exception & e) {
230
192
printf (" %s\n " , e.what ());
231
193
}
0 commit comments