┌───────────────────────┐
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
└───────────────────────┘
CVE-2017-13028: TCPdump
~ CuB3y0nd
# CVE-2017-13028
## Description

CVE: https://www.cve.org/CVERecord?id=CVE-2017-13028

# Compile

## Download

```shellsession
git clone https://github.com/the-tcpdump-group/tcpdump.git && cd tcpdump
git checkout tcpdump-4.9.2
```

 README  TCPdump  libpcap  TCPdump-4.9.2 
 libpcap  1.8.1 

```shellsession
git clone https://github.com/the-tcpdump-group/libpcap.git && cd libpcap
git checkout libpcap-1.8.1
```

## Build

 chall  ASAN  fuzz `AFL_USE_ASAN
=1` 

```shellsession
CC=clang CXX=clang++ CFLAGS="-O0 -g -fno-inline -fno-builtin -fno-omit-frame-poi
nter" CXXFLAGS="$CFLAGS" ./configure --enable-shared=no --prefix="$(realpath ../
workshop/libpcap-debug)" --disable-bluetooth --disable-dbus
make -j`nproc` && make install
make clean

AFL_USE_ASAN=1 CC=afl-clang-lto CXX=afl-clang-lto++ ./configure --enable-shared=
no --prefix="$(realpath ../workshop/libpcap-fuzz)" --disable-bluetooth --disable
-dbus
AFL_USE_ASAN=1 make -j`nproc` && AFL_USE_ASAN=1 make install
```

 tcpdump
 `LDFLAGS`  `CPPFLAGS` libpcap  tcpd
ump  libpcap 使 `--with-system-libpcap` 
 libpcap 
 libpcap


 `config.log` 
 ISO C99  `-Wno-error=im
plicit-int`  `implicit-int`  warning  error 

```shellsession
CC=clang 
CXX=clang++ 
CFLAGS="-O0 -g -fno-inline -fno-builtin -fno-omit-frame-pointer 
        -Wno-error=implicit-int" 
CXXFLAGS="$CFLAGS" 
LDFLAGS="-L$(realpath ../workshop/libpcap-debug/lib)" 
CPPFLAGS="-I$(realpath ../workshop/libpcap-debug/include)" 
./configure 
  --prefix="$(realpath ../workshop/tcpdump-debug)" 
  --with-system-libpcap
```

 configure make 


 `incomplete element type 'const struct tok'`



 grep  `struct tok`  `netdissect.h` 
 `l2vpn.h`  `#include "netdissect.h"` 

 `unknown type name 'uint32_t'` 
 `#include <stdint.h>` 

 `incomplete type 'struct in6_addr'` `#include <netinet/in.h>`
 

 `redefinition of 'UNALIGNED' with a different type: 'struct ip6_ext' vs '
struct ip6_hdr'`  grep  `UNALIGNED` 
 `#define UNALIGNED __attribute__((pac
ked))`

```c
#ifndef UNALIGNED
#define UNALIGNED __attribute__((packed))
#endif
```

 `unknown type name 'netdissect_options'` 
 `#include "netdissect.h"`
 patch 

```shellsession
make clean && make -j`nproc` && make install
```
 libpcap 1.9.0 VERSION  1.9.0 release tag 
 1.8.1

 19 
……

 fuzz 

```shellsession
make clean
AFL_USE_ASAN=1 
CC=afl-clang-lto 
CXX=afl-clang-lto++ 
CFLAGS="-Wno-error=implicit-int" 
CXXFLAGS="$CFLAGS" 
LDFLAGS="-L$(realpath ../workshop/libpcap-fuzz/lib)" 
CPPFLAGS="-I$(realpath ../workshop/libpcap-fuzz/include)" 
./configure 
  --prefix="$(realpath ../workshop/tcpdump-fuzz)" 
  --with-system-libpcap
AFL_USE_ASAN=1 make -j`nproc` && AFL_USE_ASAN=1 make install
```

# Samples

<s></s>
 AI
tcpdump 


 wireshark 
 tcpdump  fuzz  wire
shark 

# Fuzzing

