dot11(IEEE 802_11) protocol 분석과 airodump-ng 구현
과제
Beacon Frame에서 BSSID, Beacons, (#Data), (ENC), ESSID는 필수적으로 출력한다(괄호 항목은 선택).
가능하다면 Channel hopping 기능을 추가한다.
dot11?
https://en.wikipedia.org/wiki/802.11_frame_types
dot11(802.11) 프로토콜은 무선 LAN(WLAN) 통신을 위한 IEEE표준이다.
Wi-Fi라는 이름으로 널리 알려져 있으며, 무선 네트워크 장치들이 서로 통신할 수 있게 하는 기술 규격을 정의한다.
여러 버전이 있고 각 버전들은 전송 속도, 신호 범위, 사용 주파수 대역으로 구분한다.
표준에 대한 설명보다, 프로토콜 내용을 분석해보자.
802.11 프레임에는 관리, 제어, 데이터 3가지 유형이 있다. (Management Frames, Control Frames, Data Frames)
802.11 프레임 구조는 위와 같다.
여기서 Frame Control을 상세히 분석하면
위와 같이 비트마스킹 되어있다.
과제는 Beacon Frame에서 BSSID, Beacons, (#Data), (ENC), ESSID를 출력해야 한다.
Beacon Frame을 걸러내기 위해 이를 나타내는 부분을 찾는다.
Beacon Frame?
https://en.wikipedia.org/wiki/Beacon_frame
비콘 프레임은 IEEE 802.11의 관리 프레임(Management Frame)의 한 유형이다.
네트워크에 대한 정보가 포함되며, 주기적으로 전송된다.
이는 무선 LAN의 존재를 알리고 타이밍 신호를 제공하여 네트워크를 사용하는 장치와의 통신을 동기화하는 역할을 수행한다.
BSS(Basic Service Set)에서 AP가 전송한다.
Protocol Analysis
Beacon Frame은 Management Frame이므로 우선 Management Frame만을 가져오도록 한다.
이를 위해서 monitor mode interface에서 실행된 wireshark를 분석한다.
이미 wireshark에서는 beacon frame이라는 부분이 보인다.
이걸 잡아서 분석한다.
Radiotap Header, Beacon frame, Wireless Management로 되어있다.
offset 0x18 이후부터인 beacon frame라고 적힌 부분부터 분석해보자.
beacon frame 크기도 0x18이다.
Management Frame & Beacon Frame
첫 1byte는 beacon frame을 구분하는 부분이다.
다른 ack 프레임과 비교한 사진
Management Frame의 type은 0이고
Beacon의 Subtype은 1000이다.
이를 검사하면 Beacon Frame인지 판단 가능하다.
BSSID
BSSID는 7번째 요소로 위치한다.
여기까지 해서
https://dojang.io/mod/page/view.php?id=472
비트 필드가 채워지는 순서를 잘 고려하여 엔디언 헷갈리지 않고 struct를 작성한다. FrameControlField를 직접 쓸 일은 없어서 little endian으로 둔다.
typedef struct
{
union
{
struct
{
uint8_t Version : 2;
uint8_t Type : 2;
uint8_t SubType : 4;
};
uint16_t FrameControlField;
};
uint16_t Duration;
union
{
uint8_t Receiver_address[6];
uint8_t Destination_address[6];
};
union
{
uint8_t Transmitter_address[6];
uint8_t Source_address[6];
};
uint8_t BSS_Id[6];
uint8_t Fragment_number : 4;
uint16_t Sequence_number : 12;
} BeaconFrame;
Beacons
beacons는 wireshark에 나와있지 않다.
`man airodump-ng`
그래서 매뉴얼을 참고했다. 매뉴얼에는
AP에서 보낸 beacon의 갯수라고 되어있다. 같은 bssid에 대해서 세어주면 된다.
생각해보니 캡처된 beacon의 list를 만들어야 한다. 이럴 줄 알았으면 C++로 할걸 괜히 C로 하고있었다.
#Data, ENC
#data는 위에 man 캡처본에 나와있듯 managemet frame이 아니라 data frame을 캡처해야 한다. 추가하는 것은 어렵지 않겠으나 (필수가 아니므로) 후순위로 둔다. ENC도 다른 프레임이겠지 뭐..
ESSID
ESSID는 Wireless Management 부분에 위치한다.
이 부분을 분석해서 SSID를 가져온다.
CH
AP들이 좀 바뀌긴 했지만,
Wireless Management는 채널 정보 또한 가지고 있다.
dump부분과 wireshark의 Current Channel을 비교하면 채널이 일치한다.
각각의 Tag들을 분석하면 공통적으로 Tag Number와 Tag Length가 있다.
Taglength는 byte 단위이며 Taglength의 수만큼 뒤에 내용이 추가로 붙는다.
그럼 Tag가 언제까지 나오나..? 적혀있는 부분은 보이지 않는다.
length만큼 넘어가면서 single linked list 순회하듯 찾으면 될 것 같다. 따라서, tag에 대한 struct를 만든다.
typedef struct
{
uint8_t Tag_Number;
uint8_t Tag_length;
u_char *data;
} Tag;
typedef struct
{
uint64_t Timestamp;
uint16_t Beacon_Interval;
uint16_t Capabilities_Information;
} FixedParam;
Fixed 파라미터와 Tag를 따로 구분한다.
PWR
PWR은 Radiotap에 있다.
Antenna signal이 PWR인것 같아보인다.
#pragma pack(push, 1)
typedef struct
{
uint8_t Header_revision;
uint8_t Header_pad;
uint16_t Header_length;
uint64_t Present_flags;
uint8_t Flags;
uint8_t Data_Rate;
uint16_t Channel_frequency;
uint16_t Channel_flags;
uint8_t Antenna_signal;
uint8_t Reserved;
uint16_t RX_flags;
uint8_t Antenna_signal1;
uint8_t Antenna;
} Radiotap;
#pragma pack(pop)
frame capture
아..
안된다 ... 왜 segfault..
나중에 다시 해봐야겠다....