Skip to content

Commit

Permalink
Added automatic conversion of IP addresses. Allows a more feasible wa…
Browse files Browse the repository at this point in the history
…y to use the cmd line.
  • Loading branch information
crondaemon committed Aug 12, 2013
1 parent e0c3c71 commit 4418b3e
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 166 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Usage

This is the help from dines.

Dines 0.3 - The definitive DNS packet forger.
Dines 0.4 - The definitive DNS packet forger.

Fields with (F) can be fuzzed. (Example --txid F)
Fields with (R) are repeatable. (Example --answer)
Expand Down Expand Up @@ -69,6 +69,10 @@ To generate a question, issue the follogin command:
that asks for domain www.test.com, sending 1 packet only. To generate an answer, one can use the following
command

sudo ./dines --src-ip 192.168.1.1 --dst-ip 192.168.1.2 --question www.google.com,1,1 --num 1 --answer www.google.com,1,1,256,$'\xc0\xa8\01\01' --answer www.google.com,1,1,256,$'\xc0\xa8\01\02'
sudo ./dines --src-ip 192.168.1.1 --dst-ip 192.168.1.2 --question www.test.com,1,1 --num 1 --rdata-ip --answer www.test.com,1,1,256,192.168.1.1 --answer www.test.com,1,1,256,192.168.1.2

The switches related to resource records can be repeated multiple times.
The switches related to resource records can be repeated multiple times. In order to specify IP addresses on
the command line, the user must use the --rdata-ip switch. Otherwise, data will we used as is. This allows
to inject binary data directly, as in the following example

sudo ./dines --src-ip 192.168.1.1 --dst-ip 192.168.1.2 --question www.test.com,NULL,IN --num 1 --answer www.test.com,NULL,IN,0,$'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a'
11 changes: 7 additions & 4 deletions convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ uint16_t stringToQtype(const std::string& s)
if (s == "A") return 1;
if (s == "NS") return 2;
if (s == "CNAME") return 5;
if (s == "NULL") return 10;
if (s == "PTR") return 12;
if (s == "HINFO") return 13;
if (s == "MX") return 15;
Expand All @@ -47,7 +48,7 @@ uint16_t stringToQtype(const std::string& s)
unsigned n = atoi(s.c_str());

if (n > 0xFFFF || n == 0) {
throw runtime_error(string(__func__) + "Invalid qtype");
throw runtime_error(string(__func__) + ": Invalid qtype");
}

return n;
Expand All @@ -62,6 +63,8 @@ string qtypeToString(uint16_t qtype)
return "NS";
case 5:
return "CNAME";
case 10:
return "NULL";
case 12:
return "PTR";
case 13:
Expand All @@ -75,7 +78,7 @@ string qtypeToString(uint16_t qtype)
case 255:
return "ANY";
default:
throw logic_error(string(__func__) + "Invalid qtype");
throw logic_error(string(__func__) + ": Invalid qtype");
}
}

Expand All @@ -91,7 +94,7 @@ uint16_t stringToQclass(const std::string& s)
if (s == "F") return 1;

// Invalid class
throw runtime_error(string(__func__) + "Invalid qclass");
throw runtime_error(string(__func__) + ": Invalid qclass");
}

string qclassToString(uint16_t qclass)
Expand All @@ -110,6 +113,6 @@ string qclassToString(uint16_t qclass)
case 255:
return "ANY";
default:
throw logic_error(string(__func__) + "Invalid qclass");
throw logic_error(string(__func__) + ": Invalid qclass");
}
}
64 changes: 58 additions & 6 deletions dns_packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ DnsPacket::DnsPacket(Dines::LogFunc l)
_fuzzSrcIp = false;
_fuzzSport = false;

_rDataIp = false;

_log = l;

if (_log != NULL)
Expand Down Expand Up @@ -290,25 +292,35 @@ DnsQuestion& DnsPacket::addQuestion(const std::string qdomain, unsigned qtype, u
return _question;
}

ResourceRecord& DnsPacket::addRR(Dines::RecordSection section, const std::string& rrDomain, unsigned rrType,
unsigned rrClass, unsigned ttl, const char* rdata, unsigned rdatalen)
ResourceRecord& DnsPacket::addRR(Dines::RecordSection section, const std::string& rrDomain,
unsigned rrType, unsigned rrClass, unsigned ttl, const char* rdata, unsigned rdatalen)
{
string rd(rdata, rdatalen);
return addRR(section, rrDomain, rrType, rrClass, ttl, rd);
}

ResourceRecord& DnsPacket::addRR(Dines::RecordSection section, const std::string rrDomain,
const std::string& rrType, const std::string& rrClass, const std::string& ttl, const std::string& rdata)
const std::string& rrType, const std::string& rrClass, const std::string& ttl,
const std::string& rdata)
{
unsigned type = stringToQtype(rrType);
unsigned klass = stringToQclass(rrClass);
unsigned int_ttl = atoi(ttl.data());

return addRR(section, rrDomain, type, klass, int_ttl, rdata);
string localrdata = rdata;

if (_rDataIp) {
if (_log)
_log("Converting " + rdata + " to IP address");
uint32_t addr = _convertIP(rdata);
localrdata = string((char*)&addr, 4);
}

return addRR(section, rrDomain, type, klass, int_ttl, localrdata);
}

ResourceRecord& DnsPacket::addRR(Dines::RecordSection section, const std::string& rrDomain, unsigned rrType,
unsigned rrClass, unsigned ttl, const std::string& rdata)
ResourceRecord& DnsPacket::addRR(Dines::RecordSection section, const std::string& rrDomain,
unsigned rrType, unsigned rrClass, unsigned ttl, const std::string& rdata)
{
ResourceRecord rr(rrDomain, rrType, rrClass, ttl, rdata);
return addRR(section, rr);
Expand Down Expand Up @@ -410,6 +422,13 @@ void DnsPacket::txid(uint16_t txid)

void DnsPacket::nRecord(Dines::RecordSection section, uint16_t value)
{
char sect[10];
char val[11];
snprintf(sect, 10, "%u", section);
snprintf(val, 11, "%u", value);
if (_log)
_log("Setting record section " + string(sect) + " to " + string(val));

_dnsHdr.nRecord(section, value);
}

Expand Down Expand Up @@ -487,3 +506,36 @@ void DnsPacket::setLogger(Dines::LogFunc l)
{
_log = l;
}

uint32_t DnsPacket::_convertIP(string rdata)
{
uint32_t addr;
if (inet_pton(AF_INET, rdata.data(), &addr) != 1)
throw runtime_error("Can't convert IP address: " + rdata);
return addr;
}

void DnsPacket::rDataIp()
{
if (_log)
_log("Activating IP conversion");

_rDataIp = true;

uint32_t addr;
for (vector<ResourceRecord>::iterator itr = _answers.begin(); itr != _answers.end();
++itr) {
addr = _convertIP(itr->rData());
itr->rData(string((char*)&addr, 4));
}
for (vector<ResourceRecord>::iterator itr = _authorities.begin(); itr != _authorities.end();
++itr) {
addr = _convertIP(itr->rData());
itr->rData(string((char*)&addr, 4));
}
for (vector<ResourceRecord>::iterator itr = _additionals.begin(); itr != _additionals.end();
++itr) {
addr = _convertIP(itr->rData());
itr->rData(string((char*)&addr, 4));
}
}
8 changes: 8 additions & 0 deletions dns_packet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class DnsPacket {
//! DNS additionals
std::vector<ResourceRecord> _additionals;

uint32_t _convertIP(std::string rdata);

bool _rDataIp;

bool _fuzzSrcIp;

bool _fuzzSport;
Expand Down Expand Up @@ -131,6 +135,10 @@ class DnsPacket {

ResourceRecord& addRR(Dines::RecordSection section, const ResourceRecord& rr);

// Converts existing resource record rdata into IP addresses. Sets also a flag
// for future conversions
void rDataIp();

void fuzz();

void fuzzSrcIp();
Expand Down
Loading

0 comments on commit 4418b3e

Please sign in to comment.