作者归档:Jacob Nie

腾讯网站检测QQ浏览器状态相关分析

原理介绍:

  1. 浏览器是可以通过ActiveX, PPAPI来跟本机已经存在的DLL通讯的
  2. 浏览器默认检测系统盘下Porgram Files\Common Files的所有DLL,并加载扩展到其插件系统中,Chrome下可以通过chrome://plugins/查看相关插件
  3. DLL可以访问QQ客户端的状态
实现方式:
  1. QQ在安装的时候将需要的插件安装到C:\Program Files (x86)\Common Files\Tencent\,其中TXSSO只是其插件之一
  2. Chrome 浏览器在安装好以后会检测C:\Program Files (x86)\Common Files\下的所有插件,并加载启用,可以通过chrome://plugins/启用和停用
  3. 在访问腾讯需要登录网站的时候,加载sso.js,主动调用Chrome下的腾讯所属插件,实现检测QQ是否在线的通讯
浏览器兼容:
  1. 首先判断是否兼容ActiveX,如果兼容则以ActiveX的方式调用DLL
  2. 再判断是否存在MIME为application/nptxsso类型的插件,存在则以该种方式调用DLL
  3. 如果以上两种都不属于,则放弃检测
相关下载: sso.js

L2TP类VPN配置

昨天说了怎么样配置PPTP类VPN,不幸的是昨天晚上我为了设置防火墙,把自己也设置到了外面,直到今天早上才得到技术的支持,把昨天设置的VPN都给取消了。我重新按照我昨天记录的设置了一遍,但怎么测试都没能成功,无论手机还是笔记本都连不上,但到最后的关键时刻,我把公司的WIFI给关掉,直接使用手机的3G网络,竟然成功了, 我们的网络不支持VPN连接?

后面我带着这个疑问找了我们的机房管理人员,他没有给我解释什么,也没有说怎么样解决我的问题,只是说他目前也在使用VPN,而且使用我们的无线网络是可以连接的,然后就演示给我看连接的方法,我才发现他使用的是L2TP类的设置,我依希忘记好像在服务器上看到过这类的设置,于是也没就有多想,直接查找怎么样设置L2TP了
设置很快完成了,但还是不能正常使用,报789的错误代码,无法进入加密通讯 ,整个网络都找遍了,说要开启IPsec服务,但我看我的笔记本上的是开启的,一直找不到问题的所在,但我却知道并不是什么大问题。终于我偶然看到了服务器端的IPsec服务并没有启用,于是启用一下,结果还是不行,就在我快要想不出来办法的时候,我就死马当活马医,把VPN服务也重启了一下,成功了!
配置L2TP主要设置一下预置密码:
  • win + r – rrasmgmt.msc /s – 确定,右击“本地”-安全标签,勾选并设置共享密钥
  • 当然如果不使用第一步的密钥,可以使用证书,我没有实际操作,因为这样设置会更方便在手机上使用

VPS架设VPN

所谓有压迫才有反抗,我一直使用的bitbucket.org网站最近一段时间不稳定,我电脑上已经积累了很多代码没有提交了,这是一个非常不安全的问题。但无奈我翻墙只使用了SSH的代理方式,没办法将全局设置成翻墙模式,于是我想到了VPN,但网上的一些所谓免费VPN要么不能用,要么速度非常的慢,于是我想利用我自己的VPS架设一台VPN服务器,而结果,成功了,速度非常的好!下面介绍一下架设的方法(以WINDOWS 2003为例)

  1. 关闭防火墙(这个目前的原因我也不太清楚为什么,但好像VPN跟防火墙使用的路由是有冲突的,所以必须关闭防火墙服务,win + r – services.msc- 确定,找到Windows Firewall/Internet Connection Sharing (ICS),停止加禁用
  2. win + r – rrasmgmt.msc /s – 确定,右击“本地”-配置并启用路由和远程访问-下一步-自定义配置-VPN访问-下一步-确定
  3. 右击“本地” – 属性 – IP标签 – 静态IP地址 – 输入一个IP范围(如192.168.1.100-192.168.1.200)-确定 -确定
  4. win + r – compmgmt.msc /s – 确定,本地用户和组,新建用户vpn,设置密码
  5. 右击vpn用户-属性-拨入标签-允许拨入;到此为止可以成功使用客户端拨号到服务器,但无法上网
  6. 本地-IP路由选择-常规-选择“新增路由协议”-选择“NAT/基本防火墙”然后右键“NAT/基本防火墙”-新建接口-选择“本地连接”-然后将其”设置为公用接口连接至internet”-勾上“在此接口上启用NAT”

其中第6步是完成上网的重要一步,如果此时还是无法解析dns,则可以单独设置拨号的DNS为8.8.8.8

配置界面

Windows Server 2003下nginx的安装与配置,反向代理tomcat应用

IIS6.0如果仅作为中间件的话是一个不错的选择,但想要完成反向代理等复杂的功能则还是需要一个更简便的应用服务器nginx

  1. 下载nginx
  2. 双击nginx.exe就可以启动了
  3. 修改conf/nginx.conf后,直接使用nginx.exe -s reload就可以重新加载了
  4. 要想关闭nginx 使用 nginx.exe -s stop或者nginx.exe -s quit
  5. 想要关闭nginx的ip访问,可以新建一个default server,将流量导向你自己的网站或返回错误代码(404,500),配置如下

a. 导向自己的网站

server {
    listen 80 default;
    rewrite ^(.*) http://blog.tohours.com permanent;
}

b. 返回500错误

server {
    listen 80 default;
    return 500;
}
  1. tomcat下载windows zip版的时候,要选择32-bit Windows zip的版本才有service.bat
  2. service.bat install Tomcat就可以把tomcat 安装成服务
  3. 如何把nginx安装成服务呢?下载winsw-1.8-bin.exe
  4. 更改名字为myapp.exe,放到nginx目录,新建myapp.xml文件,内容如下(修改为你的路径)
<service>
    <id>nginx</id>
    <name>nginx</name>
    <description>nginx</description>
    <executable>c:nginxnginx.exe</executable>
    <logpath>c:nginx</logpath>
    <logmode>roll</logmode>
    <depend></depend>
    <startargument>-p c:nginx</startargument>
    <stopargument>-p c:nginx -s stop</stopargument>
</service>
  1. 运行myapp.exe install,将会把nginx安装成nginx的服务
  2. 配置nginx到tomcat的代理,很遗憾,没找到 xxx.tohours.com到localhost:8080/xxx的写法
server {
    listen 80;
    server_name xxx.tohours.com;
    location / {
        proxy_pass http://localhost:8080/;
        proxy_redirect     off;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_max_temp_file_size 0;
        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;
        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
    }
}

另外介绍一款工具,可以将Windows下的可执行文件变成服务:Windows Server 2003 Resource Kit Tools,具体使用方法参见这里

主要命令两个
1. instsrv Nginx c:\nginx\nginx.exe;
2. instsrv Nginx remove(当然nginx不适合这个建服务,因为nginx会提供两个进程,启动时会报错,结束时无法正确结束)

利用VisualSVN Server和hooks来实现原型提交自动同步到原型服务器

要解决的问题:设计师在页面开发完成后通过svn将页面提交到指定的目录,开发人员虽然可以从svn中获得一个拷贝,但对客户来说装个svn客户端是不现实的,所以需要一个实时的在线查看地址;

由于VusualSVN Server支持在线查看,所以如果将apache跳转到相应的页面地址,修改header返回Content-Type: text/html应该能够正常显示(但这不是我们讨论范围)

解决方法:
1、配置svn的Path属性,指向本地VisualSVN Server下的bin目录
2、win + r, 输入services.msc,找到VisualSVN Server,使用管理员账户登录
image-767262
3、书写脚本到Post-commit hook中,内容如下
image-2
set WORKING_COPY=E:\wwwroot\项目名称\
svn update %WORKING_COPY% –username xxx –password xxx
4、配置iis,将prototype.xxx.com指向wwwroot
5、当项目中有提交的时候,就会及时更新到prototype.xxx.com在线地址

MySql悬案,井号(#)和分号(;)造成的问题

来源:http://blog.tohours.com/2013/05/mysql.html

以下两个简单的insert语句,每一个单独执行都能成功,但按如下的顺序写到Navicat 8 for MySql中执行,第一句插入成功,第二句报如下错误:

[Err] 1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”’ at line 6

INSERT INTO manufacturer
  (manu_id,
   intro)
VALUES
  (130,
   ‘
#
‘);
INSERT INTO manufacturer
  (manu_id,
   intro)
VALUES
  (147,
   ‘;’);

要满足的条件:

  1. 带#的那句在前面
  2. #在一个新行的开始位置
  3. 后面一句中必须要有;出现
一个不满足都能执行成功,但实在想不明白中间的蹊跷……

使用blogger搭建自己的博客

来源:http://blog.tohours.com/2013/05/blogger.html

  1. 新建一个blogger,通过https://blogger.com可以直接访问
  2. 绑定一个域名,如我的就绑定blog.tohours.com
  3. 配置apache跳转,需要配置两个 ,一个是用来做中转到ghs.google.com的,另外一个是用来解决图片显示问题的,配置如下图:image-773968
  4. 修改模板的代码,去掉不能访问的谷歌服务,增加友言,加网等社会化评论
  5. 最终形成我目前的博客风格,可以使用gmail直接发布,但要做的一点是修改图片的地址

由request.getRemoteAddr()所想到的ip欺骗

跟一同事讨论,使用request.getRemoteAddr()来作为权限判断的安全程度,于是想知道是否可以通过ip欺骗来绕过。开始的时候先查找在http请求头部会不会出现ip的信息,结果证实是不会出现的。然后又再再看一下request.getRemoteAddr()方法是如何实现的,结果是j2ee只提供了接口,具体实现是由相应的容器来完成的。那我就推断这个ip地址是从ip包的source来的。

那我在传送http请求的时候,是否可以来更新source ip 来完成欺骗呢?如果你不在意对方的响应,是可以这样做的。黑客进行的DoS攻击就是这样来完成的。但我们模拟请求,当然想得到一些数据,但你把source ip给修改了,返回的信息是不会到你这台服务器上的,所以具体实现也是很难的。

那么这样说来这种方法做作权限验证是安全的?也不全对,如果是独立ip地址的服务器,中间不经过任何的反向代理,是安全的。如果你使用了一些框架,又没有反向代理,这种就不太安全了。经过反向代理服务器的时候由于转发时候会把source ip改成代理服务器的ip地址,所以你直接获取request.getRemoteAddr()是不一定能获得客户端的地址,于是代理服务器会在头部加上X-Forward-For的信息,来标识原始服务器的ip信息,框架会先判断是否有X-Forward-For,如果有则以X-Forward-For为准。如果这时你没有使用代理服务器,而框架又做了如此判断,就可以在header中增加X-Forward-For来作ip欺骗,完成从非法到合法的转变

抓取上海教育考试院的报名信息并短信通知

由于有过惨痛教训,老是错过重要的考试报名通知,所以这段代码抓取了上海教育考试院的报名页面,分析并发送短信通知相应的考试人员,然后将这个页面放到服务器上,每日定时检查,一有新的报名信息就能及时得知。中间涉及到部分php的知识点

    1. fscoketopen,上一篇已经写过相应的介绍,即可以用其来模拟web service调用,也可以使用其来抓取页面
    2. 正则表达式,preg_match,用来提取抓取后页面返回的数据
    3. 编码转换iconv,抓取的页面是GBK类型,如果不转换,则在控制台显示乱码。第二个是发送短信的接口,由于我使用的接口是GBK数据,所以我需要再从UTF-8转换到GBK
    4. php文件的相关操作函数:file_exists用来判断文件是否已经存在,fopen用来打开文件,fgets用来读取一行,fputs用来写入一行。
    5. 数组模拟push方法,使用arr[] = something;的形式
    6. vim 格式化代码 :gg=G
    7. vim 批量添加 //注释::10,50s#^#//#g ;批量删除 :10,50s#^//##g
    8. 定时的方法使用crontab -e,就可打开定时列表,设置成每天10点通知:
0 10 * * * /path/to/php /path/to/spta.php

spta.php

function get_spta() {
    $content = '';

    $fp = fsockopen('www.spta.gov.cn', 80);
    fwrite($fp, "GET /appendix/wsbm.html HTTP/1.0\r\n");
    fwrite($fp, "Host: www.spta.gov.cnrn");
    fwrite($fp, "Content-Type: text/html; charset=utf-8\r\n");
    fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
    fwrite($fp, "\r\n");

    fwrite($fp, $content);

    $item = array();
    while (!feof($fp)) {
        $result = iconv('GBK', 'UTF-8', fgets($fp));
        if (strpos($result, '<td align="left">') > 0) {
            preg_match('/>([^<]*)</', $result, $matches);
            $title = $matches[1];
            $url = iconv('GBK', 'UTF-8', fgets($fp));
            preg_match('/href="([^"]*)"/', $url, $matches);
            $url = $matches[1];
            $item[] = array('title' = >$title, 'url' = >$url);
        }
    }
    fclose($fp);
    return $item;
}
function sent_sms($mobile, $msg) {
    $vars = "&mobs=$mobile&msg=".iconv('UTF-8', 'GBK', $msg);
    $fp = fsockopen('smsserver.com', 80);
    fwrite($fp, "GET /sms?$vars HTTP/1.0\r\n");
    fwrite($fp, "Host: smsserver.com\r\n");
    fwrite($fp, "\r\n");

    fwrite($fp, $content);
    fclose($fp);
}
$items = get_spta();
$title = '';
$path = '/path/to/spta';
if (file_exists($path)) {
    $file = fopen($path, 'r');
    $title = fgets($file);
}
foreach($items as $bean) {
    if ($title != $bean['title']) {
        sent_sms('your mobile', $bean['title'].'[考试院]');
        echo $bean['title']."n";
    } else {
        break;
    }
}
$file = fopen($path, 'w');
fputs($file, $items[0]['title']);

使用php fsockopen 调用 .NET的WebService接口

实现代码如下所示,我们知道了可以使用Telnet模拟http访问,也想试着使用socket来调用webservice接口,原因是默认的php Soap不起作用,可能需要繁琐的配置才能实现。但在使用fsockopen调用的时候也现出了一些问题:

    1. php中,单引号中是没有转义字符的,即\r\n是原始显示的
    2. http头部使用1.1的时候,可能会出现keep-alive模式,这种情况下需要使用Content-Length来判断body的长度,取出数据结束,而不应使用feof
    3. fgets()是一次读取一行;fread()是一次读取一个字符,后面可加数量
$content = '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
$content. = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'."\r\n";
$content. = '  <soap:Body>'."\r\n";
$content. = '    <QueryBalance  xmlns="http://tempuri.org/">'."\r\n";
$content. = '      <userId>sg128</userId>'."\r\n";
$content. = '    </QueryBalance >'."\r\n";
$content. = '  </soap:Body>'."\r\n";
$content. = '</soap:Envelope>'."\r\n";

$fp = fsockopen('example.com', 80);
fwrite($fp, "POST /Service/UserService.asmx HTTP/1.0\r\n");
fwrite($fp, "Host: example.com\r\n");
fwrite($fp, "Content-Type: text/xml; charset=utf-8\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "SOAPAction: \"http://tempuri.org/QueryBalance\"\r\n");
fwrite($fp, "\r\n");

fwrite($fp, $content);

header('Content-type: text/plain');

// $length = 0;
// $line = '';
// while($line !== "\r\n") {
//     $line = fgets($fp);
//     if(substr($line, 0, 15) === 'Content-Length:') {
//         $length = intval(substr($line, 16));
//     }
// }
// echo fread($fp, $length);
while (!feof($fp)) {
    echo fgets($fp);
}
fclose($fp);