안녕하세요~ 오랜만에 블로그 글을 작성하네요 ㅎㅎ

아 포토비는 replay attack에 성공했습니다!! ㅎㅎ 조만간 그 과정을 정리해서 블로그에 작성하도록 할께요

2019년도가 매우 바빴어요 ㅎㅎ Best of the Best 8기 컨설팅트랙을 수료하고 왔습니다 예~~!!

 

최근 웹쪽에 입문을하게 되어서 관련된 글을 많이 작성하게 될것같아요 ㅎㅎ 

그럼 홧팅!!!

'Just' 카테고리의 다른 글

인사글  (0) 2019.05.20

분석을 시작하기 위한 첫 번째 도전!

데이터 전송이 어떻게 되는지 알아보기 위해 패킷을 잡아보려고 했는데요. 일단 가볍게 도전해볼 수 있는 모니터 모드로 패킷을 잡아보는 것!

 

모니터 모드란?

간단히 말해서 공중에 날아다니는 패킷을 보겠다! 공기 중에 있는 패킷을 잡아서! 보기만! 한다는 것! 

 

이것을 하기 위해선 장비가 필요한데,

내가 실제 사용한 무선랜카드 현재까지도 잘사용중이다.

다른 랜카드를 구매하고 싶다면 무작정 사지 말고 모니터 모드를 지원하는지 잘 보고 구매하자.

 

나는 위의 무선랜카드를 이용해 우분투에서 진행하였다.

 

1. 무선랜카드 끼운 후 "iwconfig" 입력

만약 잘 인식했다면 사진과같이 나올텐데 'velylan0'이 내 무선랜카드이다.

여기서 Mode : Managed 인 것을 볼 수가 있는데 우리는 이것을 Monitor로 바꾸어 줄 것이다.

('iwconfig'와 'ifconfig'의 차이점을 살짝 알려주자면 'iwconfig'는 무선, 'ifconfig'는 유선의 역할 차이가 있다.)

(랜카드의 이름은 설정으로 바꿀 수 있다!)

 

2. Monitor로 바꾸기

'velylan0'위치에 본인의 랜카드 이름을 적어주고 순서대로 명령어를 입력한다.

주의 깊게 쳐다보면 Mode : Monitor 확인할 수 있다. 

 

3. 패킷 캡처!

 

ㅇㅁㅇ! 패킷 캡처가 안돼요!

'iwconfig'를 하고 Mode 가 다시 Managed로 바뀌었다면 이것은 NetworkManager 가 일을 잘해서 나타날 수 있는데 잠시 Networkmanager를 죽여놓고 2,3 실행하면 된다! 원래대로 돌아가고 싶다면 NetworkManager를 다시 살리면 된다!

 

결과.

잡히는 패킷량이 너무 많고 모니터 모드는 패킷 손실도 있었기 때문에 사진 데이터를 찾지를 못했을뿐더러 제대로 된 분석을 하지 못했다. 실패.

 

'Photobee♡' 카테고리의 다른 글

초보가 IOT 해킹 도전하기  (0) 2019.05.24

안녕하세요!!

초보가 IOT해킹에 도전합니다!

사실 이 프로젝트는 제가 오래전에 시작했었는데요. 아직 성공은 하지 못했습니다. 그래서 원래는 '성공기!'라고 하고 싶었는데 성공을 하지 못해서 '도전하기!'라고 제목을 썼어요 ㅎㅎ 

중간에 잠깐 휴식기를 갖기도 했었고 ,,, 처음 부딪혀 보는거다보니 좀 시간이 걸리는 것도 없지 않아 있어서 오늘날에도 아직 진행 중에 있습니다. ㅎㅎ 

성공해서 정리된 글을 올리고 싶었는데 이 마음을 고쳐먹은 이유는!!!

생각보다 프로젝트 기간이 길어져서 이기도 하고 '블리의 로그' 에 맞게 실패했지만 그래도 이렇게 글을 올리다 보면 언젠가 성공한 글을 올릴 수 있겠죠??ㅎㅎ 그러면 그때 정리된 글을 올리려고 합니다. ^_^ 그리고 이 프로젝트의 히스토리를 이렇게 만들어 놓는 것도 마음에 들어요!! 

제품 소개.

