lemontree55 / packetgen

Ruby library to easily generate and capture network packets
MIT License
98 stars 13 forks source link

Dot 11 Beacon Packet Not Working Properly #99

Closed n00b110 closed 5 years ago

n00b110 commented 5 years ago

I'm trying to make a fake access point use ruby. The code for it is below:

require 'packetgen'

bssid = 'aa:aa:aa:aa:aa:aa'
broadcast = 'ff:ff:ff:ff:ff:ff'
iface = 'mon1'
ssid = 'PacketGen > PacketFu'

pkt = PacketGen.gen('RadioTap').add('Dot11::Management', mac1: broadcast, mac2: bssid, mac3:   bssid).add('Dot11::Beacon', interval: 0x600, cap: 0x401)
pkt.dot11_beacon.add_element(type: 'SSID', value: ssid)
pkt.calc

count = 100000

count.times do
  pkt.to_w(iface)
  puts 'Fake Beacon ' + ssid + ' via iface: ' + iface
end

I ran this program before and after I had updated PacketGen, and still got the same issue. I opened wireshark with my card in monitor mode; the packets are being sent as they should be; they're just not showing up as access points for any of my network devices. Is their a problem with my code or something else? Anyways, thanks to sdaubert & all the other devs for making this library what it is today!

sdaubert commented 5 years ago

@n00b110 I will have a look this week.

I am not a IEEE802.11 expert, but i wonder if a beacon should have DSset and Rates elements set.

sdaubert commented 5 years ago

Well, after a test with your script, i can see your fake AP on my phone, but it appears and disappears.

I added:

pkt.dot11_beacon.add_element(type: 'Rates', value: [0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c].pack('C*'))
pkt.dot11_beacon.add_element(type: 'DSset', value: [1].pack('C'))  # my device is configured for channel 1

But there is no change...

sdaubert commented 5 years ago

What i did before testing:

ip link set dev wlan0 down
iwconfig wlan0 mode monitor
ip link set dev wlan0 up
iw phy1 set channel 1
sdaubert commented 5 years ago

@n00b110 Fake AP appears, then disappears quickly because it does not respond to probes. If it does, it is detected by devices.

I modified your script:

require 'packetgen'

bssid = 'aa:aa:aa:aa:aa:aa'
broadcast = 'ff:ff:ff:ff:ff:ff'
iface = 'wlan0'
ssid = 'PacketGen'

interval_sec = 0.5
interval = (interval_sec / 0.001_024).to_i

pkt = PacketGen.gen('RadioTap').add('Dot11::Management', mac1: broadcast, mac2: bssid, mac3: bssid).add('Dot11::Beacon', interval: interval, cap: 0x401)
pkt.dot11_beacon.add_element(type: 'SSID', value: ssid)

Thread.new do
  count = 100000
  count.times do
    pkt.to_w(iface)
    puts 'Fake Beacon ' + ssid + ' via iface: ' + iface
    sleep interval_sec
  end
end

PacketGen.capture(iface: iface, filter: 'wlan type mgt subtype probe-req') do |pkt|
  next unless pkt.is? 'Dot11::ProbeReq'

  response = PacketGen.gen('RadioTap').add('Dot11::Management', mac1: broadcast, mac2: bssid, mac3: bssid)
  response.add('Dot11::ProbeResp', interval: interval, cap: 0x401)
  response.dot11_proberesp.add_element(type: 'SSID', value: ssid)
  response.to_w(iface)
end

This is quite violent, as this responds to all probe requests, even those for others SSID.

Does this solve your problem?

n00b110 commented 5 years ago

@sdaubert I ran your script, and I was able to see the access point on my phone!! Thanks, for your help, but I just have two questions: How am I able to see the ap on my phone but not my linux machine?, and what's the meaning of interval = (interval_sec / 0.001_024).to_i; is 0.001_024 a number, I'm a bit confused on that part, but thanks for your help! :)

sdaubert commented 5 years ago

@n00b110 0.001_024 is a number. _ is used to ease reading. It is used as interval is expressed as a number of Time Units (TU). And a TU is 1024µs.

About seeing AP: I don't known, but i guess linux does some checks. For example, in my script, probe response are broadcasted. It should be cleaner to unicast them to supplicant.

sdaubert commented 5 years ago

@n00b110 Close this as your problem is solved.