Monday, April 13, 2020

Wirelurker For OSX, iOS (Part I) And Windows (Part II) Samples


PART II

Wirelurker for Windows (WinLurker)

Research: Palo Alto Claud Xiao: Wirelurker for Windows

Sample credit: Claud Xiao



PART I


Research: Palo Alto Claud Xiao WIRELURKER: A New Era in iOS and OS X Malware

Palo Alto |Claud Xiao - blog post Wirelurker

Wirelurker Detector https://github.com/PaloAltoNetworks-BD/WireLurkerDetector


Sample credit: Claud Xiao


Download

Download Part I
Download Part II

Email me if you need the password




List of files
List of hashes 

Part II

s+«sìÜ 3.4.1.dmg 925cc497f207ec4dbcf8198a1b785dbd
apps.ipa 54d27da968c05d463ad3168285ec6097
WhatsAppMessenger 2.11.7.exe eca91fa7e7350a4d2880d341866adf35
使用说明.txt 3506a0c0199ed747b699ade765c0d0f8
libxml2.dll c86bebc3d50d7964378c15b27b1c2caa
libiconv-2_.dll 9c8170dc4a33631881120a467dc3e8f7
msvcr100.dll bf38660a9125935658cfa3e53fdc7d65
libz_.dll bd3d1f0a3eff8c4dd1e993f57185be75
mfc100u.dll f841f32ad816dbf130f10d86fab99b1a

zlib1.dll c7d4d685a0af2a09cbc21cb474358595


│   apps.ipa
│   σ╛«σìÜ 3.4.1.dmg

└───WhatsAppMessenger 2.11.7
            libiconv-2_.dll
            libxml2.dll
            libz_.dll
            mfc100u.dll
            msvcr100.dll
            WhatsAppMessenger 2.11.7.exe
            zlib1.dll
            使用说明.txt


Part I

BikeBaron 15e8728b410bfffde8d54651a6efd162
CleanApp c9841e34da270d94b35ae3f724160d5e
com.apple.MailServiceAgentHelper dca13b4ff64bcd6876c13bbb4a22f450
com.apple.appstore.PluginHelper c4264b9607a68de8b9bbbe30436f5f28
com.apple.appstore.plughelper.plist 94a933c449948514a3ce634663f9ccf8
com.apple.globalupdate.plist f92640bed6078075b508c9ffaa7f0a78
com.apple.globalupdate.plist f92640bed6078075b508c9ffaa7f0a78
com.apple.itunesupdate.plist 83317c311caa225b17ac14d3d504387d
com.apple.machook_damon.plist 6507f0c41663f6d08f497ab41893d8d9
com.apple.machook_damon.plist 6507f0c41663f6d08f497ab41893d8d9
com.apple.MailServiceAgentHelper.plist e6e6a7845b4e00806da7d5e264eed72b
com.apple.periodic-dd-mm-yy.plist bda470f4568dae8cb12344a346a181d9
com.apple.systemkeychain-helper.plist fd7b1215f03ed1221065ee4508d41de3
com.apple.watchproc.plist af772d9cca45a13ca323f90e7d874c2c
FontMap1.cfg 204b4836a9944d0f19d6df8af3c009d5
foundation 0ff51cd5fe0f88f02213d6612b007a45
globalupdate 9037cf29ed485dae11e22955724a00e7
globalupdate 9037cf29ed485dae11e22955724a00e7
itunesupdate a8dfbd54da805d3c52afc521ab7b354b
libcrypto.1.0.0.dylib 4c5384d667215098badb4e850890127b
libcrypto.1.0.0.dylib 3b533eeb80ee14191893e9a73c017445
libiconv.2.dylib 94f9882f5db1883e7295b44c440eb44c
libiconv.2.dylib fac8ef9dabdb92806ea9b1fde43ad746
libimobiledevice.4.dylib c596adb32c143430240abbf5aff02bc0
libimobiledevice.4.dylib 5b0412e19ec0af5ce375b8ab5a0bc5db
libiodb.dylib bc3aa0142fb15ea65de7833d65a70e36
liblzma.5.dylib 5bdfd2a20123e0893ef59bd813b24105
liblzma.5.dylib 9ebf9c0d25e418c8d0bed2a335aac8bf
libplist.2.dylib 903cbde833c91b197283698b2400fc9b
libplist.2.dylib 109a09389abef9a9388de08f7021b4cf
libssl.1.0.0.dylib 49b937c9ff30a68a0f663828be7ea704
libssl.1.0.0.dylib ab09435c0358b102a5d08f34aae3c244
libusbmuxd.2.dylib e8e0663c7c9d843e0030b15e59eb6f52
libusbmuxd.2.dylib 9efb552097cf4a408ea3bab4aa2bc957
libxml2.2.dylib 34f14463f28d11bd0299f0d7a3985718
libxml2.2.dylib 95506f9240efb416443fcd6d82a024b9
libz.1.dylib 28ef588ba7919f751ae40719cf5cffc6
libz.1.dylib f2b19c7a58e303f0a159a44d08c6df63
libzip.2.dylib 2a42736c8eae3a4915bced2c6df50397
machook 5b43df4fac4cac52412126a6c604853c
machook ecb429951985837513fdf854e49d0682
periodicdate aa6fe189baa355a65e6aafac1e765f41
pphelper 2b79534f22a89f73d4bb45848659b59b
sfbase.dylib bc3aa0142fb15ea65de7833d65a70e36
sfbase.dylib bc3aa0142fb15ea65de7833d65a70e36
sfbase_v4000.dylib 582fcd682f0f520e95af1d0713639864
sfbase_v4001.dylib e40de392c613cd2f9e1e93c6ffd05246
start e3a61139735301b866d8d109d715f102
start e3a61139735301b866d8d109d715f102
start.sh 3fa4e5fec53dfc9fc88ced651aa858c6
stty5.11.pl dea26a823839b1b3a810d5e731d76aa2
stty5.11.pl dea26a823839b1b3a810d5e731d76aa2
systemkeychain-helper e03402006332a6e17c36e569178d2097
watch.sh 358c48414219fdbbbbcff90c97295dff
WatchProc a72fdbacfd5be14631437d0ab21ff960
7b9e685e89b8c7e11f554b05cdd6819a 7b9e685e89b8c7e11f554b05cdd6819a
update 93658b52b0f538c4f3e17fdf3860778c
start.sh 9adfd4344092826ca39bbc441a9eb96f

