이 글은 권위있는 인터넷 해킹/보안 전자 잡지인 Phrack Magazine의 64호에 1km이 기고한 글을 참고하여 재 구성한 글입니다. 이 글을 보고 깊은 감명을 받아서 글을 쓰기 시작하였습니다. 이 글에서 소개하고 있는 기법 그 자체가 뛰어난 해킹 방법이거나, 높은 테크닉이라서가 아닌, 해커로서 갖춰야할 사물에서 문제를 추출해 낼 수 있는 통찰력 그 자체가 뛰어나기 때문에 많은 사람들과 이 글을 공유하고 싶었습니다. 해킹은 어떤 사실에서 문제를 발견해 낼 수 있는 통찰력과 그 통찰력을 실험해볼 수 있는 기술로 이루어집니다. 기술은 공부를 통해 배울 수 있지만, 통찰력은 쉽게 만들어지는 것이 아닙니다. 몇년 몇날을 계속 생각하고 스스로의 경험과 안목을 키워야 합니다. 예를 들어 파란 약을 먹으면 그림 속으로 들어가고, 빨간 약을 먹으면 그림 밖으로 빠져나온다라는 사실이 있을 때, 해커라면 좀 더 넓은 시야로, 그렇다면 그림 밖에서 빨간약을 먹으면 어떻게 되는가?를 고민해볼 수 있어야 합니다. 각설하고, 다음 소개시켜드리는 해킹 방법은 이런 통찰력이 탁월하게 발휘된 방식이니 한번 같이 보면서 익혀보겠습니다.
본 글의 원문은 http://phrack.org/issues.html?issue=64&id=15#article 를 통해 볼 수 있는데, 어찌된 일인지 지금 접속되지 않습니다.
본 글의 원문은 http://phrack.org/issues.html?issue=64&id=15#article 를 통해 볼 수 있는데, 어찌된 일인지 지금 접속되지 않습니다.
Introduction
우리가 흔히 쓰는 웹, FTP, 각종 온라인 게임, 메신져 등 거의 대부분의 온라인 서비스는 TCP 프로토콜을 사용합니다. TCP 프로토콜은 연결 지향적이라 보안상 신뢰할 수 있기 때문입니다. 보안상 신뢰할 수 있다는 것은 서버가 A라는 호스트로부터 패킷을 수신하였을 때 A라는 IP를 가진 호스트가 보내는 패킷은 모두 A가 보냈다고 신뢰할 수 있다는 것입니다. 이것은 TCP가 패킷을 주고 받기 위해 Sequence number(SEQ)와 Acknowledgement number(ACK)를 이용하기 때문입니다.
TCP 3 Way Handshaking
위 그림은 TCP의 초기 연결을 도표화 한 것입니다. 두 호스트(클라이언트, 서버)가 초기에 연결을 맺을 때 3 way handshake 방식을 이용합니다. 3 way handshake 방식은 3개의 약속된 패킷을 주고 받아 연결을 맺는 방식입니다. 처음 연결을 시도할 때 클라이언트와 서버는 Initial Sequence Number(ISN)을 발생시킵니다. 초기 연결을 맺으려고 하는 클라이언트가 ISN 5000을 발생시켜 SEQ에 넣어서 서버에 전송하면 서버는 이 ISN에 전송받은 패킷의 크기를 더해서 ACK에 넣어서 응답 패킷으로 돌려줍니다. 위 그림에서도 서버가 응답하는 패킷의 ACK가 5001이라는 것을 보실 수 있습니다. 클라이언트가 5001이라는 ACK를 받아보면, 진짜 서버에서 돌아온 응답인지 신뢰할 수 있게 됩니다. 서버가 ACK를 넘겨줄 때 서버 또한 ISN을 발생시켜서 SEQ에 넣어서 전송해줍니다. 클라이언트는 이 ISN 패킷을 받아서 받은 패킷 크기를 더해서 다음 응답 패킷의 ACK에 넣어서 넘겨줍니다. 이것을 통해 두 호스트는 서로를 완전하게 신뢰하며 연결되는 것입니다. 이렇게 하지 않으면 1.1.1.1이라는 IP를 달고 나에게 접속을 시도하는(ISN을 전송하는) 호스트가 진짜 1.1.1.1인지 알수가 없습니다. 그렇기 때문에 1.1.1.1에 192931라는 응답을 보내고, 1.1.1.1이 다시 192931이라는 값을 응답하면, 1.1.1.1이 진짜인지 알 수 있게 되는것이죠.
여기서 한가지 의문이 들 수 있습니다. 클라이언트와 서버가 보내는 패킷을 보다가 다음 ACK를 예측하여 IP를 클라이언트의 IP로 수정한 후 순간적으로 클라이언트보다 서버에 먼저 응답한다면 서버는 그 패킷을 받아들이는가 하는 것입니다. 예 맞습니다. 그것이 바로 TCP/IP Hijacking 입니다. 과거에는 꼭 클라이언트와 서버의 패킷을 모니터링 하지 않아도 이 SEQ와 ACK를 어느정도 유추할 수 있는 방법이 있었습니다. 그것은 예전 운영체제가 ISN을 정해진 공식에 의해서 발생시킨다는 것이였는데, 예를 들어 내가 서버에 접속했을 때 ISN이 1000이였다면, 그 다음에 접속할 때 ISN이 1001이 되는 식의 방법이였습니다. ISN만 예측할 수 있다면 내 IP를 바꾸어서 서버에 충분히 접속할 수 있게 됩니다. 만약 서버가 1.1.1.1이라는 IP를 신뢰하여 모든 명령을 받아들이는 상태라면 1.1.1.1로 자신의 IP를 바꾸어 서버에 명령을 내릴 수 있겠죠. 물론 서버의 응답을 받을 순 없지만, 패킷을 받아들이게 하는 것 만으로도 수많은 것을 할 수 있을 것입니다. 하지만 최신 OS는 당연히 ISN을 랜덤하게 발생시켜서 예측할 수 없게 만들고 있습니다. 해커들이 IP-Spoofing과 Hijacking을 구분하는 것은 이와 같이 처음부터 IP를 바꾸어 서버에 접속하는 것을 IP-Spoofing이라고 부르고, 아래 그림과 같이 통신하는 중간에 자신이 패킷을 껴넣어 의도하는 명령을 내리는 것을 Hijacking이라고 구분합니다. 물론 모든 해커들이 이렇게 구분하는 것은 아니고, 이 구분 자체를 하지 않는 해커들도 있습니다.

