Jump to content

BeerDNA

Members
  • Posts

    10
  • Joined

Profile Information

  • Interests
    Followers and likes

Recent Profile Visitors

1873 profile views

BeerDNA's Achievements

Newbie

Newbie (1/14)

5

Reputation

  1. Introduction A while ago we had a forensics case in which a Linux server was compromised and a modified OpenSSH binary was loaded into the memory of a webserver. The modified OpenSSH binary was used as a backdoor to the system for the attackers. The customer had pcaps and a hypervisor snapshot of the system on the moment it was compromised. We started wondering if it was possible to decrypt the SSH session and gain knowledge of it by recovering key material from the memory snapshot. In this blogpost I will cover the research I have done into OpenSSH and release some tools to dump OpenSSH session keys from memory and decrypt and parse sessions in combinarion with pcaps. I have also submitted my research to the 2020 Volatility framework plugin contest. SSH Protocol Firstly, I started reading up on OpenSSH and its workings. Luckily, OpenSSH is opensource so we can easily download and read the implementation details. The RFC’s, although a bit boring to read, were also a wealth of information. From a high level overview, the SSH protocol looks like the following: SSH protocol + software version exchange Algorithm negotiation (KEX INIT) Key exchange algorithms Encryption algorithms MAC algorithms Compression algorithms Key Exchange User authentication Client requests a channel of type “session” Client requests a pseudo terminal Client interacts with session Starting at the begin, the client connects to the server and sends the protocol version and software version: SSH-2.0-OpenSSH_8.3. The server responds with its protocol and software version. After this initial protocol and software version exchange, all traffic is wrapped in SSH frames. SSH frames exist primarily out of a length, padding length, payload data, padding content, and MAC of the frame. An example SSH frame: Example SSH Frame parsed with dissect.cstruct Before an encryption algorithm is negotiated and a session key is generated the SSH frames will be unencrypted, and even when the frame is encrypted, depending on the algorithm, parts of the frame may not be encrypted. For example aes256-gcm will not encrypt the 4 bytes length in the frame, but chacha20-poly1305 will. Next up the client will send a KEX_INIT message to the server to start negotiating parameters for the session like key exchange and encryption algorithm. Depending on the order of those algorithms the client and server will pick the first preferred algorithm that is supported by both sides. Following the KEX_INIT message, several key exchange related messages are exchanged after which a NEWKEYS messages is sent from both sides. This message tells the other side everything is setup to start encrypting the session and the next frame in the stream will be encrypted. After both sides have taken the new encryption keys in effect, the client will request user authentication and depending on the configured authentication mechanisms on the server do password/ key/ etc based authentication. After the session is authenticated the client will open a channel, and request services over that channel based on the requested operation (ssh/ sftp/ scp etc). Recovering the session keys The first step in recovering the session keys was to analyze the OpenSSH source code and debug existing OpenSSH binaries. I tried compiling OpenSSH myself, logging the generated session keys somewhere and attaching a debugger and searching for those in the memory of the program. Success! Session keys were kept in memory on the heap. Some more digging into the source code pointed me to the functions responsible for sending and recieving the NEWKEYS frame. I discovered there is a “ssh” structure which stores a “session_state” structure. This structure in turn holds all kinds of information related to the current SSH session inluding a newkeys structure containing information relating the encryption, mac and compression algorithm. One level deeper we finally find the “sshenc” structure holding the name of the cipher, the key, IV and the block length. Everything we need! A nice overview of the structure in OpenSSH is shown below: SSHENC Structure and relations And the definition of the sshenc structure: SSHENC Structure It’s difficult to find the key itself in memory (it’s just a string of random bytes), but the sshenc (and other) structures are more distinct, having some properties we can validate against. We can then scrape the entire memory address space of the program and validate each offset against these constraints. We can check for the following properties: name, cipher, key and iv members are valid pointers The name member points to a valid cipher name, which is equal to cipher->name key_len is within a valid range iv_len is within a valid range block_size is within a valid range If we validate against all these constraints we should be able to reliably find the sshenc structure. I started of building a POC Python script which I could run on a live host which attaches to processes and scrapes the memory for this structure. The source code for this script can be found here. It actually works rather well and outputs a json blob for each key found. So I demonstrated that I can recover the session keys from a live host with Python and ptrace, but how are we going to recover them from a memory snapshot? This is where Volatility comes into play. Volatility is a memory forensics framework written in Python with the ability to write custom plugins. And with some efforts, I was able to write a Volatility 2 plugin and was able to analyze the memory snapshot and dump the session keys! For the Volatility 3 plugin contest I also ported the plugin to Volatility 3 and submitted the plugin and research to the contest. Fingers crossed! Volatility 2 SSH Session Key Dumper output Decrypting and parsing the traffic The recovery of the session keys which are used to encrypt and decrypt the traffic was succesfull. Next up is decrypting the traffic! I started parsing some pcaps with pynids, a TCP parsing and reassembly library. I used our in-house developed dissect.cstruct library to parse data structures and developed a parsing framework to parse protocols like ssh. The parsing framework basically feeds the packets to the protocol parser in the correct order, so if the client sends 2 packets and the server replies with 3 packets the packets will also be supplied in that same order to the parser. This is important to keep overall protocol state. The parser basically consumes SSH frames until a NEWKEYS frame is encountered, indicating the next frame is encrypted. Now the parser peeks the next frame in the stream from that source and iterates over the supplied session keys, trying to decrypt the frame. If successful, the parser installs the session key in the state to decrypt the remaining frames in the session. The parser can handle pretty much all encryption algorithms supported by OpenSSH. The following animation tries to depict this process: SSH Protocol Parsing And finally the parser in action, where you can see it decrypts and parses a SSH session, also exposing the password used by the user to authenticate: Example decrypted and parsed SSH session Conclusion So to sum up, I researched the SSH protocol, how session keys are stored and kept in memory for OpenSSH, found a way to scrape them from memory and use them in a network parser to decrypt and parse SSH sessions to readable output. The scripts used in this research can be found here: Standalone Python POC to dump SSH session keys Volatility 2 plugin Volatility 3 plugin The SSH Protocol Parser A potential next step or nice to have would be implementing this decrypter and parser into Wireshark. Final thoughts Funny enough, during my research I also came across these commented lines in the ssh_set_newkeys function in the OpenSSH source. How ironic! If these lines were uncommented and compiled in the OpenSSH binaries this research would have been much harder.. OpenSSH source code snippet References https://fossies.org/dox/openssh-8.4p1/structssh.html https://fossies.org/dox/openssh-8.4p1/structsshenc.html sursa: https://blog.fox-it.com/2020/11/11/decrypting-openssh-sessions-for-fun-and-profit/
  2. A testat cineva? Ceva plug-in-uri interesante?
  3. Se pare ca asta a avut si repercursiuni: https://arstechnica.com/information-technology/2020/11/githubs-source-code-was-leaked-on-github-last-night-sort-of/
  4. Sorry, you cannot add any more reactions today. Nuuu! Ma asteptam sa castige Paunii, Hecarii si Tuica. BTW, cine e adragos? Frumos ca ati decis sa le oferiti un premiu si celor din echipa ByteForc3. Sigur sunteti romani?
  5. Sincer imi pare rau ca s-a intamplat atat de tarziu. Dar cei din urma vor fi cei dintai! Felicitari tuturor celor implicati! Cred ca a iesit foarte bine si poate membrii mai vechi vor dori sa contribuie la urmatoarea conferinta RST Con.
  6. Aveai bluetooth-ul activat? Cred ca in 2020 orice este posibil. Subiectul e foarte interesant. Niste articole de studiat din aceasta arie: https://en.wikipedia.org/wiki/Juice_jacking https://www.schneier.com/blog/archives/2020/07/hacking_a_power.html https://en.wikipedia.org/wiki/Row_hammer https://portswigger.net/daily-swig/battery-charger-hack-offers-covert-way-to-spy-on-mobile-devices https://www.wired.com/story/wireless-charging-with-lasers/ Nu mai fiti asa categorici! Daca nu stim noi, nu inseamna ca nu se poate.
  7. Mi-ar placea sa vorbim despre lucruri concrete. Au venit la tine si s-a facut un abuz?
  8. E cu dus si intors. Sa zicem sa sunt programator si dezvolt un crypter si vreau sa-l monetizez. Creez un website si un serviciu semi-automatizat. Totul e ok pana aici. Apoi postez pe hackforums si alte forumuri de genul, iar datele de contact sunt Jabber cu OTR. Adica asta vedem in fiecare zi la developerii legit, Jabber cu OTR. Sa fim seriosi acum! E cat se poate de clar ca oamenii vindeau si ofereau suport altora care se ocupau cu chestii ilegale. X user de pe forum programeaza un banking malware pe care il monetizeaza. El nu e responsabil, ci cei care l-au cumparat si-l folosesc, nu? Hai ma, ce naiba!
  9. Da' ce-am facut, sefu? Astia sunt? Discord:cyber.seal#0970. XMPP:cyberseal@jabb3r.org(OTR) Nu cred ca i-au saltat "degeaba". Ei erau onesti, cu frica lui Dumnezeu si cu taxele la zi si s-a abatut necazu' asupra lor.
×
×
  • Create New...