Network Convert Channel #1

(무선)네트워크 2010. 1. 18. 13:51 Posted by 알 수 없는 사용자

▷ 작성자 : 김민상 (minams@a3sc.co.kr)


Network Convert Channel #1

목  차

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 #1

1. Sniffing Communication
기존의 network통신에서 데이터를 주고 받을 때, 기 연결된 소켓을 이용하여 recv()를 호출하면 kernel에서 대응(매칭되는)하는 Packet을 알아서 전달해 주게 되어있습니다. 이것은 packet 받기 위해선 사전에 매칭되는 소켓을 가지고 있어야 함을 의미하게 됩니다. 그러나 알려진 대로 NIC는 Promiscuous Mode로 동작하기 때문에 Sniff용 소켓을 생성하는 것만으로도 packet의 수신 및 가공이 가능하게 됩니다.

다음의 화면은 간단히 채팅이 가능하도록 구현된 프로그램입니다.

[그림 1] 채팅 Client 1


[그림 2] 채팅 Client 2


위 그림들을 보면 보통의 채팅 프로그램과 유사하게 동작하는 것 같지만 WireShark등을 이용해 그 Packet을 확인해보면 보통의 채팅 프로그램과 다르다는 것을 알 수 있습니다.


[그림 3] Packet 분석

위의 packet을 가만히 보면 Destination port가 일정하지 않고 항상 다릅니다. 그 이유는 채팅을 위해 서버를 생성(Port Listening) 하지 않고 수신한 packet중 원하는 Packet만 가공(printf)하였기 때문입니다.

2. Sniff Chatting Code
이 프로그램에서는 Packet에 단순한 Signature를 삽입하여 이를 이용하여 판별하였으며, 일부 코드는 다음과 같습니다.

다음은 위 채팅코드 main의 일부 입니다.

 SOCKET SnifferSocket = SetSnifferMode(); //  Sniff 모드 Socket 생성
if(SnifferSocket == INVALID_SOCKET)

 return 0;
… 중략
while(1){
 randPort = rand() % 65535; //  목적지 port를 매번 다르게 셋팅
 SOCKADDR_IN DestAddr;
 memset(&DestAddr, 0x00, sizeof(DestAddr));
 DestAddr.sin_family = AF_INET;
 DestAddr.sin_port = randPort;
 DestAddr.sin_addr.s_addr = DestIP;
 
memset(SendBuffer, 0x00, sizeof(SendBuffer));
 
        … 중략
 PacketSend(DestAddr, SendBuffer, nSend); //  SendBuffer 전송
        // 원하는 패킷 수신 int PacketRecv(SOCKET, char *RecvBuffer)
nRecv = PacketRecv(SnifferSocket, (char *)RecvBuffer);
 printf("Recv Msg : %s", RecvBuffer);
 memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
}
return 0;

다음은 원하는 Packet을 수신하는 PacketRecv() 함수의 일부 입니다.

 SniffPacket = (unsigned char *)malloc(65536); // Packet Buffer
if(SniffPacket == NULL) return FALSE;

do{
 memset(SniffPacket, 0x00, 65535);
 nPacket = recvfrom(SnifferSocket,(char *)SniffPacket,65536,0, 0, 0);
 … 중략
 // 원하는 패킷 판별 1
if(iphdr->ip_protocol == 17&&iphdr->ip_srcaddr != ServerAddr.sin_addr.s_addr){

  UDP_HDR  *udphdr;
  unsigned short iphdrlen = iphdr->ip_header_len*4;
  udphdr = (UDP_HDR *)(SniffPacket + iphdrlen);
  MSI_MSG *msi = (MSI_MSG *)(SniffPacket + iphdrlen + sizeof(UDP_HDR));
  // 원하는 패킷 판별 2(단순한 signature 이용)
  if(!strncmp((const char *)msi->signature, SIGNATURE, 8)){
     
   DestIP = iphdr->ip_srcaddr;
   memcpy(RecvBuffer, msi->msg, 512);
   free(SniffPacket);
   return (nPacket - iphdrlen - sizeof(UDP_HDR) - sizeof(MSI_MSG) + 512);
  }
 }//if(iphdr->ip_protocol == 17){ // UDP
}while (nPacket > 0);
free(SniffPacket);



 

3. 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


※ 현재 ㈜에이쓰리시큐리티에서 테스트 및 분석 중에 있으며, 이 문서는 계속 업데이트될 것입니다. 본 문서는 보안취약점으로 인한 피해를 최소화하는 데 도움이 되고자 작성되었으나, 본 문서에 포함된 대응방안의 유효성이나 기타 예상치 못한 시스템의 오작동 발생에 대하여서는 ㈜에이쓰리시큐리티에서는 일체의 책임을 지지 아니합니다.