지금까지 내용으로, 위 그림과 같이 TCP 세션에서 Hijacking을 하려면 어떻게 해야 할까요? 첫번째로 IP를 바꾸고, ACK를 유추해서 서버에 패킷을 보내면 될것입니다. 서버는 ACK만 맞다면 패킷을 받아들여서 정상 사용자가 내린 명령이라고 판단하고 명령을 수행할 것입니다. 관리자의 TELNET 세션을 HIJACKING한다면 서버를 날려버리는 것도 가능할 것입니다. 하지만 ACK를 유추해내는 것은 세션을 실시간으로 모니터링 하지 않는 이상 거의 불가능합니다. 왜냐하면 ACK는 32 bit이므로 2의 32승 만큼의 숫자 범위 내에 있기 때문입니다. 예전 방식으로는 -2의 31승 부터 2의 31승까지 순차적으로 ACK를 만들어 보내는 방법을 사용하였습니다. ACK가 순차적으로 증가하는 버그가 있었기 때문입니다. 하지만 지금은 ACK또한 순차적으로 증가하지 않습니다. 반대로 모니터링 한다면 매우 쉽게 Hijacking할 수 있을 것입니다. ACK가 노출되어 있기 때문입니다. 그래서 세션을 모니터링 할 수 있는 사내망이나 같은 건물의 사용자, 같은 AP 사용자들은 이를 쉽게 할 수 있게 되는 것입니다. 이 사실을 안다면 공공장소에서의 중요한 작업을 자제해야겠습니다.
여기까지의 내용이 지금까지 일반적인 사람들이 생각하는 TCP Hijacking이고 이제는 이 공격으로 부터 안전하다고 많은 사람들이 생각하였습니다. 하지만 이 글을 쓴 1km는 기발한 방법으로 TCP Hijacking을 시도하려고 합니다. 그 방법을 알아보기 전에 미리 알아야 할 것들 몇가지를 더 짚어보겠습니다.
Simple ACK
Simple ACK라는 것은 TCP 헤더에 Payload 사이즈가 50이라고 명시한 패킷이 도착하였지만 Payload가 50이 아닐 경우 Size가 0인 ACK로 에러를 응답하는 것을 말합니다.
Flow control mechanism
플로우 컨트롤은 TCP에서 매우 복잡한 개념입니다. 간단하게 설명하자면 Window라는 사이즈로 플로우를 관리하고, 주어진 시간안에 호스트는 Window 크기 만큼 패킷을 수신해야 한다고 생각하시면 이 글을 이해하는데 큰 문제가 없습니다. 자세한 것은 TCP/IP와 관련된 다른 서적이나 글을 통해 공부해보시기 바랍니다.
TCP Flag
TCP 는 6개의 FLAG를 가지고 있습니다. 각각의 플래그는 1개의 BIT로 켜지고 꺼지는 것으로 TCP 패킷을 속성을 나타냅니다. 각 FLAG는 다음과 같습니다.
SYN - 세션을 설정할 때 사용됩니다.
ACK - SYN에 대한 응답 패킷을 보낼 때 사용됩니다.
FIN - 세션을 종료시키는데 사용됩니다.
RST - 비 정상적인 세션 끊기에 사용됩니다.
PSH - 패킷을 모두 수신할때까지 기다리지 않고 바로 상위 레이어로 패킷을 전달합니다.
URG - 패킷이 순차적으로 상위 레이어로 올라가는데, 이 플래그가 켜져 있으면 바로 전달합니다.
IP_ID
IP 헤더에 포함되어 있는 16-bit 숫자 입니다. 이것은 패킷별로 유일한 값을 가집니다. IP_ID 값은 패킷당 유일한 값이므로 이 값을 이용하여 IP fragmentation(최대 전송 가능한 크기로 패킷을 쪼개는 것)과 Reassembly(쪼개진 패킷을 다시 합치는데)에 사용합니다. Packet 별로 유일한 값을 가져야 하기 때문에 대부분의 OS는 이 값을 Global로 처리하여 모든 프로세스가 하나의 변수를 바라보게 합니다. Window 98, 2000, XP가 모두 그렇습니다. 생각해보면 이 값은 계속 랜덤하게 바뀌면 오히려 최악의 경우 IP_ID가 같은 두개의 패킷이 생길 수 있으므로, 패킷을 전송할때마다 증가시켜서 사용하는 것이 맞습니다. 또 대부분의 운영체제가 그렇게 관리합니다. 다음 그림과 같이 1개의 PING을 받으면 IP_ID 값이 역시 증가하는 것을 보실 수 있습니다.

