DNS Query poisoning Application UDP socket descriptor
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
eglibc (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
Problem Description:
When DNS query is fired from ubuntu (14.04) it uses random source port to send outgoing DNS request. It has been observed that random source port is not being checked if the port is already in use by other user application. As a result When DNS server sends the response, response is received by user application which may cause corruption/security issues in the application code.
To make the problem easily reproducible we have increased few system limits to create 25000 UDP servers so that UDP port conflict with DNS happen frequntly
Steps to Reproduce problem:
=======
Step 1. Increase limit
Per-User Limit
Open file: /etc/security/
Paste following towards end:
* hard nofile 500000
* soft nofile 500000
root hard nofile 500000
root soft nofile 500000
System-Wide Limit
Set this higher than user-limit set above.
Open /etc/sysctl.conf
Add following:
fs.file-max = 2097152
Step 2. Reboot ubuntu
Step 3. Verify new limits
Use following command to see max limit of file descriptors:
#cat /proc/sys/
Hard Limit
#ulimit -Hn
Soft Limit
#ulimit -Sn
Step 4. Put following code in server.c and compile it (gcc server.c -o server). This will bind 25K UDP ports.
/*
* server.c
*
* Author: Vipin Kumar Gahlaut
*
* CoreEmbedded Technologies Pvt Ltd
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#define MAX_CONNECTIONS 25000
#define MAX_IP_STR 16
#define MAX_EPOLL_
int setup_udp_
{
int sock;
struct sockaddr_in saddr;
saddr.
saddr.sin_port = htons (port);
saddr.
if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
{
return -1;
}
if (bind (sock, (struct sockaddr *)&saddr, sizeof (saddr)) < 0)
{
close (sock);
return -1;
}
return sock;
}
int main (int argc, char *argv[])
{
char ip[MAX_IP_STR];
char buf[1024];
int efd,sfd,nfds;
struct epoll_event ev,*events;
int i=0,len;
struct sockaddr_in saddr;
socklen_t addrlen=
if(argc < 2)
{
exit(0);
}
if(
{
exit(0);
}
strcpy(
if((efd = epoll_create1(0)) < 0)
{
exit(0);
}
for(i=0; i<MAX_CONNECTIONS; i++)
{
{
}
ev.events = EPOLLIN | EPOLLET | EPOLLERR;
ev.data.fd = sfd;
if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &ev) < 0)
{
}
if (getsockname(sfd, (struct sockaddr *)&saddr, &addrlen ))
{
}
printf("FD: %d Port: %d Number of active servers: %d\n",sfd, ntohs(saddr.
}
events = (struct epoll_event *)malloc(
if(events == NULL)
{
exit(0);
}
while(1)
{
nfds = epoll_wait(efd, events, MAX_EPOLL_
if (nfds < 0)
{
}
for(i = 0; i < nfds; i++)
{
if (getsockname(
{
}
{
len = recvfrom(
}
}
}
close(efd);
return 0;
}
Step 5. Run server program by providing IP address of machine (example ./server 192.168.0.2)
Step 6. User following shell script in another terminal to initiate DNS queries
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 100 ]; do
nslookup www.ubuntu.com
done
Step 7. Observe that sometime DNS response is received by ./server instead of DNS client
Problem Analysis: We have observed on wireshark that when problem happens source port used by DNS client/resolver library etc is one of the source port on which user application (in this case server) is already bind on that port and using it.
This is a big concern because it causes problem both in DNS client (times out) and user application received spurious data. To my opinion this is a security issue as I am receiving data on a port that I have not exposed to anybody and depending on data it my crash/hijack my application. So I am also marking this bug as a security vulnerability so that security team can better asses the situation.
Please note that With small number of UDP server chances of port conflict reduces but does not eliminate problem. DNS clinet/resolver library must have checked if source port is already in use or better to bind on port 0 (zero) so that system allocates available port not just random port. DNS client need to use random **available** port not just a random port.
ProblemType: Bug
DistroRelease: Ubuntu 14.04
Package: libc6-dev 2.19-0ubuntu6
ProcVersionSign
Uname: Linux 3.13.0-24-generic i686
ApportVersion: 2.14.1-0ubuntu3
Architecture: i386
CurrentDesktop: Unity
Date: Sat Apr 25 13:03:30 2015
InstallationDate: Installed on 2014-05-20 (339 days ago)
InstallationMedia: Ubuntu 14.04 LTS "Trusty Tahr" - Release i386 (20140417)
SourcePackage: eglibc
UpgradeStatus: No upgrade log present (probably fresh install)
summary: |
- DNS Query causes corruption on other UDP sockets used by user - application due to source port reuse + DNS Query poisoning Application UDP socket descriptor |
information type: | Private Security → Public |