便
 fuzz  `-t 1000+` 
`+`  afl++  timeout 
`AFL_TMPDIR=/dev/shm` 寿 `-m none` 
 ASAN  OOM 
[Notes for using ASAN with afl-fuzz](https://aflplus.plus/docs/notes_for
_asan/)

```shellsession
ASAN_OPTIONS="detect_leaks=0:abort_on_error=1:symbolize=0" AFL_TMPDIR=/dev/shm a
fl-fuzz -i corpus -o outs -s 1337 -t 1000+ -m none -- ./tcpdump-fuzz/sbin/tcpdum
p -vvvvXX -ee -nn -r @@
```

fuzzer 
 1.8.0 1.8.1
 …… `VERSION
` ……

 libpcap 1.8.0 

configure  make  dbus  bluetooth  
patch 
 `pcap_t`  `pcap_if_t`  grep 
 `#include "pcap.h"` 


```shellsession
CC=clang CXX=clang++ CFLAGS="-O0 -g -fno-inline -fno-builtin -fno-omit-frame-poi
nter" CXXFLAGS="$CFLAGS" ./configure --enable-shared=no --prefix="$(realpath ../
workshop/libpcap-debug)"
make -j`nproc` && make install
make clean

AFL_USE_ASAN=1 CC=afl-clang-lto CXX=afl-clang-lto++ ./configure --enable-shared=
no --prefix="$(realpath ../workshop/libpcap-fuzz)"
AFL_USE_ASAN=1 make -j`nproc` && AFL_USE_ASAN=1 make install
```

 libpcap  tcpdump make
 dbus  libpcap…………

 `--disable-dbus` /

 dbus  libusb  canusb……

```shellsession
AFL_USE_ASAN=1 CC=afl-clang-lto CXX=afl-clang-lto++ ./configure --enable-shared=
no --prefix="$(realpath ../workshop/libpcap-fuzz)" --disable-dbus --disable-usb 
--disable-canusb
```

 crashes 

11 
…… fuzz 
……
 configure  `AFL_USE_ASAN=1` make 

 `Compiled with AddressSanitizer/CLang.`……


 crash 
# Analysis

 debug 

```shellsession
CC=clang 
CXX=clang++ 
CFLAGS="-O0 -g -fno-inline -fno-builtin -fno-omit-frame-pointer 
        -fsanitize=address" 
CXXFLAGS="$CFLAGS" 
./configure 
  --enable-shared=no 
  --prefix="$(realpath ../workshop/libpcap-debug)" 
  --disable-dbus
  --disable-usb 
  --disable-canusb

CC=clang 
CXX=clang++ 
CFLAGS="-O0 -g -fno-inline -fno-builtin -fno-omit-frame-pointer 
        -Wno-error=implicit-int 
        -fsanitize=address" 
CXXFLAGS="$CFLAGS" 
LDFLAGS="-L$(realpath ../workshop/libpcap-debug/lib)" 
CPPFLAGS="-I$(realpath ../workshop/libpcap-debug/include)" 
./configure 
  --prefix="$(realpath ../workshop/tcpdump-debug)" 
  --with-system-libpcap
```

 crash
 CVE……

 crashes

 gdb  CVE  crash……


```bash
#!/usr/bin/env bash

TARGET="./tcpdump-debug/sbin/tcpdump"
CRASH_DIR="./outs_v3/default/crashes"
OUTPUT_LOG="crash_reports.log"

>"$OUTPUT_LOG"

echo "[+] Analysing crashes in $CRASH_DIR..."

export ASAN_OPTIONS="detect_leaks=0:abort_on_error=1:symbolize=1"

for crash_file in "$CRASH_DIR"/id:*; do
  [ -e "$crash_file" ] || continue

  echo "--------------------------------------------------" >>"$OUTPUT_LOG"
  echo "File: $(basename "$crash_file")" >>"$OUTPUT_LOG"

  gdb --batch --quiet 
    --ex "run" 
    --ex "bt" 
    --ex "quit" 
    --args "$TARGET" -vvvvXX -ee -nn -r "$crash_file" >>"$OUTPUT_LOG" 2>&1

  echo -e "n" >>"$OUTPUT_LOG"
done

echo "[+] Done! Result in: $OUTPUT_LOG"
```

 AI 

