SUA 시스템 해킹 스터디 - 쉘코드 인코딩, 쉘코드 인코더 구현

171001 9주차


1. Metasploit을 이용한 쉘코드 인코딩


[질문 내용 정리]

암호학 알고리즘 분야에서 다른 논리 게이트(OR, AND, NOR 등)들이 있는데도 사람들이 XOR만 사용하는 이유가 뭘까? 가장 보편화된 암호 기법에서도 암호화, 복호화 알고리즘이 사용하는 반도체 공간을 줄이기 위해 하드웨어적으로 설계되어 있다. 즉, 하나의 반도체 칩 내부에서 암호화와 복호화 둘 다 하려면 XOR의 반대 연산이 XOR인 것처럼 만들어야 효율적이다. 하지만 OR나 AND 같은 논리 게이트를 사용한 경우는 메시지를 암호화, 복호화하기 위해 서킷(과정)을 두 번 거쳐야 한다는 것이다. 보안 관점에서 바라볼 때, 암호 기법과 인코딩에서 XOR이나 다른 논리 게이트를 사용하는 것에 차이는 없다. 단지 난수 키 생성기의 보안성에 따라 달라질 뿐이다. (참고: 블록 암호 중 DES, AES, IDEA도 XOR 연산을 사용한다. 하드웨어적으로 굉장히 빠르고, 반대 연산이 동일하다. 횟수와 순서에 상관없이 XOR 연산이 가능하며 이해와 분석이 쉽다. 굳이 XOR을 사용하지 않아도 빠른 블록 암호는 Threefish가 있고, 숫자 이론을 바탕으로 만든 RSA, ElGamal도 XOR을 사용하지 않는다.)

프로그래밍 언어를 사용하면 여러 라이브러리들에 의해 널 바이트가 생길 수 밖에 없다. 개발할 때는 문제 없지만, 해킹할 때는 원하는 쉘코드의 문자열 복사가 제대로 이루어지지 않을 수 있기 때문에 올바른 동작을 할 수 있도록 사전에 예방하는 조치라고 볼 수 있다. 그래서 사실 파이썬, 루비, 고같은 다른 언어들로 쉘코드를 추출하면 널 바이트가 있어도 무방하다.

쉘코드에 널 바이트가 있을 때 발생하는 문제는 C 표준 문자열 라이브러리를 사용한 오버플로우로 삽입 공격 시에 일어난다. 이럴 때 널 바이트가 문자열의 끝을 의미하여 복사가 중단되는 경우다. 90년대 중반에는 이러한 쉘코드 삽입 공격이 가장 유명했지만, 현재 대부분 C 코드는 다른 함수(OpenBSD의 strlcpy, strlcat set 등)들에 의해 보호되며, 최근 C++이 널 바이트로 인한 종료 문제가 없는 문자열 라이브러리를 가지고 있다. 지금 대부분 익스플로잇의 에러들은 작은 버퍼나 입력값 미검증 등에 의해 발생한다.

간단히 널 바이트를 제거하는 방법 중 하나는 push와 pop으로 mov를 대체하는 것이다. 예를 들면, mov $0x3c, %eax 이렇게 있을 때, push $0x3c, pop %eax 이렇게 바꿀 수 있다. 결과적으로, xor %edi, %edi, push $0x3c, pop %eax, syscall로 작성하면 널 바이트가 제거된 쉘코드가 나온다.

쉘코드 실행을 방해하는 몇 가지 문자들을 Bad Characters라고 말한다. 일반적인 Bad Characters는 0x00(NULL, \0), 0x09(Tab, \t), 0x0a(Line Feed, \n), 0x0d(Carriage Return, \r), 0xff(Form Feed, \f)다. 하지만, 작성 요령과 언어 별로 쉘코드 동작 여부가 달라진다. 쉘코드에서 제거해야할 문자 중 널 바이트는 당연하지만 간혹 사람들이 0x00을 0xff로 치환하는 경우가 있다. 앞서 말한 문자들 중 0x00, 0x0a, 0x0d가 쉘코드 실행에 가장 영향력을 많이 끼쳐서 이를 0xff로 바꿔 작성했을 때, 쉘코드가 정상적으로 실행되는 경우가 많았기 때문이다. 그래도 0xff를 지우려고 하는 사람들을 위해 Metasploit 프레임워크에는 -b, –bad-chars 옵션에 0xff가 추가되어 있다.

리버스 커넥션, 역접속이란 웹 서버와 DB 같은 IT 시스템에 접근하는 과정에서 일반적인 순서로 접근하지 않고 거꾸로 접속하는 방식을 말한다. 대부분 보안 시스템은 외부의 공격을 방어하는 것이 일반적이기 때문에 바깥으로 나가는 트래픽은 정상인 것이라 믿고 방치한다. 예를 들어, 방화벽이나 라우터 정책에 의해 공격 대상 컴퓨터에 들어가는 것이 불가능할 때, 해당 컴퓨터에 설치된 백도어가 RAT(Remote Administration Tools)를 사용해서 공격자의 IP 주소로 SYN 패킷을 보내 리버스 커넥션을 이용할 수 있다. 이렇게 되면 공격자는 이 SYN 패킷이 올 때까지 기다리다가 연결을 받아들인다. 하지만, 리버스 커넥션은 이러한 취약점을 이용한 공격을 차단하려면 내부에서 나가는 비정상인 트래픽을 탐지하여 차단해야 한다. 관리 상 목적이 아닌 내부에 다른 감염된 프로그램에 의해 공개된 IP 주소로 지속적인 패킷을 보낸다면 의심해 볼 필요가 있다.