Tuesday, June 28, 2011

This is cool.

http://code.google.com/p/disruptor/

Disruptor - Concurrent Programming Framework



They claim a lot, would like to test.

Saturday, May 21, 2011

New OpenDiagnostics Live CD Release :: 394 MB

Removed wine, stupid idea to put on there.


Added mc, lftp, mdadm, a few others I can't remember off the top of my head.
Updated ClamAV to 0.97 and virus defs are good as of today.
Updated metasploit to latest SVN head
Updated kernel to latest and lucid is fully updated.

Download Here

I have been doing a lot of research into AutoIt scripting lately, as it would help tremendously at the repair shop. I have written up a few scripts to automate a few common chores such as msconfig'ing, fixing up performance options, and am in the process of writing a driver backup and general backup script. I hope to include these with some sort of easy way to use them on the root of the CD. The scripts will be compiled to executables, but the scripts will of course be made available, possibly in a google code repo. If you have any suggestions on what type of scripts you would like, or concerns about this possible change, feel free to express them in the comments

Wednesday, April 27, 2011

Fun finding things

I found a neat way to use find today. If you want to do an inverse search (think grep -v, but in find), simply use '!'. For Example:


find . '!' -name '*.zip'


Find all files that don't end in .zip.

Tuesday, February 8, 2011

OpenVAS 4 has landed in UNSTABLE in OBS

Add this to your sources.lst:

deb http://download.opensuse.org/repositories/security:/OpenVAS:/UNSTABLE:/v4/xUbuntu_10.10/ ./


Then you need to get the key and add it to apt:


wget http://download.opensuse.org/repositories/security:/OpenVAS:/UNSTABLE:/v4/xUbuntu_10.10/Release.key
apt-key add Release.key
rm Release.key


Then just
apt-get update

Tuesday, February 1, 2011

Non-trivial key names

It seems that you run into instances where someone working with the registry doesn't know quite how to use it. Well, let's start with some code first.

Say we have a regex to carve out the data we want:

Regex nk = new Regex(@"nk[\x2c|\x20]\x00.{7}\x01.{117}");

Chances are this data chunk will have a lot of junk at the end. Most key names as far as I can tell under < 65 characters long, but there are instances where a name legitimately runs longer than that. Here is one example:


It's not a root key!
Offset to Parent: 4145008
Number of Subkeys: 0
Offset to Subkey LF Blocks: 1061109567
Number of values: 1
Offset to value list: 4144959
Offset to security key: 7421704
Offset to classname: 1061109567
Offset to ?trash?: 1634757999
Name Length: 58 bytes
Classname Length: 0
Partial Name: C:|WINDOWS|Microsoft.NET|Framework|v3.5|AddInProcess3
Name: C:|WINDOWS|Microsoft.NET|Framework|v3.5|AddInProcess3

It's not a root key!
Offset to Parent: 4144959
Number of Subkeys: 0
Offset to Subkey LF Blocks: 1061109567
Number of values: 1
Offset to value list: 4144992
Offset to security key: 1061109592
Offset to classname: 4156278
Offset to ?trash?: 1231316033
Name Length: 20590 bytes
Classname Length: 28530
Partial Name: cess32,version="3.5.0.0",publicKeyToken="b77a5c561934


The first node key name has a length of 58 bytes. Pretty normal. But the second node key has a name 20590 bytes long. It also has to do with the .NET Framework. (*sigh* Microsoft...)

I can't carve out 20000 byte long chunks for each key node to satisfy the needs of names that shouldn't really be names, that would be crazy. It just so happened that this name was throwing an IndexOutOfrangeException. I decided I could use this to my advantage.

I could pick a sane number for the size of the regex that would get 90% of my key names and simply work around the longer names (in the short term at any rate).

My code ended up looking like this:


else if (i == (int)0x0048) //name length
{
byte[] lengthBytes = new byte[dword]; //should only be a word length. not sure why I need to make this dword

for (int k = 0;k<word;k++)
{
lengthBytes[k] = bs[i+k];
}

nameLength = BitConverter.ToInt32(lengthBytes, 0);

Console.WriteLine(String.Format("Name Length: {0} bytes", nameLength.ToString()));

i += word;
}

... //other else if's here

else if (i == (int)0x004C) //key name
{
int length = nameLength;

char[] blah = new char[length];

for (int k = 0; k < length;k++)
{
try
{
blah[k] = (char)bs[i+k];
}
catch(Exception ex)
{
//sometimes you get stupid long names (someone not know inghow the registry works)
//when this happens, we will just read what we can and return what we get. Doesn't have to
//be perfect since we can load the full name at a later time when the user clicks the list item
//for most names, this won't be needed.
if (ex.GetType() == typeof(IndexOutOfRangeException))
{
Console.WriteLine("Partial Name: " + new string(blah));

i += bs.Length - i;
k = length;

continue;
}
else
throw ex;

}
}

Console.WriteLine("Name: " + new string(blah));

i += bs.Length - i; //we are done.
}