Hijacking!!!
Hijacking을 하려면 어떤 정보가 필요할까요? 먼저 Hijacking하려는 두개의 클라이언트와 서버를 알아야 할 것입니다. 만약 A라는 클라이언트가 GETROOT라는 서버에 연결되어 온라인 게임을 즐기고 있다. 이것을 Hijacking 하여 내가 중간에 서버에 명령을 내려야겠다고 한다면 우리는 지금 A 클라이언트의 IP, GETROOT 게임 서버의 IP, PORT를 알수 있는 상태일 것입니다. A라는 클라이언트의 IP는 메신져나 채팅, P2P 게임등을 통해 알아냈다고 가정합니다. 이때 우리가 꼭 알아내야 할것이 A 클라이언트의 통신 중인 Source TCP port 입니다. Source port를 알아내야 GETROOT 서버에 내가 A인척 하면서 패킷을 정상적으로 전달할 수 있을 것입니다. 또 클라이언트의 SEQ와 ACK를 알아내야 합니다. 이 3가지 정보를 정확히 생성할 수 있다면 Hijacking이 성공할 수 있습니다.
클라이언트의 포트 알아내기

클라이언트가 서버와 어떤 포트로 통신하고 있는지 알아내는것만으로도 해킹할 수 있는 여지는 매우 높아집니다. 이것을 알아내는것은 생각보다 매우 쉽습니다. 이 방법은 클라이언트와 서버가 현재 통신중이라는 특성과 IP_ID를 이용합니다.
먼저 공격자가 서버에 클라이언트의 IP와 추정한 포트 번호(1~65535) 까지중 한가지로 속여서 서버에 연결 시도 패킷(SYN)을 전송합니다. 서버에서는 클라이언트의 새로운 연결 시도인 것으로 생각하고 연결에 대한 응답 패킷을 클라이언트로 전송할 것입니다. 이때 서버에서 보내는 Destination port 가 클라이언트에 열려있지 않은 포트라면 클라이언트는 열려있지 않은 포트 번호이므로 서버에 RST 패킷을 보낼 것입니다. 이때 클라이언트의 IP_ID는 패킷을 전송하였기 때문에 증가하게 됩니다. 만약 열려있는 포트라면 현재 연결된 세션에 전송된 패킷이고, 분명히 SEQ와 ACK가 틀릴 것이며 새로운 접속을 맺으려고 하는 것이기 때문에 잘못된 패킷으로 생각해서 응답을 보내지 않고 그냥 무시하게 됩니다. 이때 클라이언트의 IP_ID는 증가하지 않게 될 것입니다. 공격자는 IP_ID를 PING 패킷을 전송하여 확인할 수 있습니다. 클라이언트로 PING을 처음 보냈을 때 1이고 두번째 보냈을때 2라면 1개의 패킷당 1씩 증가한다고 추측할 수 있습니다. 이것을 이용하여 서버에 패킷을 보내고 클라이언트의 IP_ID를 확인하여 더 많은 증가가 있었다면 틀린 PORT, 증가가 없었다면 맞는 PORT라고 예측해낼 수 있는 것입니다. 최악의 경우 65535번 확인해야 하지만, 컴퓨터가 돌려서 확인하는 것이므로 아무리 오래 걸려도 1분이면 확인해 낼 수 있을 것입니다. 이 방법은 클라이언트와 서버가 서로 패킷을 주고 받지 않고 있는 상태(사용자가 쉬고 있거나 하는 상태) 라는 가정이 있습니다.
클라이언트의 SEQ와 ACK 알아내기
클라이언트의 SEQ와 ACK를 알아내기 위해서는 최소한 2^32 * 2^32번의 경우의 수를 모두 해봐야 합니다. 이것은 매우 큰 수 입니다. 이만큼의 시도를 서버에 한다는 것은 매우 큰 문제를 일으킬 수 있습니다. 하지만 이것을 IP_ID를 이용해서 조금은 쉽게 추측해낼 수 있습니다.
클라이언트에 서버로 가장하여 역시 SEQ와 ACK를 전송합니다. 맞지 않다면 SIMPLE ACK를 클라이언트가 서버로 전송할 것입니다. 이것은 IP_ID가 증가한다는 것을 의미합니다. 위의 포트를 알아내는 것과 다른 점은 포트를 알아낼때는 서버가 이미 연결된 세션을 향해 새로운 연결 시도 패킷을(SYN) 보냈다는 것입니다. 클라이언트의 IP_ID가 증가하지 않을때까지 계속 랜덤한 SEQ와 ACK를 전송하는 것으로 이 값들을 구해낼 수 있습니다. 서버에는 아무런 패킷을 전송하지 않아도 된다는 것입니다. 이것은 매우 큰 장점입니다.
더 빨리 SEQ와 ACK를 추측할 수 있는 방법을 제시하는데 제가 이해를 잘 못하는 것인지 Brute force 방법과 크게 다른점이 없어 보입니다. 만약 원문을 읽으시고 Brute force이긴 하지만 시도하는 수를 확 줄일 수 있는 방법을 제시했다면 저에게 알려주시기 바랍니다.
마치며...
이 글을 읽으며 Hijacking이 성공하겠다! 라는 느낌보다는 기존에 아무도 버그라고 생각하지 못했던 IP_ID를 이용해 클라이언트의 포트를 알아내고, SEQ, ACK 추측에 서버가 아닌 클라이언트를 이용할 수 있다는 점에, 그리고 가장 큰 문제였던 SEQ, ACK가 맞는지 아닌지 그 답을 알 수 있게 발전시킨점으로 감명을 받았습니다. 누군가가 이 방식을 조금 더 발전시켜서 SEQ와 ACK도 쉽게 추측해낼 수 있는 방법을 제시할 것으로 보입니다. 몇몇 분들은 IP_ID를 랜덤하게 만들면 되지 않겠느냐고 하는데, 예 그것만으로도 이 방법은 사용할 수 없게 됩니다. 하지만 이미 WINDOW 98, 2000, XP가 이 취약점 아닌 취약점을 가지고 있습니다.
제 글은 출처를 명시한다면 누구나 퍼가실 수 있습니다.
여기서 한가지 의문이 들 수 있습니다. 클라이언트와 서버가 보내는 패킷을 보다가 다음 ACK를 예측하여 IP를 클라이언트의 IP로 수정한 후 순간적으로 클라이언트보다 서버에 먼저 응답한다면 서버는 그 패킷을 받아들이는가 하는 것입니다. 예 맞습니다. 그것이 바로 TCP/IP Hijacking 입니다. 과거에는 꼭 클라이언트와 서버의 패킷을 모니터링 하지 않아도 이 SEQ와 ACK를 어느정도 유추할 수 있는 방법이 있었습니다. 그것은 예전 운영체제가 ISN을 정해진 공식에 의해서 발생시킨다는 것이였는데, 예를 들어 내가 서버에 접속했을 때 ISN이 1000이였다면, 그 다음에 접속할 때 ISN이 1001이 되는 식의 방법이였습니다. ISN만 예측할 수 있다면 내 IP를 바꾸어서 서버에 충분히 접속할 수 있게 됩니다. 만약 서버가 1.1.1.1이라는 IP를 신뢰하여 모든 명령을 받아들이는 상태라면 1.1.1.1로 자신의 IP를 바꾸어 서버에 명령을 내릴 수 있겠죠. 물론 서버의 응답을 받을 순 없지만, 패킷을 받아들이게 하는 것 만으로도 수많은 것을 할 수 있을 것입니다. 하지만 최신 OS는 당연히 ISN을 랜덤하게 발생시켜서 예측할 수 없게 만들고 있습니다. 해커들이 IP-Spoofing과 Hijacking을 구분하는 것은 이와 같이 처음부터 IP를 바꾸어 서버에 접속하는 것을 IP-Spoofing이라고 부르고, 아래 그림과 같이 통신하는 중간에 자신이 패킷을 껴넣어 의도하는 명령을 내리는 것을 Hijacking이라고 구분합니다. 물론 모든 해커들이 이렇게 구분하는 것은 아니고, 이 구분 자체를 하지 않는 해커들도 있습니다.
TCP/IP Hijacking
지금까지 내용으로, 위 그림과 같이 TCP 세션에서 Hijacking을 하려면 어떻게 해야 할까요? 첫번째로 IP를 바꾸고, ACK를 유추해서 서버에 패킷을 보내면 될것입니다. 서버는 ACK만 맞다면 패킷을 받아들여서 정상 사용자가 내린 명령이라고 판단하고 명령을 수행할 것입니다. 관리자의 TELNET 세션을 HIJACKING한다면 서버를 날려버리는 것도 가능할 것입니다. 하지만 ACK를 유추해내는 것은 세션을 실시간으로 모니터링 하지 않는 이상 거의 불가능합니다. 왜냐하면 ACK는 32 bit이므로 2의 32승 만큼의 숫자 범위 내에 있기 때문입니다. 예전 방식으로는 -2의 31승 부터 2의 31승까지 순차적으로 ACK를 만들어 보내는 방법을 사용하였습니다. ACK가 순차적으로 증가하는 버그가 있었기 때문입니다. 하지만 지금은 ACK또한 순차적으로 증가하지 않습니다. 반대로 모니터링 한다면 매우 쉽게 Hijacking할 수 있을 것입니다. ACK가 노출되어 있기 때문입니다. 그래서 세션을 모니터링 할 수 있는 사내망이나 같은 건물의 사용자, 같은 AP 사용자들은 이를 쉽게 할 수 있게 되는 것입니다. 이 사실을 안다면 공공장소에서의 중요한 작업을 자제해야겠습니다.
여기까지의 내용이 지금까지 일반적인 사람들이 생각하는 TCP Hijacking이고 이제는 이 공격으로 부터 안전하다고 많은 사람들이 생각하였습니다. 하지만 이 글을 쓴 1km는 기발한 방법으로 TCP Hijacking을 시도하려고 합니다. 그 방법을 알아보기 전에 미리 알아야 할 것들 몇가지를 더 짚어보겠습니다.
Simple ACK
Simple ACK라는 것은 TCP 헤더에 Payload 사이즈가 50이라고 명시한 패킷이 도착하였지만 Payload가 50이 아닐 경우 Size가 0인 ACK로 에러를 응답하는 것을 말합니다.
Flow control mechanism
플로우 컨트롤은 TCP에서 매우 복잡한 개념입니다. 간단하게 설명하자면 Window라는 사이즈로 플로우를 관리하고, 주어진 시간안에 호스트는 Window 크기 만큼 패킷을 수신해야 한다고 생각하시면 이 글을 이해하는데 큰 문제가 없습니다. 자세한 것은 TCP/IP와 관련된 다른 서적이나 글을 통해 공부해보시기 바랍니다.
TCP Flag
TCP 는 6개의 FLAG를 가지고 있습니다. 각각의 플래그는 1개의 BIT로 켜지고 꺼지는 것으로 TCP 패킷을 속성을 나타냅니다. 각 FLAG는 다음과 같습니다.
SYN - 세션을 설정할 때 사용됩니다.
ACK - SYN에 대한 응답 패킷을 보낼 때 사용됩니다.
FIN - 세션을 종료시키는데 사용됩니다.
RST - 비 정상적인 세션 끊기에 사용됩니다.
PSH - 패킷을 모두 수신할때까지 기다리지 않고 바로 상위 레이어로 패킷을 전달합니다.
URG - 패킷이 순차적으로 상위 레이어로 올라가는데, 이 플래그가 켜져 있으면 바로 전달합니다.
IP_ID
IP 헤더에 포함되어 있는 16-bit 숫자 입니다. 이것은 패킷별로 유일한 값을 가집니다. IP_ID 값은 패킷당 유일한 값이므로 이 값을 이용하여 IP fragmentation(최대 전송 가능한 크기로 패킷을 쪼개는 것)과 Reassembly(쪼개진 패킷을 다시 합치는데)에 사용합니다. Packet 별로 유일한 값을 가져야 하기 때문에 대부분의 OS는 이 값을 Global로 처리하여 모든 프로세스가 하나의 변수를 바라보게 합니다. Window 98, 2000, XP가 모두 그렇습니다. 생각해보면 이 값은 계속 랜덤하게 바뀌면 오히려 최악의 경우 IP_ID가 같은 두개의 패킷이 생길 수 있으므로, 패킷을 전송할때마다 증가시켜서 사용하는 것이 맞습니다. 또 대부분의 운영체제가 그렇게 관리합니다. 다음 그림과 같이 1개의 PING을 받으면 IP_ID 값이 역시 증가하는 것을 보실 수 있습니다.
Hijacking!!!
Hijacking을 하려면 어떤 정보가 필요할까요? 먼저 Hijacking하려는 두개의 클라이언트와 서버를 알아야 할 것입니다. 만약 A라는 클라이언트가 GETROOT라는 서버에 연결되어 온라인 게임을 즐기고 있다. 이것을 Hijacking 하여 내가 중간에 서버에 명령을 내려야겠다고 한다면 우리는 지금 A 클라이언트의 IP, GETROOT 게임 서버의 IP, PORT를 알수 있는 상태일 것입니다. A라는 클라이언트의 IP는 메신져나 채팅, P2P 게임등을 통해 알아냈다고 가정합니다. 이때 우리가 꼭 알아내야 할것이 A 클라이언트의 통신 중인 Source TCP port 입니다. Source port를 알아내야 GETROOT 서버에 내가 A인척 하면서 패킷을 정상적으로 전달할 수 있을 것입니다. 또 클라이언트의 SEQ와 ACK를 알아내야 합니다. 이 3가지 정보를 정확히 생성할 수 있다면 Hijacking이 성공할 수 있습니다.
클라이언트의 포트 알아내기
클라이언트가 서버와 어떤 포트로 통신하고 있는지 알아내는것만으로도 해킹할 수 있는 여지는 매우 높아집니다. 이것을 알아내는것은 생각보다 매우 쉽습니다. 이 방법은 클라이언트와 서버가 현재 통신중이라는 특성과 IP_ID를 이용합니다.
먼저 공격자가 서버에 클라이언트의 IP와 추정한 포트 번호(1~65535) 까지중 한가지로 속여서 서버에 연결 시도 패킷(SYN)을 전송합니다. 서버에서는 클라이언트의 새로운 연결 시도인 것으로 생각하고 연결에 대한 응답 패킷을 클라이언트로 전송할 것입니다. 이때 서버에서 보내는 Destination port 가 클라이언트에 열려있지 않은 포트라면 클라이언트는 열려있지 않은 포트 번호이므로 서버에 RST 패킷을 보낼 것입니다. 이때 클라이언트의 IP_ID는 패킷을 전송하였기 때문에 증가하게 됩니다. 만약 열려있는 포트라면 현재 연결된 세션에 전송된 패킷이고, 분명히 SEQ와 ACK가 틀릴 것이며 새로운 접속을 맺으려고 하는 것이기 때문에 잘못된 패킷으로 생각해서 응답을 보내지 않고 그냥 무시하게 됩니다. 이때 클라이언트의 IP_ID는 증가하지 않게 될 것입니다. 공격자는 IP_ID를 PING 패킷을 전송하여 확인할 수 있습니다. 클라이언트로 PING을 처음 보냈을 때 1이고 두번째 보냈을때 2라면 1개의 패킷당 1씩 증가한다고 추측할 수 있습니다. 이것을 이용하여 서버에 패킷을 보내고 클라이언트의 IP_ID를 확인하여 더 많은 증가가 있었다면 틀린 PORT, 증가가 없었다면 맞는 PORT라고 예측해낼 수 있는 것입니다. 최악의 경우 65535번 확인해야 하지만, 컴퓨터가 돌려서 확인하는 것이므로 아무리 오래 걸려도 1분이면 확인해 낼 수 있을 것입니다. 이 방법은 클라이언트와 서버가 서로 패킷을 주고 받지 않고 있는 상태(사용자가 쉬고 있거나 하는 상태) 라는 가정이 있습니다.
클라이언트의 SEQ와 ACK 알아내기
클라이언트의 SEQ와 ACK를 알아내기 위해서는 최소한 2^32 * 2^32번의 경우의 수를 모두 해봐야 합니다. 이것은 매우 큰 수 입니다. 이만큼의 시도를 서버에 한다는 것은 매우 큰 문제를 일으킬 수 있습니다. 하지만 이것을 IP_ID를 이용해서 조금은 쉽게 추측해낼 수 있습니다.
클라이언트에 서버로 가장하여 역시 SEQ와 ACK를 전송합니다. 맞지 않다면 SIMPLE ACK를 클라이언트가 서버로 전송할 것입니다. 이것은 IP_ID가 증가한다는 것을 의미합니다. 위의 포트를 알아내는 것과 다른 점은 포트를 알아낼때는 서버가 이미 연결된 세션을 향해 새로운 연결 시도 패킷을(SYN) 보냈다는 것입니다. 클라이언트의 IP_ID가 증가하지 않을때까지 계속 랜덤한 SEQ와 ACK를 전송하는 것으로 이 값들을 구해낼 수 있습니다. 서버에는 아무런 패킷을 전송하지 않아도 된다는 것입니다. 이것은 매우 큰 장점입니다.
더 빨리 SEQ와 ACK를 추측할 수 있는 방법을 제시하는데 제가 이해를 잘 못하는 것인지 Brute force 방법과 크게 다른점이 없어 보입니다. 만약 원문을 읽으시고 Brute force이긴 하지만 시도하는 수를 확 줄일 수 있는 방법을 제시했다면 저에게 알려주시기 바랍니다.
마치며...
이 글을 읽으며 Hijacking이 성공하겠다! 라는 느낌보다는 기존에 아무도 버그라고 생각하지 못했던 IP_ID를 이용해 클라이언트의 포트를 알아내고, SEQ, ACK 추측에 서버가 아닌 클라이언트를 이용할 수 있다는 점에, 그리고 가장 큰 문제였던 SEQ, ACK가 맞는지 아닌지 그 답을 알 수 있게 발전시킨점으로 감명을 받았습니다. 누군가가 이 방식을 조금 더 발전시켜서 SEQ와 ACK도 쉽게 추측해낼 수 있는 방법을 제시할 것으로 보입니다. 몇몇 분들은 IP_ID를 랜덤하게 만들면 되지 않겠느냐고 하는데, 예 그것만으로도 이 방법은 사용할 수 없게 됩니다. 하지만 이미 WINDOW 98, 2000, XP가 이 취약점 아닌 취약점을 가지고 있습니다.
제 글은 출처를 명시한다면 누구나 퍼가실 수 있습니다.




