aflnet / aflnet

AFLNet: A Greybox Fuzzer for Network Protocols (https://thuanpv.github.io/publications/AFLNet_ICST20.pdf)
Apache License 2.0
856 stars 188 forks source link

how to support SNMP? #5

Closed minifish120 closed 4 years ago

minifish120 commented 4 years ago

hi, when i tried to do something to support snmp, some issues occures: 1、i didn't know how to extract the status code from the response 2、if it needs to associate the response and the request

thuanpv commented 4 years ago

Hi,

For a protocol that doesn't have status code, you could consider to generate a hash of the response message and use this as a status code. In this DTLS tutorial, Paul does something similar to convert content_type and message_type to status code: https://github.com/aflnet/aflnet/tree/master/tutorials/tinydtls

Could you please share with me a sample PCAP file capturing the traffic between SNMP client and server? Looking at this I may have a better suggestion.

Thanks,

Thuan

minifish120 commented 4 years ago

hi, thanks for your attention, the file "snmp.pcap" is a sample pcap file capturing the traffic between SNMP client and server,and i don't know how to extract state code from response. Another issue is :the request id behind the request and the response must be identical, how i do this? thanks for your attention again!

At 2020-04-16 08:38:55, "Thuan Pham" notifications@github.com wrote:

Hi,

For a protocol that doesn't have status code, you could consider to generate a hash of the response message and use this as a status code. In this DTLS tutorial, Paul does something similar to convert content_type and message_type to status code: https://github.com/aflnet/aflnet/tree/master/tutorials/tinydtls

Could you please share with me a sample PCAP file capturing the traffic between SNMP client and server? Looking at this I may have a better suggestion.

Thanks,

Thuan

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

thuanpv commented 4 years ago

Hi, I cannot find your "snmp.pcap" file in your message.

minifish120 commented 4 years ago

i added it to https://github.com/minifish120/python-/blob/master/snmp.pcap, please check it out and support some help~~~

thuanpv commented 4 years ago

Hi,

I have looked at your pcap file and it seems that SNMP is a stateless protocol -- no "stateful" information is shown in the response message. My observation seems to be correct because in Wikipedia page for the protocol (at https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol), I also found this text "SNMPv3 (like other SNMP protocol versions) is a stateless protocol, and it has been designed with minimal amount of interactions between the agent and the manager". So to fuzz this protocol and the similar stateless ones, I would suggest you to remove the -E, -q and -s options from afl-fuzz option list to disable its stateful fuzzing mode. In this stateless fuzzing mode, you don't need to write the extract_response_codes_snmp to extract the responses of the SNMP server. All you need is to write the extract_requests_snmp function to decompose the long sequence of SNMP requests into individual ones. To do this, you can follow the structure of the request message.

I hope it helps. If it works, I would love to see a pull request from you to add a tutorial for SNMP fuzzing with AFLNet.

Thuan

amlamarra commented 4 years ago

I plan on getting AFLNet to run against a DNS server. Do you think the same thing would apply there? A sample capture: https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=dns.cap

I'll submit a PR if I get it to work.

minifish120 commented 4 years ago

I plan on getting AFLNet to run against a DNS server. Do you think the same thing would apply there? A sample capture: https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=dns.cap

I'll submit a PR if I get it to work.

yes, i think DNS and SNMP belong to the same type of protocol which can be processed in the similar way

thuanpv commented 4 years ago

Hi @amlamarra. I agree with @minifish120 that DNS is also stateless so all you need to do is to write function extract_requests_dns and update the main function accordingly to support DNS protocol. See my above reply to @minifish120 's question for more details.

amlamarra commented 4 years ago

@thuanpv You said I would not have to write an "extract_response_codes" function, so I implemented the "DNS" option like this:

8948         if (!strcmp(optarg, "RTSP")) {
8949           extract_requests = &extract_requests_rtsp;
8950           extract_response_codes = &extract_response_codes_rtsp;
8951         } else if (!strcmp(optarg, "FTP")) {
8952           extract_requests = &extract_requests_ftp;
8953           extract_response_codes = &extract_response_codes_ftp;
8954         } else if (!strcmp(optarg, "DNS")) {
8955           extract_requests = &extract_requests_dns;
8956         } else if (!strcmp(optarg, "DTLS12")) {
8957           extract_requests = &extract_requests_dtls12;
8958           extract_response_codes = &extract_response_codes_dtls12;
8959         } else

However, AFLNet segfaults as soon as the fuzzing begins. The update_fuzzs() function attempts to call whichever function is pointed to by the extract_response_codes variable:

 581 /* Update #fuzzs visiting a specific state */
 582 void update_fuzzs() {
 583   unsigned int state_count, i, discard;
 584   unsigned int *state_sequence = (*extract_response_codes)(response_buf, response_buf_size, &state_count);

What would be the proper way of doing this?

Perhaps I could implement the extract_response_codes_dns() function and use the DNS return code (https://support.umbrella.com/hc/en-us/articles/232254248-Common-DNS-return-codes-for-any-DNS-service-and-Umbrella-)

thuanpv commented 4 years ago

@amlamarra Thanks for reporting this issue. Have you removed -E, -q, and -s options from the AFLNet command line? If these options are enabled, the extract_response_codes_dns is required. I will add a check to prevent this confusing error message in the next commit.

amlamarra commented 4 years ago

Yes. I attempted fuzzing with those options removed and it segfaults. And from debugging, I located the segfault to be at line 584 in afl-fuzz.c.

andrew ~/dnsmasq-2.73rc6/src $ afl-fuzz -d -i $AFLNET/tutorials/dnsmasq/in-dns -o out-dns -N tcp://127.0.0.1/5353 -P DNS -D 10000 -K -R ./dnsmasq --no-daemon -p 5353
afl-fuzz 2.56b by <lcamtuf@google.com>
[+] You have 4 CPU cores and 4 runnable tasks (utilization: 100%).
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[*] Checking core_pattern...
[*] Setting up output directories...
[*] Scanning '/home/andrew/aflnet/tutorials/dnsmasq/in-dns'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Validating target binary...
[*] Attempting dry run with 'id:000000,orig:dns_queries_1.raw'...
[*] Spinning up the fork server...
[+] All right - fork server is up.
    len = 28, map size = 1029, exec speed = 39417 us
[!] WARNING: Instrumentation output varies across runs.
[*] Attempting dry run with 'id:000001,orig:dns_queries_2.raw'...
    len = 32, map size = 1029, exec speed = 36839 us
[!] WARNING: No new instrumentation output, test case may be useless.
[!] WARNING: Instrumentation output varies across runs.
[+] All test cases processed.

[!] WARNING: The target binary is pretty slow! See docs/perf_tips.txt.
[!] WARNING: Some test cases look useless. Consider using a smaller set.
[+] Here are some useful stats:

    Test case count : 1 favored, 2 variable, 2 total
       Bitmap range : 1029 to 1029 bits (average: 1029.00 bits)
        Exec timing : 36.8k to 39.4k us (average: 39.0k us)

[*] No -t option specified, so I'll use exec timeout of 120 ms.
[+] All set and ready to roll!

                       american fuzzy lop 2.56b (dnsmasq)

┌─ process timing ─────────────────────────────────────┬─ overall results ─────┐
│        run time : 0 days, 0 hrs, 0 min, 1 sec        │  cycles done : 0      │
│   last new path : none seen yet                      │  total paths : 2      │
│ last uniq crash : none seen yet                      │ uniq crashes : 0      │
│  last uniq hang : none seen yet                      │   uniq hangs : 0      │
├─ cycle progress ────────────────────┬─ map coverage ─┴───────────────────────┤
│  now processing : 0* (0.00%)        │    map density : 1.57% / 1.57%         │
│ paths timed out : 0 (0.00%)         │ count coverage : 1.09 bits/tuple       │
├─ stage progress ────────────────────┼─ findings in depth ────────────────────┤
│  now trying : init                  │ favored paths : 1 (50.00%)             │
│ stage execs : 0/-                   │  new edges on : 1 (50.00%)             │
│ total execs : 48                    │ total crashes : 0 (0 unique)           │
│  exec speed : 27.10/sec (slow!)     │  total tmouts : 0 (0 unique)           │
├─ fuzzing strategy yields ───────────┴───────────────┬─ path geometry ────────┤
│   bit flips : n/a, n/a, n/a                         │    levels : 1          │
│  byte flips : n/a, n/a, n/a                         │   pending : 2          │
│ arithmetics : n/a, n/a, n/a                         │  pend fav : 0          │
│  known ints : n/a, n/a, n/a                         │ own finds : 0          │
│  dictionary : n/a, n/a, n/a                         │  imported : n/a        │
│       havoc : 0/0, 0/0                              │ stability : 90.49%     │
│        trim : n/a, n/a                              ├────────────────────────┘
Segmentation fault────────────────────────────────────┘          [cpu000: 51%]
amlamarra commented 4 years ago

So I implemented the extract_response_codes_dns() function and used the DNS return code. Now it's fuzzing! Though I really don't know the effectiveness of it. I'm using a version of dnsmasq that has a known vulnerability that someone else had found by fuzzing it with AFL and modifying it's code (https://blog.skullsecurity.org/2015/how-i-nearly-almost-saved-the-internet-starring-afl-fuzz-and-dnsmasq). I'll let this run for a while, but I think I'll need to read up on increasing performance. I'll submit a PR once I've confirmed it works.

thuanpv commented 4 years ago

Thanks! To fix the previously reported bug, please check out this revision https://github.com/aflnet/aflnet/commit/f63c29451a3954ff67592e0a41fe79ce3dfe2039.