File listing

├───databases
│       foundation
├───dropped
│   ├───version_A
│   │   │   com.apple.globalupdate.plist
│   │   │   com.apple.machook_damon.plist
│   │   │   globalupdate
│   │   │   machook
│   │   │   sfbase.dylib
│   │   │   watch.sh
│   │   │
│   │   ├───dylib
│   │   │       libcrypto.1.0.0.dylib
│   │   │       libiconv.2.dylib
│   │   │       libimobiledevice.4.dylib
│   │   │       liblzma.5.dylib
│   │   │       libplist.2.dylib
│   │   │       libssl.1.0.0.dylib
│   │   │       libusbmuxd.2.dylib
│   │   │       libxml2.2.dylib
│   │   │       libz.1.dylib
│   │   │
│   │   ├───log
│   │   └───update
│   ├───version_B
│   │       com.apple.globalupdate.plist
│   │       com.apple.itunesupdate.plist
│   │       com.apple.machook_damon.plist
│   │       com.apple.watchproc.plist
│   │       globalupdate
│   │       itunesupdate
│   │       machook
│   │       start
│   │       WatchProc
│   │
│   └───version_C
│       │   com.apple.appstore.plughelper.plist
│       │   com.apple.appstore.PluginHelper
│       │   com.apple.MailServiceAgentHelper
│       │   com.apple.MailServiceAgentHelper.plist
│       │   com.apple.periodic-dd-mm-yy.plist
│       │   com.apple.systemkeychain-helper.plist
│       │   periodicdate
│       │   stty5.11.pl
│       │   systemkeychain-helper
│       │
│       └───manpath.d
│               libcrypto.1.0.0.dylib
│               libiconv.2.dylib
│               libimobiledevice.4.dylib
│               libiodb.dylib
│               liblzma.5.dylib
│               libplist.2.dylib
│               libssl.1.0.0.dylib
│               libusbmuxd.2.dylib
│               libxml2.2.dylib
│               libz.1.dylib
│               libzip.2.dylib
├───iOS
│       sfbase.dylib
│       sfbase_v4000.dylib
│       sfbase_v4001.dylib
│       start
│       stty5.11.pl
├───IPAs
│       7b9e685e89b8c7e11f554b05cdd6819a
│       pphelper
├───original
│       BikeBaron
│       CleanApp
│       FontMap1.cfg
│       start.sh
└───update
        start.sh
        update

More articles


  1. Hack Tools
  2. Hack And Tools
  3. Hacker Hardware Tools
  4. Pentest Tools Windows
  5. Pentest Tools Linux
  6. Hacking Tools Software
  7. Hack Rom Tools
  8. Free Pentest Tools For Windows
  9. Hacking Tools 2020
  10. How To Make Hacking Tools
  11. Hack Tools Online
  12. Game Hacking
  13. Hacker Search Tools
  14. New Hack Tools
  15. Hacking Tools For Games
  16. Hacking Tools For Pc
  17. Hacker Tools Free
  18. Hacking Tools Hardware
  19. Hacking App
  20. Top Pentest Tools
  21. Hack Tools Mac
  22. Hacking Tools Software
  23. Free Pentest Tools For Windows
  24. Termux Hacking Tools 2019
  25. Hack Tools Github

