|
|
| Riga 5: |
Riga 5: |
| | Usage: ./rogue_dhcp_check.py <interface_name> [timeout in seconds] | | Usage: ./rogue_dhcp_check.py <interface_name> [timeout in seconds] |
| | | | |
| | + | #!/usr/bin/env python3 |
| | | | |
| − |
| + | # This script sends a DHCP discover on the specified interface |
| − | <table class="highlight tab-size js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">
| + | # then waits for the specified number of seconds (default: 5) |
| − | <tbody><tr>
| + | # for replies from DHCP servers and prints the results. |
| − | <td id="file-rogue_dhcp_check-py-L1" class="blob-num js-line-number" data-line-number="1"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-c">#!/usr/bin/env python3</span></td>
| + | # Install dependencies: |
| − | </tr>
| + | # sudo apt install python3-pip |
| − | <tr>
| + | # sudo pip3 install scapy # do not use the one in Ubuntu apt (as of 18.04) |
| − | <td id="file-rogue_dhcp_check-py-L2" class="blob-num js-line-number" data-line-number="2"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC2" class="blob-code blob-code-inner js-file-line">
| + | # scapy API: https://scapy.readthedocs.io/en/latest/api/scapy.layers.html |
| − | </td>
| + | |
| − | </tr>
| + | # TODO |
| − | <tr>
| + | # |
| − | <td id="file-rogue_dhcp_check-py-L3" class="blob-num js-line-number" data-line-number="3"></td>
| + | # * What if a single DHCP server replies twice |
| − | <td id="file-rogue_dhcp_check-py-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># This script sends a DHCP discover on the specified interface</span></td>
| + | # or the rogue DHCP server is spoofing MAC addresses? |
| − | </tr>
| + | # * Support plain BOOTP servers |
| − | <tr>
| + | # |
| − | <td id="file-rogue_dhcp_check-py-L4" class="blob-num js-line-number" data-line-number="4"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC4" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># then waits for the specified number of seconds (default: 5)</span></td> | + | import os |
| − | </tr>
| + | import sys |
| − | <tr>
| + | from scapy.all import * |
| − | <td id="file-rogue_dhcp_check-py-L5" class="blob-num js-line-number" data-line-number="5"></td> | + | |
| − | <td id="file-rogue_dhcp_check-py-LC5" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># for replies from DHCP servers and prints the results.</span></td>
| + | def die(err): |
| − | </tr>
| + | print(err, file=sys.stderr) |
| − | <tr>
| + | sys.exit(1) |
| − | <td id="file-rogue_dhcp_check-py-L6" class="blob-num js-line-number" data-line-number="6"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC6" class="blob-code blob-code-inner js-file-line">
| + | def usage(file=sys.stdout): |
| − | </td>
| + | print("Usage:", sys.argv[0], "<interface_name> [timeout in seconds]", file=file) |
| − | </tr>
| + | |
| − | <tr>
| + | if len(sys.argv) < 2 or len(sys.argv) > 3: |
| − | <td id="file-rogue_dhcp_check-py-L7" class="blob-num js-line-number" data-line-number="7"></td>
| + | usage(sys.stderr) |
| − | <td id="file-rogue_dhcp_check-py-LC7" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># Install dependencies:</span></td>
| + | sys.exit(1) |
| − | </tr>
| + | |
| − | <tr>
| + | iface = sys.argv[1] |
| − | <td id="file-rogue_dhcp_check-py-L8" class="blob-num js-line-number" data-line-number="8"></td>
| + | timeout = 5 |
| − | <td id="file-rogue_dhcp_check-py-LC8" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># sudo apt install python3-pip</span></td>
| + | if len(sys.argv) == 3: |
| − | </tr>
| + | try: |
| − | <tr>
| + | timeout = int(sys.argv[2]) |
| − | <td id="file-rogue_dhcp_check-py-L9" class="blob-num js-line-number" data-line-number="9"></td>
| + | except: |
| − | <td id="file-rogue_dhcp_check-py-LC9" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># sudo pip3 install scapy # do not use the one in Ubuntu apt (as of 18.04)</span></td> | + | usage(sys.stderr) |
| − | </tr>
| + | sys.exit(1) |
| − | <tr>
| + | |
| − | <td id="file-rogue_dhcp_check-py-L10" class="blob-num js-line-number" data-line-number="10"></td>
| + | if timeout < 1: |
| − | <td id="file-rogue_dhcp_check-py-LC10" class="blob-code blob-code-inner js-file-line">
| + | timeout = 5 |
| − | </td>
| + | |
| − | </tr>
| + | if os.geteuid() != 0: |
| − | <tr>
| + | die("You must be root to send DHCP packets") |
| − | <td id="file-rogue_dhcp_check-py-L11" class="blob-num js-line-number" data-line-number="11"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC11" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># scapy API: https://scapy.readthedocs.io/en/latest/api/scapy.layers.html</span></td>
| + | conf.checkIPaddr = False |
| − | </tr>
| + | |
| − | <tr>
| + | try: |
| − | <td id="file-rogue_dhcp_check-py-L12" class="blob-num js-line-number" data-line-number="12"></td> | + | fam, hw = get_if_raw_hwaddr(iface) |
| − | <td id="file-rogue_dhcp_check-py-LC12" class="blob-code blob-code-inner js-file-line"> | + | except OSError as e: |
| − | </td>
| + | die(e) |
| − | </tr>
| + | |
| − | <tr>
| + | dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff") / IP(src="0.0.0.0", dst="255.255.255.255") / UDP(sport=68, dport=67) / BOOTP(chaddr=hw) / DHCP(options=[("message-type","discover"), "end"]) |
| − | <td id="file-rogue_dhcp_check-py-L13" class="blob-num js-line-number" data-line-number="13"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC13" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># TODO</span></td>
| + | print("Sending DHCP Discover packet on interface", iface) |
| − | </tr>
| + | print("Waiting", timeout, "seconds for reply") |
| − | <tr>
| + | |
| − | <td id="file-rogue_dhcp_check-py-L14" class="blob-num js-line-number" data-line-number="14"></td>
| + | ans, unans = srp(dhcp_discover, multi=True, timeout=timeout) |
| − | <td id="file-rogue_dhcp_check-py-LC14" class="blob-code blob-code-inner js-file-line"><span class="pl-c">#</span></td>
| + | |
| − | </tr>
| + | dhcp_servers = {} |
| − | <tr>
| + | for snd, rcv in ans: |
| − | <td id="file-rogue_dhcp_check-py-L15" class="blob-num js-line-number" data-line-number="15"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC15" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># * What if a single DHCP server replies twice</span></td>
| + | # We only care about message-type == 2 |
| − | </tr>
| + | # a.k.a. DHCP Offers |
| − | <tr>
| + | is_offer = False |
| − | <td id="file-rogue_dhcp_check-py-L16" class="blob-num js-line-number" data-line-number="16"></td>
| + | for opt in rcv.payload.payload.payload.payload.options: |
| − | <td id="file-rogue_dhcp_check-py-LC16" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># or the rogue DHCP server is spoofing MAC addresses?</span></td>
| + | if opt[0] == 'message-type': |
| − | </tr>
| + | if opt[1] == 2: |
| − | <tr>
| + | is_offer = True |
| − | <td id="file-rogue_dhcp_check-py-L17" class="blob-num js-line-number" data-line-number="17"></td>
| + | |
| − | <td id="file-rogue_dhcp_check-py-LC17" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># * Support plain BOOTP servers</span></td>
| + | if not is_offer: |
| − | </tr>
| + | continue |
| − | <tr>
| + | |
| − | <td id="file-rogue_dhcp_check-py-L18" class="blob-num js-line-number" data-line-number="18"></td>
| + | # rcv.fields: list fields |
| − | <td id="file-rogue_dhcp_check-py-LC18" class="blob-code blob-code-inner js-file-line"><span class="pl-c">#</span></td>
| + | # rcv.payload: the decoded payload |
| − | </tr>
| + | |
| − | <tr>
| + | if not rcv.src in dhcp_servers: |
| − | <td id="file-rogue_dhcp_check-py-L19" class="blob-num js-line-number" data-line-number="19"></td>
| + | dhcp_servers[rcv.src] = {'MAC': rcv.src, 'IP': rcv.payload.src, 'offer': rcv.payload.payload.payload.yiaddr, 'options': rcv.payload.payload.payload.payload.options} |
| − | <td id="file-rogue_dhcp_check-py-LC19" class="blob-code blob-code-inner js-file-line">
| + | |
| − | </td>
| + | print('') |
| − | </tr>
| + | print("Received", len(ans), "replies from", len(dhcp_servers), "different (based on MAC address) DHCP server(s)") |
| − | <tr>
| + | print('') |
| − | <td id="file-rogue_dhcp_check-py-L20" class="blob-num js-line-number" data-line-number="20"></td>
| + | if len(dhcp_servers) > 1: |
| − | <td id="file-rogue_dhcp_check-py-LC20" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-s1">os</span></td>
| + | print("WARNING: Looks like there might be more than one DHCP server on your network") |
| − | </tr>
| + | print('') |
| − | <tr>
| + | |
| − | <td id="file-rogue_dhcp_check-py-L21" class="blob-num js-line-number" data-line-number="21"></td>
| + | for mac in dhcp_servers: |
| − | <td id="file-rogue_dhcp_check-py-LC21" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-s1">sys</span></td>
| + | server = dhcp_servers[mac] |
| − | </tr>
| + | print("DHCP server", mac) |
| − | <tr>
| + | print(" Server IP:", server['IP']) |
| − | <td id="file-rogue_dhcp_check-py-L22" class="blob-num js-line-number" data-line-number="22"></td>
| + | print(" Offer IP:", server['offer']) |
| − | <td id="file-rogue_dhcp_check-py-LC22" class="blob-code blob-code-inner js-file-line"><span class="pl-k">from</span> <span class="pl-s1">scapy</span>.<span class="pl-s1">all</span> <span class="pl-k">import</span> <span class="pl-c1">*</span></td>
| + | print(" Options:") |
| − | </tr>
| + | for opt in server['options']: |
| − | <tr>
| + | if opt[0] == 'message-type': |
| − | <td id="file-rogue_dhcp_check-py-L23" class="blob-num js-line-number" data-line-number="23"></td>
| + | print(' message-type:', DHCPTypes[opt[1]]) |
| − | <td id="file-rogue_dhcp_check-py-LC23" class="blob-code blob-code-inner js-file-line">
| + | else: |
| − | </td>
| + | print(' ' + str(opt[0])+':', opt[1]) |
| − | </tr>
| + | print('') |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L24" class="blob-num js-line-number" data-line-number="24"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC24" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">die</span>(<span class="pl-s1">err</span>):</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L25" class="blob-num js-line-number" data-line-number="25"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC25" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s1">err</span>, <span class="pl-s1">file</span><span class="pl-c1">=</span><span class="pl-s1">sys</span>.<span class="pl-s1">stderr</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L26" class="blob-num js-line-number" data-line-number="26"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC26" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">sys</span>.<span class="pl-en">exit</span>(<span class="pl-c1">1</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L27" class="blob-num js-line-number" data-line-number="27"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC27" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L28" class="blob-num js-line-number" data-line-number="28"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC28" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">usage</span>(<span class="pl-s1">file</span><span class="pl-c1">=</span><span class="pl-s1">sys</span>.<span class="pl-s1">stdout</span>):</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L29" class="blob-num js-line-number" data-line-number="29"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC29" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">"Usage:"</span>, <span class="pl-s1">sys</span>.<span class="pl-s1">argv</span>[<span class="pl-c1">0</span>], <span class="pl-s">"<interface_name> [timeout in seconds]"</span>, <span class="pl-s1">file</span><span class="pl-c1">=</span><span class="pl-s1">file</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L30" class="blob-num js-line-number" data-line-number="30"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC30" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L31" class="blob-num js-line-number" data-line-number="31"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC31" class="blob-code blob-code-inner js-file-line"><span class="pl-k">if</span> <span class="pl-en">len</span>(<span class="pl-s1">sys</span>.<span class="pl-s1">argv</span>) <span class="pl-c1"><</span> <span class="pl-c1">2</span> <span class="pl-c1">or</span> <span class="pl-en">len</span>(<span class="pl-s1">sys</span>.<span class="pl-s1">argv</span>) <span class="pl-c1">></span> <span class="pl-c1">3</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L32" class="blob-num js-line-number" data-line-number="32"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC32" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">usage</span>(<span class="pl-s1">sys</span>.<span class="pl-s1">stderr</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L33" class="blob-num js-line-number" data-line-number="33"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC33" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">sys</span>.<span class="pl-en">exit</span>(<span class="pl-c1">1</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L34" class="blob-num js-line-number" data-line-number="34"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC34" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L35" class="blob-num js-line-number" data-line-number="35"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC35" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">iface</span> <span class="pl-c1">=</span> <span class="pl-s1">sys</span>.<span class="pl-s1">argv</span>[<span class="pl-c1">1</span>]</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L36" class="blob-num js-line-number" data-line-number="36"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC36" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">timeout</span> <span class="pl-c1">=</span> <span class="pl-c1">5</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L37" class="blob-num js-line-number" data-line-number="37"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC37" class="blob-code blob-code-inner js-file-line"><span class="pl-k">if</span> <span class="pl-en">len</span>(<span class="pl-s1">sys</span>.<span class="pl-s1">argv</span>) <span class="pl-c1">==</span> <span class="pl-c1">3</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L38" class="blob-num js-line-number" data-line-number="38"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC38" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L39" class="blob-num js-line-number" data-line-number="39"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC39" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">timeout</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-s1">sys</span>.<span class="pl-s1">argv</span>[<span class="pl-c1">2</span>])</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L40" class="blob-num js-line-number" data-line-number="40"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC40" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">except</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L41" class="blob-num js-line-number" data-line-number="41"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC41" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">usage</span>(<span class="pl-s1">sys</span>.<span class="pl-s1">stderr</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L42" class="blob-num js-line-number" data-line-number="42"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC42" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">sys</span>.<span class="pl-en">exit</span>(<span class="pl-c1">1</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L43" class="blob-num js-line-number" data-line-number="43"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC43" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L44" class="blob-num js-line-number" data-line-number="44"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC44" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-s1">timeout</span> <span class="pl-c1"><</span> <span class="pl-c1">1</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L45" class="blob-num js-line-number" data-line-number="45"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC45" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">timeout</span> <span class="pl-c1">=</span> <span class="pl-c1">5</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L46" class="blob-num js-line-number" data-line-number="46"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC46" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L47" class="blob-num js-line-number" data-line-number="47"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC47" class="blob-code blob-code-inner js-file-line"><span class="pl-k">if</span> <span class="pl-s1">os</span>.<span class="pl-en">geteuid</span>() <span class="pl-c1">!=</span> <span class="pl-c1">0</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L48" class="blob-num js-line-number" data-line-number="48"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC48" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">die</span>(<span class="pl-s">"You must be root to send DHCP packets"</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L49" class="blob-num js-line-number" data-line-number="49"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC49" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L50" class="blob-num js-line-number" data-line-number="50"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC50" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">conf</span>.<span class="pl-s1">checkIPaddr</span> <span class="pl-c1">=</span> <span class="pl-c1">False</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L51" class="blob-num js-line-number" data-line-number="51"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC51" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L52" class="blob-num js-line-number" data-line-number="52"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC52" class="blob-code blob-code-inner js-file-line"><span class="pl-k">try</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L53" class="blob-num js-line-number" data-line-number="53"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC53" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">fam</span>, <span class="pl-s1">hw</span> <span class="pl-c1">=</span> <span class="pl-en">get_if_raw_hwaddr</span>(<span class="pl-s1">iface</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L54" class="blob-num js-line-number" data-line-number="54"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC54" class="blob-code blob-code-inner js-file-line"><span class="pl-k">except</span> <span class="pl-v">OSError</span> <span class="pl-k">as</span> <span class="pl-s1">e</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L55" class="blob-num js-line-number" data-line-number="55"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC55" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">die</span>(<span class="pl-s1">e</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L56" class="blob-num js-line-number" data-line-number="56"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC56" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L57" class="blob-num js-line-number" data-line-number="57"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC57" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">dhcp_discover</span> <span class="pl-c1">=</span> <span class="pl-v">Ether</span>(<span class="pl-s1">dst</span><span class="pl-c1">=</span><span class="pl-s">"ff:ff:ff:ff:ff:ff"</span>) <span class="pl-c1">/</span> <span class="pl-v">IP</span>(<span class="pl-s1">src</span><span class="pl-c1">=</span><span class="pl-s">"0.0.0.0"</span>, <span class="pl-s1">dst</span><span class="pl-c1">=</span><span class="pl-s">"255.255.255.255"</span>) <span class="pl-c1">/</span> <span class="pl-v">UDP</span>(<span class="pl-s1">sport</span><span class="pl-c1">=</span><span class="pl-c1">68</span>, <span class="pl-s1">dport</span><span class="pl-c1">=</span><span class="pl-c1">67</span>) <span class="pl-c1">/</span> <span class="pl-v">BOOTP</span>(<span class="pl-s1">chaddr</span><span class="pl-c1">=</span><span class="pl-s1">hw</span>) <span class="pl-c1">/</span> <span class="pl-v">DHCP</span>(<span class="pl-s1">options</span><span class="pl-c1">=</span>[(<span class="pl-s">"message-type"</span>,<span class="pl-s">"discover"</span>), <span class="pl-s">"end"</span>])</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L58" class="blob-num js-line-number" data-line-number="58"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC58" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L59" class="blob-num js-line-number" data-line-number="59"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC59" class="blob-code blob-code-inner js-file-line"><span class="pl-en">print</span>(<span class="pl-s">"Sending DHCP Discover packet on interface"</span>, <span class="pl-s1">iface</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L60" class="blob-num js-line-number" data-line-number="60"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC60" class="blob-code blob-code-inner js-file-line"><span class="pl-en">print</span>(<span class="pl-s">"Waiting"</span>, <span class="pl-s1">timeout</span>, <span class="pl-s">"seconds for reply"</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L61" class="blob-num js-line-number" data-line-number="61"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC61" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L62" class="blob-num js-line-number" data-line-number="62"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC62" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">ans</span>, <span class="pl-s1">unans</span> <span class="pl-c1">=</span> <span class="pl-en">srp</span>(<span class="pl-s1">dhcp_discover</span>, <span class="pl-s1">multi</span><span class="pl-c1">=</span><span class="pl-c1">True</span>, <span class="pl-s1">timeout</span><span class="pl-c1">=</span><span class="pl-s1">timeout</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L63" class="blob-num js-line-number" data-line-number="63"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC63" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L64" class="blob-num js-line-number" data-line-number="64"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC64" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">dhcp_servers</span> <span class="pl-c1">=</span> {}</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L65" class="blob-num js-line-number" data-line-number="65"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC65" class="blob-code blob-code-inner js-file-line"><span class="pl-k">for</span> <span class="pl-s1">snd</span>, <span class="pl-s1">rcv</span> <span class="pl-c1">in</span> <span class="pl-s1">ans</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L66" class="blob-num js-line-number" data-line-number="66"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC66" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L67" class="blob-num js-line-number" data-line-number="67"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC67" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># We only care about message-type == 2</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L68" class="blob-num js-line-number" data-line-number="68"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC68" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># a.k.a. DHCP Offers</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L69" class="blob-num js-line-number" data-line-number="69"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC69" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">is_offer</span> <span class="pl-c1">=</span> <span class="pl-c1">False</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L70" class="blob-num js-line-number" data-line-number="70"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC70" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">for</span> <span class="pl-s1">opt</span> <span class="pl-c1">in</span> <span class="pl-s1">rcv</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">options</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L71" class="blob-num js-line-number" data-line-number="71"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC71" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-s1">opt</span>[<span class="pl-c1">0</span>] <span class="pl-c1">==</span> <span class="pl-s">'message-type'</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L72" class="blob-num js-line-number" data-line-number="72"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC72" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-s1">opt</span>[<span class="pl-c1">1</span>] <span class="pl-c1">==</span> <span class="pl-c1">2</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L73" class="blob-num js-line-number" data-line-number="73"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC73" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">is_offer</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L74" class="blob-num js-line-number" data-line-number="74"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC74" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L75" class="blob-num js-line-number" data-line-number="75"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC75" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-s1">is_offer</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L76" class="blob-num js-line-number" data-line-number="76"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC76" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">continue</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L77" class="blob-num js-line-number" data-line-number="77"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC77" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L78" class="blob-num js-line-number" data-line-number="78"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC78" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># rcv.fields: list fields</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L79" class="blob-num js-line-number" data-line-number="79"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC79" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># rcv.payload: the decoded payload</span></td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L80" class="blob-num js-line-number" data-line-number="80"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC80" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L81" class="blob-num js-line-number" data-line-number="81"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC81" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-s1">rcv</span>.<span class="pl-s1">src</span> <span class="pl-c1">in</span> <span class="pl-s1">dhcp_servers</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L82" class="blob-num js-line-number" data-line-number="82"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC82" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">dhcp_servers</span>[<span class="pl-s1">rcv</span>.<span class="pl-s1">src</span>] <span class="pl-c1">=</span> {<span class="pl-s">'MAC'</span>: <span class="pl-s1">rcv</span>.<span class="pl-s1">src</span>, <span class="pl-s">'IP'</span>: <span class="pl-s1">rcv</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">src</span>, <span class="pl-s">'offer'</span>: <span class="pl-s1">rcv</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">yiaddr</span>, <span class="pl-s">'options'</span>: <span class="pl-s1">rcv</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">payload</span>.<span class="pl-s1">options</span>}</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L83" class="blob-num js-line-number" data-line-number="83"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC83" class="blob-code blob-code-inner js-file-line">
| |
| − | </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L84" class="blob-num js-line-number" data-line-number="84"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC84" class="blob-code blob-code-inner js-file-line"><span class="pl-en">print</span>(<span class="pl-s">''</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L85" class="blob-num js-line-number" data-line-number="85"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC85" class="blob-code blob-code-inner js-file-line"><span class="pl-en">print</span>(<span class="pl-s">"Received"</span>, <span class="pl-en">len</span>(<span class="pl-s1">ans</span>), <span class="pl-s">"replies from"</span>, <span class="pl-en">len</span>(<span class="pl-s1">dhcp_servers</span>), <span class="pl-s">"different (based on MAC address) DHCP server(s)"</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L86" class="blob-num js-line-number" data-line-number="86"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC86" class="blob-code blob-code-inner js-file-line"><span class="pl-en">print</span>(<span class="pl-s">''</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L87" class="blob-num js-line-number" data-line-number="87"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC87" class="blob-code blob-code-inner js-file-line"><span class="pl-k">if</span> <span class="pl-en">len</span>(<span class="pl-s1">dhcp_servers</span>) <span class="pl-c1">></span> <span class="pl-c1">1</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L88" class="blob-num js-line-number" data-line-number="88"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC88" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">"WARNING: Looks like there might be more than one DHCP server on your network"</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L89" class="blob-num js-line-number" data-line-number="89"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC89" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">''</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L90" class="blob-num js-line-number" data-line-number="90"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC90" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L91" class="blob-num js-line-number" data-line-number="91"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC91" class="blob-code blob-code-inner js-file-line"><span class="pl-k">for</span> <span class="pl-s1">mac</span> <span class="pl-c1">in</span> <span class="pl-s1">dhcp_servers</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L92" class="blob-num js-line-number" data-line-number="92"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC92" class="blob-code blob-code-inner js-file-line"> <span class="pl-s1">server</span> <span class="pl-c1">=</span> <span class="pl-s1">dhcp_servers</span>[<span class="pl-s1">mac</span>]</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L93" class="blob-num js-line-number" data-line-number="93"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC93" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">"DHCP server"</span>, <span class="pl-s1">mac</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L94" class="blob-num js-line-number" data-line-number="94"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC94" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">" Server IP:"</span>, <span class="pl-s1">server</span>[<span class="pl-s">'IP'</span>])</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L95" class="blob-num js-line-number" data-line-number="95"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC95" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">" Offer IP:"</span>, <span class="pl-s1">server</span>[<span class="pl-s">'offer'</span>])</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L96" class="blob-num js-line-number" data-line-number="96"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC96" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">" Options:"</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L97" class="blob-num js-line-number" data-line-number="97"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC97" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">for</span> <span class="pl-s1">opt</span> <span class="pl-c1">in</span> <span class="pl-s1">server</span>[<span class="pl-s">'options'</span>]:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L98" class="blob-num js-line-number" data-line-number="98"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC98" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-s1">opt</span>[<span class="pl-c1">0</span>] <span class="pl-c1">==</span> <span class="pl-s">'message-type'</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L99" class="blob-num js-line-number" data-line-number="99"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC99" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">' message-type:'</span>, <span class="pl-v">DHCPTypes</span>[<span class="pl-s1">opt</span>[<span class="pl-c1">1</span>]])</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L100" class="blob-num js-line-number" data-line-number="100"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC100" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">else</span>:</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L101" class="blob-num js-line-number" data-line-number="101"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC101" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">' '</span> <span class="pl-c1">+</span> <span class="pl-en">str</span>(<span class="pl-s1">opt</span>[<span class="pl-c1">0</span>])<span class="pl-c1">+</span><span class="pl-s">':'</span>, <span class="pl-s1">opt</span>[<span class="pl-c1">1</span>])</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L102" class="blob-num js-line-number" data-line-number="102"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC102" class="blob-code blob-code-inner js-file-line"> <span class="pl-en">print</span>(<span class="pl-s">''</span>)</td>
| |
| − | </tr>
| |
| − | <tr>
| |
| − | <td id="file-rogue_dhcp_check-py-L103" class="blob-num js-line-number" data-line-number="103"></td>
| |
| − | <td id="file-rogue_dhcp_check-py-LC103" class="blob-code blob-code-inner js-file-line"> </td>
| |
| − | </tr>
| |
| − | </tbody></table>
| |