Subject: [uclibc-ng] Unpatched DNS bug affects millions of routers and
IoT devices
Good day from Singapore,
I have just come across this article. I saw uclibc-ng being mentioned,
so I thought of sharing this article.
Article: Unpatched DNS bug affects millions of routers and IoT devices
Link: https://www.bleepingcomputer.com/news/security/unpatched-dns-bug-affects-mi…
[QUOTE]
The library uClibc and its fork from the OpenWRT team, uClibc-ng. Both
variants are widely used by major vendors like Netgear, Axis, and
Linksys, as well as Linux distributions suitable for embedded
applications.
[/QUOTE]
Does it affect my TP-link AC1200 wireless router?
Regards,
Mr. Turritopsis Dohrnii Teo En Ming
Targeted Individual in Singapore
5 May 2022 Thursday
Hi All,
This is the updated and consolidated patch with the following additional
features
a) Add options to the Config.in to allow the platform developer to select
between the different supported query id generation logics using make
config/menuconfig/...
Inturn now one can select between the following modes SimpleCounter /
Urandom Only / Clock Only / PrngPlus (with automatic URandom & or Clock
based reseeding) . So based on the features available on a given target,
and or needs of a specific platform or release, uclibc's dns query id
generation can be suitably selected/adjusted.
b) The PrngPlus mode maintains its own state wrt prng, so that users of the
global random prng won't be affected by dns lookups' use of random.
c) Have hopefully tried to follow the coding style better this time.
However as I have done lot of changes to the code flow from earlier patchs,
I need to cross check once again the same.
Please do cross-check the patch once for any possible oversights and or
issues. Do note that I have tried this only on a linux vm+container setup,
by hand holding the native host build tools and inturn using the prints and
tcpdump to verify things are working as required.
If no other issues are found, I will remove some of the debug prints I have
still retained (and or convert to DPRINTF) and make a release tomorrow.
--
Keep ;-)
HanishKVC
Hi,
Have updated the logic further such that
a platform developer can force dnsrand_next to help achieve the
current/previous simple counter logic, if needed.
However if random dns query id is desired, then if urandom reading fails
(previously it would have fallen back to the simple counter) but in turn if
real time clock is available then clock_gettime is used to help reseed
through srandom. However if neither (ie urandom and clock) is available,
then now it still continues with the random prng, bcas anyway it is better
than the simple counter at some level.
Attached is the format-patch output between glibc master
(592574ae535c35de500f6c3e8d8400d0bb0d985a) till the latest flow from my
side.
--
Keep ;-)
HanishKVC
----- Forwarded message from Nozomi Networks Labs Advisory <labs-advisory(a)nozominetworks.com> -----
Date: Mon, 2 May 2022 17:01:29 +0200
From: Nozomi Networks Labs Advisory <labs-advisory(a)nozominetworks.com>
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.0
To: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Subject: Fwd: [ICS-VU-638779, CERT/CC VU#473698] Predictable DNS Transaction IDs in uClibc, uClibc-ng
Hello Waldemar,
although we would have preferred an explicit confirmation from you, given the
lack of alternatives and having received the approval from CERT/CC, we
proceeded with the disclosure of the vulnerability to the mailing list.
I kindly ask you to publish our email (the same that I am forwarding to you
now) to
https://mailman.openadk.org/mailman3/hyperkitty/list/devel@uclibc-ng.org/ .
Best regards,
Andrea Palanca
-------- Forwarded Message --------
Subject: [ICS-VU-638779, CERT/CC VU#473698] Predictable DNS Transaction IDs in
uClibc, uClibc-ng
Date: Mon, 2 May 2022 16:53:48 +0200
From: Nozomi Networks Labs Advisory <labs-advisory(a)nozominetworks.com>
To: devel(a)uclibc-ng.org
Hello,
as per our last interaction with Mr. Brodkorb (https://mailman.openadk.org/mailman3/hyperkitty/list/devel@uclibc-ng.org/th…),
in accordance with CERT/CC as per VINCE case VU#473698 (ICS-VU-638779), with
this email we proceed with the public disclosure of the vulnerability.
-----------------------------------
Vendor: uClibc, uClibc-ng
Vendor URL: https://www.uclibc.org/, https://www.uclibc-ng.org/
Affected firmware: uClibc: All versions, uClibc-ng: All versions
Vulnerability: Predictable DNS Transaction IDs
Authors: Giannis Tsaraias (Cyber Threat Analyst @ Nozomi Networks), Andrea
Palanca (Security Researcher @ Nozomi Networks)
-----------------------------------
Vulnerability:
The uClibc and uClibc-ng libraries generate DNS requests with incremental
transaction IDs, while, at the same time, not enforcing any explicit port
randomization techniques during the network connection.
This may result in the possibility for an attacker to perform DNS Cache
Poisoning attacks. More information in the "Exploitability" section here
below.
The vulnerability was confirmed statically and dynamically on version
0.9.33.2. By downloading all releases available on uClibc website, the
vulnerability was confirmed statically in all versions (up to and including
0.9.33.2).
Additionally, by downloading all releases of the uClibc-ng available, the
vulnerability was confirmed statically for this library in all versions (up to
and including 1.0.38, latest available at the time of the research).
-----------------------------------
Details:
The following analysis contains source code extracted from uClibc version
0.9.33.2.
The uClibc library implements DNS requests by calling the internal
“__dns_lookup” function, located in the source file “/libc/inet/resolv.c”.
At line #1240, the function declares a static variable “last_id”. This
variable contains the value of the transaction ID used in the last DNS
request, and is initialized with the value “1” at the first invocation of
“__dns_lookup”.
Additionally, at line #1260, the function declares a variable “local_id”. This
variable contains the value of the transaction ID that will be used in the
upcoming DNS request, and is left uninitialized.
At line #1309, at the first DNS request, the “local_id” variable is
initialized with the value of the transaction ID of the last DNS request
(“last_id”).
Line #1320 is the actual core of the vulnerability: “local_id” is updated by
incrementing by “1” its old value.
After doing a bitwise AND at line #1321, this value is also stored inside
“last_id” variable at line #1323.
Finally, at line #1335, the value of “local_id” is copied inside the struct
resolv_header “h” variable, which represents the actual content of the header
of the DNS request.
No other updates are done to the value of “local_id” or “last_id” in the
remaining part of the function.
Additionally, no UDP source port randomization is done (e.g., by explicitly
invoking a “bind” with a random UDP source port) prior to performing the
transmission of the DNS request.
-----------------------------------
Exploitability:
In order to exploit the vulnerability, given that the transaction ID is
predictable, an attacker would need to craft a DNS response that contains the
correct source port, as well as win the race against the legitimate DNS
response incoming from the DNS server. Exploitability of the issue depends
exactly on these factors.
As the function does not apply any explicit source port randomization, if the
operating system is configured to use a fixed or predictable source port, it
is likely that the issue can be trivially exploited in a reliable way.
If the operating system applies randomization of source port (which is done by
all OSs nowadays - for instance, modern Linux kernels use range 32768–60999),
exploitability depends on the capacity of the attacker to bruteforce the 16
bit source port value by sending multiple DNS responses, while simultaneously
winning the race against the legitimate DNS response. In this situation,
exploitability depends on factors such as the bandwidth at disposal of the
attacker, or on the response time of the DNS query. Additionally, it is more
likely that an attacker is able to succeed at least once in performing a DNS
poisoning attack if the target device performs a great number of identical
queries in a given time frame, compared to a target that performs just
sporadic queries.
-----------------------------------
Remediation:
It is recommended to harden the implementation of the “__dns_lookup” function
by including unpredictable, random transaction IDs at each DNS request.
pub rsa4096 2021-01-21 [SC] [expires: 2025-01-20]
8B8C7C296AEC8BD654FF69A6797E06A000A77236
uid Nozomi Networks Labs Advisory <labs-advisory(a)nozominetworks.com>
sub rsa4096 2021-01-21 [E] [expires: 2025-01-20]
pub rsa4096 2021-01-21 [SC] [expires: 2025-01-20]
8B8C7C296AEC8BD654FF69A6797E06A000A77236
uid Nozomi Networks Labs Advisory <labs-advisory(a)nozominetworks.com>
sub rsa4096 2021-01-21 [E] [expires: 2025-01-20]
----- End forwarded message -----
Hi,
THis patch fixes the oversight wrt local_id post increment, instead of the
needed pre increment, in my previous patches.
Attached is the full patch against uclibc-ng master, as well as
the delta patch against my previous patches (applies equally to both
urandomid as well as randomid patches).
The above is also available on github at
https://github.com/hanishkvc/uclibc-ng-hkvc (master_hkvc_release branch). I
understand and use git and github at the bare minimum required, so forgive
my ignorance wrt git push/pull... request etal mechanisms that may be
available for a better mode of sharing.
--
Keep ;-)
HanishKVC
Hi,
As noted in the last message, this patch uses the combination of
/dev/urandom + user space random.
Here /dev/urandom periodically (once every 128 random calls) seeds user
space using srandom. Inturn user space random prng is used to generate the
dns query id.
Attached is
a) the full patch wrt uclibc master
(592574ae535c35de500f6c3e8d8400d0bb0d985a), as well as
b) the delta patch wrt my last patch
(patch_20220505IST0032_urandomid_against_dnspoison.patch)
Based on thoughts from others also either the simple urandom only or this
urandom+random based solution could be used against the dns poison issue.
Or may be others might have some other strategy in mind.
Please do note that this is currently only tested on a x86 linux virtual
machine+container environment, by using uclibc-ng and standard linux gcc
build setup (coerced to use uclibc-ng by disabling standard includes and
passing header paths and libs manually to gcc and inturn verifying the
random id using tcpdump and dprints). So testing against other setups would
be useful. At a high level chances are on linux or freebsd or similar
targets, hopefully the patch should be fine, as it uses only /dev/urandom,
srandom and random mainly.
--
Keep ;-)
HanishKVC
Hi,
Attached is an updated patch, where I have updated/modified dnsrand_next to
int from uint16_t, so that it is the same as local_id (even though local_id
does discard the upper 16/...bits), just in case there is some issue in
some combination of buildtools/endieness/...
In future / Other possibilities:
In case reading /dev/urandom is considered to be too much overhead or
leading to eating up of entropy in the system from other users perspective
or so, one could change to a two level logic, where /dev/urandom is read
once every 128 or 256 dns queries to (re)set the seed for the random prng
call. And in turn use the random c call for getting the dns query id. As
the random prng is reseeded every 128 or 256 calls, so I am lazily assuming
that its state cant be leaked from such a short run, to allow anyone to
predict the id, before reseeding.
--
Keep ;-)
HanishKVC