Friday, February 3, 2012

What browsers support @import in their CSS?

I prefer the following CSS:
<html>
<body>
<head>
<style type="text/css">
        @import url(/css/style.css);
      </style>
</head>
</body>
</html>

But not all browsers support @import. I wanted to see exactly which ones didn't so I used browsershots.org with a simple test.

Here are the results: http://browsershots.org/http://volatileminds.net/import_test.html

Black means it supports it. White means it doesn't.

Wednesday, January 11, 2012

Communicating with your NeXpose server via Mono/.NET

I have a public repo on github that houses my nexpose-sharp library. It is written in C# and consumes the NeXpose XML API (both 1.1 and 1.2). Here is an example of how easy it is to get all the vuln checks NeXpose has:

using System;
using System.Xml;
using nexposesharp;

namespace nexposeclient
{
class MainClass
{
public static void Main (string[] args)
{
using (NexposeSession session = new NexposeSession("192.168.56.101"))
{
session.Authenticate("nexpose"/*user*/, "nexpose"/*password*/);

using (NexposeManager11 manager = new NexposeManager11(session))
{
XmlDocument vulns = manager.GetVulnerabilityListing();

int i = 0;
foreach (XmlNode vuln in vulns.FirstChild.ChildNodes)
{
string vulnID = vuln.Attributes["id"].Value;

XmlDocument deets = manager.GetVulnerabilityDetails(vulnID);

string title = deets.FirstChild.FirstChild.Attributes["title"].Value;
string severity = deets.FirstChild.FirstChild.Attributes["severity"].Value;

Console.WriteLine(String.Format("{0} has a severity of {1} and an id of {2}", title, severity, vulnID));

i++;
}

Console.WriteLine("\n\nTotal vulnerabilities in database: " + i);
}
}
}
}
}



The library has 2 manager implementations. The above example use the 1.1 API. A NexposeManager12 class exists that inherits from NexposeManager11 (available from NeXpose 4.0) and implements the extended 1.2 API (available for NeXpose installations of 4.8+). I am currently in the process of writing some unit tests, which will be committed as soon as possible.

You can grab a copy of NeXpose Community Edition today and try it out!

Friday, January 6, 2012

Reading offline registry hives in pure ruby

If you have ever wanted to peruse a registry hive on Linux, you know that options are really lacking. Most people wonder why you would even want to read a registry hive on Linux, but it is fairly straightforward when you think of the kind of people who will be traversing through registry hives in the first place. Forensics and reverse engineers will often run Linux.

Last night, I checked in my offline registry hive library written in Ruby. I had written a really crappy one in C# based on key signatures, rather than parsing the actual tree. This library does it correctly, by parsing the tree. It is still in its infancy, but it works well enough. You may view the code here. One day, I hope this gets merged in to the Metasploit trunk in some form or fashion. Tested on Ubuntu 11.10 on ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux].