NcN 2015 CTF - theAnswer Writeup


1. Overview

Is an elf32 static and stripped binary, but the good news is that it was compiled with gcc and it will not have shitty runtimes and libs to fingerprint, just the libc ... and libprhrhead
This binary is writed by Ricardo J Rodrigez

When it's executed, it seems that is computing the flag:


But this process never ends .... let's see what strace say:


There is a thread deadlock, maybe the start point can be looking in IDA the xrefs of 0x403a85
Maybe we can think about an encrypted flag that is not decrypting because of the lock.

This can be solved in two ways:

  • static: understanding the cryptosystem and programming our own decryptor
  • dynamic: fixing the the binary and running it (hard: antidebug, futex, rands ...)


At first sight I thought that dynamic approach were quicker, but it turned more complex than the static approach.


2. Static approach

Crawling the xrefs to the futex, it is possible to locate the main:



With libc/libpthread function fingerprinting or a bit of manual work, we have the symbols, here is the main, where 255 threads are created and joined, when the threads end, the xor key is calculated and it calls the print_flag:



The code of the thread is passed to the libc_pthread_create, IDA recognize this area as data but can be selected as code and function.

This is the thread code decompiled, where we can observe two infinite loops for ptrace detection and preload (although is static) this antidebug/antihook are easy to detect at this point.


we have to observe the important thing, is the key random?? well, with the same seed the random sequence will be the same, then the key is "hidden" in the predictability of the random.

If the threads are not executed on the creation order, the key will be wrong because is xored with the th_id which is the identify of current thread.

The print_key function, do the xor between the key and the flag_cyphertext byte by byte.


And here we have the seed and the first bytes of the cypher-text:



With radare we can convert this to a c variable quickly:


And here is the flag cyphertext:


And with some radare magics, we have the c initialized array:


radare, is full featured :)

With a bit of rand() calibration here is the solution ...



The code:
https://github.com/NocONName/CTF_NcN2k15/blob/master/theAnswer/solution.c





3. The Dynamic Approach

First we have to patch the anti-debugs, on beginning of the thread there is two evident anti-debugs (well anti preload hook and anti ptrace debugging) the infinite loop also makes the anti-debug more evident:



There are also a third anti-debug, a bit more silent, if detects a debugger trough the first available descriptor, and here comes the fucking part, don't crash the execution, the execution continues but the seed is modified a bit, then the decryption key will not be ok.





Ok, the seed is incremented by one, this could be a normal program feature, but this is only triggered if the fileno(open("/","r")) > 3 this is a well known anti-debug, that also can be seen from a traced execution.

Ok, just one byte patch,  seed+=1  to  seed+=0,   (add eax, 1   to add eax, 0)

before:


after:



To patch the two infinite loops, just nop the two bytes of each jmp $-0



