Develop
[C++] LibTins를 이용한 AP Scanner (Beacon Sniffer,airodump-ng)
Dork94
2017. 12. 13. 13:14
안녕하세요.
오늘은 LibTins를 이용해서 주변에 있는 AP(공유기)를 탐지하고 출력해주는 Class에 대해 살펴보도록 하겠습니다.
//APSniffer.h
#include <iostream>
#include <map>
#include <tins/tins.h>
#include <unistd.h>
class APSniffer{
char* sniffDev;
typedef Dot11::address_type bssid;
typedef std::map apList;
apList aplistMap;
void upLinePrompt(int count);
void showAPList();
bool handle(PDU& pdu);
public:
APSniffer(char* mDev);
bssid findBSSID(std::string ssid);
void run();
};
//APSniffe.cpp
void APSniffer::upLinePrompt(int count)
{
for (int i = 0; i < count; ++i) {
//printf("%c[2K",27);
std::cout<<"\33[2K"; //line clear
std::cout<<"\x1b[A"; //up line (ESC [ A) must be support VT100 escape seq
}
}
void APSniffer::showAPList()
{
std::cout<<"*************************Detected AP Lists**************************"<<std::endl;
apList::iterator it;
int count=0;
for(it=aplistMap.begin();it!=aplistMap.end();it++)
{
count++;
std::cout<<count<<" BSSID : " <<it->first<<" SSID : "<<it->second<<std::endl;
}
upLinePrompt(count+1); //console Line clear & +1 == dectected AP List
}
APSniffer::bssid APSniffer::findBSSID(std::string ssid)
{
apList::iterator it;
int loopCount=3;
int count=0;
bssid retBSSID;
while (loopCount--) //try to find BSSID 3 times
{
for(it=aplistMap.begin();it!=aplistMap.end();it++)
{
// std::cout<<"Compare "<<ssid<<" with "<<it->second<<std::endl;
if(ssid.compare(it->second)==0) //if ssid as same as it->second
{
count++;
retBSSID=it->first;
}
//looping must be loop the end cuz it that possible to duplicate SSID
}
if(count>0) //if find BSSID
break; //out
sleep(3);
}
if(count==1)
return retBSSID;
else
return nullptr;
}
bool APSniffer::handle(PDU &pdu)
{
// Get the Dot11 layer
const Dot11Beacon& beacon = pdu.rfind_pdu<Dot11Beacon>();
// All beacons must have from_ds == to_ds == 0
if (!beacon.from_ds() && !beacon.to_ds()) {
// Get the AP address
bssid addr = beacon.addr2();
// Look it up in our map
apList::iterator it = aplistMap.find(addr);
if (it == aplistMap.end()) //if not exist
{
// First time we encounter this BSSID.
try {
/* If no ssid option is set, then Dot11::ssid will throw
* a std::runtime_error.
*/
std::string ssid = beacon.ssid();
aplistMap.insert(std::pair<bssid,std::string>(addr,ssid));
//if new AP is dectected Show All Ap List
showAPList();
}
catch (std::runtime_error&) {
// No ssid, just ignore it.
}
}
}
return true;
}
APSniffer::APSniffer(char *mDev)
{
sniffDev=mDev;
}
void APSniffer::run()
{
SnifferConfiguration config;
config.set_promisc_mode(true);
config.set_filter("type mgt subtype beacon");
config.set_rfmon(true);
Sniffer sniffer(sniffDev, config);
sniffer.sniff_loop(make_sniffer_handler(this, &APSniffer::handle));
}
위와 같이 각각의 파일에 정의를 해 둔 후 해당 파일을 main에서 include 하여 아래와 같이 사용해주시면 됩니다(일부 코드는 http://libtins.github.io/examples/beacon-display/ 를 참조하였습니다).
#include <iostream>
#include "APSniffer.h"
int main()
{
//Declaration AP Sniffer
APSniffer apSniffer(monitorDev);
apSniffer.run();
return 0;
}
본인 프로그램의 목적에 맞게 프로그램을 수정하여 사용하시면 됩니다.
APList의 정보는 APlist Class의 Map에 선언되어 있습니다.