[HN Gopher] Antigravity.py (2020)
___________________________________________________________________
Antigravity.py (2020)
Author : chha
Score : 107 points
Date : 2021-08-16 13:00 UTC (10 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| Waterluvian wrote:
| Might not be obvious to all:
|
| This is in the python standard library. So you can open a python
| REPL and type `import antigravity`
| Xavdidtheshadow wrote:
| I've long known that `import antigravity` would open the xkcd
| comic, but I never knew there was also a geohashing function!
|
| That was a favorite activity of mine in high school. On Friday
| evening, we'd look at the nearest graticule(s) to our town and
| pick one for a Saturday day trip. Trucking out to a random point
| on a map is a great way to explore your metro area and see things
| you never would otherwise.
|
| Heartily recommend trying it out. Looks like the map (linked from
| the comic) is no longer working:
| http://carabiner.peeron.com/xkcd/map/map.html
|
| But, with this function, there may yet be hope!
| isp wrote:
| This looked innocuous at first glance, but this "antigravity"
| Easter egg has been found to have security implications.
|
| See "Hacking with Environment Variables", which specifically
| exploits the antigravity module for arbitrary code execution -
| https://www.elttam.com/blog/env/#content
|
| Previous HN comments:
| https://news.ycombinator.com/item?id=23828045
| thebeardisred wrote:
| Related to the idea "innocuous at first glance", that time when
| folks got cute with the man command:
|
| https://git.savannah.nongnu.org/cgit/man-db.git/commit/src/m...
|
| Turns out it was breaking a users automated tests -
| https://unix.stackexchange.com/questions/405783/why-does-man...
| chias wrote:
| I'm unconvinced. "The ability to turn this into arbitrary code
| execution depends on what other executables are available on
| the system" is doing a LOT of heavy lifting here.
|
| Remember: you have control over only the environment variables,
| and you do not have the ability to alter the arguments. In
| order for this to represent arbitrary code execution, you need
| for the system to have an executable on it that, when executed
| with the argument "https://xkcd.com/353/", grants you arbitrary
| code execution.
|
| So, you have full control over the environment variables, and
| that's it. How do you turn effectively
| [binary] "https://xkcd.com/353/"
|
| into arbitrary code execution, where [binary] is an executable
| already on the machine?
| marcinzm wrote:
| The next section of the link literally goes into how to
| achieve all of that using a call to perl.
| isp wrote:
| There is a proof of concept given, "Figure-4: arbitrary code
| execution achieved using multiple environment variables
| against Python 2 and Python 3": $ docker
| run -e 'PYTHONWARNINGS=all:0:antigravity.x:0:0' -e
| 'BROWSER=perlthanks' -e 'PERL5OPT=-Mbase;print(`id`);exit;'
| python:2.7.18 python /dev/null uid=0(root)
| gid=0(root) groups=0(root) Invalid -W option ignored:
| unknown warning category: 'antigravity.x' $
| docker run -e 'PYTHONWARNINGS=all:0:antigravity.x:0:0' -e
| 'BROWSER=perlthanks' -e 'PERL5OPT=-Mbase;print(`id`);exit;'
| python:3.8.2 python /dev/null uid=0(root) gid=0(root)
| groups=0(root) Invalid -W option ignored: unknown
| warning category: 'antigravity.x'
| ASalazarMX wrote:
| TL;DR: 'import antigravity' is fine, but Python can be
| tricked with environment variables to use Perl as the web
| browser, which has arbitrary code execution through
| environment variables.
| shaded-enmity wrote:
| Defense in depth would disagree that it is fine. I'm
| pretty sure this vulnerability can go much further if you
| combine it with, for example, the `https_proxy`
| environment variable.
| tyingq wrote:
| And Perl (specifically "perlthanks") was just the first
| thing they found that worked. Bash had similar problems
| in the past, and I imagine there's other "installed by
| default" stuff that can be coaxed into running code in
| environment variables.
| chias wrote:
| Interesting, that's pretty cool. Thanks!
| geofft wrote:
| If you can influence arbitrary environment variables, you
| _usually_ have a lot more options - you could set
| PYTHONHOME or PYTHONPATH (influence where Python finds
| imports), LD_LIBRARY_PATH (influence where shared libraries
| come from), PATH (influence where the Python command itself
| comes from), etc. etc.
|
| In this particular case, they happened to be in a situation
| where they couldn't easily figure out how to create new
| files but they could set environment variables. From a
| design perspective, as a reviewer, I would not believe that
| this makes it _safe_ to have attacker-controlled
| environment variables, although I admit I wouldn 't know
| exactly how (and this post is a pretty clever approach to
| making the attack work).
| btown wrote:
| And specifically, although it is nowadays uncommon for
| Python scripts to be run the way old-school WSGI web
| services were, with a script being fired up for every
| request and mapping user-controlled query parameters to
| environment variables, this was at one time actually the
| motivating example for
| https://www.python.org/dev/peps/pep-0333/ ! It's a common
| enough attack pattern that
| https://capec.mitre.org/data/definitions/77.html exists and
| specifically cautions applications against trusting
| environment variables. There are very few places in Python
| where upon importing a module, an environment variable is
| trusted and triggered; all of them should be seen as
| security holes.
| dpwm wrote:
| Surely this is only a security risk if antigravity is
| imported?
|
| What cause would there be to import antigravity in a CGI
| service - or anything other than a terminal in which you
| could already execute arbitrary code?
|
| I am struggling to understand, even with the proof of
| concept, how the situation could arise where an attacker
| could realistically exploit this, based largely on the
| uselessness of the antigravity module.
| geofft wrote:
| See the "Making Progress With PYTHONWARNINGS" section in
| the article posted - setting the environment variable
| PYTHONWARNINGS to a value mentioning the antigravity
| module causes it to be imported, even if there's no
| "import antigravity" statement in the actual source.
| dpwm wrote:
| Not sure how I missed that - it was even in the proof of
| concept in the message I replied to. Thanks for the help.
|
| There are multiple failings that don't seem like a big
| deal taken in isolation:
|
| - The PYTHONWARNINGS and whole Warning Filters system.
|
| - The webbrowser module executing a given executable from
| an environment variable.
|
| - The antigravity module running webbrowser.open() on
| import.
|
| All of these sort of seem a bit like sacrificing good
| taste for convenience. But in combination, in a situation
| where you don't control the environment variables, they
| do lead to arbitrary code execution.
|
| In other words, it's not all antigravity's fault, but
| those side effects on import make this possible.
| kzrdude wrote:
| You're right about sacrificing good taste for
| convenience, but since this is an easter egg, it's
| sacrificing good taste for a laugh, and I think that
| pushes it over the precipe over into being a bad idea.
| jvanderbot wrote:
| I left one window open, but what is to guarantee a
| burgler would use _that_ window??
| dpwm wrote:
| Absolutely, I agree now that I see it, and these seem
| like numerous innocent-seeming footguns just waiting for
| abuse.
|
| Add the not-too-far-fetched-seeming assumption that it's
| fine to let the Internet define your environment
| variables, and it's a plausible exploit.
|
| This is why, as another commenter points out, defense in
| depth is so important.
| [deleted]
| oyf wrote:
| If you have the ability to set environment variables then it's
| basically already game over, with or without the existence of
| the antigravity module.
|
| You could set PATH to change which files are executed in
| certain scenarios. You could set SSLKEYLOGFILE which logs
| session keys to an arbitrary file, essentially nullifying
| TLS/SSL protections. On Linux you can just set PROMPT_COMMAND
| to whatever you want and it'll be executed any time a bash
| prompt is printed.
|
| It's an interesting attack vector, but a vulnerability requires
| impact, and I'm not sure this has very much.
| [deleted]
| glofish wrote:
| reading the module, I have also learned about the Munroe
| geohashing:
|
| https://en.wikipedia.org/wiki/Geohashing
|
| and
|
| https://xkcd.com/426/
|
| official website:
|
| https://geohashing.site/geohashing/Main_Page
|
| oddly the geohash function in the antigravity module prints to
| the screen rather than returning the values ... seems odd to say
| the least
| szszrk wrote:
| I chuckled a bit, but it took me a while to realize what code
| repository it is from. Chuckled again.
| tersers wrote:
| TIL python has a webbrowser module
| mxuribe wrote:
| I just learned this myself the other day...
|
| I was looking at the "Automate the Boring Stuff with Python"
| book by Al Sweigart (which admittedly i have not read cover to
| cover, but rather use it as a reference) for some help with a
| little polite scraping, and lo and behold the webbrowser
| module...See chapter 12:
| https://automatetheboringstuff.com/2e/chapter12/
|
| I have not played much with it yet, but man, python continues
| to impress me!
| vascocosta wrote:
| Me too and I'm a long time Python programmer.
| hansor wrote:
| Me too... Hilarious!
| jp_sc wrote:
| But not a texteditor.
|
| You can use this library for that:
| https://pypi.org/project/texteditor/
|
| (Disclaimer: I'm the author)
| BiteCode_dev wrote:
| Idle
| ehsankia wrote:
| You missed the point of what the library does. Similar to
| webbrowser (which isn't a full browser), all it does is
| open your default text editor.
| diogenesjunior wrote:
| There's not really a reason for a built in text editor
| [deleted]
| jp_sc wrote:
| Is not a built in text editor, is a command to open
| programmatically your default text editor to edit a file
| (new or existing).
|
| There are several cases when you would want to do that, for
| example, think on the git CLI, that opens one so you can
| write a commit message, etc.
|
| And is not only about using the EDITOR variable, most non-
| programmers doesn't have one defined or it points to vim or
| something equally terrible for non technical users.
| boublepop wrote:
| Back in the day, python was popular because it was a "batteries
| included" language, which meant I supposedly had almost
| everything you would need right there in the standard language.
| These days of cause no one runs python without going on a
| shopping spree of additional packages on pypi, so it would be
| less of a big deal if it didn't include a browser lib, or a GUI
| lib out of the box.
| codetrotter wrote:
| And it's even using the user preferred browser!
|
| Tried it on my MacBook M1 and it opens Brave which is my main
| browser.
|
| Wonder if it's using the same mechanism as the macOS open(1)
| command does for opening URLs. Or maybe even calling the
| /usr/bin/open binary.
| zirak wrote:
| From the python source code: https://github.com/python/cpytho
| n/blob/11749e2dc20ad6a76e9a3...
|
| It seems to be shelling out to osascript, either telling it
| to OpenURL or open.
| chha wrote:
| Related: https://xkcd.com/353/
| TuringTest wrote:
| Well, it _does_ have "float" in the code, doesn't it?
| [deleted]
| codetrotter wrote:
| Well yes. From the OP link:
| webbrowser.open("https://xkcd.com/353/")
| diogenesjunior wrote:
| I get a type error in line 13 running the code:
| TypeError: openssl_md5() takes no keyword arguments
| shmageggy wrote:
| From the docs
|
| > Changed in version 3.9: All hashlib constructors take a
| keyword-only argument usedforsecurity...
| geofft wrote:
| To add to this - antigravity is part of the Python standard
| library, and you want to run the version that's shipped with
| your version of Python, not the version from the latest
| development build. Do "python3 -m antigravity".
| chronolitus wrote:
| A description of what the code does:
|
| First, the line
|
| webbrowser.open("https://xkcd.com/353/")
|
| is obvious, it opens a browser pointing to the relevant XKCD
| comic, containing a joke which inspired this code.
|
| Then, a geohash function is declared which takes the user's
| current latitude/longitude, and the current date-time, and
| returns a target latitude/longitude. According to a previous
| comic (https://xkcd.com/426/) this corresponds to the game of
| 'geohashing' where players are supposed to physically travel to
| arbitrary locations and prove it.
| nwsm wrote:
| For more context, "geohashing" is a play on geocaching [0].
|
| This is not to be confused with a geohash [1].
|
| [0] https://en.wikipedia.org/wiki/Geocaching
|
| [1] https://en.wikipedia.org/wiki/Geohash
___________________________________________________________________
(page generated 2021-08-16 23:01 UTC)