我怎么被黑了?

时间:2013-04-29 16:28:16

标签: php mysql session

我在一个文件中有以下代码,当变量$action等于某个值时,会向数据库添加一条消息,然后向用户发送一封电子邮件,通知他们该消息。简单。

在过去几天中,数据库中添加了垃圾邮件,并向用户发送了电子邮件,通知他们有新邮件。不是很多而不是一次全部,只是随机时间和内容,但显然是垃圾邮件。

我设置脚本,以便如果$from变量不等于0,那么就不要继续,但它似乎以某种方式绕过了(所有黑客条目进入db show from_userid = 0

我正在使用Cookie来检查用户是否已登录 - 当用户登录cookie时已设置。

问题:有什么地方我可以看看我是如何被黑客攻击的,如果我使用的是会话而不是cookie,会阻止文件被访问/攻击吗?

下面是代码:

// check a user logged in as soon as file accessed
if (!isset($_COOKIE['cookieName'])) { header("Location: /userlogin.html); }

现在检查$action变量并继续

$action = $_POST['action'];

if (($action=='contact') && ($_POST['from'])){ // AA

    require_once '/home/php/lib/setup.inc';
    require_once '/home/php/lib/dbconnect.inc';

    $from = mysql_real_escape_string($_POST['from']);
    $to = mysql_real_escape_string($_POST['to']);
    $from_name = mysql_real_escape_string($_POST['from_name']);
    $body = mysql_real_escape_string($_POST['body']);
    $reply_id = mysql_real_escape_string($_POST['reply_id']);

    $body = nl2br($body);

    // add message to db

    if($from!='0'){ // BB

        $additem = mysql_query("
            insert into user_messages (
            from_userid,
            to_userid,
            from_name,
            message_contents,
            reply_to_id,
            msg_read
            )
            VALUES (
            '$from',
            '$to',
            '$from_name',
            '$body',
            '$reply_id',
            'No'
            )",$db
        );

        if(!$additem) { echo mysql_error(); exit; } // debug

        // send email notif for message
        $result20 = mysql_query("select name, emailaddr from users where (user_id = '$to')",$db);
        if(!$result20) { echo 'result error'; echo mysql_error(); exit; } // debug
        $databack20 = mysql_fetch_array($result20);
        $title = 'title';
        $currentdate = date("d");
        $month = date("m");    // "02"
        $currentmonth = date("F", mktime(0, 0, 0, $month)); 
        $currentyear = date("Y");
        $email = file_get_contents('/home/public_html/pages/html_email_templates/buddymessage.php');
        $email = str_replace(">name<","$from_name",$email);
        $email = str_replace(">name2<","$databack20[name]",$email);

        // setting Content-type header
        $headers  = 'MIME-Version: 1.0' . "\r\n";
        $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

        // Additional headers
        $headers .= 'From: siteName <info@siteName.com>' . "\r\n";

                    //send mail
        mail("$databack20[emailaddr]", "siteName Message", "$email", "$headers");

        $success = "Message sent to $databack20[name]";

    } // BB

} // AA

3 个答案:

答案 0 :(得分:5)

这里真正的问题似乎是任何人都可以提交任何POST请求,而您不会检查它是否真的是他们。 真的很容易制作一个执行以下操作的机器人(并在00而不是from中使用0,因此绕过了您的“安全” - 我建议投射改为使用int:$from = (int)$from,然后检查if ($from > 0),但这不是你真正的问题):

  

POST http://www.domain.com/contact.php
  行动= <强>接触&安培;
  从= <强> 00 &安培;
  体= 垃圾&安培;
  FROM_NAME = <强>垃圾邮件发送者&安培;
  到= <强> 1

     

POST http://www.domain.com/contact.php
  行动= <强>接触&安培;
  从= <强> 00 &安培;
  体= 垃圾&安培;
  FROM_NAME = <强>垃圾邮件发送者&安培;
  to = 2 &lt; - 在循环中永远增加

它甚至可以用PHP编写,如下所示:

<?php
    $curlHandle = curl_init();

    for ($i = 1; $i < 10000; $i++) {
        curl_setopt_array($curlHandle, array(
            CURLOPT_URL            => "http://www.domain.com/contact.php",
            CURLOPT_POST           => true,
            CURLOPT_COOKIE         => "cookieName: yep",
            CURLOPT_POSTFIELDS     => array(
                "action"    => "contact",
                "from"      => rand(1, 10000),
                "to"        => $i,
                "body"      => "Spam",
                "from_name" => "Spambot"
            )
        ));
        curl_exec($curlHandle);
    }
?>

所以你应该检查一下$_SESSION cookie来查看它的来源。也许还限制一个人只能每隔 nth 分钟发送一条消息。

答案 1 :(得分:0)

如果没有关于攻击者方法的内幕知识,我们无法直接回答&#39;题。但是,这里有一些可能有用的步骤。

PHP已弃用mysql_*函数,转而使用PDO。您应该更新代码以使用PDO来利用它提供的新安全功能。

此外,请验证对数据库的访问权限是否已受到损害。您可能需要检查数据库日志以查找意外登录事件。

与此同时,在重写代码时,请考虑使用更安全的$ _SESSION调用替换以下行:

if (!isset($_COOKIE['cookieName'])) { header("Location: /userlogin.html); }

使用此代码时,恶意用户可以创建cookie以绕过您的登录要求。

答案 2 :(得分:0)

您的问题是攻击者在那里填写一个非整数值,该值由数据库转换为整数:零。

检查$from是否为整数:

if ($from > 0 && (string)((int)$from) === $from) { /* ... */ }

P.s。:您应该将用户数据存储在$_SESSION中,而不是让用户可以操纵隐藏的输入。