도전할 IOT 제품은 바로 Photobee 입니다!

자세한 url : http://photobee.photo/

바로 이 제품인데요. 제품에 대해서 살짝 설명을 드리자면  

포토비가 wifi를 뿜어내는 공유기 역할도 같이합니다.

 

사진의 설명대로 사진을 전송하면 포토비는 사진을 프린트를 시작합니다.

어떤 제품인지 감이 잡히셨나요?? ㅎㅅㅎ 

Photobee를 선택한 이유.

일단 wifi를 뿜어내요. 그걸 보고 들었던 느낌은 '어? 이거 어떻게 해볼 수 있겠는데,,?' 였어요. 그리고 제품 자체도 맘에 들었거든요~~ 그래서 만약 실패해도 제품을 사는 거에 손해 보는 느낌은 들지 않겠다!라는 생각도 조금 있었어요. ㅎㅎ 그래서 이걸 선택하게 되었죠. 

그래서 제가 어떻게 하고 싶으냐면 핸드폰에서 포토비에 보내는 사진데이터를 잡아서! 제가 replay공격을 한다던가 전송한 A사진을 B사진으로 바꿔서 포토비에 전송하는 공격을 하고 싶었어요. 좀 더 욕심을 낸다면 더 낼 수 있겠지만 일단은 이렇게 공격을 하고 싶습니다. 그래서 지금은 replay 공격을 시도하고 있어요. ^____^

 

Photobee 사용 후기 :

개인적인 사용 후기는요. 아주 맘에 들어요. ㅎㅎ 사진 인쇄 아주 깔끔하게 잘되요. 가끔 인화지에 먼지가 붙은 건지 약간 뭐가 묻은 거 같다거나 완벽히 덜 깔끔하게 인쇄될 때도 있지만 전체적으로 선명하고 깔끔하게 인쇄 잘됩니다. 그리고 용지가 스티커여서 작게 인쇄해서 오려서 다이어리에 붙이기도 너무 좋구요 보조배터리에 사진을 붙여서 꾸미기도 너무 좋아요. 사진 크기도 카드보다 조금 커서 카드지갑에 쏙! 들어가진 않지만 살짝 튀어나오게 들어가서 조금 자르면 쏙! 들어가요. 그리고 폴라로이드 느낌이라 잉크 걱정도 없어요.^~^ 단점은 용지가 전용이어서 포토비 사이트에서만 구매할 수 있고 용지의 가격이 싸진 않다는 점,,, 그리고 무게도 들고 다닐만한 무게이긴 한데 가방에 넣고 다니다 보면 무게가 생각보다 묵직해요,,ㅎ 쨋든 전체적으로는 너무 만족스럽게 사용하고 있습니다! 

*홍보글이 아닌 사비로 사용해본 솔직 후기입니다.

'Photobee♡' 카테고리의 다른 글

도전 1) 모니터모드(Monitor mode)로 패킷 캡쳐하기  (0) 2019.05.30

1. Ethernet이란?

컴퓨터 네트워크 기술의 하나로, 물리 계층과 데이터 링크계층으로 나뉜다.

물리 계층에서는 신호와 배선, 데이터 링크 계층에서 MAC패킷과 프로토콜의 형식을 정의한다. 

지금 주목할 부분은 데이터 링크 계층이다. 

 

헤더 구조.

Destination MAC

(6 bytes)

Source MAC

(6 bytes)

Type

(2 bytes)

Destination MAC (6 bytes) : 목적지 주소 

Source MAC (6 bytes) : 출발지 주소

Type (2 bytes) : 상위 계층의 프로토콜 종류를 구분

(IP : 0x0800 , ARP : 0x0806 등등)

 

2. IP 란?

IP(Internet Protocol) 의 약자로 쉽게 말해 컴퓨터가 갖게 되는 주소인데, 이것은 와이파이가 다를때마다 얻는 주소가 달라진다. 

 예를들어, 전화번호를 생각해보자. 서울은 02로 시작하고 경기도는 031로 시작한다. 서울에서 우리 집전화기를 개통해서 얻는 전화번호 02-1234-1234 이다. 서울이라는 와이파이에서 할당 받은 IP주소는 02-1234-1234가 되는 셈이다. 그리고 이 번호는 다른 전화기와 중복되지 않는다. 컴퓨터로도 마찬가지이다. 그리고 경기도에서 우리 집전화기를 개통해서 얻는 번호는 031-456-4567 이다. 여기서 우리는 경기도라는 와이파이에서 할당받은 IP주소는 031-456-4567이 된다.

 

