简单修改emlog的checkcode.php给验证码增加干扰线和噪点 emlog

以下是在论坛看到ewceo的帖子里的,但是他并没有给出具体的代码,对于菜鸟们来说就不容易;

修改过程图览:00.png01.png023.png

鉴于 @奇遇 的反垃圾评论插件(哪怕是最新3.5版)经常被非法侵入式清空设置并报错,也不知是啥BUG,只好亲自动手来反击显示为国外IP的长篇英文评论了



首先分析状况:咱EMLOG的所有文章评论表单都是使用一个相同的提交地址,只是将文章ID赋在一个INPUT之中,这就给了机器人可趁之机:提交地址固定的、验证码地址固定的(还TM特好识别),文章ID是数字的随机生成就好,EMLOG的评论表单被模似简直是史上最轻松啊!所以JS之类的手段在机器人面前都是渣……



8错,在尚无给力插件问世的情况下,治标治本的办法只有改内核文件了:



第1步:英文垃圾评论一大特色就是长篇的并夹杂着火星文字,所以必含中文这样的反制也弱爆了,comment_controller.php文件定义评论最大字符数居然为8000,这是干神马的节奏,很多文章都够不到4000字好吧,发条微博和说说都不能超140字,所以偶赶紧给改为几百压压惊,上千字的精彩评论偶不需要啊



完成第一步还得紧接着做第2步:额,斗个胆,EMLOG默认的验证码偶能吐个槽么,生成的文字中规中矩且颜色清晰好辨,根本就是鸡肋嘛,除了给真心评论的人制造一道坎外,简直就是垃圾评论机器人的帮凶,还有比这更好自动识别的验证码么?checkcode.php唯一可赞之处似乎是不涉及字体文件,代码也比较精炼,这是偶所喜欢的风格,因此就没给彻底换掉,只是加了一点代码:增加几个随机线条,文字颜色范围也弄宽了点(为了防止人眼难识别,增加了点击刷新)……


如此2招之后偶就已经开始坐等机器人了,别的没啥,偶就是在线时间多,突然发现与垃圾评论玩玩策略对抗也有点意思,话说机器人若玩不过偶就暂不上后招咯



学过php的人应该很容易修改,我在这里把我修改过的粗略代码贴出来,便于不会的朋友借鉴,也便于会的朋友给我指点:

<?php
/**
 * Emlog图片验证码生成程序
 * @copyright (c) Emlog All Rights Reserved
 * Modify By Mrxn 
 * Emlog  Site: http://www.emlog.net/
 * Mrxn's Blog: https://mrxn.net/
 */

session_start();

$randCode = '';
$chars = 'abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPRSTUVWXYZ23456789';
for ( $i = 0; $i < 5; $i++ ){
    $randCode .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}

$_SESSION['code'] = strtoupper($randCode);

$img = imagecreate(75,25) or die("创建图像资源失败,请刷新页面");
$bgColor = isset($_GET['mode']) && $_GET['mode'] == 't' ? imagecolorallocate($img,245,245,245) : imagecolorallocate($img,255,255,255);
$pixColor = imagecolorallocate($img,mt_rand(88, 245), mt_rand(55, 240), mt_rand(99, 200));
//画字符、大小
for($i = 0; $i < 5; $i++){
    $x = $i * 13 + mt_rand(3, 7) - 2;
    $y = mt_rand(0, 3);
    $text_color = imagecolorallocate($img, mt_rand(100, 250), mt_rand(80, 180), mt_rand(90, 220));
    imagechar($img, 5, $x + 5, $y + 3, $randCode[$i], $text_color);
}
//画干扰点
for($j = 0; $j < 240; $j++){
    $x = mt_rand(0,100);
    $y = mt_rand(0,40);
    imagesetpixel($img,$x,$y,$pixColor);
}
//4条横斜线
for ($i=0; $i < 5; $i++) { 
    $lineColor = imagecolorallocate($img, rand(50, 150), rand(50, 150), rand(50, 150));
    $lineX1 = 0;
    $lineX2 = 80;
    $lineY1 = ($i + 1) * 8;
    $lineY2 = ($i + 1) * 15;
    imageline($img, $lineX1, $lineY1, $lineX2, $lineY2, $lineColor);
}

//4条竖斜线
for ($i=0; $i < 5; $i++) { 
    $lineColor = imagecolorallocate($img, rand(50, 150), rand(50, 150), rand(50, 150));
    $lineY1 = 0;
    $lineY2 = 30;
    $lineX1 = ($i + 1) * 8;
    $lineX2 = ($i + 1) * 15;
    imageline($img, $lineX1, $lineY1, $lineX2, $lineY2, $lineColor);
}

header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
将以上代码保存为[code]checkcode.php[/code]放在 你网站根目录/include/lib/下 覆盖,然后重启Apache或者是Nginx 即可看到效果(当然需要后台开启验证码)
为防止真正的读者不能识别验证码,请给验证码添加上 点击刷新 功能,
参考链接:给emlog5.3添加验证码刷新功能 https://mrxn.net/emlog-teach/242.html
[red]注:在进行DIY操作之前,请先备份相关文件,以防万一!本文基于emlog 5.31测试可行,理论上兼容所有版本,只要php版本不低于4[/red]
相关参考:
https://segmentfault.com/a/1190000002924386
http://bbs.emlog.net/thread-40567-1-1.html

对于反垃圾评论,也可以试试我这款插件:

https://mrxn.net/emlog-teach/emlog-math-comment-plugin.html

http://www.emlog.net/plugin/248



admin 发布于  2016-3-28 15:52 