root@w00den-pickle:/home/bperry/tmo/hives/ntreg-ruby# ruby ntreg.rb '\Select' ../SYSTEM
Hive name: "SYSTEM"
Found root key: CMI-CreateHive{F10156BE-0E87-4EFB-969E-5DA29D131144}
The values and data of \CMI-CreateHive{F10156BE-0E87-4EFB-969E-5DA29D131144}\Select are:
"Current: \x01\x00\x00\x00"
"Default: \x01\x00\x00\x00"
"Failed: \x00\x00\x00\x00"
"LastKnownGood: \x02\x00\x00\x00"
root@w00den-pickle:/home/bperry/tmo/hives/ntreg-ruby# ruby ntreg.rb '\ControlSet001\Control\Lsa' ../SYSTEM
Hive name: "SYSTEM"
Found root key: CMI-CreateHive{F10156BE-0E87-4EFB-969E-5DA29D131144}
The children of \CMI-CreateHive{F10156BE-0E87-4EFB-969E-5DA29D131144}\ControlSet001\Control\Lsa are:
"AccessProviders"
"Audit"
"Credssp"
"Data"
"FipsAlgorithmPolicy"
"GBG"
"JD"
"Kerberos"
"MSV1_0"
"Skew1"
"SSO"
"SspiCache"
The values and data of \CMI-CreateHive{F10156BE-0E87-4EFB-969E-5DA29D131144}\ControlSet001\Control\Lsa are:
"auditbaseobjects: \x00\x00\x00\x00"
"auditbasedirectories: \x00\x00\x00\x00"
"crashonauditfail: \x00\x00\x00\x00"
"fullprivilegeauditing: \x00\x00\x00\x00"
"Bounds: \x000\x00\x00\x00 \x00\x00"
"LimitBlankPasswordUse: \x01\x00\x00\x00"
"NoLmHash: \x01\x00\x00\x00"
"Notification Packages: s\x00c\x00e\x00c\x00l\x00i\x00\x00\x00\x00\x00"
"Security Packages: k\x00e\x00r\x00b\x00e\x00r\x00o\x00s\x00\x00\x00m\x00s\x00v\x001\x00_\x000\x00\x00\x00s\x00c\x00h\x00a\x00n\x00n\x00e\x00l\x00\x00\x00w\x00d\x00i\x00g\x00e\x00s\x00t\x00\x00\x00t\x00s\x00p\x00k\x00g\x00\x00\x00p\x00k\x00u\x002\x00u\x00\x00\x00\x00\x00"
"Authentication Packages: m\x00s\x00v\x001\x00_\x000\x00\x00\x00\x00\x00"
"LsaPid: \xEC\x01\x00\x00"
"SecureBoot: \x01\x00\x00\x00"
"ProductType: \x02\x00\x00\x00"
"disabledomaincreds: \x00\x00\x00\x00"
"everyoneincludesanonymous: \x00\x00\x00\x00"
"forceguest: \x00\x00\x00\x00"
"restrictanonymous: \x00\x00\x00\x00"
"restrictanonymoussam: \x01\x00\x00\x00"
root@w00den-pickle:/home/bperry/tmo/hives/ntreg-ruby#

Wednesday, December 28, 2011

New metasploit modules in trunk

Last night HDM checked in a telnetd remote root scanner and exploit module fore BSD-derived telnetd servers (this vuln affects telnet clients as well). We were up late last night working on it. Any testing is appreciated.

Today, sinn3r checked my CorpWatch API modules into trunk. These aid in OSINT research for a company during an engagement.

Tuesday, December 13, 2011

Finding all exploits with RPORT == X

This question comes up quite a bit in the IRC channel: How can I see all exploits for a given port? You can do it easily with IRB

msf > irb
>> framework.exploits.each_module { |n,e| x=e.new; print_good("#{e.fullname}: #{x.datastore['RPORT']}") if x.datastore['RPORT'].to_i == 445   }; nil

Just replace 445 with the port you are looking for. If you want aux modules, you may replace framework.exploits with framework.auxiliary.

Wednesday, November 30, 2011

Can you crack it? (nope, I tried though)

The UK govt created a challenge to find eligible code crackers. The website is http://www.canyoucrackit.co.uk/.

I got close, but my skills aren't up to par. Here is as far as I got. They give you the following code:

eb 04 af c2 bf a3 81 ec  00 01 00 00 31 c9 88 0c
0c fe c1 75 f9 31 c0 ba  ef be ad de 02 04 0c 00
d0 c1 ca 08 8a 1c 0c 8a  3c 04 88 1c 04 88 3c 0c
fe c1 75 e8 e9 5c 00 00  00 89 e3 81 c3 04 00 00
00 5c 58 3d 41 41 41 41  75 43 48 3d 42 42 42 42
75 3b 5a 89 d1 89 e6 89  df 29 cf f3 a4 89 de 89
d1 89 df 29 cf 31 c0 31  db 31 d2 fe c0 02 1c 06
8a 14 06 8a 34 1e 88 34  06 88 14 1e 00 f2 30 f6
8a 1c 16 8a 17 30 da 88  17 47 49 75 de 31 db 89
d8 fe c0 cd 80 90 90 e8  9d ff ff ff 41 41 41 41

What jumps out at me first are the nops (90 90) in the last line. My mind automagically tells me this is shellcode. I wasn't 100% sure, but it was the only guess I had. I copied the code over into gedit, and made the following adjustments.

\xeb\x04\xaf\xc2\xbf\xa3\x81\xec\x00\x01\x00\x00\x31\xc9\x88\x0c
\x0c\xfe\xc1\x75\xf9\x31\xc0\xba\xef\xbe\xad\xde\x02\x04\x0c\x00
\xd0\xc1\xca\x08\x8a\x1c\x0c\x8a\x3c\x04\x88\x1c\x04\x88\x3c\x0c
\xfe\xc1\x75\xe8\xe9\x5c\x00\x00\x00\x89\xe3\x81\xc3\x04\x00\x00
\x00\x5c\x58\x3d\x41\x41\x41\x41\x75\x43\x48\x3d\x42\x42\x42\x42
\x75\x3b\x5a\x89\xd1\x89\xe6\x89\xdf\x29\xcf\xf3\xa4\x89\xde\x89
\xd1\x89\xdf\x29\xcf\x31\xc0\x31\xdb\x31\xd2\xfe\xc0\x02\x1c\x06
\x8a\x14\x06\x8a\x34\x1e\x88\x34\x06\x88\x14\x1e\x00\xf2\x30\xf6
\x8a\x1c\x16\x8a\x17\x30\xda\x88\x17\x47\x49\x75\xde\x31\xdb\x89
\xd8\xfe\xc0\xcd\x80\x90\x90\xe8\x9d\xff\xff\xff\x41\x41\x41\x41

I then saved this into a shellcode.c file:

char shellcode[] = "\xeb\x04\xaf\xc2\xbf\xa3\x81\xec\x00\x01\x00\x00\x31\xc9\x88\x0c\x0c\xfe\xc1\x75\xf9\x31\xc0\xba\xef\xbe\xad\xde\x02\x04\x0c\x00\xd0\xc1\xca\x08\x8a\x1c\x0c\x8a\x3c\x04\x88\x1c\x04\x88\x3c\x0c\xfe\xc1\x75\xe8\xe9\x5c\x00\x00\x00\x89\xe3\x81\xc3\x04\x00\x00\x00\x5c\x58\x3d\x41\x41\x41\x41\x75\x43\x48\x3d\x42\x42\x42\x42\x75\x3b\x5a\x89\xd1\x89\xe6\x89\xdf\x29\xcf\xf3\xa4\x89\xde\x89\xd1\x89\xdf\x29\xcf\x31\xc0\x31\xdb\x31\xd2\xfe\xc0\x02\x1c\x06\x8a\x14\x06\x8a\x34\x1e\x88\x34\x06\x88\x14\x1e\x00\xf2\x30\xf6\x8a\x1c\x16\x8a\x17\x30\xda\x88\x17\x47\x49\x75\xde\x31\xdb\x89\xd8\xfe\xc0\xcd\x80\x90\x90\xe8\x9d\xff\xff\xff\x41\x41\x41\x41";

void main() {
   int *ret;

   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;

   printf("done");

}

Running it simply returned the "done" being printed by printf. This told me that the shellcode was at least not crashing, so it was probably valid shellcode. Looks like my first impression was correct. So I jumped to the asm that the shellcode produced to get a better understanding of it:

