busybox-w32
busybox-w32 copied to clipboard
Strange current-user setting (related to ssh?)
When running busybox
from CMD, the current user in Windows is also the current user for Busybox commands:
Microsoft Windows [Version 10.0.19042.1466]
(c) Microsoft Corporation. All rights reserved.
corwin@HODOR C:\Users\corwin>busybox whoami
corwin
corwin@HODOR C:\Users\corwin>busybox sh -l
~ $
When logging into my Windows box from another machine using Windows' built-in OpenSSH server, it is always listed as root:
corwin@my-mac ~ % ssh hodor.local
Microsoft Windows [Version 10.0.19042.1466]
(c) Microsoft Corporation. All rights reserved.
corwin@HODOR C:\Users\corwin>busybox whoami
root
corwin@HODOR C:\Users\corwin>busybox sh -l
~ #
No idea what could be causing it! This may have something to do with OpenSSH or it may not.
busybox-w32 has a very limited understanding of Windows users. When it reports the user is root it indicates you're running with elevated privileges ('as administrator').
Is that what's happening here?
Well I must admit I share busybox-w32's limited understanding on the matter 😬
When logging into Windows' OpenSSH server with a username and password I expect to have the same privileges as when I am logged in locally to the desktop, if not lower. So unless this is a setting of OpenSSH on Windows that I am not aware of, then no, it does not seem that I am running it 'as administrator'.
I've set up OpenSSH on Windows 10. It seems busybox-w32 is correct: when I use SSH to log in to a local account (which is an administrator) I do have elevated privileges. For example, I'm able to access directories (like ~/Recent) which aren't available to a normal user.
I don't know how this comes to be: I didn't knowingly configure it to work this way. There have been discussions about it (here and here) but they don't increase my understanding much.
It does not appear to matter how you configure openssh here. Comparing the two methods to add keys as per the windows docs, I am not required to elevate privileges either way.
- Configure busybox64.exe to be the default shell for openssh:
if (-not(Test-Path -Path 'C:\Windows\sh.exe' -PathType Leaf))
{
Invoke-WebRequest -UseBasicParsing https://.../busybox64.exe -OutFile C:/Windows/sh.exe
}
New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name DefaultShell -Value 'C:\Windows\sh.exe' -PropertyType String -Force
Restart-Service -Name sshd
- Add your user account to be authorized
& C:/Windows/sh.exe -c "mkdir -pv C:/Users/Administrator/.ssh; curl https://github.com/corwin-of-amber.keys >>/Users/corwin/.ssh/authorized_keys"
- Login with ssh. Observe you have admin privileges. This is unexpected.
- Authorize administrative ssh access according to windows docs:
mkdir -pv C:/ProgramData/ssh
curl https://github.com/corwin-of-amber.keys >>/ProgramData/ssh/administrators_authorized_keys
icacls "C:/ProgramData/ssh/administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
- Observe you still have admin privileges.
It's my understanding that there's actually no mechanism in Windows for doing UAC privilege elevation without a desktop to interact with, i.e, nothing like su or sudo.
So the pragmatic approach is to elevate that up front for users that potentially can have admin rights, rather than set them logged in with no means to use them. I don't think it's unique to busybox or even SSH.
Here's another (closed) OpenSSH issue on the matter. (EDIT: and here's another one closed with "Resolution - By Design".)
Microsoft's point of view appears to be:
- It isn't possible for a process running in an SSH session to obtain elevated privileges.
- If a user who is an Administrator logs in over an SSH session they might want to perform administrative tasks, so they're automatically granted elevated privileges.
- If you don't want elevated privileges just log in as a user who isn't an Administrator.
- Problem solved. Have a nice day.
Possible solutions might be:
- A way for a user to obtain elevated privileges over an SSH session. Like
su
orsudo
on Unix. - A way for a process to relinquish elevated privileges.
An idea may be to support this (need to test if it allows to login also as limited users):
busybox su -c 'command_to_execute' -- user_to_login -- parameters
Maybe also supporting the -S parameter to read password from STDIN. It is a parameter of sudo but it may be helpful here.
Write the prompt to the standard error and read the password from the standard input instead of using the terminal device.
Info: https://stackoverflow.com/a/14913037 API: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw
The most recent prerelease binaries include the new runuser
applet. This is based on the application of the same name from util-linux, though it has somewhat reduced functionality.
Basically it allows a shell user to drop elevated privileges either temporarily or for the remaining life of the shell. So you can do stuff like this:
~ $ ssh localhost
rmy@localhost's password:
~ # id
uid=0(root) gid=0(root) groups=0(root)
~ # : Interactive shell with reduced privilege
~ # runuser rmy
~ $ id
uid=4095(rmy) gid=4095(rmy) groups=4095(rmy)
~ $ exit
~ # : Run a command
~ # runuser rmy -c id
uid=4095(rmy) gid=4095(rmy) groups=4095(rmy)
~ # : Drop privilege with no hope of return
~ # exec runuser rmy
~ $ id
uid=4095(rmy) gid=4095(rmy) groups=4095(rmy)
~ $ exit
Connection to localhost closed.
~ $
You have to tell runuser
the name of the user you're really running as. This is required for consistency with util-linux runuser
. It isn't possible to switch to an arbitrary user this way.
Being compatible with util-linux runuser
comes with some limitations. The latest prerelease binaries introduce drop
as an alternative to runuser
.
-
drop
works even if the current process doesn't have elevated privileges. - It isn't necessary to specify the username.
- It can run any command, not just a BusyBox shell.
- The command can be a BusyBox applet, an executable on
PATH
or an executable specified by pathname. - The command can't be a shell script: Windows doesn't know how to run those. Use
drop sh script
instead.
If the busybox-w32 binary is named drop.exe
you can configure sshd like so:
... -Name DefaultShell -Value "C:\Windows\System32\drop.exe" ...
... -Name DefaultShellArguments -Value "sh -l" ...
and all users will be able to login without getting elevated privileges:
~ $ ps | tail -7
7616 3436 root 0:00 3h39 sshd.exe
4844 7616 root 0:00 0:11 sshd.exe
8216 4844 root 0:00 0:11 conhost.exe
8700 8216 root 0:00 0:10 drop.exe
4520 8700 rmy 0:00 0:10 sh -l
936 4520 rmy 0:00 0:00 ps
6476 4520 rmy 0:00 0:00 tail -7
~ $
If you must you can even have:
... -Name DefaultShell -Value "C:\Windows\System32\drop.exe" ...
... -Name DefaultShellArguments -Value "powershell" ...
The DefaultShellArguments
registry key is only supported since version 8.6 of OpenSSH. If you have an older version the setting will be ignored and you'll always get a BusyBox shell. Check the version on the server with sshd -?
.
More churn:
-
runuser
has been removed. It may be the closest existing utility to the required functionality but it isn't a very good fit. - When
drop
is used as the SSH default shell it now properly supports running remote commands (as well as interactively). - The new
cdrop
andpdrop
applets are similar todrop
but default to usingcmd.exe
and PowerShell rather than the BusyBox shell. This makes it possible to configure SSH to use either of these shells without elevated privileges, even in old versions of OpenSSH that don't supportDefaultShellArguments
.
Things to note when configuring OpenSSH:
- The
DefaultShellArguments
aren't used when the server runs a command. - To run a command with
cmd.exe
it's necessary to setDefaultShellCommandOption
to/c
.
Hi, I'm not sure about Windows 7/10 but on older Windows the OS may get installed on D:\ and even the Windows folder name can be changed. Instead of hardcoding them I think it is better to get the paths in this way:
CMD path:
echo "${COMSPEC}"
PowerShell path:
echo "${WINDIR}\System32\WindowsPowerShell\v1.0\powershell.exe"
I think we now understand what's going on. It's clearly a Microsoft issue but the latest busybox-w32 release has a mitigation for the problem in the drop
applet.