Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a bug in NULL pointer bug when reading UDP channels #207

Merged
merged 1 commit into from
Jan 29, 2021

Conversation

zeroSteiner
Copy link
Contributor

This fixes a segmentation fault where if in udp_client_read, network_client_read_msg returns NULL it was not being checked before being passed to memcpy. This lead to the Meterpreter session crashing.
After fixing this issue, I noticed that channel_set_interactive was incorrectly using an unsigned value for buf_len causing it to not properly handle error statuses of -1. I updated that so it will only forward data to send_write_request when the value is a positive integer.

You can reproduce this using the enum_dns module.

Testing Steps

Example Output

msf6 payload(linux/x64/meterpreter/reverse_tcp) > use auxiliary/gather/enum_dns 
msf6 auxiliary(gather/enum_dns) > show options 

Module options (auxiliary/gather/enum_dns):

   Name         Current Setting                                                                Required  Description
   ----         ---------------                                                                --------  -----------
   DOMAIN                                                                                      yes       The target domain
   ENUM_A       true                                                                           yes       Enumerate DNS A record
   ENUM_AXFR    true                                                                           yes       Initiate a zone transfer against each NS record
   ENUM_BRT     false                                                                          yes       Brute force subdomains and hostnames via the supplied wordlist
   ENUM_CNAME   true                                                                           yes       Enumerate DNS CNAME record
   ENUM_MX      true                                                                           yes       Enumerate DNS MX record
   ENUM_NS      true                                                                           yes       Enumerate DNS NS record
   ENUM_RVL     false                                                                          yes       Reverse lookup a range of IP addresses
   ENUM_SOA     true                                                                           yes       Enumerate DNS SOA record
   ENUM_SRV     true                                                                           yes       Enumerate the most common SRV records
   ENUM_TLD     false                                                                          yes       Perform a TLD expansion by replacing the TLD with the IANA TLD list
   ENUM_TXT     true                                                                           yes       Enumerate DNS TXT record
   IPRANGE                                                                                     no        The target address range or CIDR identifier
   NS                                                                                          no        Specify the nameservers to use for queries, space separated
   Proxies                                                                                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RPORT        53                                                                             yes       The target port (TCP)
   SEARCHLIST                                                                                  no        DNS domain search list, comma separated
   STOP_WLDCRD  false                                                                          yes       Stops bruteforce enumeration if wildcard resolution is detected
   THREADS      1                                                                              no        Threads for ENUM_BRT
   WORDLIST     /home/smcintyre/Repositories/metasploit-framework/data/wordlists/namelist.txt  no        Wordlist of subdomains

msf6 auxiliary(gather/enum_dns) > set DOMAIN digi.ninja
DOMAIN => digi.ninja
msf6 auxiliary(gather/enum_dns) > run

[!] dns wildcard is enable OR fake dns server
[*] Querying DNS NS records for digi.ninja
[+] digi.ninja NS: dns2.zoneedit.com
[+] digi.ninja NS: dns1.zoneedit.com
[*] Attempting DNS AXFR for digi.ninja from 45.79.110.158
[*] Query digi.ninja DNS AXFR - no results were received
[*] Attempting DNS AXFR for digi.ninja from 45.77.82.193
[*] Query digi.ninja DNS AXFR - no results were received
[*] 192.168.159.128 - Meterpreter session 1 closed.  Reason: Died
^C[-] Stopping running against current target...
[*] Control-C again to force quit all targets.
[*] Auxiliary module execution completed

Up to this point used the unpatched version. Between these two lines, I compiled my changes from this PR and re-ran the mettle binary.

msf6 auxiliary(gather/enum_dns) > 
[*] Sending stage (3008420 bytes) to 192.168.159.128
[*] Meterpreter session 2 opened (192.168.159.128:4444 -> 192.168.159.128:54306) at 2021-01-28 16:03:17 -0500

msf6 auxiliary(gather/enum_dns) > 
msf6 auxiliary(gather/enum_dns) > route add 0.0.0.0 -1
[*] Route added
msf6 auxiliary(gather/enum_dns) > run

[!] dns wildcard is enable OR fake dns server
[*] Querying DNS NS records for digi.ninja
[+] digi.ninja NS: dns1.zoneedit.com
[+] digi.ninja NS: dns2.zoneedit.com
[*] Attempting DNS AXFR for digi.ninja from 45.77.82.193
[*] Query digi.ninja DNS AXFR - no results were received
[*] Attempting DNS AXFR for digi.ninja from 45.79.110.158
[*] Query digi.ninja DNS AXFR - no results were received
[*] Querying DNS CNAME records for digi.ninja
[*] Querying DNS NS records for digi.ninja
[+] digi.ninja NS: dns2.zoneedit.com
[+] digi.ninja NS: dns1.zoneedit.com
[*] Querying DNS MX records for digi.ninja
[+] digi.ninja MX: alt2.aspmx.l.google.com
[+] digi.ninja MX: alt1.aspmx.l.google.com
[+] digi.ninja MX: alt4.aspmx.l.google.com
[+] digi.ninja MX: alt3.aspmx.l.google.com
[+] digi.ninja MX: aspmx.l.google.com
[*] Querying DNS SOA records for digi.ninja
[+] digi.ninja SOA: dns0.zoneedit.com
[*] Querying DNS TXT records for digi.ninja
[+] digi.ninja TXT: v=spf1 include:_spf.google.com ~all
[+] digi.ninja TXT: keybase-site-verification=RlBQzB0npOVxkoAwBYJJuWxT8xMVqLPQ1NuBwA30Dq4
[*] Querying DNS SRV records for digi.ninja
[*] Auxiliary module execution completed
msf6 auxiliary(gather/enum_dns) > 

The udp_client_read function was not checking for a NULL pointer being
returned by network_client_read_msg, causing a segmentation fault. After
returning -1 from this function on error, it was also necessary to
update channel_set_interactive to use the proper ssize_t type for the
buf_len variable.
Comment on lines 351 to +355
void *msg_buf = network_client_read_msg(ucc->nc, &msg_len);
if (msg_buf == NULL) {
errno = EIO;
return -1;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the core bug right here. Then we return -1 and check it appropriately in channel_set_interactive.

@timwr timwr self-assigned this Jan 29, 2021
@timwr timwr merged commit cf86472 into rapid7:master Jan 29, 2021
@timwr
Copy link
Contributor

timwr commented Jan 29, 2021

Confirmed fixed. Thanks!

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants