Inspiration
During my research on RSA cryptography and the importance of a truly random number for having a large key-space, I stumbled on to FakeNameGenerator.com. I thought the concept could be really useful for certain applications and could easily envision how to implement it in C#, and make it extensible/customizable.
Take a look at these:
<?xml version="1.0" standalone="yes"?>
<DocumentElement>
<Order>
<Date>3/18/2005</Date>
<TrackingNumber>1Z 8A8 238 01 9398 182 1</TrackingNumber>
<FirstName>Keaton </FirstName>
<LastName>Day</LastName>
<StreetAddress>4828 Cherry St.</StreetAddress>
<City>Nanticoke</City>
<State>SC</State>
<Zip>89130</Zip>
<Email>HaleHale8026@mail.com</Email>
<Phone>425-765-4520</Phone>
</Order>
<Payroll>
<PhoneNumber>971-258-5703</PhoneNumber>
<AltPhoneNumber>501-769-1331</AltPhoneNumber>
<FirstName>Xyla </FirstName>
<LastName>Hoover</LastName>
<EmployeeID>499</EmployeeID>
<HireDate>5/28/2011</HireDate>
<Birthdate>5/28/1990</Birthdate>
<SSN>520-52-4275</SSN>
<AccountNumber>5696618825</AccountNumber>
<RoutingNumber>575159859</RoutingNumber>
<Address>8348 Court Ave.</Address>
<City>Pittsburgh,</City>
<State>PA.</State>
<Zip>15201</Zip>
</Payroll>
CREATE TABLE ReservationData (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`UniqueID` MEDIUMINT default NULL,
`TripDate` varchar(50) default NULL,
`FirstName` varchar(255) default NULL,
`LastName` varchar(255) default NULL,
`Phone` varchar(100) default NULL,
`AltPhone` varchar(100) default NULL,
`Email` varchar(255) default NULL,
`StreetAddress` varchar(255) default NULL,
`City` varchar(50) default NULL,
`State` varchar(50) default NULL,
`Zip` varchar(10) default NULL,
`Country` varchar(255) default NULL,
`DayOfYear` varchar(50) default NULL,
`TotalCost` varchar(50) default NULL,
`Balance` varchar(10) default NULL,
`CCard` varchar(18) default NULL,
`Expires` varchar(5) default NULL,
`CVC2` varchar(3) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1;
This would make great honey for a honey pot; just fill an SQL database with this random, realistic looking data, serve and log any and all attempts to access, query or dump the database. This can be done on a VM and you have a easily deployed, high interaction honeypot!
Aside from being able to see their IP address, I think the most useful data that can be attained is their behavior; what injection attacks are they using to drop the database? Write rules to prevent your honey against trivial attempts such as the ' AND 1=(SELECT attacks and see what they come up with next. Rule writing is inherently a cat-and-mouse game, honeypots like this clearly give the white-hats the upper hand.
Implementation
A quick, fast and dirty solution is to simply read a random line from a text file (i.e. Name_First.txt and Address_Street.txt).
This way, you can choose from names that are common, or customize your list to for different nationalities.
One could read the whole file in to a string, Parse() it into an array of strings, then randomly select an index, but this would be unacceptable for very large files. Instead, we can set the file pointer to a random position that is less than its size, roll back to the last new line and call ReadLine.
public string ReturnRandomLine(string FileName)
{
string sReturn = string.Empty;
using(FileStream myFile = new FileStream(FileName,FileMode.Open,FileAccess.Read))
{
using(StreamReader myStream = new StreamReader(myFile))
{
// Seek file stream pointer to a rand position...
myStream.BaseStream.Seek(rand.Next(1,myFile.Length),SeekOrigin.Begin);
// Read the rest of that line.
myStream.ReadLine();
// Return the next, full line...
sReturn = myStream.ReadLine();
}
}
// If our random file position was too close to the end of the file, it will return an empty string
// I avoided a while loop in the case that the file is empty or contains only one line
if(System.String.IsNullOrWhiteSpace(sReturn)) {
sReturn = ReturnRandomLine(FileName);
}
return sReturn;
}
Example use:
public string GenerateFistName()
{
return ReturnRandomLine("Name_First.txt") + " ";
}
public string GenerateLastName()
{
return ReturnRandomLine("Name_Last.txt");
}
public string GenerateFullName()
{
return GenerateFistName() + GenerateLastName();
}
public string GenerateGender()
{
if(ReturnPercent(84)) {
return "Male";
} else {
return "Female";
}
}
public string GenerateStreetNumber()
{
return rand.Next(1,9999).ToString();
}
public string GenerateStreetName()
{
return ReturnRandomLine("Address_Street.txt");
}
One limitation is where the data is relational, such as in the case of generating a random zip code along with the city and state that it exists in.
A quick work-around would be CityZipState.txt
Other types of data that can be generated that would not make sense to put in a text file:
public bool ReturnPercent(int Percent) // Return true Percent times out of 100, randomly
{
int iTemp = rand.Next(1,101);
if(iTemp<=Percent) {
return true;
} else {
return false;
}
}
public string GenerateDate(int YearFrom,int YearTo)
{
int Month = rand.Next(1,13);
int Day = rand.Next(1,32);
int Year = GenerateYear(YearFrom,YearTo);
return Month.ToString() + "/" + Day.ToString() + "/" + Year.ToString();
}
public string GenerateYear(int YearFrom,int YearTo)
{
return rand.Next(YearFrom,YearTo+1).ToString();
}
public string GeneratePhoneNumber()
{
return GeneratePhoneNumber(ReturnRandomLine("PhoneNumber_Prefix.txt"));
}
public string GeneratePhoneNumber(string Prefix)
{
int iThree = rand.Next(192,999);
int iFour = rand.Next(1000,9999);
return Prefix + iThree.ToString() + "-" + iFour.ToString();
}
public string GenerateSSN()
{
int iThree = rand.Next(132,921);
int iTwo = rand.Next(12,83);
int iFour = rand.Next(1423,9211);
return iThree.ToString() + "-" + iTwo.ToString() + "-" + iFour.ToString();
}
Obviously, these methods can be improved to conform to the standards of a real social security number, national identification number, credit card number, ect...
public string GenerateCCNum()
{
string sCCNum = string.Empty;
byte[] bCCNum = {0};
rand.NextBytes(bCCNum);
// generate random 16 digit number
int iTemp1 = rand.Next(10000000,99999999);
int iTemp2 = rand.Next(10000000,99999999);
string sTemp = iTemp1.ToString() + iTemp2.ToString();
// while loop?
while(!IsValidNumber(sTemp))
{
iTemp1 = rand.Next(10000000,99999999);
iTemp2 = rand.Next(10000000,99999999);
sTemp = iTemp1.ToString() + iTemp2.ToString();
}
sCCNum = sTemp;
return sCCNum;
}
The implementation of IsValidNumber() is left as an exercise for the reader.
The serialization of your data is a trivial matter. Please see my post on a XML Serializable Dictionary, Tuple, and Object for the code to serialize an object (such as a list, or a class).