프로젝트 개요
본 프로젝트는 네트워크의 패킷을 분석하는 프로그램을 만들어서, 네트워크 Raw 패킷을 통해서 세부적인 정보를 효율적으로 파악하는 것을 목적으로 한다. 오픈 소스 네트워크 패킷 분석 수집 프로그램인 ‘WireShark’에서는 분석 및 수집을 원하는 네트워크 영역을 선택하고, 이를 통해서 실시간으로 Host에서 일어나고 있는 네트워크 통신을 볼 수 있도록 하며, 캡쳐한 해당 패킷들을 ‘.pcap’ 파일로 저장할 수 있다. 여기서 추출해낸 ‘.pcap’ 파일을 저장하고, ‘NetworkMiner’라는 프로그램에서 불러와서 패킷을 추가적으로 분석할 수 있다.
본 프로젝트의 궁극적인 목표는 ‘NetworkMiner’에서 제공하는 패킷 분석 기능을 구현하는 것이다. 시간적 여유가 된다면, 추가적으로 ‘Wireshark’의 기능인 실시간 패킷 캡쳐 및 분석기능을 결합하고자 한다. 가상 환경에서 실시간으로 네트워크 패킷을 캡쳐하고, 해당 패킷에 내재되어 있는 정보들을 추출하여 프로그램의 사용자에게 가시적으로 보여준다.
프로토콜 분석
HTTP
- 인터넷 통신 프로토콜 (HyperText Transfer Protocol)
- 클라이언트는 서버에 Request <-> 서버는 클라이언트에 Response
- Ehternet Header + IPv4 Header + TCP Header + HTTP Data
- HTTP Data는 html 뿐만 아니라 이미지, 영상, 음성 데이터의 전송도 가능
- 연결은 3 way-handshake (SYN / SYN + ACK / ACK)
- 종료는 4 way-handshake (FIN / ACK / FIN / ACK)
- 클라이언트가 서버에 요청을 보내고, 응답을 받으면 통신이 종료
- 서버와 통신할 때 80번 포트 사용
SMTP
- 메일 전송 프로토콜 (Simple Mail Transfer Protocol)
- TCP / IP 네트워크 상에서 메일을 송수신하기 위해 제작
- 모든 메세지가 7bit ASCII로 규정되어 있어 8bit 이상의 코드를 사용할 때는 MIME 방식으로 변환되어 전달
- Ethernet Header + IPv4 Header + TCP Header + SMTP Data
FTP
- 파일 전송 프로토콜 (File Transfer Protocol)
- TCP / IP 네트워크 상에서 컴퓨터들이 파일을 주고받기 위해 제작
- Ethernet Header + IPv4 Header + TCP Header + FTP Data
구현
전체 코드는 여기에서 확인하실 수 있습니다.
HTTP 핵심 코드
// HTTP 패킷
if (http_get_data_port.size() >= 1 && src_port == 80) {
int flag1 = 0;
int port_num = -1;
for (int i = 0; i < http_get_data_port.size(); i++) {
if (dst_port == http_get_data_port[i].first) {
flag1 = 1; // 데이터가 들어오기 시작한 포트번호인 경우
port_num = i;
break;
}
}
if (flag1) { // 해당 포트번호로 들어오는 패킷 합치기
if (http_sequence_num[port_num] == 0) {
http_sequence_num[port_num] = ntohl(tcpLayer->getTcpHeader()->sequenceNumber);
} else if (http_sequence_num[port_num] < ntohl(tcpLayer->getTcpHeader()->sequenceNumber)) {
const u_char* packet;
packet = (u_char*) rawPacket.getRawData();
uint16_t start = 14 + 20 + my_ntohs(packet[46]) * 4;
int payload_start = total_length - payload_length;
uint16_t TOTAL_LENGTH = ntohs(ipLayer->getIPv4Header()->totalLength) + 14;
if (!(packet[payload_start] == 0x48 && packet[payload_start + 1] == 0x54 &&
packet[payload_start + 2] == 0x54 && packet[payload_start + 3] == 0x50)) {
for (int i = payload_start; i < total_length; i++) {
http_data[port_num][http_data_idx[port_num]++] = packet[i];
}
}
}
}
/* 중략 */
}
SMTP 핵심 코드
// SMTP 패킷
if ((src_port == 25 || src_port == 465 || src_port == 587 ) || (dst_port == 25 || dst_port == 465 || dst_port == 587)) {
printf("\n[ SMTP Packet ]\n");
const u_char* packet;
packet = (u_char*) rawPacket.getRawData();
string smtp_response_code = "";
// SMTP response code 가져오기
for (int i = payload_start; i < payload_start + 3; i++) {
smtp_response_code += packet[i];
}
if (smtp_response_code == "220") { // 220이면 TCP 연결 시작, 서버 준비완료, SMTP 통신 시작
server_port = src_port ;
client_port = dst_port ;
} else {
if (src_port == server_port) { // server -> client
printf("(server) -> (client) \n");
for(int i= payload_start; i < total_length; i++) {
printf("%c", packet[i]);
}
}
}
/* 중략 */
}
FTP 핵심 코드
// FTP 패킷
if (src_port == 21) { // FTP Response 패킷이라면...
printf("\n[ FTP Response Packet ]\n");
const uint8_t* packet = rawPacket.getRawData();
uint16_t start = 14 + 20 + my_ntohs(packet[46]) * 4;
uint16_t TOTAL_LENGTH = ntohs(ipLayer->getIPv4Header()->totalLength) + 14;
printf("TCP header len is %d\n", my_ntohs(packet[46]) * 4);
printf("start index is %d\n", start);
printf("total length is %d\n", total_length);
printf("\nResponse: ");
for (int i = payload_start; i<total_length; i++) {
printf("%c", packet[i]);
}
std::string ftp_command = "";
// FTP response code 가져오기
printf("\nResponse Code : ");
for (int i = start; i < start + 3; i++) {
ftp_command += (u_char) packet[i];
}
ftp_response_code = atoi(ftp_command.c_str());
printf("%d", ftp_response_code);
/* 중략 */
}
프로그램 실행 결과
공통
프로그램 실행 시 출력되는 헤더 정보
프로그램 실행 시 생성되는 로그 파일
HTTP
터미널 화면에 출력되는 HTTP 관련 정보
HTTP 프로토콜에서 추출한 파일들
WireShark에서 본 HTTP 프로토콜의 Object List
프로그램 실행 시 생성된 index.action
SMTP
터미널 화면에 출력되는 SMTP 관련 정보
SMTP 프로토콜에서 추출한 파일들
프로그램 실행 시 생성된 winmail.dat
FTP
터미널 화면에 출력되는 FTP 관련 정보
FTP 프로토콜에서 추출한 파일들
프로그램 실행 시 생성된 BoB9_network.docx
프로그램 실행 시 생성된 bob-logo1.png
추후 보완 사항
- SMTP 내에서의 멀티미디어 컨텐츠 인코딩
- 라이브 패킷 분석 기능 추가
- FTP Active Mode 지원