有人入侵了我的数据库 - 如何?

Someone has hacked my database - how?

提问人:xRobot 提问时间:11/22/2010 最后编辑:CerbrusxRobot 更新时间:11/9/2023 访问量:12051

问:

有人入侵了我的数据库并删除了该表。

在我的PHP页面中,有一个查询,我使用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);

并且被禁用register_globals

那么,我的数据库是如何被黑客入侵的呢?

php mysql sql 注入

评论

7赞 Haim Evgi 11/22/2010
stackoverflow.com/questions/1220182
1赞 cdhowie 11/22/2010
您的连接使用什么字符集?
5赞 jwueller 11/22/2010
看看PDO及其准备好的声明。这将为您节省大量时间和麻烦。
0赞 jwueller 11/22/2010
你为什么要使用两次?mysql_select_db()
5赞 11/23/2010
为什么在这个时代,有人会为SQL使用脑死亡的动态生成字符串?(实际有效的用例非常遥远,介于两者之间。

答:

1赞 dartacus 11/22/2010 #1

从表面上看,您没有为 sql 注入攻击留下任何机会。此代码摘录是否绝对是发生入侵的代码摘录?

我唯一能看到的是托管服务提供商关于ucwords的模棱两可的公告:http://2by2host.com/articles/php-errors-faq/disabled_ucwords/

G

4赞 atmorell 11/22/2010 #2

也许您有一个密码较弱的MySQL用户。我会更改所有密码并检查谁有权连接到MySQL数据库。锁定防火墙,以便仅打开所需的端口(80,443?

以下是一些关于锁定 php 代码的文章 http://www.addedbytes.com/writing-secure-php/

此致敬意。 阿斯比约恩·莫雷尔

评论

2赞 cyber-guard 11/22/2010
现在,默认情况下,对MySQL的远程访问是禁用的,并且通常也被列入白名单,除非您的主机很糟糕。
0赞 ajreal 11/22/2010
remote access to MySQL is disabled by default- 能证明这一点吗?或提供更多信息?
0赞 cyber-guard 11/22/2010
当您安装MySQL服务器时,远程访问,即从运行MySQL守护程序的服务器以外的计算机登录,将被禁用;这意味着您必须明确允许它。因此,即使人们拥有MySQL用户名/密码,他们也无法利用它并登录,除非他们能够在远程机器上执行代码;在这种情况下,无论如何,整个服务器的安全性都会完全受到损害......MySQL、FTP和SSH的重用密码是完全不同的,虽然问题非常迫在眉睫,但它与MySQL本身的安全性无关。
1赞 ajreal 11/22/2010
至少对于 linux 盒子来说,这不是真的,而是由特权控制的。
2赞 cyber-guard 11/22/2010 #3

您的数据库遭到入侵并不意味着存在 sql 注入。如果需要,可以共享访问日志,该日志应提供足够的线索,说明攻击者的进入位置。我的猜测是本地文件包含,他包含配置文件,或者可能是某种代码执行漏洞。如果没有更多信息,它只是猜测,它也可能是很好的社会工程工作,或者网络钓鱼攻击......

评论

0赞 xRobot 11/22/2010
在哪里可以查看访问日志?我有 Cpanel 和一个共享主机:)
0赞 cyber-guard 11/22/2010
不幸的是,这在很大程度上取决于您的主机和 cpanel 版本。将它们放在根目录的“logs”目录中是很常见的;通常也可以通过cPanel访问,查找“服务器信息/日志”等...如果您找不到它们,我建议您询问您的托管服务提供商。
2赞 cyber-guard 11/22/2010
那么恐怕入侵者很有可能删除了日志,所以现在有办法找出来......您可能仍想联系您的托管服务提供商并请求日志,通常他们会保留客户端也无法访问的副本。鉴于攻击者可能具有写入访问权限,我会检查网站是否有任何可能留下的后门、php shell 等。
6赞 Paul Dixon 11/22/2010 #4

看起来您粘贴的代码没有提供合适的攻击。我对此进行调查的方法是扫描MySQL二进制日志中的相关DROP TABLE语句,以给我一个时间戳。然后,您可以使用该时间戳来查找可以与之关联的 Apache 请求。

然后,只需仔细审核每个候选请求中的代码,直到您确定它:(

66赞 ajreal 11/22/2010 #5

mysql_real_escape_string

MySQL 连接。如果未指定链接标识符,则假定 mysql_connect() 打开的最后一个链接。如果没有找到这样的链接,它将尝试创建一个链接,就好像调用了 mysql_connect() 而不带参数一样。如果未找到或未建立连接,则会生成E_WARNING级错误。

正如这里解释的那样:mysql_real_escape_string()是否完全防止SQL注入?

根据代码片段,您已经连接了两次数据库。

$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']); 

因此,mysql_set_charset对为多字节字符提供的实际转义没有影响。$_POST

建议

  • 删除第二个mysql_connect($db_host,$username,$password);
  • 在执行时显式添加$db_conmysql_real_escape_string

评论

2赞 Awais Qarni 8/11/2011
伙计解释得很好。+1 为您的井解释和链接
1赞 pablofiumara 10/20/2013
2013 年 10 月更新:mysql_real_escape_string 已被弃用。使用 mysqli_real_escape_string() 或 PDO::quote()
0赞 Your Common Sense 9/13/2016
给可能读者的说明。这个“答案”并没有解释数据库是如何被黑客入侵的。因为对于 OP 中提供的代码,不可能注入任何东西。链接帖子中提到的编码均未使用,因此使用默认的 latin1,这意味着此代码是无懈可击的。
0赞 Alireza 8/24/2012 #6

我认为这是通过php shell(后门)完成的。 那是共享主机吗?如果是这样,请检查同一服务器上的其他网站是否也受到攻击,这将帮助您了解攻击者是否从您的邻居进入您的网站。要查看服务器上的网站,您需要反向 IP 扫描。