← All talks

SSH Grabber: Sniffing Linux Passwords from a Compromised Host

Bsides CT · 201819:32120 viewsPublished 2018-11Watch on YouTube ↗
Speakers
Tags
CategoryTechnical
TeamRed
About this talk
Jon Williams demonstrates a lightweight bash-based technique for extracting SSH credentials from a compromised Linux system. Using strace to monitor the SSH daemon's child processes, the tool captures plaintext passwords as they traverse kernel syscalls. The talk covers tool dependencies, code walkthrough, live demonstration, and practical scenarios where credential capture aids lateral movement.
Show original YouTube description
BSidesCT 2018 - Jon Williams - SSH Grabber - A Simple Hack to Sniff Linux Passwords from a Controlled Host Got a foothold in a target network and can’t get the creds you need to pivot? This simple tactic might just help you grab some SSH passwords so you can penetrate deeper into the environment.
Show transcript [en]

hello everybody can you hear me sound good all right our emcee has stepped away so I'm going to introduce myself thanks for coming to my talk this is SSH grabber which is about a simple hack to sniff Linux passwords from a control host our agenda for today we're gonna do a very quick introduction we'll talk about the dependencies for the tool that I wrote and do a little overview about how it works from there we'll step through the code do a bit of code review see exactly how it does it's magic God's willing we'll have a live demo after that you can see how it actually works we'll talk about some limitations and criticisms of it after that and follow

that up with a proof of concept see what where this tool would actually be useful we'll walk through some scenarios where you can actually put it into practice and we'll end with the tool release you can test it play with it see how it goes alright so without further ado Who am I my name is John I'm a network security engineer I work in the financial industry here in Connecticut my primary responsibilities are centered around Incident Response and Red Team operations I do have a sip I also got to test the the pen test Plus while it was in beta phase which was very interesting experience I tried the OS CP I failed the OS CP and I'm currently in the

process of trying harder I've been a b-sides organizer for the last two years it's good fun you might see me up in the CTF room if you haven't yet come check it out is we're having a good time today I'm a security researcher on my own time I build a test I break I play a lot of CTF and according to hack the box I'm a pro hacker so it must be true dependencies so this tool is written in bash it's simple bash script and it's basically got two programs that it depends upon first one I bet you're all familiar with it's sshd right a little background on this tool SSH stands for secure shell it was designed to replace

telnet which came before and the whole purpose of that tool was to allow remote administration of your servers right the telnet was never built for security everything all its authentication all its commands everything are transmitted in clear text which is a problem nowadays because if you're in the middle of the wire you can see everything going through you can capture credentials it's just terrible so they replaced it with SSH SSH does the same thing has the same basic functionality but it adds encryption from end to end on that connection so that you can administer your servers more securely uses TLS for that and it's designed to work with RSA keys so you've got a key pair for authentication which

you can handoff securely using diffie-hellman and the whole thing is secured but it's flexible it doesn't just use keys it can also work with whatever authentication your OS is using so it can be local authentication or it can use Pam your pluggable authentication module so you can do LDAP or whatever else your system is designed to handle so it's great that way SSH is designed to be a client server system so on the server side you have sshd your daemon which is running listening for connections to come in on the client side you've got a small program as long as it's built to work with the protocol it can interact with the server and establish your connection okay

pretty basic dependency number two is this trace ok system call tracer this program is designed to show interactions between a process and the kernel it's a simple debugger you often find it pre-installed on Linux systems it's great because it's super lightweight but it'll give you all kinds of visibility into process that you're running nice thing about s trace is that you can use it to spawn a process and then debug it from end to end or you can attach it to one that's already running which becomes very useful in this scenario normally SSH doesn't give you any way to view or log the credentials that it's capturing but you throw s trace into the mix and

suddenly things get a little more interesting so here's a theory of how this tool works pretty simple honestly you have a server it's running SSH listening for connections you have a client initiates a connection to the server and the SSH daemon forks a process off of that and see it actually runs a separate child process for every connection that comes in which is great it can multitask it's well designed if you're running SSH grabber on your server it'll see that child fork off and it'll attach s trace to it so now we can start capturing what's coming in when the client sends its input to authenticate to the server s trace we'll see that coming in on the socket and

calling to the kernel so now you have visibility into that authentication process as trace logs those kernel calls then all we have to do is parse the output and we can get the creds easy right so let's look at the code they're basically two parts to the way this script works first we find the right process to processes to attach s trace onto in the second part is we have to parse out the krint as I already mentioned SH sshd multitasks is creating new Forks every time somebody connects so we have to figure out how to attach to those so the first step here is simple we have a while loop that runs infinitely and it uses the PS utility to

