SSID Finder

It’s good to know how you play with a lower level of Ruby socket and see how powerful it’s. As I’ve experienced, it’s a matter of your knowledge about the protocol you’re about to play with. I’ve tried to achieve this mission using Packetfu gem, but it’s not protocol aware, yet. So I fired-up my Wireshark(filter: wlan.fc.type_subtype == 0x08) and start inspecting the wireless beacon structure and checked how to go even deeper with Ruby socket to lower level socket not just playing with TCP and UDP sockets.

The main task was

  • Go very low level socket(Layer 2)
  • Receive every single packet no matter what protocol is it
  • Receive packets as raw to process it as far as I learn from wireshark

I went through all mentioned references below and also I had a look at /usr/include/linux/if_ether.h which gave me an idea about ETH_P_ALL meaning and more. In addition, man socket was really helpful to me.

Note: The Network card interface must be set in monitoring mode, to do so (using airmon-ng)

  1. # Run you network car on monitoring mode
  2. airmon-ng start wls1
  3. # Check running monitoring interfaces
  4. airmon-ng
  1. #!/usr/bin/env ruby
  2. require 'socket'
  3. # Open a Soccket as (very low level), (receive as a Raw), (for every packet(ETH_P_ALL))
  4. socket = Socket.new(Socket::PF_PACKET, Socket::SOCK_RAW, 0x03_00)
  5. puts "\n\n"
  6. puts " BSSID | SSID "
  7. puts "-------------------*-------------------"
  8. while true
  9. # Capture the wire then convert it to hex then make it as an array
  10. packet = socket.recvfrom(2048)[0].unpack('H*').join.scan(/../)
  11. #
  12. # The Beacon Packet Pattern:
  13. # 1- The IEEE 802.11 Beacon frame starts with 0x08000000h, always!
  14. # 2- The Beacon frame value located at the 10th to 13th byte
  15. # 3- The number of bytes before SSID value is 62 bytes
  16. # 4- The 62th byte is the SSID length which is followed by the SSID string
  17. # 5- Transmitter(BSSID) or the AP MAC address which is located at 34 to 39 bytes
  18. #
  19. if packet.size >= 62 && packet[9..12].join == "08000000" # Make sure it's a Beacon frame
  20. ssid_length = packet[61].hex - 1 # Get the SSID's length
  21. ssid = [packet[62..(62 + ssid_length)].join].pack('H*') # Get the SSID
  22. bssid = packet[34..39].join(':').upcase # Get THE BSSID
  23. puts " #{bssid}" + " " + "#{ssid}"
  24. end
  25. end

References - very useful!