oschina看到一篇关于爆discuz后台的文章,一想不太对, discuz本身通过代码做了一层密码尝试过多干掉ip的功能,也就是表 pre_common_failedlogin
实际拿了代码跑了下竟然是可以的,具体看了下discuz代码.
source/class/discuz/discuz_application.php中:
private function _get_client_ip() {
$ip = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
foreach ($matches[0] AS $xip) {
if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
$ip = $xip;
break;
}
}
}
return $ip;
}
获取ip的最后一段是根据头部x_forwarded_for做ip设置,所以在发送模拟post的时候增加HTTP_X_FORWARDED_FOR就能轻松跳过ip failed.
找了下资料在这里扒皮说下:
一、没有使用代理服务器的PHP获取客户端IP情况: REMOTE_ADDR = 客户端IP HTTP_X_FORWARDED_FOR = 没数值或不显示 二、使用透明代理服务器的情况:Transparent Proxies REMOTE_ADDR = 最后一个代理服务器 IP HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215) 这类代理服务器还是将客户端真实的IP发送给了访问对象,无法达到隐藏真实身份的目的. 三、使用普通匿名代理服务器的PHP获取客户端IP情况:Anonymous Proxies REMOTE_ADDR = 最后一个代理服务器 IP HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215) 这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的. 四、使用欺骗性代理服务器的情况:Distorting Proxies REMOTE_ADDR = 代理服务器 IP HTTP_X_FORWARDED_FOR = 随机的 IP(经过多个代理服务器时,这个值类似:220.4.251.159, 203.98.182.163, 203.129.72.215) 这种情况下同样透露了客户端是使用了代理服务器,但编造了一个虚假的随机IP(220.4.251.159)代替客户端的真实IP来欺骗它. 五、使用高匿名代理服务器的PHP获取客户端IP情况:High Anonymity Proxies (Elite proxies) REMOTE_ADDR = 代理服务器 IP HTTP_X_FORWARDED_FOR = 没数值或不显示 无论是REMOTE_ADDR还是HTTP_FORWARDED_FOR,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP头消息.因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值.
在我们实际使用过程中,我们会有更多的选择如:
HTTP_X_REAL_IP
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
REMOTE_ADDR
推荐检查顺序从上往下, 最靠谱的是REMOTE_ADDR
文章参考:
修复discuz获取用户ipbug
HTTP_X_FORWARDED_FOR,REMOTE_ADDR区别
推荐get_real_ip()
暴力破解dz密码