Winpcap으로 이용하여 Web 방화벽 제작을 할려고합니다!
Linux를 사용하다 Winpcap을 이용하니 여간 힘든게 아니군요...
SQL injection을 탐지하고 방어하는 프로그램을 제작할려고 합니다.
우선 Promiscuous 모드로 패킷을 받고
목적지 IP가 Server IP주소이고 사용된 port가 80번 일시 Detect기능 수행
해당 웹서버에 ID, PASSWORD에 '-- 'having 'union 등 sql 쿼리문 이용시 탐지하여
그 쿼리문의 사용한 컴퓨터 IP에서 SQLinjection공격!!! 라는 식의 알람이 발생하는 프로그램을 제작할려합니다.
어떤식으로 소스를 짜야되고 ㅠ 내가 필요한 부분을 캡쳐 해서 Detection룰에 비교하는지
가르켜주시면 감사하겠습니다!!!!!!!
/////이 Winpcap 소스를 예제로 바꿀려 합니다 ////
#include "pcap.h"
#include
#include
/* 패킷이 캡처 됬을때, 호출되는 콜백 함수 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
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) //실제 캡처된 패킷 데이터
{
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
//출력 포맷 설정
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
// port 80에 해당되는 패킷만 캡처된다.
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}
gilgil.net
올리신 소스는 패킷을 잡아서 애플리케이션으로 올려 주는 예제입니다. 중요한 것은 잡힌 패킷을 어떻게 분석(parsing)하고 처리(process)하느냐가 더 중요합니다.
>> 해당 웹서버에 ID, PASSWORD에 '-- 'having 'union 등 sql 쿼리문 이용시 탐지하여...
패킷이 HTTP protocol로 한정을 한다라고 가정을 하면, 우선 TCP payload의 시작 위치를 알아내야 하겠죠.
packet_handler callback에서 3번째 인자(pkt_data)가 바로 잡힌 패킷(프레임)에 대한 버퍼의 시작 위치입니다.
ethernet 환경이라고 한다면, ETH, IP, TCP header 구조체를 이용하여 각 header별 분석을 하고 TCP payload의 시작 위치를 먼저 추출해 보세요.
거기까지 하신다면 대충 감이 잡히실 겁니다.
www.gilgil.net
정보 감사합니다!
추가로 리눅스에는 ETHERTYPE_IP 등 if(ip_h->ip_p == IPPROTO_TCP )에
TCP 프로토콜등 프로토콜에 대한 접근을 쉽게 할 수 있는데
winpcap자료를 제가 찾아봤는데 windows 자체에 protocol.h 라는 헤더가 정의 되어있다 라고 하는데..
제 컴퓨터랑 다른사람 컴퓨터에 아무리봐도 protocol.h라는 게 없네요.. frame.h를 쓰는 것도 있고...
무슨 헤더를 사용해야되는지 정보좀 부탁드립니다 ㅠ
현재 제가 windows에서 사용하는 헤더들
#include "pcap.h"
#include
#include
전에 pcap수업때 짰던 헤더들
#include //표준 입출력 헤더
#include //ethernet 헤더가 참조하는 내용이 저장
#include //libpcap 헤더 참조로 패킷을 캡쳐하기 위해 사용
#include //네트워크 계층 상위 프로토콜이 Numbering되어 정의
#include //ip헤더 필드가 정의
#include //tcp헤더 필드가 정의
/////제가 리눅스로 짠 소스예/////
if(ether_type == ETHERTYPE_IP) //IP패킷일시 실행
{
ip_h = (struct ip *) tmp_data;
//tmp_data가 가르키는 곳에 ip_h 정보가 들어감
if(ip_h->ip_p == IPPROTO_TCP ) // 만약 TCP 프로토콜이면
{
tcp_h = (struct tcphdr *)(tmp_data + ip_h->ip_hl*4);
//tmp_data 크기기 + ip헤더의 길이 = 34byte
i = sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct tcphdr);
찾았습니다!
winpcap 홈페이지에 source zip파일에 보는데
ethertype.h가 ETHERTYPE_IP를 갖고 있더군요..
그래서 visual stdudio \include 폴더에 libpcap 폴더를 통째로 복사해서
#include 를 쓰니
에러가 없어졌어요! 또 다른 프로토콜이 머필요한지만 부탁드립니다!ㅠ
gilgil.net
1. 각각의 protocol에 해당하는 구조체(struct)를 자체적으로 만들어 사용.
2. 기존에 만들어 져 있는 구조체를 사용.
2번을 생각하신다고 한다면 libnet을 추천합니다. 웬만한 protocol header는 거의 다 정의되어 있습니다.
http://code.google.com/codesearch - "libnet-headers.h,v 1.14"으로 검색.
http://code.google.com/codesearch#search/&q=libnet-headers.h,v%201.14&type=cs
최신 버전은 v1.14로 알고 있구요(2004년3월 11일자 버전), 그 다음 버전이 나왔는지는 잘 모르겠네요.
libnet을 사용하는 경우 다음 header 파일만 있으면 됩니다.
config.h
libnet-asn1.h
libnet-functions.h
libnet-headers.h
libnet-macros.h
libnet-structures.h
libnet-types.h
www.gilgil.net
감사합니다!
제가 구성하는 방식은
랜카드 2개를 장착한 PC를 게이트웨이로 하여 양단간의 트래픽을 캡쳐한 후 이를 분석 및 필터링하여 Server로 전송하게 프로그램을 작성할려 합니다!
libnet은 조사해보니 리눅스에서 쓴다고 나오는데...
windows에도 사용이 가능한가요??
http://code.google.com/codesearch#klGbP25EZjw/trunk/src/win32/WIN32-Includes/libnet/libnet-headers.h&q=libnet-headers.h%20win32&type=cs
이자료를 찾긴했는데 처음 접하는 라이브러리라ㅠㅠ 확신이 안섭니다..
그리고 제가 원하는 방식이라면 http://kldp.org/node/43568
이자료를 보니 pcap_sendpacket 함수를 사용하면 된다하는데...
취업 포트 폴리오를 Web방화벽으로 만들려고하는데 첫 단추가 정말 힘드네요...
원래 제 프로젝트 양식을 파일로 올립니다 !!
해당 라이브러리를 사용하라는게 아닌 헤더 파일을 참고
해당 라이브러리를 사용하라는게 아닌 헤더 파일을 참고 하라는 겁니다.
댓글 달기