just monitor a process list in that list it's looking for two key words ssh and net Wynette because that's what we can use to distinguish between the parent process and the children it has both of those then we know it's a child once we spot that in the list we grab the process identifier and then we use the pin to attach s trace - it s trace has a lot of different options for it so it's important to make sure we're configuring it in a way that's efficient for our needs so have a look at the flags there first one we have Q which makes it quiet which means it's not gonna log anything that we don't care about you know

telling us that it's attaching to a process it's only gonna give us the output the X flag is important because it makes the contents of the calls that it's logging B output in hexadecimal why is that important because the logs that come from s trace aren't really that nice and it they include brackets they include quotes they include other things and if you're manually parsing that output it can be hard to distinguish the contents of the call from the other stuff that's logged we put the contents in hexadecimal then it's really easy to extract it without messing up our parser the S flag here sets the size of our string buffer this again is important because s trace by

default only captures 32 characters of whatever call it's bringing in and this screwed me up for a while when I was writing it because I couldn't figure out why I was only getting partial passwords logged out make that string buffer nice and long and you'll get whatever you need do you hundred fifty should be good if you're catching passwords longer than that feel free to you know bullet out the e call this is basically a filter for which calls s trace should care about in this case we really only care about rights and this is just you know from straight-up testing and watching how SSH does it's magic it turns out that all of the user input is being

written to the kernel because of the socket it's being written to the socket and so that's how the kernel sees it so anything that's not a right call to the kernel we don't care about P flag tells us what process to attach to we already got the pig from above and then the O flag just sets the filename of the log that we're gonna store this data into and so what this means is for every child process that comes in its gonna be generating a separate log file and that log file will only have the information from that process so it's nice and clean the double and means that after the S trace process finishes and quits it'll

move on to the next part which just passes the log file that was created into our parse Kranz function yeah nice and easy now some of you who are familiar with s trace might be asking the question why didn't you just use its built-in capability to follow Forks and that's a perfectly valid question because it can do that the reason why we're doing it this way is because if we use if we use the process to follow Forks automatically then there's only one s trace process running the whole time the script is running it never finishes which means we don't have an easy way to pipe its output to our parsing function so if we use even

though this is a little bit less clean using PS to monitor manually for those processes allows us to pipe the output every time a session closes make sense and if somebody knows a better way to code this to me feel free to fork this in github and now here's a sample of what the output looks like coming from s trace and they're basically five components to this first we have the name of the call which in this case it's always going to be right because that's what we told it we only want to see writes that second thing the number that comes right after is the file descriptor the identifier of where the content is being written to

which in this case is a socket and again it's for just because testing shows it always ends up being on for what we have in quotes after that is the actual content of the call which you can see is all in hexadecimal after that the number you see at the end is the length of the content and then the final thing after the equal sign is the result which ends up being the same the length of the content now anybody familiar enough with hexadecimal tell me what that actually says no yeah so first four but bits there are nothing there just metadata and the ones a fights sorry not bits the ones after that spell secret so that was

part one part two is our parsing function right so each log is gonna be passed into this so we can try and get the creds out of it now the ssh process the way it works when you try and log in the first thing you do is you send it your username and then it'll prompt you for a password you can either pass the username on the command line or if you have a different client it'll prompt you when you connect but username goes first and then you have up to three tries to enter your password and if you don't get it by the third one then it just closes out so this is nice because it means

that it'll close cleanly each time we have a distinction between our logs so we're gonna bring read the file in and go through it line by line and filter out the lines that we care about now in this case we already established file descriptor four is the one that's being used for user input so we only care about ones with that file descriptor the other thing we care about is the length in this case we want to make sure it's more than five characters long why five well for the first four we already established our metadata and this is just part of the protocol that SSH uses I don't know what they actually do but

it doesn't matter because irrelevant to what we're doing we're just gonna skip those four but the fifth one there are also some control plane commands that are five characters long and so it turns out if you just ignore those ones then you you get your user input pretty reliably so this won't work if you're only capturing a password that's one character long because it's gonna ignore it but if that's your target then you really don't need this script so now we've narrowed it down so we can extract the content from it which is in hex we're gonna drop the first four characters off of it and then we'll do one more check for filtering right

