When LaunchServer
was added (#1958) it was decided that executing any file was acceptable as it was not possible to pass command line arguments. This poses several problems.
This service effectively undermines the security benefits enforced with pledge()
and unveil()
by allowing execution of arbitrary executable files in a new process (unsandboxed, with the privileges of the user). As such, care should be taken to ensure it is not abused.
Launching a file marked executable (+x) causes the file to be executed immediately, without warning, and silently (except for dbg()
output in the console logs). This can be used to perform a privilege escalation attack through social engineering, or simply in the event of a misclick. The file is executed regardless of the file extension.
Although adoption of LaunchServer
has been slow, it is currently used in a few places, such as the Terminal
, File Manager
and the WebContent
renderer in TextEditor
.
Clicking a file called workbook.sheets
in Terminal
will execute the file directly as an executable if it has execute +x permissions, rather than open the file in the program associated with the .sheets
extension (Spreadsheet
). Although the file is marked with a *
and green text, this behaviour may still be surprising. Additionally, given that zip archive files preserve their file permissions, it's not uncommon to unzip a compressed file and be presented with a directory full of files with 777
permissions.
This behaviour can be abused to perform a privilege escalation attack through social engineering (not-a-virus.txt
), or a misclick.
Additionally, should you happen to click inside the Terminal window, perhaps some time after doing ls /bin
, and happen to click on the reboot
executable, the system will reboot without warning, potentially causing loss of data. All your in-progress Piano compositions and Spreadsheet sheets will be lost.
Similarly, the /bin/TelnetServer
application does not require any command line arguments to start the server and binds on all interfaces 0.0.0.0
by default; however, the connection to LaunchServer
is performed as anon
, not root
, so attempts to bind to the default telnet port 23 will fail. Else this would provide a trivial privilege escalation vector by enabling the server given that the root
account does not have a password by default.
Similar to Terminal, however, File Manager
does not use clickable links with file://
URLs. As such, a double click is required, making this less of an issue.
Additionally, File Manager
shows the appropriate executable icon, rendering social engineering less likely, until such time as executable files are permitted to show their own icon (PE executables?). Unlikely.
Perhaps most interesting is the TextEditor
application, which automatically renders HTML (*.html
) and Markdown (*.md
) documents in a preview window rendered with WebContent
.
TextEditor
is the default application for opening markdown documents, althought it is reasonable to expect that users will also open HTML files for editing with TextEditor file.html
.
The WebContent
preview window is opened automatically for these file types. WebContent
is capable of launching files from file:///
hyperlinks upon click using the LaunchServer
.
This can be used to perform a privilege escalation attack in the event that a user clicks (or misclicks) a hyperlink in the preview window.
PoC (markdown):
[Hello friends!](file:///bin/reboot)
PoC (HTML):
<a href="file:///bin/reboot">Hello friends!</a>
Of course, as it is not possible to pass arguments to the executable, an attacker must have permission to create a file on the file system and set the file executable +x first. This is feasible in a local privilege escalation scenario and leads to arbitrary command execution. Additionally, as the root
user does not make use of a password by default, a sucessful attack against a user in the wheel
group (such as anon
) leads to arbitrary command execution as root by passing commands to su
.
The likelihood of a successful social engineering attack is increased by the ability to craft HTML content. For example, it is possible to embed a large object (such as an image) which is effectively invisible (ie, a large white image on the default white background). This causes the page to overflow the window size, requiring a scroll bar. As the image is used within an <a></a>
element, clicking anywhere on the image will result in command execution.
Personally, I'm in the habit of clicking in a window to give it focus before using the mouse wheel to scroll. This would result in code execution (without warning) and silently (except for the hand cursor over the hyperlink).
For example:
<html>
<body>
<a href="file:///home/test/lol"><img src="file:///res/graphics/buggie.png" height=1000></a>
</body>
</html>
#!/bin/sh
echo > /tmp/win
/bin/id >> /tmp/win
echo >> /tmp/win
echo /bin/id | su >> /tmp/win
Fortunately, execution via Launcher
requires a click event. I wasn't able to find a way to work around this requirement.
It seems that LibWeb/LibJS do not yet have sufficient support in the Event
class for click events. At least, I wasn't able to find a way to force a click event to gain command execution without the user having manually issued a click event. If/when more support for Events is added in the future, the potential for forcing a click event on a hyperlink within WebContent
is something to be wary of.
As an aside, this check exists in LibDesktop
:
serenity/Libraries/LibDesktop/Launcher.cpp
Lines 86 to 90 in a498025
I haven't looked into this code thoroughly, but given that LaunchServer can execute arbitrary applications, that code comment doesn't seem to have any relation to reality.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too