Commit cafb7472 authored by Jay Kamat's avatar Jay Kamat

Add web page for information about Next vulnerability

parent 571f174f
......@@ -65,6 +65,7 @@
:sitemap-sort-folders first
:exclude "blog/rss.org"
:sitemap-sort-files anti-chronologically
:exclude-tags ("onlyrss" "noexport")
:publishing-function org-html-publish-to-html)
("jgkamat.gitlab.io-blogmap"
:base-directory ,(concat project-base "./blog")
......@@ -97,6 +98,7 @@
:exclude ".*"
:include ("./rss.org")
:rss-extension "xml"
:exclude-tags ("norss" "noexport")
:publishing-function (org-rss-publish-to-rss)))))
(setq org-export-date-timestamp-format "%Y-%m-%d"
......
#+TITLE: Next Browser RCE
#+AUTHOR: Jay Kamat
#+DATE: <2019-05-19 Sun>
#+OPTIONS: auto-id:t tags:nil
* Overview
:PROPERTIES:
:CUSTOM_ID: h:2b4a6585-9d29-41ac-8231-6432eecb69aa
:END:
Next Browser's XML-RPC was (from about ~1.0~ to ~1.2.1~) vulnerable to remote
exploitation. If you use Next, please upgrade to ~1.2.2~ immediately.
Both the lisp core and the platform ports listen on all interfaces with no
authentication. This means that anyone on your network or any site you visit can
send commands over the XML-RPC. Some interesting commands in the platform port
include ~buffer.evaluate.javascript~ and ~set.proxy~. Some interesting commands
in the lisp core include ~make.buffers~ and ~push.input.event~.
* Demos
:PROPERTIES:
:CUSTOM_ID: h:20651f2f-a42f-4e44-bb2a-3c56f95d2674
:END:
** Open A Window
:PROPERTIES:
:CUSTOM_ID: h:df8e5447-a0fd-4cf1-85fc-c96467ebcf07
:END:
The most basic exploit, this sends a single request to open a new window.
[[file:../img/next-rce-1.gif][file:../img/next-rce-1.gif]]
** Basic Keypresses
:PROPERTIES:
:CUSTOM_ID: h:d2dd8937-193f-41ac-a2e9-7b615261beb0
:END:
A basic example to demo pressing keys. This one will open the first url selected
by the search 'f'.
[[file:../img/next-rce-2.gif][file:../img/next-rce-2.gif]]
** Full RCE
:PROPERTIES:
:CUSTOM_ID: h:af763cf4-c2f3-461b-89d8-86ea03db8932
:END:
Uses ~COMMAND-EVALUATE~ to execute arbitrary code on the system. This also seems
to cause next to hang, but the payload is already executing by the time it's
hanging.
[[file:../img/next-rce-3.gif][file:../img/next-rce-3.gif]]
* Takeaways
:PROPERTIES:
:CUSTOM_ID: h:ee246a46-a43c-428e-83d0-e4d511327f17
:END:
If you open a port, even if it's only accessible from your own machine, treat it
as if it's open to the world. See [[http://web.archive.org/web/20181130174629/https://bouk.co/blog/hacking-developers/][this blog post]] for more information.
If you find these kind of things worrying, install a uMatrix-style plugin.
Such a plugin in a strict mode will mitigate some of these attacks.
* Methodology
:PROPERTIES:
:CUSTOM_ID: h:404ae134-3d55-46df-bcfa-e504d93575e7
:END:
This is the first proper security issue that I have worked on in the wild, so I
decided to document my methodology. We were initially tipped off from [[https://web.archive.org/web/20190508210200/https://next.atlas.engineer/article/technical-design.org][a quote
on this page]]:
#+begin_quote
XML-RPC can be used over HTTP sockets, and this is what we do. This comes with a
nice side effect: we don't even need to run the separate parts on the same
machine, they can be connected remotely over the Internet!
...
The security-sensitive part, i.e. the renderer, is contained into a relatively
simple executable. It's possible to start this executable within a container, so
that security issues with the renderer (or, who knows, with the GUI toolkit)
won't ever reach beyond the boundaries of the RPC calls.
#+end_quote
My personal effort was then focused towards the next core XML-RPC server, as
that seemed the most likely to be vulnerable. After a bunch of tweaking, I
eventually was able to fire the ~make.buffers~ rpc call over a local client,
and then over a local js browser, and lastly a remote website, validating the
approach.
Finding how to turn this access into RCE was a bit tricky. The commands offered
by the core didn't seem very useful at first, mainly due to not fully
understanding them. I then pivoted to trying to exploit the platform port, but I
quickly found that:
1. It was unstable, closing whenever any invalid arguments were passed to it.
2. It offered much more in terms of api functionality, but it wouldn't be a
good target if we're aiming for RCE due to sandboxing. It might be possible
to get XSS or some man in the middle attack, but that wasn't my goal.
3. Snooping on calls from core to the platform port is harder, as in order to do
that, you need to kill the platform port (at which point, you wouldn't have
any window to control).
I then decided to forcibly kill the core (which seemed to leave the platform
port running as if nothing had happened). I then put an echo server on the same
port and was able to immediately see all requests being made by the port. After
finding out that the port sent keystrokes to the core, and that there was a
default command called ~COMMAND-EVALUATE~, the rest was trivial.
In retrospect, I would have liked to have handled disclosure a bit better. It's
probably a good idea to give core developers a heads up as soon as you even
think there's an issue, to maximize the time they have to fix it. I spent a lot
of time sitting on this issue, leaving people vulnerable for longer than they
should have been.
** Further Work and Mitigation
:PROPERTIES:
:CUSTOM_ID: h:47b6f0fd-a5a9-4175-9e86-84442d2f29c6
:END:
- Next still listens over the network on all interfaces. Ideally there would
be nothing listening on a port at all, and if something must be exposed, it
could be exposed only on localhost. However, it looks like the host is
hard-coded in ~s-xml-rpc~:
#+begin_src lisp
(sb-bsd-sockets:socket-bind socket #(0 0 0 0) port)
#+end_src
The next developers are planning on switching to other formats for
communication, which will fix this and other issues in this list.
- Authentication tokens are passed from the core to the platform port in a
less-than-ideal way. This isn't much of an issue, but is an area for
improvement.
- Authentication tokens are passed during calls as the first argument, which is
prone to errors or missed validation.
- It's too easy to start slime, which exposes a port without authentication in
much the same way as Next used to. It [[http://web.archive.org/web/20190517202908/https://github.com/slime/slime/issues/286#issuecomment-491246670][dosen't look like this will be fixed
on slime's end]].
* Credits
:PROPERTIES:
:CUSTOM_ID: h:c118d540-d79c-4798-8c38-61576907356d
:END:
Thanks to:
- Florian Bruhin (The-Compiler) for initially suspecting the vulerability, and
providing advice.
- Vasilij Schneidermann (wasamasa) for initial work on discovering the
vulnerability, making the initial report, and providing advice on a fix, and
reviews.
- Pierre Neidhardt (Ambrevar) and John Mercouris (jmercouris) for finalizing,
reviewing, and committing fixes.
* Navigation
:PROPERTIES:
:CUSTOM_ID: h:a5d62f40-d44b-46a9-8ad5-aee792bd0ffe
:END:
#+BEGIN_SRC emacs-lisp :exports results :results raw
(gen-prev-next)
#+END_SRC
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment