Fooling app with MockServer (HTTPS)

Sometimes the app’s communication is written in a way that cannot be intercepted by Burp Suite, OWASP ZAP, etc. but it’s still HTTPS communication. For example, I wrote an app that can download a site, but its traffic cannot be seen via proxy.

After clicking download you see source code of the site. 

It’s time to check from what server our target app downloads data. In most cases, such an  app will use its domain name and not the IP, so there’re many ways to check that domain’s name. You can, e.g. check DNS tables, look for DNS communication, etc.

However, in this case we will be checking the domain’s name out in the apps files. I’d advise to search for the “https://” through the binary data to find links.

Now we see the app has been downloadedexample.com domain. App the domain name translated to IP via system, and it will be really useful to convince the system to translate the domain name to our hacker PC. It’s possible to spoof DNS remotely, but a simpler way is to edit /etc/hosts file that contains static translations.

After checking via ping, our device thinks example.com is our hacker device.

So, now the app will not download the source from example.com and in case we don’t have implemented any service on port for HTTPS, the app will hang.

It’s finally time to create our fake server which will provide the same data as provided by the original server. We, of course, will not create a copy of the server, but we will create a fake server that will copy the request from the client, send to the original server and return to the client a copied response like a proxy.

To accomplish this, we will use Mock Server

Files:

  • ./mockserver.jar – jar file form https://www.mock-server.com/
  • ./mockserver.properties – configuration file
  • ./certs/CertificateAuthorityCertificate.pem – ssl cert for our server
  • ./certs/PKCS8CertificateAuthorityPrivateKey.pem – ssl key for our server

[mockserver.properties]

# Certificate Generation

# dynamically generated CA key pair (if they don't already exist in specified directory)
mockserver.dynamicallyCreateCertificateAuthorityCertificate=false
# save dynamically generated CA key pair in working directory
mockserver.directoryToSaveDynamicSSLCertificate=./certs/
# certificate domain name (default "localhost")
mockserver.sslCertificateDomainName=localhost
# comma separated list of ip addresses for Subject Alternative Name domain names (default empty list)
mockserver.sslSubjectAlternativeNameDomains=www.example.com,www.another.com
# comma separated list of ip addresses for Subject Alternative Name ips (default empty list)
mockserver.sslSubjectAlternativeNameIps=127.0.0.1
mockserver.certificateAuthorityPrivateKey=./certs/PKCS8CertificateAuthorityPrivateKey.pem
mockserver.certificateAuthorityCertificate=./certs/CertificateAuthorityCertificate.pem


# CORS

# enable CORS for MockServer REST API
mockserver.enableCORSForAPI=true
# enable CORS for all responses
mockserver.enableCORSForAllResponses=true

You can generate keys and certs by command:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout PKCS8CertificateAuthorityPrivateKey.pem -out CertificateAuthorityCertificate.pem

You can generate keys and certs by command:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout PKCS8CertificateAuthorityPrivateKey.pem -out CertificateAuthorityCertificate.pem

Remember to install a certificate as the system certificate on the target device to fool app that the certificate is valid and approved.

Time to start a fake server. Port 443 because is an HTTPS port, and we also want to copy example.com also from port 443.

java -jar mockServer.jar -serverPort 443 -proxyRemotePort 443 -proxyRemoteHost example.com

Now we can click download in the app, and we will see a normal response.

And also in the terminal we can see request and response, but it is not easy to read it in this form. 

However, MockServer has a web dashboard which can be used via browser with address

<ip>:<port>/mockserver/dashboard

If you expand FORWARD_REQUEST, you can see our request from app.

But now, we also need to replace some responses, so I created a file, “responses.json”…

[
  {
    "httpRequest": {
      "path": "/"
    },
    "httpResponse": {
      "body": "hacked by mock server"
    }
  }
]

and started MockServer with one more argument:

java -Dmockserver.initializationJsonPath="./responses.json" -jar mockServer.jar -serverPort 443 -proxyRemotePort 443 -proxyRemoteHost example.com

Now, the app will replace responses for path “/” and after clicking “Download” we can see that the app will display “hacked by mock server” instead of site source code.

Leave a Reply

Your email address will not be published.