给emlog5.3.1版本验证码添加点击刷新功能的方法 emlog

Emlog默认模板下验证码是没有点击刷新功能的,要刷新验证码的话还是得按F5刷新整个页面重新获得验证码,虽然emlog验证码看得比较清楚,但要通过重新刷新网页来获得新的验证码的方法对于网站负荷和用户体验来讲都并不合适,所以有必要给验证码添加点击刷新功能了。

    若要给emlog验证码添加点击刷新功能,还是很简单的,因为emlog的验证码也是img形式存在的,所以和其它类似的验证码一样,为img标签添加onclick属性就行了。

    Emlog有用到验证码的源代码有如下文件:

Emlog碎语:/t/index.php

Emlog评论:/include/controller/log_controller.php

Emlog管理后台登录:include\lib\loginauth.php


将以上文件的验证码位置的img标签添加以下语句即可实现点击刷新验证码功能:


<pre style="overflow:auto" ;class="prettyprint lang-php linenums">style=\"cursor:pointer;\" alt=\"未显示?请点击刷新\" title=\"看不清楚?请点击刷新\" onclick=\"this.src=this.src+'?'\"
如Emlog评论:/include/controller/log_controller.php, 有以下验证码源码:



<pre style="overflow:auto" ;class="prettyprint lang-php linenums"><img src=\"".BLOG_URL."include/lib/checkcode.php\" align=\"absmiddle\" /><input name=\"imgcode\" type=\"text\" class=\"input\" size=\"5\" tabindex=\"5\" />
改成如下代码即可添加上点击刷新验证码功能:



<pre style="overflow:auto" ;class="prettyprint lang-php linenums"><img src=\"".BLOG_URL."include/lib/checkcode.php\" align=\"absmiddle\" style=\"cursor:pointer;\" alt=\"未显示?请点击刷新\" title=\"看不清楚?请点击刷新\" onclick=\"this.src=this.src+'?'\" /><input name=\"imgcode\" type=\"text\" class=\"input\" size=\"5\" tabindex=\"5\" />
其它几个页面中添加验证码刷新功能方法类似,此略,注:此方法在em5.3.1正常使用,其他版本未测试。



另一种方法,来源于论坛,简爱发布:前提是当前模板要加载过 jQuery,没有的可以自己添加一下,直接在后台 添加统计代码的位置添加即可 (下面的代码 也在此位置添加,适用于全部正规模板)



<pre style="overflow:auto" ;class="prettyprint lang-php linenums"><font size="4" face="黑体">$('img[src="checkcode.php"]') // jQuery 筛选器
.attr('title', '单击刷新验证码') // 添加 title
.click(function(){ // 单击事件
this.src = this.src.replace(/\?.
$/, "") +'?'+ new Date().getTime(); // 重新设置 验证码 图片地址 checkcode.php?r=当前毫秒数
});</font>



admin 发布于  2015-8-2 15:16 

修复emlog绕过验证码刷评论的bug 代码人生

 最近博客常常被人刷评论,最狠的一次被刷了10000多广告。

    先看看评论验证码是怎么检查的。

    emlog/include/controller/comment_controller.php,先获得$imgcode:

<pre style="overflow:auto" ;class="prettyprint lang-php linenums">$imgcode = isset($_POST['imgcode']) ? addslashes(trim(strtoupper($_POST['imgcode']))) : '';

  检查:


<pre style="overflow:auto" ;class="prettyprint lang-php linenums">} elseif (ISLOGIN == false && Option::get('comment_code') == 'y' && session_start() && $imgcode != $_SESSION['code']) {
emMsg('评论失败:验证码错误');
}


上述代码,几个判断依次是:

  1. 没有登录(非管理员和作者)
  2. 后台开启了评论验证码
  3. 开启session
  4. 将session中的code与$imgcode比较,不相等则验证码错误


    第4步明显有问题。熟悉php验证码流程的同学应该清楚,验证码生成的时候将会设置一个session,这里就是code,再和POST过来的也就是用户输入的做比较。

    然而如果我们并没有访问验证码生成页面,那么也就没生成session。那么$_SESSION['code']就是NULL。

    php中==是弱类型比较,NULL和''(空字符串)比较的结果是TRUE的。

    所以这里,我们的$imgcode如果输入一个空值,并且不去访问生成验证码的页面,那么这个$imgcode != $_SESSION['code']就不成立,就不会提示验证码错误,从而绕过了验证码检查逻辑。

    所以,我这里做测试。

    先正常留言,填写验证码,中途抓包:

    QQ20150614-1@2x.png

    将PHPSESSID修改成随意一个值,目的是让其$_SESSION不存在。再将imgcode修改成空:

    QQ20150614-2@2x.png

    发送数据包,可见没有提示失败(302跳转了),说明评论成功:

    QQ20150614-3@2x.png

    载入一个字典,即可刷评论:

    QQ20150614-4@2x.png

    QQ20150614-5@2x.png


    修复方法是判断session是否为空:


<pre style="overflow:auto" ;class="prettyprint lang-php linenums">empty($_SESSION['code']) || $_SESSION['code'] != $imgcode


  不满足这个条件即提示错误。

    另外的方法是和我博客一样,使用第三方验证码,简洁又方便:极验

还有就是像我博客这样,增加一个打勾的措施也可以在一定程度上防止机器人刷评论.

注:  这只是对开了验证码的有效,没有开验证码想我博客这样的可以不修改.

原文地址:https://www.leavesongs.com/PENETRATION/emlog-comment-captcha-bypass.html


admin 发布于  2015-6-18 14:22