Skip to main content

Why you should always cautious on your VPN: Study Case on Broken Cryptography of Android VPN (day 91) ಠ_ಠ


source: https://me.me/i/when-you-make-a-meme-in-europe-but-you-use-22778509

Disclaimer: This blog post is heavily based on https://www.youtube.com/watch?v=ofTts7jlC2Y&t=177s created by Lukas Stefanko. I strongly suggest you guys check his youtube videos it contain many great android security study cases that you can learn free

Background:

Who doesn't know VPN, right?!

It is a wonderful program that lets us maintain the confidentiality of our identity and information while surfing the internet.

It is fast and more importantly is "FREE!" there are tons of free VPN applications that you can download in play store and use it in a click of a button.

The workflow is also not really that difficult to understand:

Source: https://blog.sucuri.net/2020/03/vpn-secure-online-work-environment.html

Pay attention to the above figure, this diagram explains the difference in our connection when using a VPN and not using VPN. When using a VPN before we connect to the ISP tower, our connection is redirected to the VPN gateway(VPN client) that will encrypt our connection and send it to the ISP but before sending it to the intended website or system it bounces its connection one more time to VPN server.

But are you really sure that you can trust VPN entirely?

If you say yes, you may have to think twice because in this post I will show you how an attacker can intercept your VPN connection and get your personal data by taking advantage of the vulnerability in the app itself

How it all starts:

 

According to VPNpro(https://vpnpro.com/blog/google-removes-one-of-biggest-vpn-apps-from-play-store-due-to-vulnerability/)

"Google has confirmed that SuperVPN, which has 100 million installs, has a vulnerability that allows for a critical MITM attack. On April 7, it was finally removed from the Google Play store."

I think the important points of the news are already covered by this statement. Let's try to find the vulnerable application in the third party repository since Google already taking out the application from the play store.

link: https://apkcombo.com/supervpn-free-vpn-client/com.jrzheng.supervpnfree/download/2.6.2-92-zip



unzip the file and you will have a bunch of multiple versions of the apk file, pick the first entry and let's try to reverse engineer the apk.



I use the JADX command-line tool to reverse engineer the sample. It is a really famous to decompile android app back to its java source code

Static Analysis:

According to the previous article one of the vulnerabilities that are found in the app is Hardcoded encryption keys. It's pretty easy to look for Harcoded key for encryption in android, you can start by doing a string search any of the programs that contain "SecretKeySpec" or encryption algorithms such as "AES" or "DES" like the below figure



Basically "SecretKeySpec" use in android to construct the secret key for the encryption and decryption process. link: https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/SecretKeySpec.html

Lets open "c/d/a/d/e.java" file



First, we can see that the secret key is created from variable called "f1657" that will decode into a byte array. We can see that f1567 is contained "6c" + a() + "63lEyY=" where a() is comprised with "GDH". Combine all of this together it will become "6cGDH63lEyY="



moving down a little bit we can see that the secret key is used in function a and b(). The function a() used to decrypt the ciphertext whereas b() used to encrypt the plaintext. Let's try to trace the function call to see when is the app used this particular function.



luckily there is only one class that called this particular function





we can see in function e(c cvar) the request is encrypted first using function b() and stores in variable b3 then the result is put into RequestBody.create() function that used to form an HTTP packet(in this case we sending a JSON packet) and send it to the backend using OkHttpClient library function which is newCall(). Once the request is complete the response will be decrypted back using function a()

we could safely assume that this function is responsible for sending an encrypted VPN request to the backend.

Dynamic Analysis:

Let's try to prove this by intercepting the request using burpsuite.

upon starting the application it seems to create some connection to several VPN gateway



unfortunately, the contacted backend is not responding by the application leading to error to the application but it's okay as long as we have the request packet.



now that you have encrypted communication and the secret key let's try to decrypt it. First, you need to convert the secret key to the hexadecimal value



Second, you also need to decode the captured connection to its original raw byte.



finally, you can decrypt the encrypted communication from http://des.online-domain-tools.com/



make sure you delete the whitespace of the hexadecimal value



Taddaaaaa! we got the unencrypted communication, pretty sweet, right?!

Can we do it programmatically?

Sure you can!

you might notice that the application contact several different backends, try to compare each one of the requests, is there anything different? You will see that only the first few bytes of the content are different while the rest is pretty much the same. Let's try to create a program that decrypts all of this request



I create an android application that will automatically decrypt all captured data that I saved in "captured_data.txt", I format the content to be like this:

<ip address>, <encrypted content>

I install and run the application in my dummy phone then we get all of the plain text:









we can see from the result that there are several data from our phone that are sent to the backend such as IMSI, device manufacture, location, and model. At the end of the JSON file, we can see that the data is to "/api/register.json"

Conclusion:

so what we can learn from this study case, I think you must stay cautious on the VPN app that you used, make sure you are using the updated version and remain vigilant by doing some little testing if the app actually follows the implementation of good cryptography

That's all folks I hope you enjoy this post, see you in the next post :)

Comments

Popular posts from this blog

Having fun analyzing nginx log to find malicious attacker in the net (ง'̀-'́)ง (day 37)

  What makes you sleepless at night? is it because of a ghost or scary stories? is it because you have an important meeting tomorrow? or is it because you have an exam? For me, what keeps me up all night is that I keep thinking about what happens to a website that I just created, is it safe from an attacker (certainly not) or did I missing some security adjustments that lead to vulnerability? well I'm not the best secure programmer in the world, I'm still learning and there is a big possibility that I can make a mistake but for me, a mistake can be a valuable investment to myself or yourself to be better so from this idea, I want to know more about what attackers casually do when attacking a website. Here in this post, I'm going to show you how I analyzed attack to the website that I have permission to design and also some interesting findings that I could get from the analysis Background: All of this analysis comes from the traffic that is targeted to th...

Utilize Pwntools for crafting ROP chain :') (day 69)

who doesn't like pwntools? it is a very versatile tool and can be customized according to our need using the python script but did you need to know that pwntools itself can help us to automatically craft a rop chain for us? so in this post, I will show you how to make rop chain less painful and make pwntools do all the heavy lifting. To demonstrate this I will use the binary challenge callme 64 bit from ropemporium link: https://ropemporium.com/challenge/callme.html Crashing the app: Like any other exploitation process, we need to crash the program by generating a long string pattern to determine the offset. based on the information from the above figure we can see that we required to provide 40 bytes of offset Fun stuff: now this where the fun stuff began write the following python script: as in the guideline of the challenged said we need to chain the function call by first to call the callme_one function, callme_two function and then callme_three funct...