Malicious server can bypass gpg verification and inject malicious images
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
simplestreams (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Trusty |
Fix Released
|
Undecided
|
Unassigned | ||
Vivid |
Fix Released
|
Undecided
|
Unassigned | ||
Wily |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
If the image file returned by an HTTP simplestreams mirror is returned in the body of a 403 response instead of a standard 200 response, then simplestreams fails to verify the gpg signature yet still returns the image to the caller to be treated as verified. A malicious mirror operator can exploit this behaviour to inject arbitrary disk images to a client posing as signed simplestream images (such as Ubuntu cloud images). If the client isn't using HTTPS (reasonable since simplestreams is supposed to be end-to-end authenticated with gpg) then a man-in-the-middle attack can also achieve malicious image injection in the same way.
My example case does this to a uvtool user; bug 1485785 suggests to me that the same mechanism can used to compromise images registered in Glance in a production OpenStack deployment.
Steps to reproduce:
1. Start with a fresh Trusty install (I used LXC).
2. sudo apt-get update && sudo apt-get -y install uvtool simplestreams ubuntu-
3. Mirror an image from the upstream Ubuntu cloud image source: sudo sstream-mirror --keyring /usr/share/
4. Now copy the mirrored image found in /var/www/
5. Force the authentic image URL to 403: sudo chmod 0 /var/www/
6. Arrange for the 403 error document to contain the malicious image: sudo sed -i '/DocumentRoot/a\ ErrorDocument 403 /backdoored.img' /etc/apache2/
7. Restart Apache: sudo service apache2 restart
8. Work around gpg/simplestreams sudo file ownership issue (DO NOT DO THIS ON YOUR OWN MACHINE!): sudo rm -rf ~/.gnupg
9. Make sure you belong to the libvirtd group for uvtool libvirt access: newgrp libvirtd
10. Sync from local mirror: uvt-simplestrea
Expected behaviour: gpg authentication failure, file not mirrored
Actual behaviour: malicious image mirrored. Verify by examining the contents of /var/lib/
Credit is due to bug 1485456 and 1485785 which made me suspicious enough to do some further investigation.
Changed in simplestreams (Ubuntu Trusty): | |
status: | New → Confirmed |
Changed in simplestreams (Ubuntu Vivid): | |
status: | New → Confirmed |
Changed in simplestreams (Ubuntu Wily): | |
status: | New → Confirmed |
no longer affects: | simplestreams (Ubuntu Precise) |
information type: | Private Security → Public Security |
tags: | added: patch |
This is my current proposed fix. ntentSource' and pass it as the contentsource when calling 'insert_item'.
Basically what we do is create a 'ChecksummingCo
That contentsource will raise exception if expected size amount of bytes are read and size is available.
We log warning if no checksums are available in the source information.
If there is no 'size' available, currently that would require the consumer of this to invoke 'check'
Its non-trivial to automatically do that, as we can't just do it in 'close()' as close could be done for any reason and the caller would not generally expect a exeption to be raised.
comments?