Ok, but repairing this binary is harder than building a decryptor, we need to fix more things:

  •  The sleep(randInt(1,3)) of the beginning of the thread to execute the threads in the correct order
  •  Modify the pthread_cond_wait to avoid the futex()
  • We also need to calibrate de rand() to get the key (just patch the sleep and add other rand() before the pthread_create loop
Adding the extra rand() can be done with a patch because from gdb is not possible to make a call rand() in this binary.

With this modifications, the binary will print the key by itself. 

Related word


  1. Hacker Tools For Ios
  2. Beginner Hacker Tools
  3. Pentest Tools Review
  4. Pentest Tools Android
  5. Top Pentest Tools
  6. Hacker Tools Software
  7. Install Pentest Tools Ubuntu
  8. Hack Tools For Mac
  9. Hacking Tools For Games
  10. Kik Hack Tools
  11. What Is Hacking Tools
  12. Blackhat Hacker Tools
  13. Ethical Hacker Tools
  14. How To Hack
  15. Hacking Tools Mac
  16. Pentest Tools Website
  17. Hacking Tools Github
  18. Hacker Tools Hardware
  19. Hack Tools For Games
  20. Hack Tools For Ubuntu
  21. Hack Tools 2019
  22. Hack Tools For Games
  23. Hack Tools Github

CVE-2020-2655 JSSE Client Authentication Bypass

TLDR: If you are using TLS ClientAuthentication in Java 11 or newer you should patch NOW. There is a trivial bypass.


During our joint research on DTLS state machines, we discovered a really interesting vulnerability (CVE-2020-2655) in the recent versions of Sun JSSE (Java 11, 13). Interestingly, the vulnerability does not only affect DTLS implementations but does also affects the TLS implementation of JSSE in a similar way. The vulnerability allows an attacker to completely bypass client authentication and to authenticate as any user for which it knows the certificate WITHOUT needing to know the private key. If you just want the PoC's, feel free to skip the intro.





DTLS

I guess most readers are very familiar with the traditional TLS handshake which is used in HTTPS on the web.


DTLS is the crayon eating brother of TLS. It was designed to be very similar to TLS, but to provide the necessary changes to run TLS over UDP. DTLS currently exists in 2 versions (DTLS 1.0 and DTLS 1.2), where DTLS 1.0 roughly equals TLS 1.1 and DTLS 1.2 roughly equals TLS 1.2. DTLS 1.3 is currently in the process of being standardized. But what exactly are the differences? If a protocol uses UDP instead of TCP, it can never be sure that all messages it sent were actually received by the other party or that they arrived in the correct order. If we would just run vanilla TLS over UDP, an out of order or dropped message would break the connection (not only during the handshake). DTLS, therefore, includes additional sequence numbers that allow for the detection of out of order handshake messages or dropped packets. The sequence number is transmitted within the record header and is increased by one for each record transmitted. This is different from TLS, where the record sequence number was implicit and not transmitted with each record. The record sequence numbers are especially relevant once records are transmitted encrypted, as they are included in the additional authenticated data or HMAC computation. This allows a receiving party to verify AEAD tags and HMACs even if a packet was dropped on the transport and the counters are "out of sync".
Besides the record sequence numbers, DTLS has additional header fields in each handshake message to ensure that all the handshake messages have been received. The first handshake message a party sends has the message_seq=0 while the next handshake message a party transmits gets the message_seq=1 and so on. This allows a party to check if it has received all previous handshake messages. If, for example, a server received message_seq=2 and message_seq=4 but did not receive message_seq=3, it knows that it does not have all the required messages and is not allowed to proceed with the handshake. After a reasonable amount of time, it should instead periodically retransmit its previous flight of handshake message, to indicate to the opposing party they are still waiting for further handshake messages. This process gets even more complicated by additional fragmentation fields DTLS includes. The MTU (Maximum Transmission Unit) plays a crucial role in UDP as when you send a UDP packet which is bigger than the MTU the IP layer might have to fragment the packet into multiple packets, which will result in failed transmissions if parts of the fragment get lost in the transport. It is therefore desired to have smaller packets in a UDP based protocol. Since TLS records can get quite big (especially the certificate message as it may contain a whole certificate chain), the messages have to support fragmentation. One would assume that the record layer would be ideal for this scenario, as one could detect missing fragments by their record sequence number. The problem is that the protocol wants to support completely optional records, which do not need to be retransmitted if they are lost. This may, for example, be warning alerts or application data records. Also if one party decides to retransmit a message, it is always retransmitted with an increased record sequence number. For example, the first ClientKeyExchange message might have record sequence 2, the message gets dropped, the client decides that it is time to try again and might send it with record sequence 5. This was done as retransmissions are only part of DTLS within the handshake. After the handshake, it is up to the application to deal with dropped or reordered packets. It is therefore not possible to see just from the record sequence number if handshake fragments have been lost. DTLS, therefore, adds additional handshake message fragment information in each handshake message record which contains information about where the following bytes are supposed to be within a handshake message.


If a party has to replay messages, it might also refragment the messages into bits of different (usually smaller) sizes, as dropped packets might indicate that the packets were too big for the MTU). It might, therefore, happen that you already have received parts of the message, get a retransmission which contains some of the parts you already have, while others are completely new to you and you still do not have the complete message. The only option you then have is to retransmit your whole previous flight to indicate that you still have missing fragments. One notable special case in this retransmission fragmentation madness is the ChangecipherSpec message. In TLS, the ChangecipherSpec message is not a handshake message, but a message of the ChangeCipherSpec protocol. It, therefore, does not have a message_sequence. Only the record it is transmitted in has a record sequence number. This is important for applications that have to determine where to insert a ChangeCipherSpec message in the transcript.

As you might see, this whole record sequence, message sequence, 2nd layer of fragmentation, retransmission stuff (I didn't even mention epoch numbers) which is within DTLS, complicates the whole protocol a lot. Imagine being a developer having to implement this correctly and secure...  This also might be a reason why the scientific research community often does not treat DTLS with the same scrutiny as it does with TLS. It gets really annoying really fast...

Client Authentication

In most deployments of TLS only the server authenticates itself. It usually does this by sending an X.509 certificate to the client and then proving that it is in fact in possession of the private key for the certificate. In the case of RSA, this is done implicitly the ability to compute the shared secret (Premaster secret), in case of (EC)DHE this is done by signing the ephemeral public key of the server. The X.509 certificate is transmitted in plaintext and is not confidential. The client usually does not authenticate itself within the TLS handshake, but rather authenticates in the application layer (for example by transmitting a username and password in HTTP). However, TLS also offers the possibility for client authentication during the TLS handshake. In this case, the server sends a CertificateRequest message during its first flight. The client is then supposed to present its X.509 Certificate, followed by its ClientKeyExchange message (containing either the encrypted premaster secret or its ephemeral public key). After that, the client also has to prove to the server that it is in possession of the private key of the transmitted certificate, as the certificate is not confidential and could be copied by a malicious actor. The client does this by sending a CertificateVerify message, which contains a signature over the handshake transcript up to this point, signed with the private key which belongs to the certificate of the client. The handshake then proceeds as usual with a ChangeCipherSpec message (which tells the other party that upcoming messages will be encrypted under the negotiated keys), followed by a Finished message, which assures that the handshake has not been tampered with. The server also sends a CCS and Finished message, and after that handshake is completed and both parties can exchange application data. The same mechanism is also present in DTLS.

But what should a Client do if it does not possess a certificate? According to the RFC, the client is then supposed to send an empty certificate and skip the CertificateVerify message (as it has no key to sign anything with). It is then up to the TLS server to decide what to do with the client. Some TLS servers provide different options in regards to client authentication and differentiate between REQUIRED and WANTED (and NONE). If the server is set to REQUIRED, it will not finish the TLS handshake without client authentication. In the case of WANTED, the handshake is completed and the authentication status is then passed to the application. The application then has to decide how to proceed with this. This can be useful to present an error to a client asking him to present a certificate or insert a smart card into a reader (or the like). In the presented bugs we set the mode to REQUIRED.

State machines

As you might have noticed it is not trivial to decide when a client or server is allowed to receive or send each message. Some messages are optional, some are required, some messages are retransmitted, others are not. How an implementation reacts to which message when is encompassed by its state machine. Some implementations explicitly implement this state machine, while others only do this implicitly by raising errors internally if things happen which should not happen (like setting a master_secret when a master_secret was already set for the epoch). In our research, we looked exactly at the state machines of DTLS implementations using a grey box approach. The details to our approach will be in our upcoming paper (which will probably have another blog post), but what we basically did is carefully craft message flows and observed the behavior of the implementation to construct a mealy machine which models the behavior of the implementation to in- and out of order messages. We then analyzed these mealy machines for unexpected/unwanted/missing edges. The whole process is very similar to the work of Joeri de Ruiter and Erik Poll.


JSSE Bugs

The bugs we are presenting today were present in Java 11 and Java 13 (Oracle and OpenJDK). Older versions were as far as we know not affected. Cryptography in Java is implemented with so-called SecurityProvider. Per default SUN JCE is used to implement cryptography, however, every developer is free to write or add their own security provider and to use them for their cryptographic operations. One common alternative to SUN JCE is BouncyCastle. The whole concept is very similar to OpenSSL's engine concept (if you are familiar with that). Within the JCE exists JSSE - the Java Secure Socket Extension, which is the SSL/TLS part of JCE. The presented attacks were evaluated using SUN JSSE, so the default TLS implementation in Java. JSSE implements TLS and DTLS (added in Java 9). However, DTLS is not trivial to use, as the interface is quite complex and there are not a lot of good examples on how to use it. In the case of DTLS, only the heart of the protocol is implemented, how the data is moved from A to B is left to the developer. We developed a test harness around the SSLEngine.java to be able to speak DTLS with Java. The way JSSE implemented a state machine is quite interesting, as it was completely different from all other analyzed implementations. JSSE uses a producer/consumer architecture to decided on which messages to process. The code is quite complex but worth a look if you are interested in state machines.

So what is the bug we found? The first bug we discovered is that a JSSE DTLS/TLS Server accepts the following message sequence, with client authentication set to required:


JSSE is totally fine with the messages and finishes the handshake although the client does NOT provide a certificate at all (nor a CertificateVerify message). It is even willing to exchange application data with the client. But are we really authenticated with this message flow? Who are we? We did not provide a certificate! The answer is: it depends. Some applications trust that needClientAuth option of the TLS socket works and that the user is *some* authenticated user, which user exactly does not matter or is decided upon other authentication methods. If an application does this - then yes, you are authenticated. We tested this bug with Apache Tomcat and were able to bypass ClientAuthentication if it was activated and configured to use JSSE. However, if the application decides to check the identity of the user after the TLS socket was opened, an exception is thrown:

The reason for this is the following code snippet from within JSSE:


As we did not send a client certificate the value of peerCerts is null, therefore an exception is thrown. Although this bug is already pretty bad, we found an even worse (and weirder) message sequence which completely authenticates a user to a DTLS server (not TLS server though). Consider the following message sequence:

If we send this message sequence the server magically finishes the handshake with us and we are authenticated.

First off: WTF
Second off: WTF!!!111

This message sequence does not make any sense from a TLS/DTLS perspective. It starts off as a "no-authentication" handshake but then weird things happen. Instead of the Finished message, we send a Certificate message, followed by a Finished message, followed by a second(!) CCS message, followed by another Finished message. Somehow this sequence confuses JSSE such that we are authenticated although we didn't even provide proof that we own the private key for the Certificate we transmitted (as we did not send a CertificateVerify message).
So what is happening here? This bug is basically a combination of multiple bugs within JSSE. By starting the flight with a ClientKeyExchange message instead of a Certificate message, we make JSSE believe that the next messages we are supposed to send are ChangeCipherSpec and Finished (basically the first exploit). Since we did not send a Certificate message we are not required to send a CertificateVerify message. After the ClientKeyExchange message, JSSE is looking for a ChangeCipherSpec message followed by an "encrypted handshake message". JSSE assumes that the first encrypted message it receives will be the Finished message. It, therefore, waits for this condition. By sending ChangeCipherSpec and Certificate we are fulfilling this condition. The Certificate message really is an "encrypted handshake message" :). This triggers JSSE to proceed with the processing of received messages, ChangeCipherSpec message is consumed, and then the Certifi... Nope, JSSE notices that this is not a Finished message, so what JSSE does is buffer this message and revert to the previous state as this step has apparently not worked correctly. It then sees the Finished message - this is ok to receive now as we were *somehow* expecting a Finished message, but JSSE thinks that this Finished is out of place, as it reverted the state already to the previous one. So this message gets also buffered. JSSE is still waiting for a ChangeCipherSpec, "encrypted handshake message" - this is what the second ChangeCipherSpec & Finished is for. These messages trigger JSSE to proceed in the processing. It is actually not important that the last message is a Finished message, any handshake message will do the job. Since JSSE thinks that it got all required messages again it continues to process the received messages, but the Certificate and Finished message we sent previously are still in the buffer. The Certificate message is processed (e.g., the client certificate is written to the SSLContext.java). Then the next message in the buffer is processed, which is a Finished message. JSSE processes the Finished message (as it already had checked that it is fine to receive), it checks that the verify data is correct, and then... it stops processing any further messages. The Finished message basically contains a shortcut. Once it is processed we can stop interpreting other messages in the buffer (like the remaining ChangeCipherSpec & "encrypted handshake message"). JSSE thinks that the handshake has finished and sends ChangeCipherSpec Finished itself and with that the handshake is completed and the connection can be used as normal. If the application using JSSE now decides to check the Certificate in the SSLContext, it will see the certificate we presented (with no possibility to check that we did not present a CertificateVerify). The session is completely valid from JSSE's perspective.

Wow.

The bug was quite complex to analyze and is totally unintuitive. If you are still confused - don't worry. You are in good company, I spent almost a whole day analyzing the details... and I am still confused. The main problem why this bug is present is that JSSE did not validate the received message_sequence numbers of incoming handshake message. It basically called receive, sorted the received messages by their message_sequence, and processed the message in the "intended" order, without checking that this is the order they are supposed to be sent in.
For example, for JSSE the following message sequence (Certificate and CertificateVerify are exchanged) is totally fine:

Not sending a Certificate message was fine for JSSE as the REQUIRED setting was not correctly evaluated during the handshake. The consumer/producer architecture of JSSE then allowed us to cleverly bypass all the sanity checks.
But fortunately (for the community) this bypass does not work for TLS. Only the less-used DTLS is vulnerable. And this also makes kind of sense. DTLS has to be much more relaxed in dealing with out of order messages then TLS as UDP packets can get swapped or lost on transport and we still want to buffer messages even if they are out of order. But unfortunately for the community, there is also a bypass for JSSE TLS - and it is really really trivial:

Yep. You can just not send a CertificateVerify (and therefore no signature at all). If there is no signature there is nothing to be validated. From JSSE's perspective, you are completely authenticated. Nothing fancy, no complex message exchanges. Ouch.

PoC

A vulnerable java server can be found _*here*_. The repository includes a pre-built JSSE server and a Dockerfile to run the server in a vulnerable Java version. (If you want, you can also build the server yourself).
You can build the docker images with the following commands:

docker build . -t poc

You can start the server with docker:

docker run -p 4433:4433 poc tls

The server is configured to enforce client authentication and to only accept the client certificate with the SHA-256 Fingerprint: B3EAFA469E167DDC7358CA9B54006932E4A5A654699707F68040F529637ADBC2.

You can change the fingerprint the server accepts to your own certificates like this:

docker run -p 4433:4433 poc tls f7581c9694dea5cd43d010e1925740c72a422ff0ce92d2433a6b4f667945a746

To exploit the described vulnerabilities, you have to send (D)TLS messages in an unconventional order or have to not send specific messages but still compute correct cryptographic operations. To do this, you could either modify a TLS library of your choice to do the job - or instead use our TLS library TLS-Attacker. TLS-Attacker was built to send arbitrary TLS messages with arbitrary content in an arbitrary order - exactly what we need for this kind of attack. We have already written a few times about TLS-Attacker. You can find a general tutorial __here__, but here is the TLDR (for Ubuntu) to get you going.

Now TLS-Attacker should be built successfully and you should have some built .jar files within the apps/ folder.
We can now create a custom workflow as an XML file where we specify the messages we want to transmit:

This workflow trace basically tells TLS-Attacker to send a default ClientHello, wait for a ServerHelloDone message, then send a ClientKeyExchange message for whichever cipher suite the server chose and then follow it up with a ChangeCipherSpec & Finished message. After that TLS-Attacker will just wait for whatever the server sent. The last action prints the (eventually) transmitted application data into the console. You can execute this WorkflowTrace with the TLS-Client.jar:

java -jar TLS-Client.jar -connect localhost:4433 -workflow_input exploit1.xml

With a vulnerable server the result should look something like this:

and from TLS-Attackers perspective:

As mentioned earlier, if the server is trying to access the certificate, it throws an SSLPeerUnverifiedException. However, if the server does not - it is completely fine exchanging application data.
We can now also run the second exploit against the TLS server (not the one against DTLS). For this case I just simply also send the certificate of a valid client to the server (without knowing the private key). The modified WorkflowTrace looks like this:

Your output should now look like this:

As you can see, when accessing the certificate, no exception is thrown and everything works as if we would have the private key. Yep, it is that simple.
To test the DTLS specific vulnerability we need a vulnerable DTLS-Server:

docker run -p 4434:4433/udp poc:latest dtls

A WorkflowTrace which exploits the DTLS specific vulnerability would look like this:

To execute the handshake we now need to tell TLS-Attacker additionally to use UDP instead of TCP and DTLS instead of TLS:

java -jar TLS-Client.jar -connect localhost:4434 -workflow_input exploit2.xml -transport_handler_type UDP -version DTLS12

Resulting in the following handshake:

As you can see, we can exchange ApplicationData as an authenticated user. The server actually sends the ChangeCipherSpec,Finished messages twice - to avoid retransmissions from the client in case his ChangeCipherSpec,Finished is lost in transit (this is done on purpose).


Conclusion

These bugs are quite fatal for client authentication. The vulnerability got CVSS:4.8 as it is "hard to exploit" apparently. It's hard to estimate the impact of the vulnerability as client authentication is often done in internal networks, on unusual ports or in smart-card setups. If you want to know more about how we found these vulnerabilities you sadly have to wait for our research paper. Until then ~:)

Credits

Paul Fiterau Brostean (@PaulTheGreatest) (Uppsala University)
Robert Merget (@ic0nz1) (Ruhr University Bochum)
Juraj Somorovsky (@jurajsomorovsky) (Ruhr University Bochum)
Kostis Sagonas (Uppsala University)
Bengt Jonsson (Uppsala University)
Joeri de Ruiter (@cypherpunknl)  (SIDN Labs)

 

 Responsible Disclosure

We reported our vulnerabilities to Oracle in September 2019. The patch for these issues was released on 14.01.2020.
Related news

Saturday, April 11, 2020

All Aboard The S.S. Anne!

