Skip to main content

ShellRandomListen1434

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: SLAE64-1434

Target Operating System: 64 bit Linux (x86_64 GNU/Linux)

GutHub Link: https://github.com/rtaylor777/nasm/blob/master/ShellRandomListen1434.nasm

Published: https://www.exploit-db.com/exploits/41468/

Size = 54 bytes
NULLS = 0

ShellRandomListen1434.nasm

Intro

This shellcode when executed will listen on a random port for a connection and when a client connects it will present a /bin/sh shell for the client to interact with.

Testing

Download:
wget https://raw.githubusercontent.com/rtaylor777/nasm/master/ShellRandomListen1434.nasm

Assuming you have the NASM assembler ( http://www.nasm.us/ ):
Assemble:
nasm -felf64 ShellRandomListen1434.nasm -o ShellRandomListen1434.o

Link:
ld ShellRandomListen1434.o -o ShellRandomListen1434

Run:
./ShellRandomListen1434

In another terminal use nmap to discover what port the shellcode is listening on:
nmap -sS -p- 127.0.0.1

Then connect with the client once you know the port:
nc 127.0.0.1 55763

It is important to use nmap with the -sS option because if nmap actually completed a connection to our listener, our shellcode would execute the accept system call and it would be too late to connect with netcat and get a /bin/sh shell.

shellcode.c

If you missed it from my previous blog posts the shellcode.c file is auto generated by my helper scripts. See: http://a41l4.blogspot.ca/2017/02/slae-helper-scripts.html

 

Please See

If you are new to shellcode or shellcoding you should start by reading my blog post: http://a41l4.blogspot.ca/2017/01/execvestack1434.html

Also if you are new to Socket programming with assembly language you should start by reading my blog post: http://a41l4.blogspot.ca/2017/02/assignment-1b.html

Discussion

This shellcode is a little different in that although we did not call Bind, we still ended up binding to a port and listening on it. The key difference is that we did not get to specify which port to listen on.

The main advantage of this shellode over BindShell1434.nasm is that it is small and would enable compromise of smaller buffers in a vulnerable program.

Because the Close system call is not called for the original listening socket this shellcode may be a little less stealthy because the socket is still listening for the duration of the /bin/sh session.

If you reviewed my http://a41l4.blogspot.ca/2017/02/assignment-1b.html blog post you will probably understand most of what is happening in this shellcode. I will cover some key differences with this shellcode from the BindShell1434 shellcode.

In the Listen section:
man listen
int listen(int sockfd, int backlog);

This is the POSIX description and it says: "A backlog argument of 0 may allow the socket to accept connections, in which case the length of the listen queue may be set to an implementation-defined minimum value." I referred to the above document because this code is setting RSI to zero and RSI being the second argument for listen would normally be set to a value indicating the number of connections you wish to accept.

Line 42 xchg eax,edi is used because we want the returned socket descriptor to be in RDI and we want a defined (known) value in RAX, the value that we set RDI to for the create socket call or in other words 2.

Background
With Linux, everything is a file: https://en.wikipedia.org/wiki/Everything_is_a_file

"The interface used by the Berkeley Sockets API uses file descriptors to identify sockets from user space. This allows standard interfaces such as the read and write system calls to operate on sockets as well as pipes, devices, and regular files" from http://isomerica.net/~dpn/socket_vfs.pdf

The default maximum open file descriptors limit is 1024 for Linux. On Linux systems where there are Enterprise Applications running this default limit is increased considerably. On Oracle SOA for example I had to set the limit to 16k open files and on OBIEE (Oracle Business Intelligence Enterprise Edition) the performance tuning guide suggests:
Make the following changes to the /etc/security/limits.conf file:
* soft nofile 131072
* hard nofile 131072
* soft nproc 131072
* hard nproc 131072

So what am I trying to say? When you are using this shellcode to compromise an already running process, there is not only no guarantee that the socket descriptor you get will have the value 3 when you create a socket, but there is no guarantee the size of the value for the sockfd returned will even fit in a byte (AL). We will see why this is important later. For now we have circumvented a programming flaw by putting a known value (2) into RAX before the mov al,50 line.

Here is a snapshot of what the socket descriptor values look like for a process on one of my relatively idle test servers:
For this process, none of the socket descriptor values would have fit in a byte. But they easily fit in a 32 bit (4 byte) register which is why there is no risk using xchg eax,edi.

In the Accept section:

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

RDI is still set to the sockfd. RSI and RDX are still zero. "When addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL." from the man page. The return value of the listen system call is 0 for a successful call and so RAX is zero. This makes the instruction mov al,43 safe. The accept system call will block (wait) until a client connects.

The Dup2 section:


man dup2
int dup2(int oldfd, int newfd);

In this section we get to discuss a bit more about why I inluded the background section concerning file descriptors. If you run the shellcode as a stand alone program, the socket descriptor which is currently in RDI will almost certainly have a value of 3. So if, and only if, you wish to run this as a standalone program you can reduce the size of the shellcode by one byte by pushing RDI and popping it into RSI instead of pushing 3 and popping it into RSI. What happens when the value in RDI is greater that 3? The dup2loop will map all the file descriptors and socket descriptors that are open to redirect to our client connection. How this will impact our client is something to be discovered. For my part I prefer to waist a byte by being sure that the value 3 gets into RSI.

On line 51 we use xchg edi,eax (same bytecode as xchg eax,edi) again but the result is a little different in that there is no guarantee that what we end up with in RAX fits entirely in a byte (0-255).

To be safe we push 33 and pop it into RAX which is one byte larger than the instruction mov al, 33. If you are running this program standalone, or you are certain the vulnerable program you are compromising is not a heavy user of open file and socket descriptors you can save a byte by using the mov al, 33 instruction.

The loop, if  you have not seen it before is simply mapping the standard error, standard out, and standard read file descriptors 2,1,0 to our client's socket connection. This enables the client to interact with the /bin/sh shell when we launch that next.

Execve

This last part is the Execve system call which is very similar to what I documented in my Blog post here: http://a41l4.blogspot.ca/2017/01/execvestack1434.html
So the main difference of note here is that at this point in this code RAX, RSI, and RDX are all set to 0 already as we enter this section. So we do not need the cdq instruction to clear RDX.

Summary

The ShellRandomListen1434 shellcode listens on a random port and when a client connects it will provide the client with a /bin/sh shell. At 54 bytes, this shellcode may allow you to compromise a vulnerability that you may not have been able to with the BindShell1434 due to the small size of the vulnerable buffer.

If you wish to learn more about assembly language, I highly recommend the "SecurityTube Linux Assembly Expert course and certification."

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

Comments

Popular posts from this blog

GIAC GXPN Review – SANS SEC660 (Advanced Penetration Testing, Exploit Writing, and Ethical Hacking)   Intro  SANS is a well respected and premier cyber security training company that employs industry experts as instructors. GIAC is a company that produces testing to validate the skills of security professionals. GIAC exams validate the learning outcomes of the SANS courses. Prerequisites Before attempting this course you should be familiar with penetration testing as this is an advanced course. I would say that you should also be familiar with assembly language and shellcoding. It would be best if you have studied basic stack overflow exploits prior to this course. You will need a basic understanding of programming in C or C++ (preferably both). Scripting using Python would be a useful prerequisite. If you could learn a bit of Ruby scripting it would help for the Metasploit module creation. Be familiar with various routing and networking protocols. Course Coverage This course covers ma

PolySetuidExecve1434

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: SLAE64-1434 Target Operating System : 64 bit Linux (x86_64 GNU/Linux) This blog post is part of Assignment 6: http://a41l4.blogspot.ca/2017/03/assignment-6.html The Original Version: http://shell-storm.org/shellcode/files/shellcode-77.php My Version: GitHub Link : https://github.com/rtaylor777/nasm/blob/master/PolySetuidExecve1434.nasm Published : https://www.exploit-db.com/exploits/41498/ Original Shellcode bytes = 49 My version: Number of bytes = 31 Number of nulls = 0 PolySetuidExecve1434.nasm Intro This shellcode when executed will first setuid(0) and then execute /bin/sh and provide you with a shell. The purpose of calling setuid(0) is, suppose that you have managed to inject this shellcode into an executable that is Set-UID root. I

PolyFlushIPTables1434

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: SLAE64-1434 Target Operating System : 64 bit Linux (x86_64 GNU/Linux) This blog post is part of Assignment 6: http://a41l4.blogspot.ca/2017/03/assignment-6.html The Original Version: http://shell-storm.org/shellcode/files/shellcode-683.php Original size: 50 bytes (don't believe what he says :) My Version: GitHub Link : https://github.com/rtaylor777/nasm/blob/master/PolyFlushIPTables1434.nasm Published : https://www.exploit-db.com/exploits/41503/ My version: Number of bytes = 47 Number of nulls = 0 PolyFlushIPTables1434.nasm  Intro This shellcode basically just executes /sbin/iptables -F without any other parameters. man iptables "-F, --flush [chain]               Flush  the  selected  chain (all the chains in the table if none i