Search

'network'에 해당되는 글 2건

  1. 2010.01.18 Network Convert Channel #2 2
  2. 2010.01.18 Network Convert Channel #1

Network Convert Channel #2

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

▷ 작성자 : 김민상 (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을 생성하게 됩니다.

 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을 사용하였습니다.
 

int SetUdpPacket(unsigned char *Packet, char *SourceIP, char *DestinationIP, char *SendBuffer)
{
…중략
 // 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);

…중략

 iphdr = (IPV4_HDR *)Packet;


// 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));
…중략

// UDP 해더 셋팅------------------------------------------------------------------
 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);
…중략

 return 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


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

 


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


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