secdev / scapy

Scapy: the Python-based interactive packet manipulation program & library.
https://scapy.net
GNU General Public License v2.0
10.8k stars 2.03k forks source link

srp() does not catch the response #4559

Closed Lopkop closed 1 month ago

Lopkop commented 1 month ago

Brief description

srp() function does not get a DHCPOFFER response from a self-written scapy dhcp server. While debugging I saw, that AsyncSniffer, that runs from this function _sndrcv_rcv in this file sendrecv.py does not even catch that response packet. Then i added iface argument in that sniffer and problem resolved.

Scapy version

2.6.0

Python version

3.12.6

Operating system

Linux archlinux 6.6.52-1-lts

Additional environment information

No response

How to reproduce

  1. copy this dhcp server code: https://pastebin.com/naEcVuG1
  2. copy this client code: https://pastebin.com/9gk0nxB9
  3. run wireshark or similar and filter by dhcp to check requests and responses
  4. run dhcp server code, then client code
  5. check, that server sent offer response, but srp() did not catch that.
  6. add iface=conf.iface argument in self.sniffer._run inside _sndrcv_rcv function in the file sendrecv.py.
  7. check, that srp() caught that response.

Actual result

If you want more details check out this: I sent DISCOVER request, but scapy's internal sniffer did not catch the offer response (that was sent):

Begin emission
Finished sending 1 packets
Ether / IPv6 / TCP 2a06:98c1:3123:e000:::https > 2a02:2168:8046:5400:9c83:fcb6:f6a4:85b8:595** PA / Raw
.Ether / IPv6 / TCP 2a06:98c1:3123:e000:::https > 2a02:2168:8046:5400:9c83:fcb6:f6a4:85b8:595** A
.^C

Expected result

But if i add iface=conf.iface argument in self.sniffer._run inside _sndrcv_rcv function in this file sendrecv.py, then we see the OFFER response by the server:

Begin emission
Ether / IP / UDP / BOOTP / DHCP Discover
.
Finished sending 1 packets
Ether / IP / UDP / BOOTP / DHCP Offer
.^C

Related resources

No response

gpotter2 commented 1 month ago

This is expected. srp can take an iface argument.

Lopkop commented 1 month ago

@gpotter2 I actually passed iface to srp as an argument, that's the point of this issue. Did you check the code?

gpotter2 commented 1 month ago

Your issue is that you are using the default interface.

If you use srp, it uses a conf.L2socket which filters outgoing traffic. That makes sense, you don't want to match what you are sending as a response. Your fake server response is marked as "OUTGOING", as it's coming out of the interface, therefore it is filtered by srp. If you were running each scripts on different machines, it would work.

Use the loopback interface for your local testing.