I figure for a list of values, you won't be showing more than 100 or so characters until you pick the specific key out of the list and it loads the full details. At that point you can read the entire name and show it to the full user.

Monday, January 31, 2011

Windows Registry with Mono, pt2 - Node Keys

I have had a bit more time on my hands to work on being able to read the registry without using advapi32.dll. Today I was able to hack up a small (incomplete) class for node keys that builds the framework for breaking apart and manipulating the data.

To start off, from this file, we can get the offsets we need to read to get the right data.


the nk-Record
=============

Offset Size Contents
0x0000 Word ID: ASCII-"nk" = 0x6B6E
0x0002 Word for the root-key: 0x2C, otherwise 0x20
0x0004 Q-Word write-date/time in windows nt notation
0x0010 D-Word Offset of Owner/Parent key
0x0014 D-Word number of sub-Keys
0x001C D-Word Offset of the sub-key lf-Records
0x0024 D-Word number of values
0x0028 D-Word Offset of the Value-List
0x002C D-Word Offset of the sk-Record
0x0030 D-Word Offset of the Class-Name
0x0044 D-Word Unused (data-trash)
0x0048 Word name-length
0x004A Word class-name length
0x004C ???? key-name


It's pretty straight forward. In every fragment, we can go to specific offsets and get the data we want. This ends up looking like this:


public NodeKey (string data)
{
ASCIIEncoding enc = new ASCIIEncoding();

byte[] bs = enc.GetBytes(data);

//the lengths we will be working with.
int word = 2;
int dword = word+word; //double word
int qword = dword+dword; //quad word

for (int i = 0; i < bs.Length;)
{
//making sure it is nk
if (i == (int)0x0000) //header
{
if ((int)bs[0] == 110)
{
if ((int)bs[1] == 107)
{
i += word;
continue;
}
else
{
throw new Exception("This may be a damaged nk block. If so, fix the header and try again.");
}
}
else
{

throw new Exception("Not a nk");
}
}

else if (i == (int)0x0002) //is it a root key?
{
if (bs[i] == (byte)0x2C)
{
//It's a root key!
Console.WriteLine("It's a root key!");

}
else
{
//it's not a root key!
Console.WriteLine("It's not a root key!");
}

i += word; //move up 2 elements
continue;
}

else if (i == (int)0x0004) //timestamp in long smb form blegh
{
byte[] blah = new byte[qword];
for (int k = 0;k<qword;k++)
{
blah[k] = bs[i+k];
}

i+= qword;
}
else if (i == (int)0x0010) //offset to parent
{
i += dword;
}
else if (i == (int)0x0014) //number of subkeys
{
i += dword;
}
else if (i == (int)0x001C) //offset to subkey lf blocks
{
i += dword;
}
else if (i == (int)0x0024) //number of values
{
i += dword;
}
else if (i == (int)0x0028) //offset of value list
{
i += dword;
}
else if (i == (int)0x002C) //offset to the sk block
{
i += dword;
}
else if (i == (int)0x0030) //offset to classname
{
i += dword;
}
else if (i == (int)0x0044) //this is trash supposedly
{
i += dword;
}
else if (i == (int)0x0048) //name length
{
i += word;
}
else if (i == (int)0x004A) //class name length
{
i += word;
}
else if (i == (int)0x004C) //key name
{
int length = bs.Length - i;

char[] blah = new char[length];

for (int k = 0; k < length;k++)
{
blah[k] = (char)bs[i+k];
}

Console.WriteLine(blah);

i += length; //we are done.
}
else i+= word; //debugging purposes
}
}



If you notice, however, my code is not complete. I am starting with the most useful stuff first and moving on that way. A more complete class will keep the key name length in a local variable and use that instead of bs.Length when reading the key name later. With the current implementation, I read in too many bytes and grab some extra key headers :-/. You could create properties that are privately set and publicly get'able and set the properties to their respective values, to make it truly object oriented.

Another thing to point out is i is being incremented by the length read each time. It isn't arbitrary. This way next go around we are at the offset we need to be at.

One thing I look forward to implementing is lazy loading of parents and children. If you would like to test this, class, you can see my previous post on initially reading and deciphering the windows registry in C#. Just use this in your for loop instead:


foreach (Match mx in nk.Matches (d)) {

all++;
NodeKey key = new NodeKey(mx.Value);
}

Wednesday, January 5, 2011

Analyzing the Windows NT registry without advapi32.dll using Mono (PoC)

I have been doing some challenges for a contest and one requires analyzing a set of Windows NT registry hives. Regedit really sucks (though it does run in wine). I decided it would be more fun to write a small library that can read the registry hives without relying on p/invoke and advapi32.dll on Windows. I have some small code that carves out the data I need, though I am running into a problem on the software hive supplied. Maybe someone can point me in the right direction.

A lot of my information came from this text file which I found, and have updated some with information that I found missing.

As far as I can tell, there are 6 data types to be carved out of the hives. regf file headers, hbin blocks, node keys, value keys, and lf/h (lh on XP) blocks. There are also security keys (with a sk header) within node keys. The following regex's should carve out the data from the registry files so you may parse out the information you need.


Regex regf = new Regex (@"^regf.{508}");
Regex nk = new Regex (@"nk[\x2c|\x20]\x00.{7}\x01.{64}");
Regex vk = new Regex (@"vk.{3}\x00\x00[\x00|\x80].{64}");
Regex hbin = new Regex (@"hbin.{4}\x00\x10\x00\x00.{8}");
Regex lf = new Regex (@".{4}l[f|h][0-65535].{8}"); //lf or lh on winxp


But in order to search the hive, we need to read it in. This isn't very efficient, and I am aware of this. It works.


using (FileStream fs = File.OpenRead (path)) {
var data = new byte[checked((int)fs.Length)];
int i = 0;
int read;

using (var ms = new MemoryStream (checked((int)fs.Length))) {

while ((read = fs.Read (data, 0, data.Length)) > 0) {
ms.Write (data, 0, read);
i += read;
}

byte[] hive = ms.ToArray ();
char[] cList = new char[fs.Length];

i = 0;
foreach (byte b in hive)
cList[i++] = (char)b;

string d = new string (cList);


int all = 0;

foreach (Match mx in lf.Matches (d)) { //you can change out the regex you want here.
byte[] bb = new byte[mx.Value.Length];
char[] cb = new char[mx.Value.Length];

for (int k = 0; k < mx.Value.Length; k++) {
bb[k] = (byte)mx.Value[k];
cb[k] = (char)bb[k];

}

all++;

//Console.WriteLine (new string (cb));
}

Console.WriteLine (all.ToString ());
all = 0;
}
}


Basically, we read in the hive into a MemoryStream, convert the stream into a byte array, move that into a char array from which we create a string to search for the regexs in. Yes, we store 4 copies of the registry in memory. I am sure there are better ways to do this.

Then we loop through each match and count them. Of course we are working with binary streams, so if you choose to write the data carved out to the console, it will look like random data (to the untrained eye at least).

Running through all the hives supplied, I get this output:



/home/bperry/SAM
nk[\x2c|\x20]\x00.{7}\x01.{64}
47
.{4}l[f|h][0-65535].{8}
0
vk.{3}\x00\x00[\x00|\x80].{64}
36
hbin.{4}\x00\x10\x00\x00.{8}
6
^regf.{508}
1

/home/bperry/software
nk[\x2c|\x20]\x00.{7}\x01.{64}
43147
.{4}l[f|h][0-65535].{8}
6
vk.{3}\x00\x00[\x00|\x80].{64}
54708
hbin.{4}\x00\x10\x00\x00.{8}
2917
^regf.{508}
0

/home/bperry/system
nk[\x2c|\x20]\x00.{7}\x01.{64}
11189
.{4}l[f|h][0-65535].{8}
4
vk.{3}\x00\x00[\x00|\x80].{64}
21926
hbin.{4}\x00\x10\x00\x00.{8}
1121
^regf.{508}
1

/home/bperry/default
nk[\x2c|\x20]\x00.{7}\x01.{64}
554
.{4}l[f|h][0-65535].{8}
0
vk.{3}\x00\x00[\x00|\x80].{64}
1014
hbin.{4}\x00\x10\x00\x00.{8}
58
^regf.{508}
1

/home/bperry/SECURITY
nk[\x2c|\x20]\x00.{7}\x01.{64}
220
.{4}l[f|h][0-65535].{8}
0
vk.{3}\x00\x00[\x00|\x80].{64}
147
hbin.{4}\x00\x10\x00\x00.{8}
10
^regf.{508}
1



The number printed after the regex is the number of matches found. The data is fully carved out, so the only thing left is to break it apart to get the relevant data. If you will notice however, software reports 0 regf file headers, and I cannot figure out why. Any thoughts?