My first morning in Vermilion City, I found myself down at the docks pushing my way through the crowds. Vermilion Port was easily the busiest place I'd ever been in my life up to that point. The sheer number of ships and trucks moving goods in and out of the Kanto region was overwhelming. Even still, the S.S. Anne stood out of the crowd as a majestic ocean liner built for luxurious and excessive lifestyles. It's glorious, gleaming white hull was a beacon you could see almost anywhere in Vermilion City. I'd had my eye on her since I came into town the night before and I had no trouble finding my way to the pier at which she was docked. Getting on to that pier without a ticket or an invitation to the tournament was a trial all its own. I spent most of the morning looking for a way past security.
The story of how I got aboard the S.S. Anne is a story of chance encounters and dumb luck. The first of which was a man fishing off the end of an unused pier. I was attempting to get a better vantage point of the S.S. Anne at the time, but I was also curious about the old fisherman. I sat with him a moment and he showed me how he supported himself just fishing up Pokémon out of the Vermilion Bay. After spending perhaps half an hour watching and listening to his old fish tales, he offered me one of his old rods that he wasn't too attached to. I was surprised at his generosity and thanked him graciously. He said the old rod wasn't great at pulling up any big catches, but it was a good starter rod to learn how to handle myself. I was eager to try it out.
There didn't seem to be any restrictions posted on where you were allowed to fish in Vermilion Port, so I plopped myself down right at the edge of the S.S.Anne pier. I cast my line into the waters and waited. Patiently. For a long time. As I sat there on the edge of the dock, I could hear battles going on the deck above me. I could hear the whoops and cheers of the gathered crowds as local trainers, decadent cruise passengers, and members of the crew fought for fun and money. I knew that as long as there were trainers ready to battle, the registration for this exhibition would be open, but I had to get aboard soon.
There was a tug on the line! A new type of Pokémon battle had begun. It was my strength and determination against that of whatever was on the other end of that line. I struggled for several minutes, worried that this old rod would snap clear in half at the tension on the line. Finally, a red scaled fish Pokémon lurched out of the water and flopped on to the pier. I frowned slightly. It was a Magikarp. I should have known. It was too weak to weaken, so I had Arnold put it to sleep and I carefully tried to get it into a Pokéball. The damn thing casually slapped 4 of my balls into the ocean in its fitful slumber before finally being secured in the 5th ball. I named him Royal, and although he was weak now, I had some big dreams for Royal in the distant future.
I had no idea at the time, but the entire Magikarp episode was being watched by a gentleman nearby. I called out Royal to get a good look at him and size up his potential - which admittedly was limited right now. As I was gazing down at him, a firm hand clasped my shoulder.
"I say, good show, old sport. Good show."
"Thank you," I managed to sputter in sudden confusion.
"Oh, I daresay, where are my manners? My name is Reginald and I'm the Chairman of the Pokémon Fan Club. We are headquartered right here in Vermilion City! I have personally collected over 100 Pokémon and I'm very fussy when it comes to Pokémon. I see you are less fussy and I admire your spirit, old sport." He motioned to Royal. "I could never bother myself with Pokémon like that, but there is something special about you. Come now, join me aboard the S.S. Anne, would you? I can see you are itching to join the tournament. Meanwhile, let me tell you all about my favorite Pokémon, Rapidash. It is the most spectacular and ravishing of all the Pokémon, don't you agree?"
All I really heard was "join me aboard the S.S. Anne" and I was packing up my belongings as quickly as I could. While Chairman Reginald prattled on and on about Rapidash, my attention was mainly focused on shoving the old rod into my backpack, and making sure my Boulder and Cascade Badges were clearly visible. I wanted everyone to know how far I'd come as we made our way on board the cruise ship.

Once aboard, I listened to Chairmain Reginald talk about Rapidash for what felt like an eternity a polite amount of time considering the great favor he'd just done for me. Eventually I excused myself and I found my way to the registration desk. I showed off my two badges and was put into a mid-level bracket. The tournament was scored on a point system where trainers lost the most points when their Pokémon fainted, and since I was determined not to allow them to faint I was sure to score very highly in the preliminary matches.
All the matches were happening along the promenade deck with spectators above able to look down into most of the arenas that were setup. As I stood along the promenade, it was crowded and difficult to see much, but I managed to push my way toward my first match-up near the aft of the ship. I was going to face off against an older gentlemen who happened to be a passenger aboard the cruise wanting to test his skill against the Kanto trainers. I was nervous, but also excited. He opened with a Growlithe - a Pokémon I'd never seen before. It was obviously a fire-type and so Douglas was the right choice. He needed the battle experience, as well.
Growlithe was faster than I anticipated! He landed a desperate attack on Douglas's head which nearly incapacitated him. I was shocked. I'd almost lost a Pokémon due to my overconfidence in type match-ups. I switched out Douglas for Rascal Jr. hoping to get the edge in speed. My swap paid off because Rascal Jr. landed a monstrous hyper fang on this Growlithe and knocked it completely out. The crowd went wild at this turn around and I remember how uplifting it made me feel. I couldn't help from smiling like a fool.
The passenger tossed out another Growlithe who met the same OHKO fate to the power of Rascal Jr. To punctuate just how amazing Rascal's victory over the Growlithe duo actually was, Rascal Jr. evolved into a Raticate in front of the entire crowd. It generated some hushed awe from the spectators, but I was just ecstatic to see Rascal Jr. grow in power. Rascal and I were victorious in our first match, but there were still several more ahead of us before we'd meet with the captain.

Current Team:
Attacks in Blue are recently learned.

Bill's Storage: Shakespear (Spearow) & Royal (Magikarp)

Old Man Daycare: Charlie (Pidgey)

Wednesday, April 8, 2020

Oceanhorn Is Coming To Android - Steam Mac Version Out Now!

Oceanhorn – Classic Adventure Game for you favorite platform




Android has been one of the most requested platforms from us and we are happy to announce that Oceanhorn's world domination continues and Oceanhorn is coming to Android! Same team that works on console versions are behind the quality Android port. We'll get back to you with a release date later on!

In other news, we have just released an update for Steam version. It will add a support for Steam Controller and Steam link, but most importantly you can now play Steam version on your Mac! Save games in Steam are cross platform compatible.

So, in 2016 you will be able to play Oceanhorn not just on iOS, Apple TV or PC – but on Mac, PS4, Xbox One and even on your Android devices and Android TV!

Oceanhorn is the classic adventure game for your favorite gaming platform!



I am eager to tell you all what we have been working on for the past year – but it will have to wait just a little bit longer. ^_^