헤더 구조.

Version (4bits) : IP의 버전을 나타낸다. (IPv4/IPv6)

Header Length (4bits) : IP헤더의 길이를 알수있는 필드값이다. 헤더길이는 필드값 * 4 이다.

                           (일반적으로 길이값은 20이 나오지만 고정값이 아니니 주의하고 계산해야한다.)

Type-of-Service Flags (1byte) : 서비스의 우선 순위를 제공한다.

Total Packet Length (2bytes) : Eth패킷과 패킷끝에 필요없는 부분?을 제외한 IP부터 패킷의 끝의 총 길이.

Fragment identifier (2bytes) :  분열이 발생 했을때 원래의 데이터를 식별하기 위해서 사용한다. 

Fragmentation Flags (3bits) : 

x - 항상 0으로 설정

D - 분열 여부를 나타냄 0 : 분열 가능, 1 : 분열방지

M - 분열되 조각이 더 있는지 판단 0 : 마지막 조각 , 1 : 조각 더 있음

Frgmentation Offset (13bits) : 8바이트 오프셋으로 조각에 저장된 원래 데이터의 바이트 범위를 나타냄

Time-to-live (1byte) : 데이터을 전달할 수 없는 것으로 판단되어 소멸되기 이전에 데이터가 이동할 수 있는 단계의 수를 나타냄

Protocol Identifier (1byte) : 상위계층 프로토콜 표시 (TCP : 6, UDP: 17)

Header Checksum (2bytes) : IP헤더의 체크섬을 저장 

Source IP Address (4bytes) : 출발지 IP 주소 

Destiantion IP Address (4bytes) : 목적지 IP 주소 

 

3. TCP 란? 

데이터를 송수신하기 위해 IP를 사용하는 프로토콜 이다. 데이터를 세그먼트 단위로 쪼개어 전송후 재조립 하는 과정을 거친다. 

예를 들어 설명하자면, 완전한 데이터를 완성된 퍼즐이라고 생각해보자. 퍼즐을 완전히 분해하여 조각을 하나씩 전송하고 도착지에서 퍼즐을 다시 완성하는 방식이다.

 

헤더 구조.

Source Port (2bytes) : 데이터를 전송하는 곳의 포트 번호

Destination Port (2bytes) : 목적지의 포트번호 (80 : HTTP, 443 : HTTPS)

Sequence Number (4bytes) : 데이터 바이트의 고유한 일련번호, 순서가 어긋나게 도착해도 이를 이용하여 올바르게 재배열 한다

Acknowledgement Number (4bytes) : 다음 세그먼트 수신준비가 되었다는 여부와 수신이 완료되었다는 확인 메세지를 전달 한다

Header Length (4ytes) : 필드값 * 4 = Tcp header 길이 값

Reserved (6 bits) : 차후 사용을 위한 예약 필드

Control Flags (6 bits) : 

-C : 혼잡 윈도우 크기 감소

-E : 혼잡을 알림 

-U : 필드가 가르키는 세그먼트 번호까지 긴급 데이터를 포함한다는 것을 알림(0이라면 무시)

-A : 확인 응답 메세지 

-P : 데이터를 포함한다는 것을 말함

-R : 수신거부 할때 사용

-S :  확인 메세지 전송

-F : 연결을 종료하고자 할때 사용

Window Size (2bytes) : 송신 시스템의 가용 수신 버퍼의 크기를 바이트 단위로 나타냄

Checksum (2bytes) : TCP 세그먼트 내용이 유효 및 손상여부 검사

pcap 이란?

간단히 말해 말그대로 packet capture 를 뜻한다.

윈도우에서는 Winpcap을, 유닉스 계열애서는 libpcap을 이용하여 네트워크 상의 패킷을 캡쳐해 분석할 수 있다. 여기서 짚고 넘어갈점은 "catch" 가 아니라 "capture" 라는 것이다. 패킷을 잡아서 어떻게 할 수 있다는게 아니라 지나가는것을 들여다 보기만 한다.

 

