| 2393 | |
| 2394 | @conf.commands.register |
| 2395 | def fragleak(target, sport=123, dport=123, timeout=0.2, onlyasc=0, count=None): |
| 2396 | load = "XXXXYYYYYYYYYY" |
| 2397 | pkt = IP(dst=target, id=RandShort(), options=b"\x00" * 40, flags=1) |
| 2398 | pkt /= UDP(sport=sport, dport=sport) / load |
| 2399 | s = conf.L3socket() |
| 2400 | intr = 0 |
| 2401 | found = {} |
| 2402 | try: |
| 2403 | while count is None or count: |
| 2404 | if count is not None and isinstance(count, int): |
| 2405 | count -= 1 |
| 2406 | try: |
| 2407 | if not intr: |
| 2408 | s.send(pkt) |
| 2409 | sin = select.select([s], [], [], timeout)[0] |
| 2410 | if not sin: |
| 2411 | continue |
| 2412 | ans = s.recv(1600) |
| 2413 | if not isinstance(ans, IP): # TODO: IPv6 |
| 2414 | continue |
| 2415 | if not isinstance(ans.payload, ICMP): |
| 2416 | continue |
| 2417 | if not isinstance(ans.payload.payload, IPerror): |
| 2418 | continue |
| 2419 | if ans.payload.payload.dst != target: |
| 2420 | continue |
| 2421 | if ans.src != target: |
| 2422 | print("leak from", ans.src) |
| 2423 | if not ans.haslayer(conf.padding_layer): |
| 2424 | continue |
| 2425 | leak = ans.getlayer(conf.padding_layer).load |
| 2426 | if leak not in found: |
| 2427 | found[leak] = None |
| 2428 | linehexdump(leak, onlyasc=onlyasc) |
| 2429 | except KeyboardInterrupt: |
| 2430 | if intr: |
| 2431 | raise |
| 2432 | intr = 1 |
| 2433 | except KeyboardInterrupt: |
| 2434 | pass |
| 2435 | |
| 2436 | |
| 2437 | @conf.commands.register |