0000000000601040 :
  601040: eb 04                 jmp    601046 
  601042: af                    scas   %es:(%rdi),%eax
  601043: c2 bf a3              retq   $0xa3bf
  601046: 81 ec 00 01 00 00     sub    $0x100,%esp
  60104c: 31 c9                 xor    %ecx,%ecx
  60104e: 88 0c 0c              mov    %cl,(%rsp,%rcx,1)
  601051: fe c1                 inc    %cl
  601053: 75 f9                 jne    60104e 
  601055: 31 c0                 xor    %eax,%eax
  601057: ba ef be ad de        mov    $0xdeadbeef,%edx
  60105c: 02 04 0c              add    (%rsp,%rcx,1),%al
  60105f: 00 d0                 add    %dl,%al
  601061: c1 ca 08              ror    $0x8,%edx
  601064: 8a 1c 0c              mov    (%rsp,%rcx,1),%bl
  601067: 8a 3c 04              mov    (%rsp,%rax,1),%bh
  60106a: 88 1c 04              mov    %bl,(%rsp,%rax,1)
  60106d: 88 3c 0c              mov    %bh,(%rsp,%rcx,1)
  601070: fe c1                 inc    %cl
  601072: 75 e8                 jne    60105c 
  601074: e9 5c 00 00 00        jmpq   6010d5 
  601079: 89 e3                 mov    %esp,%ebx
  60107b: 81 c3 04 00 00 00     add    $0x4,%ebx
  601081: 5c                    pop    %rsp
  601082: 58                    pop    %rax
  601083: 3d 41 41 41 41        cmp    $0x41414141,%eax
  601088: 75 43                 jne    6010cd 
  60108a: 48 3d 42 42 42 42     cmp    $0x42424242,%rax
  601090: 75 3b                 jne    6010cd 
  601092: 5a                    pop    %rdx
  601093: 89 d1                 mov    %edx,%ecx
  601095: 89 e6                 mov    %esp,%esi
  601097: 89 df                 mov    %ebx,%edi
  601099: 29 cf                 sub    %ecx,%edi
  60109b: f3 a4                 rep movsb %ds:(%rsi),%es:(%rdi)
  60109d: 89 de                 mov    %ebx,%esi
  60109f: 89 d1                 mov    %edx,%ecx
  6010a1: 89 df                 mov    %ebx,%edi
  6010a3: 29 cf                 sub    %ecx,%edi
  6010a5: 31 c0                 xor    %eax,%eax
  6010a7: 31 db                 xor    %ebx,%ebx
  6010a9: 31 d2                 xor    %edx,%edx
  6010ab: fe c0                 inc    %al
  6010ad: 02 1c 06              add    (%rsi,%rax,1),%bl
  6010b0: 8a 14 06              mov    (%rsi,%rax,1),%dl
  6010b3: 8a 34 1e              mov    (%rsi,%rbx,1),%dh
  6010b6: 88 34 06              mov    %dh,(%rsi,%rax,1)
  6010b9: 88 14 1e              mov    %dl,(%rsi,%rbx,1)
  6010bc: 00 f2                 add    %dh,%dl
  6010be: 30 f6                 xor    %dh,%dh
  6010c0: 8a 1c 16              mov    (%rsi,%rdx,1),%bl
  6010c3: 8a 17                 mov    (%rdi),%dl
  6010c5: 30 da                 xor    %bl,%dl
  6010c7: 88 17                 mov    %dl,(%rdi)
  6010c9: 47                    rex.RXB
  6010ca: 49 75 de              rex.WB jne    6010ab 
  6010cd: 31 db                 xor    %ebx,%ebx
  6010cf: 89 d8                 mov    %ebx,%eax
  6010d1: fe c0                 inc    %al
  6010d3: cd 80                 int    $0x80
  6010d5: 90                    nop
  6010d6: 90                    nop
  6010d7: e8 9d ff ff ff        callq  601079 
  6010dc: 41                    rex.B
  6010dd: 41                    rex.B
  6010de: 41                    rex.B
  6010df: 41 00 00              add    %al,(%r8)

Definitely legitimate shellcode. The x86 asm gcc spits out is exactly what I wanted to see. Not only that, but do you see the 0xdeadbeef?

Once I knew I was in the right direction, I loaded the binary into gdb. I through a breakpoint on the printf line with
break printf
and ran the binary. I looked at the stack frame, traversed through the memory and found the strings I suspected were what we were supposed to be looking for. However, they seemed to be all multi-byte characters. I wasn't able to decipher any of them within the time limit. I had found out about the contest about 2 hours before it was over. This took me about an hour to get to traversing the stack for the strings, and I got stuck.

Oh well. Maybe next time if I have more time I can get a bit further.

Saturday, November 26, 2011

Easily splitting and storing traceroute data

Traceroute is very useful, but the data it spits out can be a bit tough to chew on. I came up with this one-liner to make it more CSV compatible so you can Split() on commas and have the correct data where you expect it.
traceroute google.com | sed 's/  /,/g' | sed 's/ ms / ms,/g'
This take load balancers into account as well, so when your route slightly changes during a hop, you can still easily grok the data coming back. Basically, take double-spaces and replace them with a comma. The second sed is what takes the load balancers into account, fixing the output so it is the same as the prior hop test.