winpcap을 이용한 sql injection공격 방어 소스제작
winpcap을 이용한 sql injection공격 방어 소스제작
랜카드 2개를 장착한 PC를 게이트웨이로 하여 양단간의 트래픽을 캡쳐한 후
이를 분석 및 필터링하여 Server로 전송하게 프로그램을 작성할려 합니다!
Linux를 사용하다 Winpcap을 이용하니 여간 힘든게 아니군요...
SQL injection을 탐지하고 방어하는 프로그램을 제작할려고 합니다.
우선 Promiscuous 모드로 패킷을 받고
목적지 IP가 Server IP주소이고 사용된 port가 80번 일시 Detect기능 수행
해당 웹서버에 ID, PASSWORD에 '-- 'having 'union 등 sql 쿼리문 이용시 탐지하여??
( 아니면 for문을 돌려 packet[i]에 순서대로 ', -, - 문자가 들어오면이 좋은가요?)
그 쿼리문의 사용한 컴퓨터 IP에서 SQLinjection공격!!! 라는 식의 알람이 발생하는 프로그램을 제작할려합니다.
어떤식으로 소스를 짜야되고 ㅠ 내가 필요한 부분을 캡쳐 해서 Detection룰에 비교하는지
가르켜주시면 감사하겠습니다!!!!!!!
////현재 winpcap을 이용하여 tcp port80번 만 캡쳐하여 data를 출력하는 소스 입니다 필터룰좀 부탁드립니다 ㅠ////
#include "pcap.h"
#pragma comment (lib, "wpcap.lib")
typedef struct ip_address{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;
typedef struct ip_header
{
u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
u_char tos; // Type of service
u_short tlen; // Total length
u_short identification; // Identification
u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; // Time to live
u_char proto; // Protocol
u_short crc; // Header checksum
ip_address saddr; // Source address
ip_address daddr; // Destination address
u_int op_pad; // Option + Padding
}ip_header;
/* UDP header*/
typedef struct udp_header{
u_short sport; // Source port
u_short dport; // Destination port
u_short len; // Datagram length
u_short crc; // Checksum
}udp_header;
/* eternet header */
struct ether_header
{
u_char dst_host[6];
u_char src_host[6];
u_short frame_type;
}ether_header;
typedef struct tcp_header
{
u_short sport; // Source port
u_short dport; // Destination port
u_int seqnum; // Sequence Number
u_int acknum; // Acknowledgement number
u_char hlen; // Header length
u_char flags; // packet flags
u_short win; // Window size
u_short crc; // Header Checksum
u_short urgptr; // Urgent poㅠㅜ inter...still don't know what this is...
}tcp_header;
/* 패킷이 캡처 됬을때, 호출되는 콜백 함수 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
////////////////////// main 부분 ////////////////////////
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
//필터룰 지정
char *filter = "port 80";
struct bpf_program fcode;
bpf_u_int32 NetMask;
/* 네트워크 다바이스 목록을 가져온다. */
/* alldevs에 리스트 형태로 저장되며, 에러시 errbuf에 에러 내용 저장 */
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* 네트워크 다바이스명을 출력한다. */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
/* 에러 처리 */
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
/* 캡처할 네트워크 디바이스 선택 */
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
/* 입력값의 유효성 판단 */
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* 장치 목록 해제 */
pcap_freealldevs(alldevs);
return -1;
}
/* 사용자가 선택한 장치목록 선택 */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* 실제 네트워크 디바이스를 오픈 */
if ((adhandle= pcap_open_live(d->name, // 디바이스명
65536, // 최대 캡처길이
// 65536 -> 캡처될수 있는 전체 길이
1, // 0: 자신에게 해당되는 패킷만 캡처
// 1: 들어오는 모든 패킷 캡처
1000, // read timeout
errbuf // 에러내용 저장변수
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* 장치 목록 해제 */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* 넷마스크 지정, 이부분은 아직 잘 모르겠음 */
NetMask=0xffffff;
// 사용자가 정의한 필터룰 컴파일
if(pcap_compile(adhandle, &fcode, filter, 1, NetMask) < 0)
{
fprintf(stderr,"\nError compiling filter: wrong syntax.\n");
pcap_close(adhandle);
return -3;
}
// 사용자가 정의한 필터룰 적용
if(pcap_setfilter(adhandle, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter\n");
pcap_close(adhandle);
return -4;
}
/* 장치 목록 해제 */
pcap_freealldevs(alldevs);
/* 캡처 시작 */
pcap_loop(adhandle, // pcap_open_live통해 얻은 네트워크 디바이스 핸들
0, // 0 : 무한루프
// 양의정수 : 캡처할 패킷수
packet_handler, // 패킷이 캡처됬을때, 호출될 함수 핸들러
NULL); // 콜백함수로 넘겨줄 파라미터
pcap_close(adhandle); // 네트워크 디바이스 핸들 종료
return 0;
}
/* 패킷이 캡처 됬을때, 호출되는 콜백 함수 */
void packet_handler(u_char *param, //파라미터로 넘겨받은 값
const struct pcap_pkthdr *header, //패킷 정보
const u_char *pkt_data) //실제 캡처된 패킷 데이터
{
int i;
// 아이피, 포트를 구하기 위한 변수
ip_header *ih;
udp_header *uh;
tcp_header *th;
u_int ip_len;
/* retireve the position of the ip header */
ih = (ip_header *) (pkt_data + 14); //length of ethernet header
/* retireve the position of the udp header */
ip_len = (ih->ver_ihl & 0xf) * 4;
uh = (udp_header *) ((u_char*)ih + ip_len);
if(ih->proto==6)
{
th = (tcp_header*) (ih + ip_len);
printf("TCP\n");
}
else if(ih->proto==17)
{
uh=(udp_header*) (uh + ip_len);
printf("UDP\n");
}
/* Print the packet */
for (i=1; (i < header->caplen + 1 ) ; i++)
{
printf("%.2x ", pkt_data[i-1]);
if ( (i % 16) == 0) printf("\n");
}
printf("\n\n");
}
댓글 달기