Socket을 이용하는 Remote BOF 공격에서 대게 Bind Shell Code를 사용하게 된다.

이 쉘코드가 어떻게 구성되어있고, 왜 Remote BOF에서는 Bind Shell Code를 써야하는지 알아보았다.


1. Bind Shell Code의 구성

우선 통신을 위해 TCP와 같이 구성이 된다.

Socket() -> Bind() -> Listen() -> Accept()

또한 표준입출력을 위해 dup2함수와 쉘을 띄우기 위한 execve함수로 구성할 수 있다.


2. Bind Shell Code의 목적

Remote 환경에서는 쉘이 소켓이 종료된 뒤에 떨어지기 때문에 이 통신을 유지시켜줄 필요가 있다. 따라서 Bind Shell Code를 이용하여 포트를 열고 쉘을 받아오는 것이다. 하지만 소켓을 통해서는 서버에서 사용되는 표준입출력을 받을 수 없기 때문에 dup2 함수가 사용된다. 

이 함수는 사용자가 원하는 파일 디스크립터를 복사할 수 있게 해주는 역할을 한다.

즉, Socket()를 사용할 때 생성된 소켓의 파일 디스크립터 번호에 표준입출력 번호를 할당해 줌으로써 소켓을 통해서 쉘코드를 표준입력으로 전달하고 그 결과 얻은 쉘을 표준출력으로 돌려받을 수 있게 되는 것이다.


※ 파일 디스크립터 : 파일을 관리하기 위해 운영체제가 할당하는 번호로 0/1/2의 고정된 번호가 있으며 이 이후부터 순차적으로 번호가 매겨지게 된다. 주로 Open()함수를 통해 파일을 생성하거나 Socket()로 소켓을 생성할 때도 번호가 붙게 된다.


※ 파일 디스크립터에 고정적으로 할당된 표준입출력 번호

표준 입력 : 0

표준 출력 : 1

표준 에러 : 2

(해커스쿨 문제를 풀면서 2 > /dev/null 를 쓰면 에러가 안 보이는 이유이다.)


3. Assembly Code

dup2(int s_fd, int d_fd)로 구성이 되는데 인자는 각각 순서대로 ebx, ecx에 들어가게 된다.

실제 Bind Shell Code를 구성하는 다음 코드를 보면 이해에 도움이 될 것 같다.

  xchg eax, ebx               ; 소켓 파일디스크립터를 ebx에 저장
  push BYTE 0x2
  pop ecx                        ; ecx를 표준에러(2)부터 소켓 파일 디스크립터에 복사
dup_loop:
  mov BYTE al, 0x3F          ; dup2() 시스템콜 63(0x3F)
  int 0x80                          ; 시스템 콜 호출
  dec ecx                         ; ecx--(표준에러 / 표준출력 / 표준입력 순으로 복사 됨)
  jns dup_loop                  ; ecx가 음인 경우 부호플래그가 참이 되어 루프 종료

 

원본출처 : http://inhack.org/wordpress/?p=2502

 

생성된 소켓의 파일 디스크립터를 ebx에 넣어 dup2의 인자로 사용하고 ecx에서 2번(에러출력)부터 0번까지 루프를 돌면서 파일 디스크립터를 복사해준다.

 

이 과정을 거치기 때문에 Bind Shell Code 사용 시에 소켓을 통해서도 표준 입출력을 전달 받고 쉘을 얻을 수 있게 된다. = )







+ Recent posts

티스토리 툴바