Bind TCP Shellcode - Linux x86 (Null free/PI)
Before we start , I would like to bring your attention to this SLAE course from securitytube which will help you learn Shellcoding - http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
AGENDA :
1. Introduction to Bind shell
2. Analysis of Bind Shell
3. Writing Bind tcp shellcode
1. Introduction to Bind shell
Bind Shell :-
With a bind shell, you open up a communication port or a listener on the target machine. The listener then waits for an incoming connection, you connect to it, the listener accepts the connection and gives you shell access to the target system.
I would define bind shell with reference to above diagram :
First Step : a bind shell basically opens a port(listener port) on target machine and waits for incoming requests on that port
Second Step : An Attacker try to connect using the target ip address and target listner port and gets a shell :)
2. Analysis of Metasploit Bind Shell through Libemu
From above diagram it is clear that main syscalls are :
socket,bind,listen,accept,dup2 and execve
3. Writing Bind TCP Shellcode
Lets look for syscalls number and arguements from following link :
http://man7.org/linux/man-pages/man2/socketcall.2.html
Task :
1. Create A shell Bind Tcp -
[x] Binds to a port
[x] Exec shell on incoming connection
[x] Null Free
[x] Register Independent
[x] Short and sweet ;) :p
Lets break the task in small parts -
[x] Create a socket
[x] Bind to a specific port
[x] Setting up listener
[x] Accepting incoming connections
[x] dup2 (Redirect stdin, stdout and stderr)
[x] Spawns Shell
Let's start writing :
[x] Create a Socket ;) [ int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); ]
I have commented the explanation so that it would be easy for the readers to understand each instruction step by step .
int socketcall(int call, unsigned long *args);
Socketcall needs EBX to be 1 i.e SYS_Socket number and ECX should contain pointer to arguments therefore for a successful call , I have pushed the socket arguments on stack in order IPPROTO_IP,
SOCK_STREAM,AF_INET because we are dealing with stack . :p
As the requirement says that we need ECX to contain pointer to arguments therefore MOV ECX,ESP is used .
At last :
EAX= 0x66 [socket sys call number]
EBX= 0x1 [SOCKET create number]
ECX= pointer to socket arguments [ 2 1 0]
Note: I used the push pop method to save few bytes , you can either use xor eax with itself and then move the socket sys call number in AL and so on .
After a successful sys call by calling interrupt 0x80 at the end EAX will contain the socket file descriptor which needs to be saved for future use . I have used ESI register to save sockfd .
[x] Bind [ bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); ]
Bind is lil messy :p so I will try to explain this with a diagram . Before that let's see which registers should contain what ?
EAX = socket sys call number 0x66
EBX= SYS_BIND number
ECX= pointer to arguments which are : sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)
sockfd and size can be given easily but second parameter deal with structures therefore I have broken the second parameter in simple parts :
Now again pushing the parameters in way - length of sockaddr,ECX,sockfd
Saving pointer to argument in ECX will solve the purpose and ECX will contain all the three parameters which are required .
At last -
EAX = 0x66
EBX= SYS_BIND number - 2
ECX= pointer to arguments
[x] Listen [ listen(sockfd, 2); ]
For listen we need only two arguments in ECX and EBX should contain SYS_LISTEN number(4) and obviously EAX should contain socket sys call number .
I hope this not a big deal so skipping the explanation because its already there in comments .
[x] Accept [accept(sockfd, (struct sockaddr *)&cli_addr, &sin_size); | here accept(int sockfd, NULL, NULL);]
accept(int sockfd, NULL, NULL);
For accept only three parameters should be used which are sockfd which we already saved in esi then rest two parameter should be null as we don't require them as of now .
SO basically
EAX = 0x66 socket sys call number
EBX= SYS_ACCEPT number - 5
ECX= pointer to arguments [sockfd null null]
[x] Dup2
[x] Spawn Shell [ execve("/bin//sh", NULL, NULL); ]
EXECVE call is made in order to spawn shell on incoming connection in above scenario . For execve call we need - EAX to contain execve sys call number EBX to contain pointer to /bin//sh string[which is null terminated] ECX contains null This part is easy and can be understand by comments so skipping this .
[x] All together ;)
Let's compile using my script and test the shellcode .
[x] C code here - https://github.com/hexachordanu/SLAE/blob/master/Assignment-1/shellcode.c
[x] bindtcp.nasm - https://github.com/hexachordanu/SLAE/blob/master/Assignment-1/bindtcp.nasm [92 bytes]
I have commented the Port number field and can be easily configured .. Check Configure your port comment string in comments of bindtcp.nasm .
Proof of Concept :
Thanks for Reading !!!! :)
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student-ID: SLAE-1219
Before we start , I would like to bring your attention to this SLAE course from securitytube which will help you learn Shellcoding - http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
AGENDA :
1. Introduction to Bind shell
2. Analysis of Bind Shell
3. Writing Bind tcp shellcode
1. Introduction to Bind shell
Bind Shell :-
With a bind shell, you open up a communication port or a listener on the target machine. The listener then waits for an incoming connection, you connect to it, the listener accepts the connection and gives you shell access to the target system.
I would define bind shell with reference to above diagram :
First Step : a bind shell basically opens a port(listener port) on target machine and waits for incoming requests on that port
Second Step : An Attacker try to connect using the target ip address and target listner port and gets a shell :)
2. Analysis of Metasploit Bind Shell through Libemu
From above diagram it is clear that main syscalls are :
socket,bind,listen,accept,dup2 and execve
3. Writing Bind TCP Shellcode
Lets look for syscalls number and arguements from following link :
http://man7.org/linux/man-pages/man2/socketcall.2.html
Task :
1. Create A shell Bind Tcp -
[x] Binds to a port
[x] Exec shell on incoming connection
[x] Null Free
[x] Register Independent
[x] Short and sweet ;) :p
Lets break the task in small parts -
[x] Create a socket
[x] Bind to a specific port
[x] Setting up listener
[x] Accepting incoming connections
[x] dup2 (Redirect stdin, stdout and stderr)
[x] Spawns Shell
Let's start writing :
[x] Create a Socket ;) [ int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); ]
I have commented the explanation so that it would be easy for the readers to understand each instruction step by step .
int socketcall(int call, unsigned long *args);
Socketcall needs EBX to be 1 i.e SYS_Socket number and ECX should contain pointer to arguments therefore for a successful call , I have pushed the socket arguments on stack in order IPPROTO_IP,
SOCK_STREAM,AF_INET because we are dealing with stack . :p
As the requirement says that we need ECX to contain pointer to arguments therefore MOV ECX,ESP is used .
At last :
EAX= 0x66 [socket sys call number]
EBX= 0x1 [SOCKET create number]
ECX= pointer to socket arguments [ 2 1 0]
Note: I used the push pop method to save few bytes , you can either use xor eax with itself and then move the socket sys call number in AL and so on .
After a successful sys call by calling interrupt 0x80 at the end EAX will contain the socket file descriptor which needs to be saved for future use . I have used ESI register to save sockfd .
[x] Bind [ bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); ]
Bind is lil messy :p so I will try to explain this with a diagram . Before that let's see which registers should contain what ?
EAX = socket sys call number 0x66
EBX= SYS_BIND number
ECX= pointer to arguments which are : sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)
sockfd and size can be given easily but second parameter deal with structures therefore I have broken the second parameter in simple parts :
Now again pushing the parameters in way - length of sockaddr,ECX,sockfd
Saving pointer to argument in ECX will solve the purpose and ECX will contain all the three parameters which are required .
At last -
EAX = 0x66
EBX= SYS_BIND number - 2
ECX= pointer to arguments
[x] Listen [ listen(sockfd, 2); ]
For listen we need only two arguments in ECX and EBX should contain SYS_LISTEN number(4) and obviously EAX should contain socket sys call number .
I hope this not a big deal so skipping the explanation because its already there in comments .
[x] Accept [accept(sockfd, (struct sockaddr *)&cli_addr, &sin_size); | here accept(int sockfd, NULL, NULL);]
accept(int sockfd, NULL, NULL);
For accept only three parameters should be used which are sockfd which we already saved in esi then rest two parameter should be null as we don't require them as of now .
SO basically
EAX = 0x66 socket sys call number
EBX= SYS_ACCEPT number - 5
ECX= pointer to arguments [sockfd null null]
[x] Dup2
[x] Spawn Shell [ execve("/bin//sh", NULL, NULL); ]
EXECVE call is made in order to spawn shell on incoming connection in above scenario . For execve call we need - EAX to contain execve sys call number EBX to contain pointer to /bin//sh string[which is null terminated] ECX contains null This part is easy and can be understand by comments so skipping this .
[x] All together ;)
Let's compile using my script and test the shellcode .
[x] C code here - https://github.com/hexachordanu/SLAE/blob/master/Assignment-1/shellcode.c
[x] bindtcp.nasm - https://github.com/hexachordanu/SLAE/blob/master/Assignment-1/bindtcp.nasm [92 bytes]
I have commented the Port number field and can be easily configured .. Check Configure your port comment string in comments of bindtcp.nasm .
Proof of Concept :
Thanks for Reading !!!! :)
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student-ID: SLAE-1219
Comments
Post a Comment