댓글을 달아 주세요
Thank you 2009.04.07 11:26 신고 댓글주소 수정/삭제 댓글쓰기
랜덤으로 왔다가 좋은 글 잘 읽고 갑니다.^^
TCP에 대한 지식이 방대하지 않아 100%이해는 불가능 하였지만
개인적으로 도움이 많이 되었네요~ 감사합니다.
감사합니다. ^^ 자주 놀러오셔서 자료 많이 공유해주세요.
Shuzy 2009.07.31 16:00 댓글주소 수정/삭제 댓글쓰기
http://www.hackthissite.org/
추천합니다 ^^ 한국인의 실력을 보여주세요~
xoen 2011.04.07 19:39 댓글주소 수정/삭제 댓글쓰기
웹 해킹과 보안에 대해서 찾아보다가 정말로 좋은 자료 많이 보고 갑니다^^ 이런 포스팅 많이 해주세요!
XaaEon 2012.06.18 15:55 댓글주소 수정/삭제 댓글쓰기
구글링중 잘읽고 출저 명시하며 퍼갑니다^^ 포스팅 기대하겠습니다! 감사합니다
김진리 2013.11.25 10:56 신고 댓글주소 수정/삭제 댓글쓰기
잘읽었습니다 ㅎㅎ 퍼가기 기능이 없네요 본문 복사해야하나..
키위 2015.11.30 20:26 댓글주소 수정/삭제 댓글쓰기
정말 유익한 글이네요 ㅎㅎ 잘 보고 갑니다