【问题标题】:Someone has hacked my database - how?有人入侵了我的数据库 - 如何?
【发布时间】:2011-05-13 17:17:39
【问题描述】:

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

在我的 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禁用

那么,我的数据库是如何被黑的?

【问题讨论】:

  • 您的连接使用什么字符集?
  • 看看 PDO 及其准备好的语句。它会为您节省大量时间和麻烦。
  • 你为什么使用mysql_select_db()两次?
  • 为什么,在这个时代,还有人使用脑死亡的 SQL 动态生成字符串? (实际有效的用例非常遥远。)

标签: php mysql sql-injection


【解决方案1】:

mysql_real_escape_string

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

解释如下:Does mysql_real_escape_string() FULLY protect against SQL injection?

根据您的代码 sn-p,您已经连接了两次数据库。

$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);
  • 在做mysql_real_escape_string时明确添加$db_con

【讨论】:

  • 老兄解释得很好。 +1 为您提供良好的解释和链接
  • 2013 年 10 月更新:mysql_real_escape_string 已被弃用。使用 mysqli_real_escape_string() 或 PDO::quote()
  • 给可能的读者的说明。这个“答案”没有解释数据库是如何被黑客入侵的。因为对于 OP 中提供的代码,不可能注入任何东西。没有使用链接帖子中提到的任何编码,因此使用默认的 latin1,这意味着该代码是无懈可击的。
【解决方案2】:

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

那么这只是一个仔细审核每个候选请求中的代码直到你确定它的情况:(

【讨论】:

    【解决方案3】:

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

    这里有一些关于锁定 php 代码的文章 http://www.addedbytes.com/writing-secure-php/

    最好的问候。 阿斯比约恩·莫雷尔

    【讨论】:

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

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

    【讨论】:

    • 在哪里可以看到访问日志?我有 Cpanel 和共享主机 :)
    • 不幸的是,这在很大程度上取决于您的主机和 cpanel 版本。将它们放在根目录的“日志”目录中是很常见的;并且通常也可以通过 cpanel 访问,查找“服务器信息/日志”等...如果找不到,我建议您询问您的托管服务提供商。
    • 那么我担心入侵者很可能删除了日志,所以现在有办法找出来......您可能仍然想联系您的托管服务提供商并请求日志,通常他们会保留副本客户也无法访问。鉴于攻击者可能具有写访问权限,我会检查网站是否存在任何可能留下的后门、php shell 等。
    【解决方案5】:

    从表面上看,您没有为 sql 注入攻击留下任何漏洞。这段代码摘录肯定是入侵发生的地方吗?

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

    G

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 2012-02-06
        • 1970-01-01
        • 2015-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-30
        相关资源
        最近更新 更多