0

I'm trying to reverse engineer a wifi webcam that connects to an Android app. I sniffed the traffic and found that the transaction is initiated when the app sends a series of 8 UDP packets, at which point the camera will stream video to the phone as a series of UDP packets. I want to send the 8 initiation packets to the camera from my computer to see if I can get the camera to stream to my computer. It looks like netcat could be useful, but the data isn't nice ASCII strings as in the netcat examples I've found. The data is actually

4a:48:43:4d:44:d0:02
4a:48:43:4d:44:d0:02
4a:48:43:4d:44:d0:02
4a:48:43:4d:44:20:00:00:00:00:00
4a:48:43:4d:44:20:00:00:00:00:00
4a:48:43:4d:44:10:00
4a:48:43:4d:44:d0:01
4a:48:43:4d:44:d0:01

How can I send UDP packets with this data to a specific IP address and port in less than 0.2s, ideally with a simple CL tool?

0

2 Answers 2

1

This task isn't very well suited for doing via command line utilities - you'd be better off doing it in something like Perl or Python if you can, where the networking APIs are much richer.

That being said ... you could certainly use netcat to send your packets, piping the hex data into something like xxd (part of the vim-common package on RHEL/CentOS/Fedora - YMMV if you're using a different Linux distro than that...).

There's a tool called PacketSender (that I admit I haven't actually used, but it looks interesting) that includes command-line functionality to do what you want - the challenge is that I'm not aware of it being packaged for any Linux distros, so you'd either have to build it from source yourself, or use the author's pre-packaged AppImage release if your distro can use that.

3
  • I'm on Linux Mint. So I do have xxd, and can use the PacksetSender AppImage. For now, I'd like to exhaust the command line option. I've seen a Python program that does IP stuff and it looked pretty intimidating. Can you please give an example of how to use netcat with xxd to handle a packet of hex data?
    – ttshaw1
    Commented Oct 3, 2020 at 4:53
  • 1
    You can use xxd to "un-hex" the data - to see an example of this, try running echo '48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a' | xxd -r -p. To send your packet of hex data, you'd just do something like echo (hex data here...) | xxd -r -p | nc --udp 1.2.3.4 9999 (where "1.2.3.4" represents the IP address of the camera, and "9999" represents the UDP port number it's listening for packets on - substitute these appropriately for your environment).
    – patbarron
    Commented Oct 3, 2020 at 5:12
  • 1
    This worked. echo | nc winds up running a process and I'm not sure when that process would terminate. In order to get the timing right I had each echo (hex data here...) | xxd -r -p | nc --udp 1.2.3.4 9999 & end with the ampersand to run in the background, and slept for 1ms between echos. I threw those into a bash script and ran it. Wireshark confirms the packets were as expected, and the camera started spitting data at my computer.
    – ttshaw1
    Commented Oct 3, 2020 at 20:20
0

This may be pretty far outside what you were looking for, but you could also do this in C. Here's a sample program that sends the bytes in your example:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>

/* You'd need to change the following values to match your environment */
#define DESTINATION_ADDRESS "127.0.0.1"
#define DESTINATION_PORT    8080
#define MAX_MESSAGE_LENGTH 11

struct message {
    int length;
    char bytes[MAX_MESSAGE_LENGTH];
};

int main(void)
{
    const int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    const struct message messageList[] = {
        { .length =  7, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0xd0, 0x02} },
        { .length =  7, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0xd0, 0x02} },
        { .length =  7, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0xd0, 0x02} },
        { .length = 11, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00} },
        { .length = 11, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00} },
        { .length =  7, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0x10, 0x00} },
        { .length =  7, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0xd0, 0x01} },
        { .length =  7, .bytes = { 0x4a, 0x48, 0x43, 0x4d, 0x44, 0xd0, 0x01} },
        { },
    };

    const struct sockaddr_in servaddr = {
        .sin_family      = AF_INET,
        .sin_port        = htons(DESTINATION_PORT),
        .sin_addr.s_addr = inet_addr(DESTINATION_ADDRESS),
    };

    for (int i = 0; messageList[i].length != 0; ++i) {
        if (sendto(sockfd,
                   messageList[i].bytes,
                   messageList[i].length,
                   0,
                   (const struct sockaddr*) &servaddr,
                   sizeof(servaddr)) < 0) {
            perror("sendto");
        }
    }

    close(sockfd);
    return EXIT_SUCCESS;
}

The program creates an array of messages called messageList. Each entry in the array includes (1) the length of the message, and (2) an array of the bytes in the message. A message of length 0 terminates the list.

Next the program creates an object named servaddr that describe where to send the message and the protocol.

Finally the program loops over the messages, one by one, and sends them to the target.

To compile the program:

$ gcc client.c

That's produce a program called a.out.

You can set up tcpdump to watch the messages:

$ sudo tcpdump -i lo -Xn '(udp port 8080)'
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes

Then run a.out:

$ ./a.out

And I get the following output from tcpdump:

20:18:19.429320 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 7
    0x0000:  4500 0023 bf9f 4000 4011 7d28 7f00 0001  E..#..@.@.}(....
    0x0010:  7f00 0001 e623 1f90 000f fe22 4a48 434d  .....#....."JHCM
    0x0020:  44d0 02                                  D..
20:18:19.429629 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 7
    0x0000:  4500 0023 bfa0 4000 4011 7d27 7f00 0001  E..#..@.@.}'....
    0x0010:  7f00 0001 e623 1f90 000f fe22 4a48 434d  .....#....."JHCM
    0x0020:  44d0 02                                  D..
20:18:19.429842 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 7
    0x0000:  4500 0023 bfa1 4000 4011 7d26 7f00 0001  E..#..@.@.}&....
    0x0010:  7f00 0001 e623 1f90 000f fe22 4a48 434d  .....#....."JHCM
    0x0020:  44d0 02                                  D..
20:18:19.429906 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 11
    0x0000:  4500 0027 bfa2 4000 4011 7d21 7f00 0001  E..'..@.@.}!....
    0x0010:  7f00 0001 e623 1f90 0013 fe26 4a48 434d  .....#.....&JHCM
    0x0020:  4420 0000 0000 00                        D......
20:18:19.429979 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 11
    0x0000:  4500 0027 bfa3 4000 4011 7d20 7f00 0001  E..'..@.@.}.....
    0x0010:  7f00 0001 e623 1f90 0013 fe26 4a48 434d  .....#.....&JHCM
    0x0020:  4420 0000 0000 00                        D......
20:18:19.430086 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 7
    0x0000:  4500 0023 bfa4 4000 4011 7d23 7f00 0001  E..#..@.@.}#....
    0x0010:  7f00 0001 e623 1f90 000f fe22 4a48 434d  .....#....."JHCM
    0x0020:  4410 00                                  D..
20:18:19.430539 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 7
    0x0000:  4500 0023 bfa5 4000 4011 7d22 7f00 0001  E..#..@.@.}"....
    0x0010:  7f00 0001 e623 1f90 000f fe22 4a48 434d  .....#....."JHCM
    0x0020:  44d0 01                                  D..
20:18:19.430652 IP 127.0.0.1.58915 > 127.0.0.1.8080: UDP, length 7
    0x0000:  4500 0023 bfa6 4000 4011 7d21 7f00 0001  E..#..@.@.}!....
    0x0010:  7f00 0001 e623 1f90 000f fe22 4a48 434d  .....#....."JHCM
    0x0020:  44d0 01                                  D..

Notice that each message begins with JHCMD -- that might be interesting as part of your investigation (e.g., https://shkspr.mobi/blog/2020/06/review-wifi-endoscope/).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .