Android 애플리케이션에 연결된 Wi-Fi 웹캠을 리버스 엔지니어링하려고 합니다. 트래픽을 스니핑한 결과 애플리케이션이 일련의 8개 UDP 패킷을 보낼 때 트랜잭션이 시작되었다는 사실을 발견했습니다. 이 시점에서 카메라는 일련의 UDP 패킷으로 비디오를 전화기에 스트리밍합니다. 내 컴퓨터에서 카메라로 8개의 부팅 패킷을 보내고 카메라가 내 컴퓨터로 스트리밍되도록 할 수 있는지 확인하고 싶습니다. netcat이 유용할 것 같지만 데이터는 내가 찾은 netcat 예제에서처럼 멋진 ASCII 문자열이 아닙니다. 데이터는 실제로
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
이 데이터가 포함된 UDP 패킷을 0.2초 내에 특정 IP 주소 및 포트로 보내려면 어떻게 해야 합니까(간단한 CL 도구 사용 권장)?
답변1
이 작업은 명령줄 유틸리티를 통해 수행하는 데 적합하지 않습니다. 가능하다면 네트워킹 API가 더 풍부한 Perl이나 Python과 같은 것을 사용하는 것이 더 나을 것입니다.
즉, netcat을 사용하여 패킷을 보내고 16진수 데이터를 유사한 것으로 전송할 수 있습니다 xxd
(RHEL/CentOS/Fedora 패키지의 일부 vim-common
- YMMV, 다른 Linux 배포판을 사용하는 경우...).
라는 도구가 있습니다.패킷 발신자(실제로 사용하지는 않았지만 흥미로울 것 같습니다.) 원하는 것을 달성하기 위한 명령줄 기능이 포함되어 있습니다. 문제는 이것이 Linux 배포판용으로 패키지되어 있다는 것을 모른다는 것입니다. 소스에서 빌드하여 직접 수행하거나 배포판에서 사용할 수 있는 경우 작성자가 미리 패키지한 AppImage 버전을 사용하세요.
답변2
이는 아마도 여러분이 찾고 있는 범위를 훨씬 벗어나는 것일 수 있지만 C에서도 이 작업을 수행할 수 있습니다. 다음은 바이트를 보내는 샘플 프로그램입니다.
#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;
}
프로그램은 이름이 붙은 메시지 배열을 생성합니다 messageList
. 배열의 각 항목은 (1) 메시지 길이와 (2) 메시지의 바이트 배열로 구성됩니다. 길이가 0인 메시지는 목록을 종료합니다.
다음으로 프로그램은 servaddr
메시지가 전송되는 위치와 프로토콜을 설명하는 개체를 만듭니다.
마지막으로 프로그램은 메시지를 하나씩 반복하여 대상으로 보냅니다.
컴파일러:
$ gcc client.c
그러면 이라는 프로그램이 생성됩니다 a.out
.
메시지 보기를 설정할 수 있습니다 tcpdump
.
$ 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
그런 다음 다음을 실행하십시오 a.out
.
$ ./a.out
나는 다음과 같은 결과를 얻습니다 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..
각 메시지는 JHCMD
--로 시작합니다. 이는 조사의 일부로 흥미로울 수 있습니다(예:https://shkspr.mobi/blog/2020/06/review-wifi-endscope/).