现在一些投票的系统,都会限制IP。即一个IP只允许投一次票。那么,假设我们要作弊刷票,思路就是每次请求投票api的时候,伪造不同的IP地址,这样就可以无限刷票了。
PHP服务端分析
基本来说,现在大家基本会采取下列代码去获取请求用户的IP。这时候要从header
入手分析。但凡HTTP_*
这样的,是由请求方发送的header,OK,那么我们就可以从HTTP_CLIENT_IP
和HTTP_X_FORWARDED_FOR
做文章了。
//获取客户端用户IP
function GetIP()
{
if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
$cip = $_SERVER["HTTP_CLIENT_IP"];
} elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} elseif (!empty($_SERVER["REMOTE_ADDR"])) {
$cip = $_SERVER["REMOTE_ADDR"];
} else {
$cip = "0.0.0.0";
}
return $cip;
}
服务端实验准备
server.php
function GetIP()
{
if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
$cip = $_SERVER["HTTP_CLIENT_IP"];
} elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} elseif (!empty($_SERVER["REMOTE_ADDR"])) {
$cip = $_SERVER["REMOTE_ADDR"];
} else {
$cip = "0.0.0.0";
}
return $cip;
}
echo "您的IP为".GetIP();
模拟访问
curl.php
模拟GET,POST,PHP的已经有了神器拓展CURL
,同学们记得用之前先开启起来。
接下去我们就可以随心所欲伪造IP了
$curl = curl_init(); //初始化一个curl对象
curl_setopt($curl, CURLOPT_URL, "127.0.0.1/server.php");
$header = array( //构造头部
'CLIENT-IP:58.68.44.61',
'X-FORWARDED-FOR:58.68.44.61',
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$str = curl_exec($curl); //执行请求
curl_close($curl); //关闭c
echo $str; //输出抓取的结果
实验结果
总结
我们成功地伪造了IP。那这个有什么意义呢。谈不上来,上文所说的刷票。还有一个很恶心的。如果假设别人后台需要显示用户IP地址的。那么他们又没有防止XSS攻击的
$header = array( //构造头部
'CLIENT-IP:<script>一些JS作恶代码</script>',
);
那么很可能这段JS代码会入库,然后只要在页面显示出来,就执行了。可能会被人劫持了session。我只要拿到你所有cookie,就相当于做了登录。
当然上述只是在一个理想的状态下,现在大部分人都会做过滤。
还有最重要的一点!!!!!!
作为服务端的话,如果改变上述获取IP的方法,以$_SERVER["REMOTE_ADDR"]
优先。那么防作弊就妥妥的了。如果你的服务隐藏在负载均衡或者缓存系统后面,那么前两个是可信的。