32

Someone has hacked my database and has dropped the table.

In my PHP page there is one single query where I am using mysql_real_escape_string:

$db_host="sql2.netsons.com";
$db_name="xxx";
$username="xxx";
$password="xxx";    

$db_con=mysql_connect($db_host,$username,$password);    

$connection_string=mysql_select_db($db_name);
mysql_connect($db_host,$username,$password);    
mysql_set_charset('utf8',$db_con); 

$email= mysql_real_escape_string($_POST['email']);
$name= mysql_real_escape_string($_POST['name']);
$sex= mysql_real_escape_string($_POST['sex']);    

if($_POST['M']!=""){  $sim = 1;  }else {  $sim = 0;   }

$query = "INSERT INTO `users` (`email`, `name`, `sex`, `M`) VALUES
( '".$email."', '".ucwords(strtolower($name))."', '".$sex."','".$sim."')";    

$res = mysql_query($query) or die("Query fail: " . mysql_error() );

mysql_close($db_con);

And register_globals is disabled.

So, how was my database hacked?

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
xRobot
  • 25,579
  • 69
  • 184
  • 304

6 Answers6

66

mysql_real_escape_string

The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If no connection is found or established, an E_WARNING level error is generated.

As explain here : Does mysql_real_escape_string() FULLY protect against SQL injection?

Based on your code snippet, you have connected database twice.

$db_con=mysql_connect($db_host,$username,$password);    

$connection_string=mysql_select_db($db_name);
mysql_connect($db_host,$username,$password);    
mysql_set_charset('utf8',$db_con); 

And you did not supply the database link identifier for :

$email= mysql_real_escape_string($_POST['email']);
$name= mysql_real_escape_string($_POST['name']);
$sex= mysql_real_escape_string($_POST['sex']); 

Therefore, mysql_set_charset has no effect to real escape supplied$_POST for multi-bytes characters.

Suggestion

  • remove the second mysql_connect($db_host,$username,$password);
  • explicitly add $db_con when doing mysql_real_escape_string
Community
  • 1
  • 1
ajreal
  • 46,720
  • 11
  • 89
  • 119
  • 2
    dude very well explaned. +1 for your well explanation and links – Awais Qarni Aug 11 '11 at 13:05
  • 1
    Update October 2013: mysql_real_escape_string has been deprecated. Use mysqli_real_escape_string() or PDO::quote() – pablofiumara Oct 20 '13 at 12:17
  • A note for the possible readers. This "answer" doesn't explain how the database was hacked. Because for the code provided in the OP, it is impossible to inject anything. None of the encodings mentioned in the linked post are used, and therefore default latin1 is used, means this code is invulnerable. – Your Common Sense Sep 13 '16 at 09:02
6

It doesn't look like the code you pasted provides a suitable attack. The way I would investigate this is scan the MySQL binary logs for the relevant DROP TABLE statement, to give me a timestamp. Then you can use that timestamp to look for Apache requests you can correlate with it.

Then it's just a case of carefully auditing the code in each candidate request until you nail it :(

Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
4

Maybe you have a MySQL user with a weak password. I would change all passwords and check who is authorized to connect to the MySQL database. Lock down your firewall so that only needed ports are opened (80,443?)

Here is some articles about locking down your php code http://www.addedbytes.com/writing-secure-php/

Best regards. Asbjørn Morell

atmorell
  • 3,052
  • 6
  • 30
  • 44
  • 2
    Now a days, remote access to MySQL is disabled by default, and normally white listed as well, unless you have crappy host. – cyber-guard Nov 22 '10 at 10:18
  • `remote access to MySQL is disabled by default` - can justify this ? or provide more information on this ? – ajreal Nov 22 '10 at 10:20
  • When you install MySQL server, the remote access, i.e. logging in from computer other then the server where the MySQL daemon is running, will be disabled; this means that you must allow it explicitly. So even if person has MySQL username/password, they won't be able to take advantage of it and log in, unless they are able to execute code on the remote machine; in which case the security of the whole server is compromised completely anyway... Reused passwords for MySQL, FTP and SSH is totally different, although very imminent issue, but it has nothing to do with the security of MySQL itself. – cyber-guard Nov 22 '10 at 10:55
  • 1
    this is NOT true at least for linux box, is controlled by privileges instead. – ajreal Nov 22 '10 at 12:15
2

The fact your database has been compromised doesn't mean there was a sql injection. If you want, you can share the access log, which should provide enough clues as where the attacker got in. My guess would be local file inclusion, where he included the config file, or perhaps some kind of code execution vulnerability. Without more information it is just guessing though, it may as well have been good social engineering job, or phishing attack...

cyber-guard
  • 1,776
  • 14
  • 30
  • where can I see the access logs ? I have Cpanel and a shared hosting :) – xRobot Nov 22 '10 at 10:55
  • This highly depends on your host and cpanel version unfortunately. It is quite common to have them in a 'logs' directory in your root directory; and normally access via cpanel is also possible, look for 'server information/logs' etc... If you can't find them, I would suggest asking your hosting provider. – cyber-guard Nov 22 '10 at 11:06
  • 2
    Then I am afraid that the intruders most likely deleted the logs, so there is now way of finding out... You may still want to contact your hosting provider and request the logs, normally they keep copy which the clients don't have access to as well. Given that the attackers had possibly write access privilege, I would check the website for any backdoors that may be left behind, php shells etc. – cyber-guard Nov 22 '10 at 13:54
1

On the face of it, you haven't left any openings for an sql injection attack. Is this code excerpt definitely the one where the intrusion is taking place?

The only thing I can turn up is this ambiguous announcement from a hosting provider about ucwords: http://2by2host.com/articles/php-errors-faq/disabled_ucwords/

G

dartacus
  • 654
  • 1
  • 5
  • 16
0

I think this is done via php shell ( backdoor). Is that a sharing host? if so, check if other website on the same server are attacked too or not, this will help you to see if the attacker is getting into your site from your neighborhood. To see websites on your server you need reverse ip scan.

Alireza
  • 5,444
  • 9
  • 38
  • 50