taint的使用和源码修改
taint是什么?它是一个可以检测XSS漏洞的php扩展。
说明和初步的使用请查看http://www.laruence.com/2012/02/18/2560.html
taint目前最新的0.41
通过查看源码,可以发现它只能跟踪3种变量POST,GET,COOKIE。另外的REQUEST由于是通过这几个构造的。所以也可跟踪。
有3个函数是可以让我们直接调用的,
分别是taint,untaint,is_tainted
1)taint($string)
参数是一个字符串,可以定制跟踪的字符串。
比如如下代码将会抛错
结果会
Warning: main(): Attempt to echo a string that might be tainted in /media/d/htdocs/1.php on line 4 Hello Taint
2)untaint($string)
参数也是一个字符串,这个函数的作用是取消已经taint标记的变量,
比如
这个不会触发taint的报警
3)is_tainted()
无参数,返回布尔值,表示是否已经开启taint
taint是无法覆盖所有代码逻辑的,部分地方还是会没法检测到。
另外只能对已经存在的变量进行跟踪。
比如如下部分的$b是无法被跟踪到的
========================================================
下面这个taint版本是我用pecl最新的那个0.41改的
加入了一个taint_enable()函数
——–update: 请教了二姐5.3因为运行机制的原因是无法在请求开始的时候自动跟踪,但是用这个函数就可以实现了
这个函数不仅仅用于开启taint跟踪,同时会跟踪无法自动启用跟踪的$_SERVER , $_ENV, $_FILES这三个全局变量
另外改进了taint()和untaint()函数,让参数可以接受数组输入
自己测试了下,暂时没发现bug。
下载地址
[download id=”37″]
data2db beta版发布&开源啦
什么是data2db?
这是一个数据导入的工具,可以方便的把一些有格式的文件转换成sql语句方便导入到数据库
平常我们需要导入某些文件(比如csv,tsv文件)到数据库的话,需要单独写个脚本或者小程序。一些通用的工具只能批量全部导入,不能对导入的数据进行定制或者进行二次导入。
比如 我需要同时导入成两个表。而且第二个表中需要一个第一次导入的主键的值,现有工具均不能满足要求了
目前beta版可以导入csv及其他自定义格式的文件
在线使用: http://data2db.techest.net 备用 http://data2db.sinaapp.com
详细的使用说明:
这是一个样例文件,假设是运营叫给我们的excel数据。我们要把他导入到数据库内
首先,上传这个文件到data2db
然后点击下一步,接下来需要设置数据源的格式
上图是csv默认的配置,可以按照实际的需求修改。也可以填入自己的符号,符号支持正则表达式
点击预览后可以看到从你的文件实际读取的情况。方便您修改
如图可以看到预览的情况。如果有乱码,可以尝试下左边的文件编码选项。
点击下一步后进入到格式调整。可以对字段进行拆分合并操作。
比如我的源数据的3,4,5列我想合并到一起。点击新增合并规则,然后点击3,4,5。因为只是合并,合并符号中留空
如果填写了合并符号,各列中间将插入合并符号
点击下一步,可以看到合并后的结果
然后可以继续进行拆分和合并操作,
拆分的话,假设我的第二列是12:30。 我在拆分符号中填写:
则第二列将变为两列,一列是12,另外一列是30
点击下一步后进入目标mapping设置
每一个列即代表一次单行插入操作
这张图中的设置,我对一条数据会进行两次插入操作。
其中第二次插入的时候会映射第一次插入的主键
点击预览可以看到将生成的SQL语句
点击下一步后就可以下载了
然后让数据库执行这个文件即可以导入到数据库里面啦~
源代码下载:
debian,ubuntu一键安装vpn服务器脚本
使用这个脚本可以在ubuntu上快速进行vpn服务器的安装。
wget http://lab.haku.hk/install_vpn_ubuntu.sh; sh install_vpn_ubuntu.sh
手动安装请【参考这里】
安装第一步会询问服务器的外网ip,填写好即可
装好后有个默认账号admin 密码admin
另外如果想高级点,用这个。
wget http://lab.haku.hk/PPTPD.tar ; tar xvf PPTPD.tar ; sh PPTPD/ubuntu.sh
这个还会安装Freeradius。和RAD。可以用web界面去管理vpn账号,还可以限制流量什么的。
php扩展开发(一)
要开发php的扩展,php的源代码是必须的
首先从php官网下载回源代码
http://www.php.net/downloads.php
然后解压出来,进入ext目录下面
使用它附带的工具ext_skel
比如我要创建一个名为xsscheck的插件
./ext_skel –extname=xsscheck
ext目录内就会生成xsscheck文件夹,并会出现怎样使用你的插件的提示
下面依次进行操作
打开xsscheck文件夹内的config.m4文件
把以下部分的注释取消掉
修改完毕后退出
运行phpize(如果没有,请先编译你的php源代码,在bin目录下)
如果发生错误Cannot find autoconf. ,请先安装autoconf
然后配置上php-config
./configure –with-php-config=/root/php/bin/php-config
make install 之后会有信息出现
可以在当前目录的module目录里面找到编译好的.so扩展
改动php.ini加载它就可以了
另外。开发的时候调试可以用netbeans
通过写的shell去重新加载插件。
注意,如果用apache模块方式启动的php,要重启apache才能重新加载php的插件
ps:
= =.本来打算做这个xsscheck插件的。 发现超级大牛已经做了一个taint。
我技术还不成熟额。呵呵,学习之。 之后会通过这个taint插件学习下一些ZendApi
附件:
【[download id=”36″]】
用swig构建php扩展
swig是个将使用c/c++编写的软件与其他编程语言对接的工具
简单的说,它可以把你已经写好的c/c++源代码通过转换变成python,php,java等的扩展
让你可以在这类高级语言中使用底层c++
它支持php,可以编译成php的扩展供我们调用
下面是一段c++函数
#include <stdio.h> #include <stdlib.h> #include <string.h> char *helloworld(); char *helloworld() { char *target = "helloworld"; return target;
}
然后我们试试把它搞成一个php扩展。
上面的文件是helloworld.c
我们需要先安装swig。
源码可以从http://www.swig.org/download.html获取,然后编译安装
或者从apt源中获取,core中已经包含有swig,使用apt-get install swig安装。
然后在他目录下新建一个helloworld.i,写入swig的模块规则
%module helloworld
%{
extern char * helloworld();%}
extern char * helloworld();
接下来使用swig
swig -php helloworld.i
然后你会发现目录里面多出几个文件
helloworld_wrapper.c
helloworld.php
其中的helloworld_wrapper.c是通过转换后的c代码,把他编译成so模块
cc -fpic -c helloworld.c
gcc `php-config –includes` -fpic -c helloworld_wrap.cgcc -shared helloworld.o -o helloworld.so
注意其中使用了php-config –includes,这个命令是获得php源码的include目录
如果你没有php源码。去下载一个吧。或者用apt-get install php-dev安装附属的头和库文件
编译好的helloworld.so就可以放php扩展里面试试了。复制到php扩展目录,修改好php.ini
然后重启apache。
我们来试试
<?php echo helloworld(); ?>
恩..就可以看到效果了
当然,每次调试都很麻烦。自己写个shell什么的会快一点
像这样,
#!/bin/bash rm *.o -f swig -php $1.i cc -fpic -c $1.c gcc `php-config --includes` -fpic -c $1_wrap.c gcc -shared *.o -o $1.so sudo cp $1.so `php-config --extension-dir` service apache2 restart
参考文档:
http://www.ibm.com/developerworks/cn/opensource/os-php-swig/index.html
服务器被入侵记.
今天查看我的一个站点biewang.net,长期没有维护。想试试还能用不
右键看源码无意间发现被挂上了东西。
在页面脚部有大量的垃圾链接。虽然因为页面css的原因屏蔽掉了没有展示出来,但是seo依然会被严重打击下来。
找找原因。
首先想是不是代码有漏洞被利用了。
这个站是用的之前写的框架的。页面输入都严格过滤了。
想了下也没有文件操作的部分会使用户传入恶意的东西吧主页改掉的。
然后想是不是给提权了。于是看了下改主机上的其他几个站。包括这个博客。
没有发现被入侵的迹象。php是用suphp模式运行的。没有殃及其他站也就是说是通过别忘这个站进来的。
还是查查apache的日志。只找这个站最近的记录。
cat /var/log/httpd/access_log | grep ‘biewang.net’ > a_log.txt
看了下。没可疑的。也就是说并没有通过代码入侵。
再看看另外一个日志.
tail /var/log/secure
= =…
原来是ftp被爆破了 = =。
改掉所有密码.顺便把ftp端口也改了。
检查下有没后门留下。
cat */*.php | grep ‘eval’
以后得注意.. 不能再用弱密码了.
swfupload的session问题
swupload是个一个客户端文件上传工具
让这个上传flash嵌入在网页里面可以使用一些非常棒的特性
官网在这里http://code.google.com/p/swfupload/
最近使用的时候发生一个问题
文件上传的session和页面session不同步
demo里面有提到设置post_params
让swfupload吧页面的session_id作为参数传递
但是实际使用的时候依然有问题
具体表现就是在文件上传处理页面设置的session无法在当前页面得到
使用fidder抓包后发现原因是swfupload里面的cookie上也带有一个sessid
POST字段里面才是实际需要的sessid
因为swfupload使用的是socket方式 所以和我们的浏览器不是共享cookie的
但是php的session一般是通过cookie上的PHPSESSID进行会话
而这里的cookie上是错误的,于是造成了PHPSESSID不一致
我们需要使用POST字段上的,
解决方案有很多
其中之一是直接强制用post里面的设置为sessid
php可以使用函数session_id($_POST["PHPSESSID"]);强制更改
当然.也可以把cookie重设,不过得刷新页面了
pafetion1.4版本发布
近期很多同学反映接口不能使用.
然后改动了下接口
并把以前不规范的cookie获取方式修改了
直接使用
下载地址
[download id=”35″]
调用例子
1.发送消息
http://lab.haku.hk/f/do?phone=xxxxxx&pwd=xxx&to=xxxx,xxxx,xxxx&msg=xxxx
2.添加好友
http://lab.haku.hk/f/do?phone=xxxxxx&pwd=xxx&add=xxxx,xxxx,xxxx
说明:
phone 发送者手机号码 (-v1)
pwd 发送者飞信密码 (-v1)
———————————————-
to 接收者的标志 (可以是手机号 也可以是昵称 ,昵称如果有重复的默认发第一个的)
msg 消息的正文(默认gbk 编码)
(可选) u 是否使用utf8编码(默认的编码是gbk , 此参数用于一些需要对中文特殊处理的地方 比如, 如果您需要做一个在线发什么东西的)
———————————————-
add 需要添加成好友的手机号码
name 好友请求验证时看到的姓名
关于一致性哈希
1. 一致性哈希
2.1 基本场景
比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache ;
hash(object)%N
一切都运行正常,再考虑如下的两种情况;
1 一个 cache 服务器 m down 掉了(在实际应用中必须要考虑这种情况),这样所有映射到 cache m 的对象都会失效,怎么办,需要把 cache m 从 cache 中移除,这时候 cache 是 N-1 台,映射公式变成了 hash(object)%(N-1) ;
2 由于访问加重,需要添加 cache ,这时候 cache 是 N+1 台,映射公式变成了 hash(object)%(N+1) ;
1 和 2 意味着什么?这意味着突然之间几乎所有的 cache 都失效了。对于服务器而言,这是一场灾难,洪水般的访问都会直接冲向后台服务器;
再来考虑第三个问题,由于硬件能力越来越强,你可能想让后面添加的节点多做点活,显然上面的 hash 算法也做不到。
有什么方法可以改变这个状况呢,这就是 consistent hashing…
2.2 hash 算法和单调性
Hash 算法的一个衡量指标是单调性( Monotonicity ),定义如下:
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
容易看到,上面的简单 hash 算法 hash(object)%N 难以满足单调性要求。
如果我们的node2节点挂掉了..
新的hash()%3
node1 应存放1 2 3 4 node3 应放 5 6 7 8 node4 应放 9 10 11 12
需要迁移的节点 node1 1个 node3 3个 node4 1个
总共需迁移5个 比例数5/12 差不多到50%了..
如果value更多呢..后果不堪设想..
2.3 consistent hashing 算法的原理
consistent hashing 是一种 hash 算法,简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在 key 映射关系,尽可能的满足单调性的要求。
下面就来按照 5 个步骤简单讲讲 consistent hashing 算法的基本原理。
2.3.1环形hash 空间
考虑通常的 hash 算法都是将 value 映射到一个 32 为的 key 值,也即是 0~2^32-1 次方的数值空间;我们可以将这个空间想象成一个首( 0 )尾( 2^32-1 )相接的圆环,如下面图 1 所示的那样。
图 1 环形 hash 空间
2.3.2 把对象映射到hash 空间
接下来考虑 4 个对象 object1~object4 ,通过 hash 函数计算出的 hash 值 key 在环上的分布如图 2 所示。
hash(object1) = key1;
… …
hash(object4) = key4;
图 2 4 个对象的 key 值分布
2.3.3 把cache 映射到hash 空间
Consistent hashing 的基本思想就是将对象和 cache 都映射到同一个 hash 数值空间中,并且使用相同的hash 算法。
假设当前有 A,B 和 C 共 3 台 cache ,那么其映射结果将如图 3 所示,他们在 hash 空间中,以对应的 hash值排列。
hash(cache A) = key A;
… …
hash(cache C) = key C;
图 3 cache 和对象的 key 值分布
说到这里,顺便提一下 cache 的 hash 计算,一般的方法可以使用 cache 机器的 IP 地址或者机器名作为hash 输入。
2.3.4 把对象映射到cache
现在 cache 和对象都已经通过同一个 hash 算法映射到 hash 数值空间中了,接下来要考虑的就是如何将对象映射到 cache 上面了。
在这个环形空间中,如果沿着顺时针方向从对象的 key 值出发,直到遇见一个 cache ,那么就将该对象存储在这个 cache 上,因为对象和 cache 的 hash 值是固定的,因此这个 cache 必然是唯一和确定的。这样不就找到了对象和 cache 的映射方法了吗?!
依然继续上面的例子(参见图 3 ),那么根据上面的方法,对象 object1 将被存储到 cache A 上; object2和 object3 对应到 cache C ; object4 对应到 cache B ;
2.3.5 考察cache 的变动
前面讲过,通过 hash 然后求余的方法带来的最大问题就在于不能满足单调性,当 cache 有所变动时,cache 会失效,进而对后台服务器造成巨大的冲击,现在就来分析分析 consistent hashing 算法。
a) 移除 cache
考虑假设 cache B 挂掉了,根据上面讲到的映射方法,这时受影响的将仅是那些沿 cache B 逆时针遍历直到下一个 cache ( cache C )之间的对象,也即是本来映射到 cache B 上的那些对象。
因此这里仅需要变动对象 object4 ,将其重新映射到 cache C 上即可;参见图 4 。
图 4 Cache B 被移除后的 cache 映射
b) 添加 cache
再考虑添加一台新的 cache D 的情况,假设在这个环形 hash 空间中, cache D 被映射在对象 object2 和object3 之间。这时受影响的将仅是那些沿 cache D 逆时针遍历直到下一个 cache ( cache B )之间的对象(它们是也本来映射到 cache C 上对象的一部分),将这些对象重新映射到 cache D 上即可。
因此这里仅需要变动对象 object2 ,将其重新映射到 cache D 上;参见图 5 。
图 5 添加 cache D 后的映射关系
2.4 虚拟节点
考量 Hash 算法的另一个指标是平衡性 (Balance) ,定义如下:
平衡性
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。
hash 算法并不是保证绝对的平衡,如果 cache 较少的话,对象并不能被均匀的映射到 cache 上,比如在上面的例子中,仅部署 cache A 和 cache C 的情况下,在 4 个对象中, cache A 仅存储了 object1 ,而 cache C 则存储了 object2 、 object3 和 object4 ;分布是很不均衡的。
为了解决这种情况, consistent hashing 引入了”虚拟节点”的概念,它可以如下定义:
“虚拟节点”( virtual node )是实际节点在 hash 空间的复制品( replica ),一实际个节点对应了若干个”虚拟节点”,这个对应个数也成为”复制个数”,”虚拟节点”在 hash 空间中以 hash 值排列。
仍以仅部署 cache A 和 cache C 的情况为例,在图 4 中我们已经看到, cache 分布并不均匀。现在我们引入虚拟节点,并设置”复制个数”为 2 ,这就意味着一共会存在 4 个”虚拟节点”, cache A1, cache A2 代表了 cache A ; cache C1, cache C2 代表了 cache C ;假设一种比较理想的情况,参见图 6 。
图 6 引入”虚拟节点”后的映射关系
此时,对象到”虚拟节点”的映射关系为:
objec1->cache A2 ; objec2->cache A1 ; objec3->cache C1 ; objec4->cache C2 ;
因此对象 object1 和 object2 都被映射到了 cache A 上,而 object3 和 object4 映射到了 cache C 上;平衡性有了很大提高。
引入”虚拟节点”后,映射关系就从 { 对象 -> 节点 } 转换到了 { 对象 -> 虚拟节点 } 。查询物体所在 cache时的映射关系如图 7 所示。
图 7 查询对象所在 cache
“虚拟节点”的 hash 计算可以采用对应节点的 IP 地址加数字后缀的方式。例如假设 cache A 的 IP 地址为202.168.14.241 。
引入”虚拟节点”前,计算 cache A 的 hash 值:
Hash(“202.168.14.241”);
引入”虚拟节点”后,计算”虚拟节”点 cache A1 和 cache A2 的 hash 值:
Hash(“202.168.14.241#1”); // cache A1
Hash(“202.168.14.241#2”); // cache A2
2.5 参考
a) http://www.codeproject.com/KB/recipes/lib-conhash.aspx
b) http://www.jiacheo.org/blog/174
另外附上我用php实现的crc32版本的一致性hash
没有做节点迁移
[download id=”34″]
phpcurl模块
1 概述
PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。
目前支持http、https、ftp、gopher、telnet、dict、file和ldap协议。libcurl同时也支持HTTPS认证、HTTP POST、HTTP PUT、 FTP 上传(这个也能通过PHP的FTP扩展完成)、HTTP 基于表单的上传、代理、cookies和用户名+密码的认证。
为什么不用socket?
curl,是client url的简写,用来模拟浏览器的功能,浏览器能做的它基本都能实现,登陆,上传文件,下载…
socket可以理解为通信链的句柄,比CURL更底层一点
某些时候我们可能更需要简单模拟下浏览器功能即可,所以用CURL
到底能干什么??
sample : http://haku.hk/?p=2177 飞信API
2 安装
1. 编译方式安装
./configure –prefix=%PHP_DIR% –with-curl
make
make install
- 模块安装
复制mod_curl.so到module目录
修改php.ini
加入module=mod_curl.so
然后重启apache服务器
用phpinfo如果能看到就说明安装成功
3 使用例子
$curl= curl_init();
curl_setopt($curl, CURLOPT_URL, “http://baidu.com”);
// 设置header
curl_setopt($curl, CURLOPT_HEADER, 1);
// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
// 运行cURL,请求网页
$data = curl_exec($curl);
在执行curl_exec的时候会阻塞线程,直到返回结果
cookie的使用可以用
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar);
或者从响应头拆分set-cookie出来
7.4 关于CURL_MULTI
考虑如下情形,你需要从google.com.hk和baidu.com拿到他们的首页资料
前面已经说过执行curl_exec(的时候会阻塞线程。如果使用它,相当于分两次请求,每次1个网站。
平均执行时间如下
用wiresharp抓包可以发现系统的两个请求,第二个等待第一个返回后才发出的
curl_ multi的功能是并发地执行几个请求
curl_multi_exec($mh,$running);
这个函数是非阻塞的,返回的$running是表示当前是否还有正在处理的curl进程
之前的代码改用multi_exec实现
平均结果为
用wiresharp抓包可以看到系统同时发出了两个请求
5 附录:TIPS
- 命令行版的CURL的使用参考
a) http://www.ruanyifeng.com/blog/2011/09/curl.html
b) http://curl.haxx.se/docs/httpscripting.html
- 超时设置
CURLOPT_CONNCETTIMEOUT_MS支持毫秒级别的超时
不过只有在CURL7.16.2和5.2.3同时满足的情况下才可用