```python
#!/usr/bin/env python3

import os
import binascii
from scapy.all import *

# 
load_contrib("bgp")
load_contrib("ospf")

# 
CORPUS_DIR = "corpus"
if not os.path.exists(CORPUS_DIR):
    os.makedirs(CORPUS_DIR)

def save_pcap(name, pkts):
    wrpcap(os.path.join(CORPUS_DIR, f"{name}.pcap"), pkts)

def generate_corpus():
    print("...")

    # 1.  + IPv4 + TCP ()
    save_pcap("tcp_flags", [
        Ether()/IP(dst="1.2.3.4")/TCP(dport=80, flags="S"),
        Ether()/IP(dst="1.2.3.4")/TCP(dport=80, flags="PA"),
        Ether()/IP(dst="1.2.3.4")/TCP(dport=80, flags="F"),
        Ether()/IP(dst="1.2.3.4")/TCP(dport=80, flags="R"),
    ])

    # 2. UDP + DNS 
    save_pcap("dns_query", [
        Ether()/IP(dst="8.8.8.8")/UDP(dport=53)/DNS(rd=1, qd=DNSQR(qname="www.go
ogle.com"))
    ])

    # 3. ICMP (Ping, Unreachable)
    save_pcap("icmp", [
        Ether()/IP(dst="1.2.3.4")/ICMP(type=8),  # Echo Request
        Ether()/IP(dst="1.2.3.4")/ICMP(type=3, code=3),  # Port Unreachable
    ])

    # 4. IPv6 
    save_pcap("ipv6_base", [
        Ether()/IPv6(dst="2001:4860:4860::8888")/TCP(dport=443),
        Ether()/IPv6(dst="2001:4860:4860::8888")/ICMPv6EchoRequest(),
    ])

    # 5. ARP 
    save_pcap("arp", [
        Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.1"),
        Ether()/ARP(op=2, psrc="192.168.1.1", hwsrc="00:11:22:33:44:55")
    ])

    # 6. HTTP  ()
    http_payload = "GET / HTTP/1.1rnHost: example.comrnrn"
    save_pcap("http_get", [
        Ether()/IP(dst="1.2.3.4")/TCP(dport=80, flags="PA")/Raw(load=http_payloa
d)
    ])

    # 7.  IP/TCP ()
    save_pcap("options", [
        Ether()/IP(dst="1.2.3.4", options=[IPOption(b'x83x03x10')])/TCP(dport=80
),
        Ether()/IP(dst="1.2.3.4")/TCP(dport=80, options=[('MSS', 1460), ('NOP', 
None), ('WScale', 7)])
    ])

    # 8.  (Fragmentation)
    payload = "A" * 100
    pkts = fragment(IP(dst="1.2.3.4")/UDP(dport=123)/payload, fragsize=40)
    save_pcap("fragments", pkts)

    # 9. BOOTP & DHCP ()
    # 9.1  BOOTP 
    save_pcap("bootp_base", [
        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(op=1, chaddr="00:11:22:33:44:55"),
        Ether(src="00:11:22:33:44:55")/IP(src="192.168.1.1", dst="192.168.1.100"
)/UDP(sport=67, dport=68)/BOOTP(op=2, yiaddr="192.168.1.100", siaddr="192.168.1.
1", chaddr="00:11:22:33:44:55")
    ])

    # 9.2 DHCP  (Discover, Offer, Request, Ack)
    chaddr = "00:de:ad:be:ef:00"
    transaction_id = 0x12345678
    save_pcap("dhcp_full_flow", [
        # 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(xid=transaction_id, chaddr=chaddr)/DHCP(options=[(
"message-type", "discover"), "end"]),
        # Offer
        Ether(dst=chaddr)/IP(src="192.168.1.1", dst="192.168.1.100")/UDP(sport=6
7, dport=68)/BOOTP(op=2, xid=transaction_id, yiaddr="192.168.1.100", siaddr="192
.168.1.1", chaddr=chaddr)/DHCP(options=[("message-type", "offer"), ("server_id",
 "192.168.1.1"), ("lease_time", 86400), "end"]),
        # Request
        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(xid=transaction_id, chaddr=chaddr)/DHCP(options=[(
"message-type", "request"), ("requested_addr", "192.168.1.100"), ("server_id", "
192.168.1.1"), "end"]),
        # Ack
        Ether(dst=chaddr)/IP(src="192.168.1.1", dst="192.168.1.100")/UDP(sport=6
7, dport=68)/BOOTP(op=2, xid=transaction_id, yiaddr="192.168.1.100", siaddr="192
.168.1.1", chaddr=chaddr)/DHCP(options=[("message-type", "ack"), ("server_id", "
192.168.1.1"), ("lease_time", 86400), "end"])
    ])

    # 9.3  DHCP ()
    save_pcap("dhcp_options", [
        Ether()/IP(src="0.0.0.0", dst="255.255.255.255")/UDP(sport=68, dport=67)
/BOOTP(chaddr=chaddr)/DHCP(options=[
            ("message-type", "discover"),
            ("hostname", "fuzz-target-node"),
            ("param_req_list", [1, 3, 6, 12, 15, 28, 42]),
            ("vendor_class_id", b"MSFT 5.0"),
            ("client_id", b"x01" + binascii.unhexlify(chaddr.replace(':',''))),
            "end"
        ])
    ])

    # 10. BGP ()
    #  BGP Keepalive  Open 
    save_pcap("bgp", [
        Ether()/IP(dst="1.1.1.1")/TCP(sport=179, dport=179)/BGPHeader(type=4), #
 Keepalive
        Ether()/IP(dst="1.1.1.1")/TCP(sport=179, dport=179)/BGPHeader(type=1)/BG
POpen(my_as=65000, hold_time=180) # Open
    ])

    # 11. SNMP ()
    save_pcap("snmp", [
        Ether()/IP(dst="1.2.3.4")/UDP(sport=161, dport=161)/SNMP(community="publ
ic", PDU=SNMPget(varbindlist=[SNMPvarbind(oid=ASN1_OID("1.3.6.1.2.1.1.1.0"))]))
    ])

    # 12. OSPF ()
    save_pcap("ospf", [
        Ether()/IP(dst="224.0.0.5")/OSPF_Hdr(type=1)/OSPF_Hello(router="1.1.1.1"
, mask="255.255.255.0")
    ])

    # 13.  (Fuzz )
    #  IP 
    malformed_ip = IP(len=100, dst="1.2.3.4")/TCP(dport=80)
    save_pcap("malformed_len", [Ether()/malformed_ip])

    # 14. 802.1Q VLAN 
    save_pcap("vlan", [
        Ether()/Dot1Q(vlan=10)/Dot1Q(vlan=20)/IP()/TCP()
    ])

    print(f" {CORPUS_DIR} ")

if __name__ == "__main__":
    generate_corpus()
```

 `AFL_LLVM_CMPLOG=1`  CMPLOG 使 fuzz
 线/mad

```shellsession
mkdir -p /dev/shm/asan
mkdir -p /dev/shm/asan_cmplog

AFL_TMPDIR=/dev/shm/asan 
afl-fuzz -i clean_seeds_v4 
         -o outs_v4 
         -s 1337 
         -m none 
         -M asan 
         -- ./tcpdump-fuzz/sbin/tcpdump -vvvvXX -ee -nn -r @@

AFL_TMPDIR=/dev/shm/asan_cmplog 
afl-fuzz -i clean_seeds_v4 
         -o outs_v4 
         -m none 
         -c ./tcpdump-fuzz-cmplog/sbin/tcpdump 
         -S asan_cmplog 
         -- ./tcpdump-fuzz-cmplog/sbin/tcpdump -vvvvXX -ee -nn -r @@
```



 fuzz  CVE CVE-2017-13028 …… c
hall 使 ASAN 

btw ASAN  backtrace