▷ 작성자 : 김민상 (minams@a3sc.co.kr)
Network Convert Channel #2
목 차
I. 개요
1. 연구 개요
2. 연구 주제
II. NETWORK CONVERT CHANNEL #1
1. SNIFFING COMMUNICATION
2. SNIFF CHATTING CODE
3. REFERENCE
I. 개요
1. 연구 개요
09. 09 A3 지식사업팀에서는 좀 더 한정된 PT환경에서 DNS서버의 해킹으로 인한 내부 서버의 위협가능성을 판단하고 이를 보완하고자 자체적으로 PT(터널링)툴 개발을 진행하였으며, 개발 과정에 연구된 내용을 바탕으로 작성하게 되었습니다.
2. 연구 주제
Network Layer에서의 Convert Channel 기법
구분
주제
Network Convert Channel #1
Sniffing 기법을 이용한 Convert Channel
Network Convert Channel #2
UDP Outbound Session을 이용한 사설망 접근
II. Network Convert Channel #2
1. UDP Outbound Session
흔히 NAT에서 outbound/inbound라고 표현을 하며, session을 붙여 inbound session(밖에서 안으로 성립/허가된 session), outbound session(안에서 밖으로 성립/허가된 session)이라 합니다. 정리하면,
구분
설명
inbound
(NAT) 밖에서 안으로 향하는 Packet
outbound
(NAT) 안에서 밖으로 향하는 Packet
inbound session
밖에서 안으로 향하는 허가(성립)된 연결
outbound session
안에서 밖으로 향하는 허가(성립)된 연결
기존에 outbound session을 이용하여 inbound 방화벽을 우회하는 Reverse Connection이라든가 Reverse Tunneling 등의 위협은 잘 알려져 있습니다. 이러한 outbound session을 이용(UDP)하여 외부에서 사설망 내부IP에 접근하는 기법에 대하여 이야기 하고자 합니다.
다음은 네트워크 UDP packet을 dump한 화면입니다.
[그림 1] UDP Dump
위 Packet들을 유심히 들여다보면 168.126.63.1은 외부에서 사설망 내부 IP로 접근을 했다는 사실을 알 수 있습니다. 그래서 어떻게 해서 외부에서 내부 IP에 접근할 수 있었냐를 확인해본 결과, UDP packet의 src IP/Port, dst IP/Port 의 쌍이 그 답이었습니다.
다음은 두 packet의 in/outbound packet dump 화면입니다.
[그림 2] outbound packet
[그림 3] inbound packet
외부에서 들어온 inbound packet의 MAC Address를 확인해보면 실제 서버의 MAC이 아닌 Gateway의 MAC이며, 이는 외부에서 session을 유지한 채 packet을 전송하기 위해서 전송해야 할 IP가 내부 IP가 아닌 Gateway의 IP가 되어야 함을 의미하게 됩니다.
다음은 위의 두 packet의 MAC Address가 Gateway의 MAC Address임을 확인하는 화면입니다.
[그림 4] Gateway MAC Address
다음과 같은 outbound packet에 대하여 대응(연결)는 inbound packet을 구성해보면 다음과 같습니다.
outbound packet
inbound packet
Source IP
192.168.0.2
1.1.1.1
Source Port
9090
53
Destination IP
1.1.1.1
192.168.0.2 사설망의 외부IP(Gateway)
Destination Port
53
9090
위의 서버를 생성(Port Listening) 하지 않고 수신한 packet중 원하는 Packet만 가공(printf)하였기 때문입니다.
2. Outbound Session이용하기
다음 그림과 같이 내부에서 주기적으로 다음과 같은 packet을 전송하고 있습니다.
[그림 5] Outbound Packet
이 packet으로 인하여 Gateway(192.168.0.1-10.10.10.86)에는 내부PC-192.168.0.2(9090)에서 10.10.10.86(53)으로 나가는 Outbound Session이 생겨났습니다.
[그림 6] Packet Capture 1
그 다음 같은 사설망이 아닌 외부 PC에서 사설망 Gateway IP(10.10.10.84)로 아래의 그림과 같이 Source IP, Port와 Destination Port를 맞춰 data(ShowMe?)를 전송하도록 하였습니다.
[그림 7] Inbound Packet
그 결과 외부 IP(10.10.10.86, 192대역 사설망에서의 외부)에서 192.168.0.2로 원하는 data 수신이 가능하였습니다.
[그림 8] Inbound Packet Capture
지극히 당연한 결과지만 이를 통해 다음과 같은 내용들을 확인할 수 있습니다.
첫째로, 내부에서 의도적인 outbound session 생성 즉, 목적지 IP, Port와 Gateway의 IP만 알 수 있다면 Raw Packet을 이용(임의의Source IP, Port 셋팅)하여 외부의 그 어떤 PC를 이용하더라고 원하는 data를 전송할 수 있습니다.
둘째로, 문서에 테스트과정을 포함시키지 않았지만 나와있지 않지만, Gateway에서는 초기 outbound packet의 IP와 Port를 이용하여session을 맺기 때문에 내부의 PC 한대로 또 다른 내부의 PC로의 data전송이 가능(Source IP 수정하는 방법을 사용 시)하였습니다.
이러한 방법을 이용하면 외부의 IP추적이 어려워지며, 두 번째 방법을 적용하게 되면 실제 data를 수신한 PC만으로는 통신내역을 분석할 방법이 없다는 것입니다.
3. in/outbound packet 생성 코드
이 테스트 프로그램은 정상적인 packet으로 위장하기 위하여 정상적인 DNS packet에 data를 추가하는 방법을 사용하여 packet을 전송하였습니다.
다음은 테스트 프로그램의 main()함수 입니다. UDP timeout session을 유지하기 위하여 반복적으로 session을 생성하게 됩니다. int SetUdpPacket(unsigned char *Packet, char *SourceIP, char *DestinationIP, char *SendBuffer) …중략 iphdr = (IPV4_HDR *)Packet; // UDP 해더 셋팅------------------------------------------------------------------ return nSend;
USHORT checksum(USHORT *buffer, int size);
void UdpPseudoHeaderChecksum(void *iphdr, UDP_HDR *udphdr, char *payload, int payloadlen);
int SetUdpPacket(unsigned char *Packet, char *SourceIP, char *DestinationIP, char *SendBuffer);
bool SendRawPacket(unsigned char *Packet, int nSend);
int SetFakeDnsQueryBuffer(char *SendBuffer, char *SendData, int nSendData);
int main(int argc, char *argv[])
{
unsigned char Packet[MAX_PACKET] = {0x00,};
int nSend = SetUdpPacket(Packet, argv[1], argv[2], argv[3]);
while(1){
SendRawPacket(Packet, nSend);
Sleep(30000);
}
}
다음은 미리 약속한 IP, Port 를 이용하여 session을 맺기 위하여 RAW socket을 사용하였습니다.
{
…중략
// Source IP, Port 셋팅
SourceInfo.sin_addr.s_addr = inet_addr(SourceIP);
SourceInfo.sin_port = htons(53);
// Destination IP, Port 셋팅
DestinationInfo.sin_addr.s_addr = inet_addr(DestinationIP); // 외부IP(외부로 나가는 IP면 어디든 상관없음)
DestinationInfo.sin_port = htons(9090);
// IP 해더 셋팅--------------------------------------------------------------------
iphdr->ip_version = 4;
//iphdr->ip_header_len = (4 << 4) | (sizeof(IPV4_HDR) / sizeof(unsigned long)); //ip_version, ip_header_len setting
iphdr->ip_header_len = sizeof(IPV4_HDR) / sizeof(unsigned long);
iphdr->ip_tos = (unsigned char)0;
iphdr->ip_total_length = htons(iphdr_len + udphdr_len + nSend /* Total length */);
iphdr->ip_id = 0;
iphdr->ip_ttl = (unsigned char)128;
iphdr->ip_protocol = (unsigned char)IPPROTO_UDP;//IPPROTO_UDP
iphdr->ip_checksum = (unsigned short)0; // checksum 구하기 전에 0으로 셋팅
iphdr->ip_srcaddr = SourceInfo.sin_addr.s_addr;
iphdr->ip_destaddr = DestinationInfo.sin_addr.s_addr;
iphdr->ip_checksum = checksum((unsigned short *)iphdr, sizeof(IPV4_HDR));
…중략
udphdr = (UDP_HDR *)(Packet + iphdr_len);
udphdr->source_port = SourceInfo.sin_port;
udphdr->dest_port = DestinationInfo.sin_port;
udphdr->udp_length = htons(udphdr_len + nSend);
UdpPseudoHeaderChecksum(iphdr, udphdr, SendBuffer, nSend);
…중략
}
4. Reference
[site]
http://support.microsoft.com/kb/190351/ko
http://netcat.sourceforge.net/
http://wiki.kldp.org/Translations/Raw_IP_FAQ-KLDP
http://www.winpcap.org/docs/docs_41b5/html/main.html
http://www.codesos.com/book/network/IN_ADDR.html
http://uuzazuk9.egloos.com/906428
[book]
윈도우 네트워크 프로그래밍 TCP/IP 소켓 프로그래밍
Network Programming for Microsoft Windows 2nd Edtion
※ 현재 ㈜에이쓰리시큐리티에서 테스트 및 분석 중에 있으며, 이 문서는 계속 업데이트될 것입니다. 본 문서는 보안취약점으로 인한 피해를 최소화하는 데 도움이 되고자 작성되었으나, 본 문서에 포함된 대응방안의 유효성이나 기타 예상치 못한 시스템의 오작동 발생에 대하여서는 ㈜에이쓰리시큐리티에서는 일체의 책임을 지지 아니합니다.