[HN Gopher] Remote Code Execution in OpenSSH's forwarded SSH-agent
       ___________________________________________________________________
        
       Remote Code Execution in OpenSSH's forwarded SSH-agent
        
       Author : vitplister
       Score  : 107 points
       Date   : 2023-07-19 17:36 UTC (5 hours ago)
        
 (HTM) web link (blog.qualys.com)
 (TXT) w3m dump (blog.qualys.com)
        
       | 1letterunixname wrote:
       | I use a USB security key for gpg-agent.
       | 
       | gpg-agent is used as an ssh-agent replacement (also replaces the
       | venerable monkeysphere script). gpg agent forwarding is also
       | needed via StreamLocalBindUnlink for signing built RPMs in a
       | docker container on a remote (local LAN) Docker host. Sometimes
       | rarely, I need to enable "ssh-agent" forwarding where I probably
       | could proxyjump instead. My interactive ssh workflow is sometimes
       | slowed as I use TOTP (via PAM) for 2FA. Noninteractive system
       | accounts get dedicated ssh keys. host keys are constantly scanned
       | and compared to a source of truth. Maybe I'll get around to
       | deploying LDAP with OpenSSH-LPK to move away from flat files.
       | 
       |  _Knee-jerk suggestion to rewrite the world in Rust combined with
       | formal verification._
       | 
       | But seriously, being an expert knife juggler is still gambling
       | with the obvious compared to using safer tools in a safer manner.
       | Rust needs the ubiquity of GCC[0] (partially by adding them to
       | LLVM and adding std crates) and more attention paid to bloat
       | (cargo-bloat, etc) before attempting to rewrite the world (apart
       | from special cases).
       | 
       | 0. https://gcc.gnu.org/backends.html
        
       | apienx wrote:
       | Agent forwarding is discouraged by the OpenSSH crew. Yet, it's
       | commonly used because of the convenience it affords.
       | 
       | "Agent forwarding should be enabled with caution. Users with the
       | ability to bypass file permissions on the remote host (for the
       | agent's UNIX-domain socket) can access the local agent through
       | the forwarded connection." https://man.openbsd.org/ssh.1
       | 
       | Glad the vulnerability got fixed.
        
       | shandor wrote:
       | I can't parse the exact meaning of the "victim system" and
       | "attacker controlled system" in the OpenSSH release page.
       | 
       | Does this vulnerability allow the attacker to compromise the
       | original system where the user starts the agent-forwarded
       | connection? Or "only" compromise machines forward from the jump
       | host?
       | 
       | http://www.openssh.com/releasenotes.html#9.3p2
        
         | perlgeek wrote:
         | If an attacker can compromise the jump host, they can
         | compromise the system where the user starts the agent-forwarded
         | connection.
        
           | shandor wrote:
           | Ouch, that's horrible.
           | 
           | Time to prompt everyone at $WORK to upgrade...
        
             | Arnavion wrote:
             | To be clear, agent-forwarding to a (potentially) malicious
             | ssh server has always been a bad idea. Yes TFA's bug makes
             | it a _worse_ idea and it 's absolutely worth it to patch
             | it, but you should not be agent-forwarding to (potentially)
             | malicious ssh servers in the first place.
        
           | gunapologist99 wrote:
           | That's 100% correct. This is why no one should use agent
           | forwarding with a jumpbox. Only -J. (see
           | https://userify.com/docs/jumpbox )
           | 
           | Another point is that no one should have any real access to
           | the jumpbox and it should be as minimal and stripped-down as
           | possible. It's literally your bastion host, so you've got to
           | keep it as strong as possible.
        
       | slt2021 wrote:
       | what is CVSS/severity of this? Critical? 9+?
        
         | tptacek wrote:
         | CVSS is meaningless, literally a Ouija board that reflects the
         | intuition of whoever's computing the score. A more reasonable
         | way to look at severity is on a two dimensional scale of lo-hi
         | severity and lo-hi situationality. This is a high-severity,
         | moderately situational bug (it would be highly situational if
         | it required user interaction, and not situational at all if it
         | didn't require control over the remote SSH server).
        
         | tedunangst wrote:
         | CVSS with rice: 10/10
        
           | slt2021 wrote:
           | do you have a source for this by any chance? or screenshot?
           | 
           | thank you
        
             | wiml wrote:
             | He's just making a reference to an old reddit joke, I don't
             | think it's a CVSS 10
        
         | NoZebra120vClip wrote:
         | CVSS are bunk. https://portswigger.net/daily-swig/cvss-system-
         | criticized-fo...
        
       | gunapologist99 wrote:
       | Note: you are not vulnerable if you're not doing agent forwarding
       | (-A).
       | 
       | Honestly, you probably should never do -A anyway; use -J
       | (proxyjump) instead.
       | 
       | https://www.man7.org/linux/man-pages/man1/ssh.1.html
       | 
       | https://userify.com/docs/jumpbox
        
         | pcthrowaway wrote:
         | There are situations where `-J` won't work.
         | 
         | For example, if I'm on a remote server and I want to clone or
         | pull from a private repository, or push to any repository
         | 
         | In fact, VS code expects you to forward an agent when
         | developing on a remote instance with the remote-ssh extension.
         | I believe it uses it for syncing repo changes primarily
         | 
         | I agree though that you should consider it insecure to forward
         | a connection to a shared host if it has other users who are
         | equally privileged, or more privileged
        
           | gunapologist99 wrote:
           | > There are situations where `-J` won't work.
           | 
           | That is true, but actually you should avoid -A in those
           | situations also.
           | 
           | > In fact, VS code expects you to forward an agent when
           | developing on a remote instance with the remote-ssh
           | extension. I believe it uses it for syncing repo changes
           | primarily
           | 
           | That's the case if you're ever trying to initiate an SSH
           | connection via Git _from_ a remote host. That 's because the
           | actual SSH connection isn't being triggered on your desktop
           | or laptop, where -J would do it, but because it's being
           | initiated right on the remote server itself.
           | 
           | Let's call the remote server VSCODE (your desktop-in-the-
           | cloud), your laptop/desktop LAPTOP, and the remote repo
           | GITHUB.
           | 
           | So, the correct answer there is actually counter-intuitive:
           | 
           | Generate a private key on VSCODE (not LAPTOP) for that GITHUB
           | repo. This key will be used only on that originating remote
           | server (VSCODE), never anywhere else.
           | 
           | In fact, that repo key will ideally be scoped as tightly as
           | possible in Github/Gitlab/etc.
           | 
           | As a general rule of thumb, generate at least one SSH key for
           | each "location" where you'll be logging into another
           | location. Keep your connections point-to-point unless you can
           | use proxyjump.
        
             | pcthrowaway wrote:
             | > Generate a private key on VSCODE (not LAPTOP) for that
             | GITHUB repo. This key will be used only on that originating
             | remote server (VSCODE), never anywhere else.
             | 
             | Deploy keys are more secure in most situations, but I'm not
             | convinced that generating a bunch of additional keys with
             | write access to your repo is _always_ more secure.
             | 
             | Regardless, it doesn't really fulfill the same need of "get
             | access to repo from cloud desktop asap". I work with 20-30
             | private repos at my company, and I don't have admin access
             | to most of them (so I couldn't create deploy keys for
             | them). That would need to be kicked up and down a request
             | pipeline, for each user accessing remotely, for each host
             | they're accessing it from. It's _much_ easier to Get The
             | Work Done if I just forward my agent.
             | 
             | And sure, the company could maybe set up better practices
             | (though again, I'm not even really clear on how much more
             | secure it would be to generate untold numbers of deploy
             | keys), but I'm more likely to get the axe for not producing
             | fast enough than they are to make sweeping changes to their
             | security practices.
        
               | gunapologist99 wrote:
               | Then just create a key on that box and use it for _all_
               | of your repos (add it to your github keychain); you 're
               | still much better off than with one key to rule them all
               | (and one RCE to rule your laptop ha)
        
               | pcthrowaway wrote:
               | That's a good point, probably the best way to do this,
               | but does require manual management steps for every VM you
               | want to use (which is perhaps a feature)
        
         | yjftsjthsd-h wrote:
         | > Honestly, you probably should never do -A anyway; use -J
         | (proxyjump) instead.
         | 
         | I want to copy files between servers, ex. `ssh -A serverA` then
         | `rsync ./foo serverB:`. Is there a way to do that without `ssh
         | -A`? (And obviously without creating an actual private SSH key
         | on either server)
        
           | gunapologist99 wrote:
           | Yes. Create a temporary (or permanent) private key on server
           | A and then put its public key in server B.
           | 
           | That's the correct way to handle this situation, definitely
           | not -A.
        
       | berkle4455 wrote:
       | What's a better solution if you want to be able to SSH across
       | multiple machines? Do you need to always close the current
       | connection to get back to localhost prior to a fresh SSH?
       | 
       | e.g. how would I ssh into foo, and then later into bar, or
       | perhaps pull some code from github onto foo that is authenticated
       | by my key?                   localhost -> foo -> bar
       | localhost -> foo -> github access
       | 
       | It seems like the answer is either: a) ssh -A, or b) install my
       | private key on foo.
        
         | gunapologist99 wrote:
         | Better options:
         | 
         | c) use proxyjump (-J) to access bar
         | (https://www.man7.org/linux/man-pages/man1/ssh.1.html), and/or
         | 
         | d) generate a new private key on foo and use that to access
         | github.
         | 
         | You might think that's a crazy waste of time compared to
         | forwarding, but it's actually much, much safer and actually
         | only takes a moment:                   ssh-keygen -t ed25519
         | cat ~/.ssh/id_ed25519.pub
         | 
         | and then just paste that in Github.
         | 
         | See also https://userify.com/docs/jumpbox for more jumpbox
         | docs.
        
         | cassianoleal wrote:
         | As others have pointed out already, JumpHost or -J is the
         | preferred way.
        
           | [deleted]
        
           | gunapologist99 wrote:
           | I agree!
           | 
           | The Github example complicates things, but the correct
           | solution is actually another key:
           | 
           | Generate a separate private key on foo and place that one in
           | github, ideally per project as a deploy key.
        
         | totallywrong wrote:
         | You can set up an ssh tunnel on localhost to any port on bar or
         | github via foo.
        
         | [deleted]
        
         | slt2021 wrote:
         | I use hashi corp's stack: Boundary + Vault for ssh credential
         | injection
         | 
         | https://developer.hashicorp.com/boundary/tutorials/credentia...
         | 
         | it completely replaces the need for bastion hosts and ssh-agent
         | at scale (I'm a hashicorp's paying customer)
         | 
         | compared to Teleport, boundary is lightweight (you dont need to
         | install agent on each target server) and is integrated with the
         | Vault for certificate based auth or simple cred brokering
        
           | wahern wrote:
           | I wrote a macOS app that supports using Vault Transit Engine
           | keys with OpenSSH, as well as GnuPG and PKCS#11. (OpenSSH is
           | supported via both the agent protocol and PKCS#11.) You can
           | even use an Apple T2 (Secure Enclave) key for peer mTLS
           | authentication to the Vault server. https://www.keymux.com/
           | 
           | Using this teams can _share_ an SSH key without exposing the
           | key; nor do you need to configure certificate PKI, use jump
           | hosts, or otherwise change your existing software or
           | workflows.
        
         | aberoham wrote:
         | Teleport is far and away the leading solution in this area --
         | certificate based end-to-end bastion style topology with many
         | nice features including support for kubectl.
        
         | throwawaaarrgh wrote:
         | Make an ssh connection to foo with a port forward. Then make an
         | ssh connection to bar through foo. Keys stay on your machine.
         | I'm pretty sure there's built in features to do this.
        
           | gunapologist99 wrote:
           | That won't work for a connection to github that's being
           | initiated from foo.
           | 
           | The best solution in that situation is a separate key that's
           | private to foo.
        
       | binkHN wrote:
       | Full details:
       | https://www.qualys.com/2023/07/19/cve-2023-38408/rce-openssh...
        
       | aidenn0 wrote:
       | Even without this announcement, friends don't let friends forward
       | their ssh agent. It essentially grants that machine access to
       | your private keys. A RCE vulnerability is strictly worse than key
       | exposure, but you probably shouldn't have been using it anyways.
        
         | starfallg wrote:
         | Yup, and this is explained in detail in the ssh(1) man page.
         | No-one should be using -A. Using a jump host via -J is the way
         | to go.
        
           | Arnavion wrote:
           | One use of -A, namely using the ssh server as a jumphost, is
           | covered by -J. The general use of -A, namely doing operations
           | on the ssh server that require keys from the ssh client, is
           | not.
           | 
           | If I'm on machine foo and I want to connect to
           | bar.example.org and clone a git repo there from
           | baz.example.org, and baz.example.org requires an identity key
           | that is in foo's ssh agent, then -A is the only option.
        
             | gunapologist99 wrote:
             | No, you might as well copy the keys over there for all the
             | security you're getting (actually, that's safer given this
             | RCE which compromises both sides, even given that there's
             | no real way to shred the leaked key, but of course I'm not
             | actually suggesting this! they're both really bad.)
             | 
             | Your best option is too easy: just generate a new keypair
             | on foo.
             | 
             | Then you can populate baz.example.org with that public key
             | instead of your own.
        
               | Arnavion wrote:
               | >No, you might as well copy the keys over there
               | 
               | Only if the keys are insecure enough to be copied, ie not
               | backed by an HSM, or backed by an HSM but marked
               | exportable.
               | 
               | >for all the security you're getting (actually, that's
               | safer given this RCE which compromises both sides, even
               | given that there's no real way to shred the leaked key,
               | but of course I'm not actually suggesting this! they're
               | both really bad.)
               | 
               | Connecting to a malicious SSH server is already
               | dangeorous with or without this vulnerability, and with
               | or without agent forwarding. Eg a malicious server can
               | modify the shell to emit VT codes to mess up your
               | terminal.
               | 
               | >Your best option is too easy: just generate a new
               | keypair on foo.
               | 
               | Sure, but this creates additional identities that
               | baz.example.org must be taught to trust, which is not
               | always desirable or even an option.
        
               | gunapologist99 wrote:
               | > Only if the keys are insecure enough to be copied, ie
               | not backed by an HSM, or backed by an HSM but marked
               | exportable.
               | 
               | Agent forwarding forwards _the keys_ insecurely. If you
               | can launch an agent-forwarded connection, then the HSM is
               | already irrelevant.
               | 
               | > "Connecting to a malicious SSH server" is already
               | dangeorous with or without this vulnerability, and with
               | or without agent forwarding. Eg a malicious server can
               | modify the shell to emit VT codes to mess up your
               | terminal.
               | 
               | yes, but messing up your terminal is not an RCE (and you
               | should be able to fix it with stty sane). It's just an
               | annoyance and just tipped you off that obviously there's
               | something _wrong_ there. :) Obviously you should be
               | checking your host keys etc and ideally you woud never
               | accidentally connect to a malicious server.
               | 
               | However, in the unlucky but perhaps inevitable event that
               | you do connect to a malicious server, you shouldn't risk
               | exposing your entire client workstation! (through this or
               | another RCE) or your SSH private keys! (through normal
               | agent forwarding operation) with agent forwarding.
               | 
               | > Sure, but this creates additional identities that
               | baz.example.org must be taught to trust, which is not
               | always desirable or even an option.
               | 
               | A key is not necessarily an identity. Most platforms
               | permit more than one public key to be associated with a
               | user, including github, gitlab, userify, etc.
               | 
               | However, ideally you are correct -- this would result in
               | a new user account that has limited access to only the
               | things it really needs (principle of least privilege).
        
               | Arnavion wrote:
               | >Agent forwarding forwards the keys insecurely. If you
               | can launch an agent-forwarded connection, then the HSM is
               | already irrelevant.
               | 
               | No? ssh-agent works fine with keys that are not
               | exportable from the HSM. By the very definition it's not
               | possible for anything to export the key, ssh-agent or
               | otherwise.
               | 
               | >yes, but messing up your terminal is not an RCE
               | 
               | It has been, and can be again.
               | 
               | https://www.cyberark.com/resources/threat-research-
               | blog/dont...
        
             | drdaeman wrote:
             | Another relatively popular use case is pam_ssh_agent_auth
             | for passwordless-but-authenticated sudo. This, by
             | definition, requires agent forwarding.
             | 
             | (I don't use ssh-agent, I use gpg-agent with an SSH socket
             | - I suppose I'm fine?)
        
             | GauntletWizard wrote:
             | ssh-askpass is a great tool in these situations. It
             | intercedes and allows you to manually control all key usage
             | attempts.
        
               | Arnavion wrote:
               | I'm not sure what relevance ssh-askpass has to what I
               | wrote.
        
               | GauntletWizard wrote:
               | Right, this recipe isn't well known.
               | 
               | `ssh-add -c` will cause your ssh agent to pop up with
               | ssh-askpass every time it does an authentication. This is
               | fiddly; You need to have configured your ssh-agent right,
               | and there's a slightly different version to use keychains
               | on macos that's equivalent.
        
               | Arnavion wrote:
               | Once again, I'm not sure what relevance this has to the
               | discussion.
        
               | devnullbrain wrote:
               | Ah, a skillful execution of Cunningham's Law
        
         | willbicks wrote:
         | I prefer using hardware tokens (in most cases a PKCS#11 smart
         | card) because it means that even with a forwarded SSH agent,
         | every request to use my private key requires a PIN on my client
         | which is verified by the isolated cryptographic processor. It's
         | impossible for my private key to leave that card and get cached
         | anywhere else. While I haven't enabled it on my Yubikey I
         | understand they can do similar.
         | 
         | The downside is that compatibility in edge cases, while much
         | better than I'd expect, is still not perfect. In particular
         | Windows support outside of Putty gets challenging.
        
           | gorkish wrote:
           | The RCE is related to ssh-agent's support for PKCS#11, so,
           | yeah you are right this is a valid method to prevent key
           | access or theft via the agent (I also have to approve every
           | use of my PK), but in this case it's not protecting against
           | the RCE, and the workaround in the meantime is to disable
           | PKCS#11 `ssh-agent -P ''`
        
           | gunapologist99 wrote:
           | That won't save you for this RCE!
        
           | toast0 wrote:
           | The other downside is it's much harder to do bulk operations
           | against a fleet. It's not reasonable to enter a PIN for each
           | access when you need to push something to 1000 nodes. 100
           | nodes is probably ok, but not great.
        
           | throwawaaarrgh wrote:
           | or you could just use the -c option to ssh-add and be
           | prompted every time the key is handed over
        
         | salawat wrote:
         | Real talk though.
         | 
         | How do you manage ssh chaining then? Unique set of keys per
         | user per machine?
         | 
         | Short of scp'ing your private key over from your starting box,
         | I can't really think of another way. Then again, if it's not
         | your box, (you don't own the hardware have sole monopoly of
         | root), you probably shouldn't be ssh'ing from it anyway. I've
         | always held there are no true secrets on a computer... Until
         | multi-billion dollar companies decide to collude anyway.
         | 
         | Anywho, honest question. I'm a big fan of ssh roaming, never
         | realized that ssh-agent was a thing, but after reading this, if
         | I were to use it, I'd most certainly be doing it witout pkcs11
         | built in. Shotgunning shared libs for side-effects is
         | absolutely mad. Need to slot that into my source code reading
         | list.
        
           | jcotton42 wrote:
           | Depending on your usecase, ProxyJump may suffice
           | https://www.redhat.com/sysadmin/ssh-proxy-bastion-proxyjump
        
           | aidenn0 wrote:
           | > How do you manage ssh chaining then
           | 
           | ProxyJump in the .ssh/config file. If your SSH is too old to
           | support ProxyJump, you should probably upgrade, but this
           | works as well:                  ProxyCommand ssh -q -W %h:%p
           | jumpost
        
             | salawat wrote:
             | Noted... Guess I know what I'm doing today!
             | 
             | Edit: Nevermind, tried it, not sufficient for my use case.
             | 
             | I tend to do a lot of mesh-y bouncing around between
             | servers, and -J seems to be more intended for a
             | star/hub&spoke topology. Common ssh priv-key to all
             | machines, or alternatively, a unique set of priv_keys per
             | user per dest machine is about the way to go. You still
             | have privilege escalations to worry about, but thems the
             | breaks.
             | 
             | It's a neat trick, I'll give it that.
        
               | aidenn0 wrote:
               | It's not limited to star topologies; You can use
               | ProxyJump for any topology that includes fixed routes
               | from a client to a host. Just add a separate host entry
               | for each machine.
               | 
               | 4 server example (this assumes your client can connect to
               | only host C) with the following topology:
               | C -> B -> A          \-> D
               | 
               | ssh configuration snippet:                   Host A
               | ProxyJump B              Host B           ProxyJump C
               | Host D           ProxyJump C
               | 
               | This example is a tree-like topolgy, but you can use host
               | aliases (i.e. add a HostName that is different from the
               | host entry) to define any fixed route to any machine you
               | like.
        
               | saltcured wrote:
               | For me, the main use of agent-forwarding is that I need
               | to use a command that expects to use SSH to get between
               | leaf nodes. For example git or rsync CLIs that need to
               | manipulate the local filesystem and tunnel their own
               | protocol over SSH to talk to another remote server.
               | 
               | At times, I've wished for something like uMatrix but for
               | ssh-agent forwarding, so I could have policies for which
               | peer-to-peer authentications should be allowed for which
               | keys and whether these specific uses should require
               | interactive confirmation.
        
               | gunapologist99 wrote:
               | Just generate a new keypair there on your bounce box
               | then. Don't do -A because this RCE means that not only do
               | you lose your keys, but you lose your laptop, too!
        
         | TechBro8615 wrote:
         | I think SSH agent forwarding is a fairly common setup with
         | VSCode Remote, where the developer wants to forward their keys
         | to the remote dev server so that they can perform Git
         | operations using their credentials.
        
           | gunapologist99 wrote:
           | Easy fix: generate private keys on the remote dev server and
           | then use those keys instead of your own with git.
        
             | lxgr wrote:
             | This exposes your private keys to a potentially less-
             | trusted dev server. It also just doesn't work with hardware
             | tokens for the same reason.
        
       | WhackyIdeas wrote:
       | Am I reading this right - any system with ssh-agent installed by
       | default is vulnerable?
       | 
       | The link is short on specifics.
        
         | kam wrote:
         | It's exploitable only by a SSH server that you connect to with
         | agent forwarding enabled (i.e. one that you're already trusting
         | with access to your SSH keys).
        
         | jonas-w wrote:
         | If I read this correctly it is only when you forward your ssh-
         | agent with the "-A" or "ForwardAgent" option
        
         | tetha wrote:
         | As far as I read it, it's about _forwarded_ ssh agents.
         | Basically, if you `ssh -A user@system`, something might be able
         | to execute commands locally. For example, this might turn messy
         | for infrastructures using jump-hosts extensively, if people are
         | used to  <ssh -A jumphost> so they can easily <ssh system>
         | afterwards. If you pop the jump host, you could pivot to the
         | workstations with this.
         | 
         | At the same time, ssh-agent forwarding makes me queasy from a
         | security perspective even without this. As far as I know, if
         | you <ssh -A> into a system, admins with privileges on the
         | system can gain access to your local ssh-agent already. In the
         | example of the jump host, if you popped the jump host and stuck
         | around for a while, you could probably harvest SSH keys and
         | have some fun later.
        
           | spladug wrote:
           | FWIW, `ProxyJump` is a safer way to go through a bastion
           | without having to expose your agent to either the bastion or
           | the target host behind it.
        
             | chaosite wrote:
             | And since the person you're replying to was mentioning
             | command-line parameters, it's worth mentioning that this
             | can be done with `ssh -J jumphost user@system`.
        
             | tetha wrote:
             | Useful, I didn't know that so far.
             | 
             | We don't use bastion servers. My only real use case for ssh
             | agent forwarding is if I need some scp / rsync between two
             | remote systems during emergencies and those systems have no
             | trust via SSH keys setup between them. In that very
             | specific case, I don't know a better way than <ssh -A> to
             | the first system and have some <rsync -e ssh> from there to
             | the second system. Still doesn't feel great, even though I
             | know only the people who could steal my keys are on my
             | team.
        
               | spladug wrote:
               | Ah yeah. Not sure on that one. scp does have the `-3`
               | option to copy between two remote hosts via the local
               | host, but that can be significantly slower if the remote
               | hosts are in the same network and local host is not.
        
               | tetha wrote:
               | Exactly. If I need to move a few megabytes around, <scp
               | -3> and a coffee or a few simple tickets is a good way. A
               | year ago or so, I needed 600GB moved between two systems
               | ASAP during an outage that'd turn into a money-bleed at
               | 6am. If I piped that through the VPN and my workstation,
               | I'd probably still be waiting today.
        
               | LinuxBender wrote:
               | Some time take a look at lftp [1] _and its mirror
               | subsystem_ for this. It can break up a batch of files or
               | even one large file into multiple SFTP streams. Another
               | upside is that it can replicate most rsync behavior in a
               | SFTP-Only Chroot account. Downside is that without a
               | corresponding daemon _like rsync_ on the other end
               | directory enumeration is slow which isn 't a problem if
               | one does not have a complex directory structure.
               | 
               | Play around with the built in rate limit options _total
               | and per thread_ to keep the network people happy.
               | 
               | [1] - https://linux.die.net/man/1/lftp
        
         | tedunangst wrote:
         | Well, any system that auto maps the stack executable when
         | loading a library. There are details on the specific
         | requirements in the advisory.
         | 
         | https://www.qualys.com/2023/07/19/cve-2023-38408/rce-openssh...
        
         | more_corn wrote:
         | I'd you forward your agent to a remote host, that host can mess
         | with you.
        
       | sullivanmatt wrote:
       | This sounds way worse than it is.
       | 
       | To be clear, the "remote" part of the code execution is that an
       | attacker controlling your destination server can cause your
       | _client_ to run an attacker-controlled payload, _if_ the client
       | is forwarding their credentials (`ssh -A`). Most people don 't
       | tend to make connections to arbitrary SSH hosts, and certainly
       | they don't do it while forwarding their credentials along.
       | 
       | It's a neat attack, and I applaud the Qualys team on their find,
       | but this is not any sort of emergency situation for 99.99% of
       | systems.
        
         | justsomeadvice0 wrote:
         | Lots of people end up with AgentForward on by default as a sort
         | of "make it work" fix, and lots of people use `git+ssh` on
         | untrusted servers. Here's an example:
         | 
         | https://abyssdomain.expert/@filippo/109659699817863532
         | 
         | TBF this is a vulnerable config either way; but RCE on the
         | client shouldn't be possible.
        
           | tinus_hn wrote:
           | I'm not so sure git is secure against a malicious server,
           | even if you're not simply pulling in a Makefile written by
           | the attacker.
        
         | gunapologist99 wrote:
         | I beg to differ: this does _not_ sound way worse than it is. If
         | anything, it 's understating the issue.
         | 
         | Not only can it be exploited across a wide variety of clients
         | across multiple platforms, but all that's required is that
         | you're using key forwarding.
         | 
         | This is devastating, because it's not just that you control the
         | destination server and steal the keys, but you can take over
         | the user's entire workstation.
         | 
         | Once you've got the user's entire workstation, you potentially
         | have access to everything else they have, from their email, to
         | other SSH hosts, to key loggers, to Git repos. This is about as
         | bad as it gets, and all because someone is using Agent
         | Forwarding.
         | 
         | Best of all, the victim has _no idea_ that they 've been
         | completely compromised. They can live inside your machine for
         | years, upgrade their sploits, and generally exfiltrate all of
         | your secrets.
         | 
         | Never use agent forwarding. Just don't. "Agent forwarding
         | should be enabled with caution" in the man page is another
         | massive understatement. Even if you _think_ you need it, check
         | the other responses in this thread for examples of how to work
         | around it.
        
           | dumpsterdiver wrote:
           | > Never use agent forwarding
           | 
           | Agreed. As this exploit proves, it's not even safe to log
           | into your own servers using ssh forwarding if any service is
           | exposed remotely, because if an attacker compromises that
           | exposed service and gains root then they could extend the
           | attack to your workstation, and that's a huge deal -
           | especially considering that you have the private key to log
           | into that server on your computer (so it's not an unsafe bet
           | there might be other keys).
        
         | TechBro8615 wrote:
         | The attacker controlled destination server could be a
         | compromised host, so this enables lateral movement from a
         | deployed VM or remote dev machine into a developer laptop.
        
         | gunapologist99 wrote:
         | Aren't all SSH hosts potentially attacker-controlled? ;)
        
           | nocsi wrote:
           | Yea, but there's a security boundary wherein you don't want
           | the SSH host to be executing code in _your_ environment. Of
           | course, the attackers can backdoor sshd to log credentials,
           | setup init scripts on the host to execute code every client
           | login and other shenanigans.
        
             | gunapologist99 wrote:
             | Of course. So it's not really that out of the question _if_
             | you are using agent forwarding, so, yeah, this is a big
             | deal.
        
         | malux85 wrote:
         | Yeah if I'm reading the technical analysis right, your
         | conditions that you mention have to be correct and also the
         | attacker must have "poisoned" library files on the targets
         | machine so they can dlopen them, is that right?
         | 
         | Pretty unlikely
        
           | Arnavion wrote:
           | The libraries are on the client's machine, not the server's.
           | And they're not "poisoned"; the default distro-provided libs
           | already provide the remote execution capabiity (eclipse-
           | titan, libkf5sonnetui5, libns3-3v5 and systemd-boot packages
           | from Ubuntu 22.04).
        
             | malux85 wrote:
             | Ahh I see I thought the attacker also had to have custom
             | malicious libs deployed on the client machine I wasn't sure
             | if standard ones would do, thanks for clarifying that
        
           | sullivanmatt wrote:
           | There must be a specific set of libs present on the victim
           | (client), correct. Qualys claims that stock Ubuntu Desktop
           | systems often have these libs, and that they haven't looked
           | into whether other distros tend to.
           | 
           | But yes, your point stands. Huge number of preconditions here
           | to fulfill.
        
         | e28eta wrote:
         | I don't know how prevalent it is as a network architecture, but
         | it seems like a bastion host / jump box would be a juicy target
         | for this exploit, since it'd let the attacker jump upstream.
        
           | jmalicki wrote:
           | Sure, but first they have to root the bastion box.
           | 
           | If you root the bastion box, you have user credentials for
           | anything inside the network. Controlling the user's laptop
           | seems unlikely to be your most profitable next step.
        
             | yjftsjthsd-h wrote:
             | It really depends on the setup; ex. I imagine it's easier
             | to steal company code from a laptop than server, while data
             | is the other way around.
        
             | gunapologist99 wrote:
             | > If you root the bastion box, you have user credentials
             | for anything inside the network.
             | 
             | But that's not how a (properly-configured!) bastion host
             | works.
             | 
             | You won't have user credentials for anything UNLESS users
             | are using Forward Agent (which they shouldn't! simplest
             | explanation here.. https://userify.com/docs/jumpbox ).
             | 
             | That's the point behind using ProxyJump. Your connection
             | actually jumps THROUGH the bastion box and doesn't stop for
             | interception along the way.
             | 
             | (And, of course, an attacker can't do anything very useful
             | with ssh public keys except for maybe traffic analysis or
             | learning more target IP's.)
        
           | akerl_ wrote:
           | Increasingly, the role of a bastion host is served either by
           | something like Teleport, which handles authn/z and proxying
           | without needing forwarded agents, or newer options in OpenSSH
           | like ProxyJump where you hop via a bastion host but without
           | ever forwarding your agent.
        
       | wahern wrote:
       | musl libc refuses to implement dlclose[1] for precisely the
       | reason that modules too often misbehave when dropped at runtime,
       | and requiring this behavior is very rarely needed if ever. The
       | number of modules that will be loaded is almost always bounded,
       | and keeping a module around in memory is mostly harmless;
       | certainly less harmful on average than trying to unload it.
       | 
       | [1] see https://wiki.musl-libc.org/functional-differences-from-
       | glibc...
        
       | a-dub wrote:
       | why publish this before the patches are out?
        
         | tedunangst wrote:
         | The patches are out.
        
           | a-dub wrote:
           | where? i couldn't find them on the openssh webpage and my
           | distro has not released a new openssh either.
           | 
           | edit: nvm. i see the release now. just no release for openbsd
           | itself it seems.
        
             | tedunangst wrote:
             | http://www.openssh.com/releasenotes.html#9.3p2
        
             | davidcuddeback wrote:
             | > _just no release for openbsd itself it seems._
             | 
             | It was posted to announce@openbsd.org a few hours ago.
             | Binary patches are available through syspatch and source
             | patches on the errata page.
        
       | kneebonian wrote:
       | Can I just say I know it's really dumb, but I loved that they
       | published the explanation as a simple txt file, instead of
       | setting up some whizbang website for it, or embedding it in their
       | company blog.
       | 
       | https://www.qualys.com/2023/07/19/cve-2023-38408/rce-openssh...
        
       | tptacek wrote:
       | This is the bug of the year.
       | 
       | It's well established that if Alice forwards an SSH agent to Bob,
       | Bob can use the SSH agent protocol to make Alice open DLLs,
       | because there's an agent protocol command
       | (SSH_AGENTC_ADD_SMARTCARD_KEY) that OpenSSH implements with
       | dlopen: when you ask the agent to access a smart card, OpenSSH
       | dlopen()'s the library corresponding to the `id` of the device.
       | This is a Jann Horn bug from 2016, and OpenSSH fixed it by
       | whitelisting DLLs to /usr/lib and directories like it.
       | 
       | The Qualys bug builds on Horn's bug. When OpenSSH dlopen()'s the
       | library, it then tries to look up a PKCS#11 entry point function,
       | and, when it doesn't find it, it dlclose()'s the library and
       | returns an error.
       | 
       | The issue is that most of the libraries in system library paths
       | were never intended to be opened maliciously, and so they do all
       | sorts of stuff in their constructors and destructors (any
       | function marked `__attribute__((constructor))` or `destructor` is
       | called by dlopen and dlclose respectively). In particular, they
       | register callbacks and signal handlers. Most of these libraries
       | are never expected to dlclose at all, so they tend not to be
       | great about cleaning up. Better still, if you randomly load
       | oddball libraries into random programs, some of them crash,
       | generating SIGBUS and SIGSEGV.
       | 
       | So you've got a classic UAF situation here: (1) force Alice to
       | load a library that registers a SIGBUS handler; it won't be a
       | PKCS#11 handler so it'll get immediately dlclose()'d, but won't
       | clean up the handler. (2) Load another library, which will take
       | over the program text address the signal handler points to. (3)
       | Finally, load a library that SIGBUS's. If you manage to get a
       | controlled jump swapped into place in step (2), you win.
       | 
       | If you're thinking "it's pretty unlikely you're going to be able
       | to line up a controlled jump at exactly the address previously
       | registered as a signal handler", you're right, but there's
       | another quirk of dlclose() they take advantage of: there's an ELF
       | flag, NODELETE, that instructs the linker not to unmap a library
       | when it's unloaded, and a bunch of standard libraries set it, so
       | you can use those libraries to groom the address space.
       | 
       | Finally, because some runtimes require executable stacks, there
       | are standard libraries with an ELF flag that instructs the
       | process to make the stack executable. If you load one of these
       | libraries, and you have a controlled jump, you can write
       | shellcode into the stack like it's 1998.
       | 
       | To figure out the right sequence of steps, they basically
       | recapitulated the original ROP gadget research idea: they swept
       | all the standard Ubuntu libraries with a fuzzer to find
       | combinations of loads that produced controlled jumps (ie, that
       | died trying to execute stack addresses).
       | 
       | A working exploit loads a pattern of "smartcards" that looks like
       | this (all in /usr/lib):
       | syslinux/modules/efi64/gfxboot.c32 (execstack)
       | pulse-15.0+dfsg1/modules/module-remap-sink.so (groom)
       | x86_64-linux-gnu/libgnatcoll_postgres.so.1 (SIGBUS handler)
       | pulse-15.0+dfsg1/modules/module-http-protocol-unix.so (groom)
       | x86_64-linux-gnu/sane/libsane-hp.so.1.0.32 (groom)
       | libreoffice/program/libindex_data.so (groom)
       | x86_64-linux-gnu/gstreamer-1.0/libgstaudiorate.so (groom)
       | libreoffice/program/libscriptframe.so (groom)
       | x86_64-linux-gnu/libisccc-9.16.15-Ubuntu.so (groom)
       | x86_64-linux-gnu/libxkbregistry.so.0.0.0 (groom)
       | debug/.build-id/15/c0bee6bcb06fbf381d0e0e6c52f71e1d1bd694.debug
       | (SIGBUS)
       | 
       | The paper goes on to classify like 4 more patterns whereby you
       | can get unexpected control transfers by dlopen() and immediately
       | dlclosing() libraries. The kicker:                   we noticed
       | that one shared library's constructor function         (which can
       | be invoked by a remote attacker via an ssh-agent forwarding)
       | starts a server thread that listens on a TCP port, and we
       | discovered a         remotely exploitable vulnerability (a heap-
       | based buffer overflow) in         this server's implementation.
        
       ___________________________________________________________________
       (page generated 2023-07-19 23:01 UTC)