查看: 18393|回复: 15

由一张不科学的图片说起

[复制链接]
  • TA的每日心情
    无聊
    2020-8-3 22:39
  • 签到天数: 84 天

    [LV.6]常住居民II

    发表于 2013-9-1 16:11:41 | 显示全部楼层 |阅读模式
    本帖最后由 Free_小东 于 2013-9-1 16:16 编辑

    【转载本文不写出处的,男的木丁丁,女的满脸都是丁丁】

    昨晚上偶然看到个比较坑爹的日志,正文有一张图片,在好友动态列表查看的时候可以显示自己(不是发日志的好友,是你自己)的头像和QQ号码、昵称。正文的文字称,这是“本年度最给力神奇魔力日志(转载会看到你最熟悉的身影)”,并且在文章底部附加了一个发广告的QQ号码。

    由于这张坑爹图片的存在,文章转发量短短三天内过千。这招可比那些疯狂加群发广告的来的更有创意和杀伤力,转载传播图片(包括日志当中的广告)的人几乎是全网用户(跟所谓病毒营销差不多了)。好奇的话可以看这篇日志最初来源:hXXp://user.qzone.qq.com/732678621/blog/1363502247

    一看就知道是检测referer的把戏。早在几年前BBS还在流行的时候,很多人设置的签名图具有天气预报、客户端信息(浏览器、操作系统、IP所在地之类)、随机笑话、倒计时等五花八门的功能。这都得益于服务器端脚本的图像处理功能。而客户端的检测则是基于HTTP请求中的UserAgent和Referer等信息。

    但是印象中QQ空间为了防止referer潜在的安全问题和防止图片被防盗链瞎了很大功夫,凡是发表到QQ空间的日志,正文都会把引用到的所有第三方图片资源缓存到腾讯的云端上。所以直接在日志正文中引用的图片,是不会提交REFER到我们的服务器脚本上的。

    文中特别称,“请转载后用电脑进入个人中心看”。为什么要特别说明是“个人中心”呢?我刷新了好久的动态,终于看到了图片所说的效果。页面生成的DOM代码为:
    [HTML] 纯文本查看 复制代码
    <img src="http://qq.sennvwu.com/qzone/do.php"
     onload="QZFL.media.reduceImage(0,400,300,{trueSrc:'http:\/\/qq.sennvwu.com\/qzone\/do.php',callback:function(img,type,ew,eh,o){var _h = Math.floor(o.oh/o.k),_w = Math.floor(o.ow/o.k);if(_w&lt;=ew &amp;&amp; _h&lt;=eh){var p=img.parentNode;p.style.width=_w+'px';p.style.height=_h+'px';}}})"
     width="400">

    原来QQ空间还是会显示源地址的图片的,仅限于在“个人中心”。这时候请求图片附带的HTTP_REFERER的值为
    [AppleScript] 纯文本查看 复制代码
    http://user.qzone.qq.com/123456789/infocenter

    号码就是这样提取到的。如果REFERER不满足条件,这个php将在header中发送Location跳转到同一目录下的no.png。

    那么后台是如何取到QQ头像、昵称等信息的呢?我Google到了一个腾讯的WebService接口:
    http://base.qzone.qq.com/fcg-bin ... .fcg?uins=123456789

    不需要任何凭证信息即可获取uins指定的QQ号码的头像、昵称信息,返回的格式为JSON。另外上面的图片还有一个显示地理位置和ISP的功能,这个就比较常见了。我找到了一个比较好用的接口,来自TB:
    http://ip.taobao.com/service/getIpInfo.php?ip=127.0.0.1

    格式同样也是JSON。

    接下来实现这个效果就比较简单了,通过REFERER检测用户的QQ号码,然后在后台下载头像、昵称等信息,用GD函数绘制上图片,返回客户端。

    我也折腾了一个‘神奇图片“发到空间,居然捉弄了一群人。下面是php语言的实现代码。为了减少后端的流量,对下载的头像做了缓存处理:
    [PHP] 纯文本查看 复制代码
    <?php
    error_reporting(0);
    ob_start();
    header('Content-Type: image/png');
     
    define('IMG_NO', "no.png"); #刚开始显示的提示信息
    define('IMG_BACKGROUND', "background.png");
    define('IMG_WIDTH', 400);
    define('IMG_HEIGHT', 128);
    define('FONT_NAME', "AdobeHeitiStd-Regular.otf"); #字体文件名
    define('CACHE_PATH', rtrim(realpath("./cache"), '/').'/'); #缓存目录
    define('CACHE_EXPIRE', 60*60); #缓存时间,单位秒
     
    #(!is_dir(CACHE_PATH) && is_writable(CACHE_PATH)) || die;
     
    /*
     $remote: 远程URL
     $local: 本地缓存路径
     $expire: 过期时间。为-1时,永久不更新缓存
    */
    function load_from_cache($remote, $local, $expire = CACHE_EXPIRE, $as_path = false) {
     //过滤潜在的危险字符
     $local = preg_replace("/[.\/\\\?\*\'\"\|\:\<\>]/", "_", $local);
     $cache = CACHE_PATH.$local;
     //查找缓存
     if(file_exists($cache) && ($expire = -1 || filemtime($cache) - time() < $expire))
     return $as_path ? $cache : file_get_contents($cache);
     
     //文件不存在或缓存过期,重新下载
     $content = file_get_contents($remote);
     file_put_contents($cache, $content);
     return $as_path ? $cache : $content;
    }
     
    /*
     返回客户端信息。
    */
    function client_info() {
     $url = "http://ip.taobao.com/service/getIpInfo.php?ip=";
     $ip = ($_SERVER["HTTP_VIA"] && $_SERVER["HTTP_X_FORWARDED_FOR"] ?
     $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"]);
     $info = explode('"', load_from_cache($url.$ip, $ip, -1));
     $string = $info[7].$info[23].$info[31].$info[47];
     return json_decode('"'.$string.'"');
    }
     
    $referer = $_SERVER['HTTP_REFERER'];
    //$referer = "http://user.qzone.qq.com/123456789/infocenter";
     
    $pattern = "/http:\/\/user.qzone.qq.com\/(\d+)\/infocenter/";
    if(preg_match($pattern, $referer, $matches)) {
     //获取QQ号码
     $uin = $matches[1];
     $info = explode('"', load_from_cache(
     "http://base.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?uins=".$uin, $uin));
     $avatar = $info[3];
     $nickname = iconv("GBK", "UTF-8//IGNORE", $info[5]);
     $client = client_info();
     
    //重点来了,生成图片
     try{
     $im = imagecreatefrompng(IMG_BACKGROUND);
     
    //绘制头像
     $avatar_file = load_from_cache($avatar, $uin.".jpg", 60*60*24, true);
     $im_avatar = imagecreatefromjpeg($avatar_file);
     imagecopymerge($im, $im_avatar, 14, 14, 0, 0, 100, 100, 100);
     imagedestroy($im_avatar);
     
    //绘制文字
     $blue = imagecolorallocate($im, 0, 0x99, 0xFF);
     
    $white = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);
     
    $texts = array(
     array(12, 148, 40, $white, $uin),
     array(18, 125, 70, $blue, $nickname),
     array(16, 125, 100, $blue, $client)
     );
     
    foreach($texts as $key=>$value) {
     imagettftext($im, $value[0], 0, $value[1], $value[2], $value[3], FONT_NAME,
     mb_convert_encoding($value[4], "html-entities", "utf-8")); //解决乱码问题
     }
     
    imagepng($im);
     imagedestroy($im);
     
    header("Content-Length: ".ob_get_length());
     ob_end_flush();
     } catch (Exception $e) {
     
    //die($e->getMessage());
     $error = true;
     }
    } else {
     $error = true;
    }
     
    if($error){
     header('Content-Length: '.filesize(IMG_NO));
     echo file_get_contents(IMG_NO);
    }

    游客,如果您要查看本帖隐藏内容请回复

    评分

    参与人数 3i币 +10 收起 理由
    小白菜 + 2 还是不懂如何制作..
    90_ + 4 打赏你的
    Sinboy + 4 楼主很有探索精神~

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情

    2021-9-9 23:35
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2013-9-1 19:12:45 | 显示全部楼层
    好像魔方日志
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2013-9-1 19:48:51 | 显示全部楼层
    一直想弄清这原理,只不过自己技术不行
    回复 支持 反对

    使用道具 举报

    水寒 该用户已被删除
    发表于 2013-9-1 20:56:18 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2015-6-15 16:33
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2013-9-1 22:45:11 | 显示全部楼层
    看看,这个就是小东?读高五的娃娃?

    点评

    傻屌 你听90扯淡  详情 回复 发表于 2013-9-2 00:13
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2020-8-3 22:39
  • 签到天数: 84 天

    [LV.6]常住居民II

     楼主| 发表于 2013-9-2 00:13:06 | 显示全部楼层

    RE: 由一张不科学的图片说起

    浩森 发表于 2013-9-1 22:45
    看看,这个就是小东?读高五的娃娃?

    傻屌  你听90扯淡
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-6-21 14:48
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2013-9-2 12:56:41 来自手机 | 显示全部楼层
    来看看看咯。原来如此
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2016-12-17 22:59
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    发表于 2013-9-15 19:44:37 | 显示全部楼层
    不错。。。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2015-12-28 00:09
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2013-9-16 10:41:28 | 显示全部楼层
    似乎我看懂了。以前我也一直想了解这个原理。
    回复 支持 反对

    使用道具 举报

    Snakey 该用户已被删除
    发表于 2013-9-16 15:50:14 来自手机 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-12-24 04:06 , Processed in 0.032584 second(s), 23 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部