we're going to check for null bytes the reason for that of course is that if you're sending user input to a service there should not be any null characters and if there are then you've got other issues going on in your network but in this case it means if you find a null byte it means that there's another control plane you know command going through so we ignore all of those and what's left should be up to four strings so we convert them to ASCII last bit is just to differentiate between the username and the passwords which I said before is as simple as is it the first one then it's the user name if it's not

then it's a password so we get those all set up and that's it that's the body of the script right there the actual script has a little bit more because I have to close the loops and increment counters I also have some code at the beginning that checks your dependencies before you run it to make sure that everything's in line but otherwise that's it dead simple all right now it's demo time if anybody wants to fire up sh and hit that IP address just give me one quick second so I can actually start the process that's listening and you can see it in action

here we go you can see what I've done is I started SSH and then I started SSH grabber and if anybody tries to authenticate right now you should see the username and password drop in if nobody does it quickly I'll do it myself

they won't drop until the session closes if you've failed three times it won't show up until you actually finish the last one see what it yep all right well there's mine oh no that's not mine somebody else got one in there so there you go that's the tool it shows you what's going on there now if I cancel this if it'll let me somebody must have a session open let's get that part I was just gonna show that it also it will log him to a file too so you can go back and just dump the log to see all your creds later on so that's the tool and so let's think about that for a minute that's handy it's very

simple does something very obvious but there are some problems with it right don't you need root in the first place to be able to run as trace on the box okay I mean if you have root already you can dump the password hashes you can change passwords so who cares why does this even matter right also if you're attacking a box and you compromised the box maybe it doesn't even have s Tracey installed like so what do you do that and I mean what if you don't want to install it because you're gonna trip somebody's alarm also as we pointed out earlier this only works for passwords right if you're using RSA keys to do

your authentication this isn't going to help you because it won't capture the keys they're never actually transmitted to the server that's the way it's designed to work so okay oops these are all really valid points right these are limitations of the script so when is it actually useful I mean the obvious case of course is if you compromise a box and it does have s Trace installed then you're golden right also if you can install it it's just a simple apt-get to get it on the box and if depending on your environment that may not be a problem but consider this like what if you have a transient compromised so you've gotten in through a web server or

so thing else and you've elevated your privileges to route you don't actually have the password you want to get it so that you have easier access to the box you don't password hashes but you can't seem to crack it if you can get this on there you can sit and wait and see if they log in and then you'll actually have the password and clear text also consider scenario where they're using Pam instead of local authentication if they're connected to LDAP or even better if they're in a Windows domain then all the users that are logging into this box are not saving their credentials locally you wouldn't have any way to get it from the box directly so if you have this

sitting there running suddenly you can start grabbing credentials off the network this is getting a little more interesting what if the host is a bastion what if this is the box that sits on the edge of network that grants everybody access into the network and they have to go through as at stage suddenly this is starting to look a little more compelling right now proof of concept right even better is when you actually own the box so consider this take a Raspberry Pi install SSH and SSH grabber on it and then drop it into network so now you got a rogue host right along comes a spider spider is your asset inventory okay this is your

process on the network that's going around interrogating every box to make sure it actually belongs there all right it's an AK network access control now how do these work with Linux typically at least in my experience they tend to try and authenticate over SSH if they can log in then they know who you are and if they'll either accept that as proof that you belong there or they'll go on to interrogate you once they have an authenticated account so this box logs in suddenly now you've grabbed the credentials from the neck not bad and what else have you learned from it you know the IP address now you've got enough information that you can impersonate the nak you know the address

you know the credentials and let me just ask a question but how many of you work in companies where the service accounts are reused and over privileged yeah I thought so so chances are if your nak is using password authentication in the first place instead of RSA keys like it should do you've probably just landed some accounts that have serious privilege in the network so now it's time to do your own spidering right now you've got a PI that can traverse the network log into just about anything or at least anything that's configured with SSH and get in with likely some pretty decent privilege this could all be automated right with SSH grabber at the middle doing the

credentials you can easily build this out to do the whole attack stream automatically and if you add an out-of-band communication channel suddenly now you got a walking talking laterally hopping now we're getting behemoth so go get the creds and of course if you're on blue team it makes a really nice honeypot so that's it tools on github go check it out I hope you like the talk any questions yes sure you could yes in fact I think some of the when I was doing research for this I'm pretty sure some people have played with that I hadn't seen them try and do it this way through s trace but Pam modules you might have a starting point to work

with anyone else well thank you very much [Applause]