목적.

pcap 프로그래밍을 하면서 가장 큰 목적은 패킷을 분석할 줄 알고,  패킷 헤더의 구조를 이해하는 것이라고 생각한다. 

(헤더구조를 모르겠다면 https://velys-log.tistory.com/4 참고)

 

개발환경.

우분투, Qt 

pcap_test.c

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

#include <stdio.h>

#include <stdlib.h>

#include <pcap.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

 

#define BUFSIZE 1024

 

typedef struct EthernetHeader{

    unsigned char DesMac[6];

    unsigned char SrcMac[6];

    unsigned short Type;

}EthernetH;

typedef struct IPHeader{

    unsigned char Version : 4;

    unsigned char IHL : 4;

    unsigned char TOS;

    u_short TotalLen;

    unsigned short Identifi;

    unsigned char Flagsx : 1;

    unsigned char FlagsD : 1;

    unsigned char FlagsM : 1;

    unsigned int FO : 13;

    unsigned char TTL;

    unsigned char Protocal;

    unsigned short HeaderCheck;

    struct in_addr SrcAdd;

    struct in_addr DstAdd;

}IPH;

typedef struct TCPHeader{

    unsigned short SrcPort;

    unsigned short DstPort;

    unsigned int SN;

    unsigned int AN;

    unsigned char Offset : 4;

    unsigned char Reserved : 4;

    unsigned char FlagsC : 1;

    unsigned char FlagsE : 1;

    unsigned char FlagsU : 1;

    unsigned char FlagsA : 1;

    unsigned char FlagsP : 1;

    unsigned char FlagsR : 1;

    unsigned char FlagsS : 1;

    unsigned char FlagsF : 1;

    unsigned short Window;

    unsigned short Check;

    unsigned short UP;

}TCPH;

typedef struct HttpH

{

    uint16_t HTP[16];

}HttpH;

 

void PrintEthernetHeader(const u_char *packet);

void PrintIPHeader(const u_char *packet);

void PrintTCPHeader(const u_char *packet);

void PrintHttpHeader(const uint8_t *packet);

 

void help(){

    printf("Write Interface Name\n");

    printf("Sample : pcap_test ens33\n");

}

 

int main(int argc, char* argv[]) {

    if (argc != 2){

        help();

        exit(1);

    }

    struct pcap_pkthdr* header;

    const u_char* packet;

    char* dev = argv[1];

    char errbuf[PCAP_ERRBUF_SIZE];

    IPH *tlen;

    u_int lengh;

    pcap_t* handle = pcap_open_live(dev, BUFSIZE, 11000, errbuf);

    if (handle == NULL){

        printf("%s : %s \n", dev, errbuf);

        exit(1);

    }

 

    while(1){

 

        int res = pcap_next_ex(handle, &header, &packet);

        if (res == 0continue;

        if (res == -1 || res == -2) exit(1);

        PrintEthernetHeader(packet);

        packet += 14;

        PrintIPHeader(packet);

        tlen = (IPH *)packet;

        lengh = htons(tlen->TotalLen) - (uint16_t)(tlen->IHL)*4;

        packet +=(uint16_t)(tlen->IHL)*4;

        PrintTCPHeader(packet);

        packet += ( u_char)lengh;

        PrintHttpHeader(packet);

    }

 

    pcap_close(handle);

    return 0;

}

 

void PrintEthernetHeader(const u_char *packet){

    EthernetH *eh;

    eh = (EthernetH *)packet;

    printf("\n======== Ethernet Header ========\n");

    printf("Dst Mac %02x:%02x:%02x:%02x:%02x:%02x \n",eh -> DesMac[0],eh -> DesMac[1],eh -> DesMac[2],eh -> DesMac[3],eh -> DesMac[4],eh -> DesMac[5]);

    printf("Src Mac %02x:%02x:%02x:%02x:%02x:%02x \n",eh -> SrcMac[0],eh -> SrcMac[1],eh -> SrcMac[2],eh -> SrcMac[3],eh -> SrcMac[4],eh -> SrcMac[5]);

 

}

 

void PrintIPHeader(const u_char *packet){

    IPH *ih;

    ih = (IPH *)packet;

    printf("======== IP Header ========\n");

    if (ih -> Protocal == 0x06printf ("TCP\n");

    printf("Src IP  : %s\n", inet_ntoa(ih->SrcAdd) );

        printf("Dst IP  : %s\n", inet_ntoa(ih->DstAdd) );

 

}

 

void PrintTCPHeader(const u_char *packet){

    TCPH *th;

    th = (TCPH *)packet;

    printf("======== TCP Heather ========\n");

    printf("Src Port : %d\n", ntohs(th ->SrcPort));

    printf("Dst Port : %d\n", ntohs(th -> DstPort));

}

 

void PrintHttpHeader(const uint8_t *packet){

    HttpH *hh;

    hh = (HttpH *)packet;

    printf("======== Http Heather ========\n");

    for(int i =0; i<16; i++) {

        printf("%02x ",hh -> HTP[i]);

    }

    printf("\n");

}

Colored by Color Scripter

cs

10줄~53줄 : 각각 프로토콜의 헤더를 공부하면서 직접만든 구조체

55줄~58줄 : Print해줄 함수의 선언

66줄~69줄 : 인자값이 2개가 아니라면 help함수 호출후 강제종료

76줄~80줄 : pcap을 오픈하는데 NULL 값을 반환한다면 오류 print후 강제종료

84줄~86줄 : 다음 패킷을 읽는데 -1 또는 -2를 리턴한다면 강제종료

87줄~95줄 : 읽은 패킷의 값을 각 Print함수로 보낸다

98줄 : 오픈한 pcap을 닫는다

102줄~137줄 : 패킷의 데이터 값들을 출력

참고 : https://github.com/jungvely97/pcap_test

 

사용한 pcap 함수

 

1. pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

-피캡을 오픈하는 함수

device : 패킷을 오픈할 인터페이스

snaplen : 받아들일수 있는 패킷의 최대 크기(byte)

promisc : 네트워크 디바이스를 promiscuous mode 로 할것인지를 결정하기 위해서 사용한다.  promisc 가 1일경우 promiscuous 모드가 되며, 로컬 네트웍의 모든 패킷을 캡쳐하게 된다. 0 일경우 에는 자기에게만 향하는 패킷을 캡쳐하게 되는데, 몇몇 경우에  있어서 promiscuous 모드로 작동하기도 한다.

to_ms : 읽기 시간초과(time out) 지정을 위해서 사용되며 millisecond 단위이다

.ebuf : pcap_open_live 함수 호출에 문제가 생겼을경우 에러 메시지를 저장하기 위해서 사용한다.

return :성공시 패킷 캡쳐 descriptor를 반환, NULL 을 리턴하고 에러내용을 ebuf에 복사한다.

 

2. int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data)

- 다음 패킷을 읽는 함수

p : 오픈된 피캡

pkt_header : 패킷을 위한 구조체를 가르킴

pkt_data : 읽은 패킷의 데이터

return : 성공시 1을 반환, timeout이 만기될 경우 0을 반환, 에러시 -1을 반환, EOF시 -2를 반환

 

3. void pcap_close (pcap_t * p)

- p와 연관된 파일을 닫고 자원을 할당 해제

안녕하세요? ㅎㅎ

 블로그를 보기만 했지 작성하는 건 처음이라 어떻게 작성해야 할지 많이 고민이 되네요. ㅎㅎ

일단 편하게 시작하려구 합니다. 한창 공부하고 있는중이에요 ㅎㅎ 만약 이 글을 읽으시는 분이 초보자라면 반갑습니다! 동지네요!! 만약 전문가시라면 응원이나 조언 부탁드려요 ㅎㅎ 

 제가 이 블로그를 개설한 목적은 제가 공부한 걸 남기고 싶고 공유하고 싶고 저처럼 어려움을 격는 누군가에게 도움이 되고 싶어서입니다. 그래서 제가 올리는 자료가 성공적이지 않을 수 도있고 끝나지 않은 프로젝트 일 수도 있고 실패한것 일수도있고 정확하지 않을 수 도있습니다. 최대한 정확한 자료 그리고 성공적인 자료를 올리도록 노력하겠습니다.

하띵!!

'Just' 카테고리의 다른 글

2020년 여름 ☆  (0) 2020.08.14

+ Recent posts