PHP伪造header头信息获取数据
通过PHP来采集别人网站数据时如果对方服务器或者程序里面有对来源URL或者IP等信息进行检查的话,普通的内容获取方法可能就无法得到正确的数据了。这个时候就需要伪造客户端请求的 header 信息了,

这是服务器返回的头信息 header 中的参数就类似这样的。
下面贴出关键代码部分:
<?php
/**
* 获取伪造来源ip网址 header 信息
*
* @param string $url 来源网址
* @param string $myIp 来源ip
* @return array 返回伪造后的 header
*/
function getSpoofingHeader($url, $myIp = null)
{
// 分解url
$temp = parse_url($url);
$query = isset($temp['query']) ? $temp['query'] : '';
// 随机ip
if (! $myIp) {
$myIp = randIp();
}
$cookies= '';
if(count($_COOKIE)) {
foreach($_COOKIE as $cookie_name => $cookie_var) {
$cookies .= $cookies != '' ? '; '.$cookie_name.'='.$cookie_var :$cookie_name.'='.$cookie_var;
}
}
$path = isset($temp['path']) ? $temp['path'] : '/';
$header = array (
"GET {$path}?{$query} HTTP/1.1",
"Host: {$temp['host']}",
'Accept: */*',
"Referer: http://{$temp['host']}/",
"Cookie: $cookies",
'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1)',
'via: 1.1 JEJE1:80 (squid/2.5.STABLE4-NT-CVS)',
"X-Forwarded-For: {$myIp}",
"Connection: Close"
);
return $header;
}
/**
* 获取随机ip
*
* @return string
*/
function randIp()
{
$ip2id = round(rand(600000, 2550000) / 10000); //第一种方法,直接生成
$ip3id = round(rand(600000, 2550000) / 10000);
$ip4id = round(rand(600000, 2550000) / 10000);
//下面是第二种方法,在以下数据中随机抽取
$arr_1 = array('218','218','66','66','218','218','60','60','202','204','66','66','66','59','61','60','222','221','66','59','60','60','66','218','218','62','63','64','66','66','122','211');
$randarr = mt_rand(0,count($arr_1)-1);
$ip1id = $arr_1[$randarr];
$ip = $ip1id . '.' . $ip2id . '.' . $ip3id . '.' . $ip4id;
return $ip;
}
/**
* 获取远程链接内容
*
* @param string $url 远程网址
* @param string $charset 目标网页的编码格式 默认为 UTF-8 则无须转码
* @param string $spoofing 是否伪造ip网址来源
* @return string
*/
function getContents($url, $charset = 'UTF-8', $spoofing = true)
{
$ch = curl_init();
$timeout = 20;
// 获取伪造来源ip网址
if ($spoofing) {
$header = getSpoofingHeader($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
$contents = trim(curl_exec($ch));
curl_close($ch);
return ($charset == 'UTF-8') ? $contents : iconv($charset, 'UTF-8', $contents);
//return ($charset == 'UTF-8') ? $contents : mb_convert_encoding($contents, 'UTF-8', $charset);
}
?>
上面三个函数 getSpoofingHeader 是用来生成伪造 header 头信息的,还有个 randIp 是生成随机IP, 另外 getContents 是通过CURL获取远程链接的内容。
下面做个小测试看看头信息伪造有没有效果。
在本机配置的环境下,访问 http://localhost/test.php 让程序采集我另外一个网站淘瑞网的空间里面放的测试页面 http://www.taory.com/test_server.php
test.php 文件代码:
<?php
// 这里加载上面的三个函数,省略掉了哈
// ..........
// 下面只需要执行一个函数 getContents 就可以了,其他不用管
$url = 'http://www.taory.com/test_server.php';
echo getContents($url);
?>
test_server.php 文件代码:
<?php
// 偷懒了直接输出服务器获得的客户端和本地所有信息
echo 'this is server :<br />';
print_r($_SERVER);
?>
this is server :<br />Array
(
[ALL_HTTP] => HTTP_CONNECTION:Close
HTTP_VIA:1.1 JEJE1:80 (squid/2.5.STABLE4-NT-CVS)
HTTP_ACCEPT:*/*
HTTP_COOKIE:_ourplusFirstTime=2011-2-6-18-18-55; _ourplusReturnTime=2011-2-6-18-18-55; __utma=1.312278111.1296987536.1296987536.1296987536.1; __utmz=1.1296987536.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
HTTP_HOST:www.taory.com
HTTP_REFERER:http://www.taory.com/
HTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1)
HTTP_X_FORWARDED_FOR:60.180.77.118
HTTP_X_REWRITE_URL:/test_server.php
[HTTPS] => off
[SCRIPT_NAME] => /test_server.php
[HTTP_COOKIE] => _ourplusFirstTime=2011-2-6-18-18-55; _ourplusReturnTime=2011-2-6-18-18-55; __utma=1.312278111.1296987536.1296987536.1296987536.1; __utmz=1.1296987536.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
[AUTH_PASSWORD] =>
[AUTH_TYPE] =>
[AUTH_USER] =>
[CONTENT_LENGTH] => 0
[CONTENT_TYPE] =>
[PATH_TRANSLATED] => d:\freehost\zsj\web
[QUERY_STRING] =>
[REMOTE_ADDR] => 115.200.215.39
[REMOTE_HOST] => 115.200.215.39
[REMOTE_USER] =>
[REQUEST_METHOD] => GET
[SERVER_NAME] => www.taory.com
[SERVER_PORT] => 80
[SERVER_PROTOCOL] => HTTP/1.1
[SERVER_SOFTWARE] => Microsoft-IIS/6.0
[APPL_MD_PATH] => /LM/W3SVC/780/Root
[APPL_PHYSICAL_PATH] => d:\freehost\zsj\web\
[INSTANCE_ID] => 780
[INSTANCE_META_PATH] => /LM/W3SVC/780
[LOGON_USER] =>
[REQUEST_URI] => /test_server.php
[URL] => /test_server.php
[SCRIPT_FILENAME] => d:\freehost\zsj\web\test_server.php
[ORIG_PATH_INFO] => /test_server.php
[PATH_INFO] =>
[ORIG_PATH_TRANSLATED] => d:\freehost\zsj\web\test_server.php
[DOCUMENT_ROOT] => d:\freehost\zsj\web
[PHP_SELF] => /test_server.php
[HTTP_CONNECTION] => Close
[HTTP_VIA] => 1.1 JEJE1:80 (squid/2.5.STABLE4-NT-CVS)
[HTTP_ACCEPT] => */*
[HTTP_HOST] => www.taory.com
[HTTP_REFERER] => http://www.taory.com/
[HTTP_USER_AGENT] => Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1)
[HTTP_X_FORWARDED_FOR] => 60.180.77.118
[HTTP_X_REWRITE_URL] => /test_server.php
[REQUEST_TIME] => 1297758739
)
上面就是服务器端PHP程序得到的伪造 header 头所产生的假的信息
一般判断URL来路就是红色标注的带有 [HTTP_REFERER] => http://www.taory.com/ 的这个参数的值,这个域名如果不是你要访问的网站的域名那么别人就可以把你的访问请求给中断,禁止访问了。我们如果是在自己的网站或者其他地方来采集别个的网站的话这个值就会是是你自己的域名或者其它无效值,如果被采集的网站有这个来路判断,那么就无法采集,现在伪造之后,他网站的这个判断基本上就失效了。
另外一个是封IP,如果你是在服务器上进行采集,那么多几次之后,别人一旦发现了,而你的服务器特别是国内的,基本上就是一个IP,国外可能有多个,但基本上就是固定IP了吧,那么他要封你的采集就很容易了,上面红色里面标注的带IP的就是我们随机生成的一个IP [HTTP_X_FORWARDED_FOR] => 60.180.77.118,你自己可以测试,每次刷新这个标为红色的IP值都会变,不过只有一个绿色标注的那个参数 [REMOTE_ADDR] => 115.200.215.39 [REMOTE_HOST] => 115.200.215.39,那个就是是绝对真实的你自己的IP,这个貌似改不掉啊,我也不太懂这个了,我以前在自己的服务器上测试过,伪造的IP貌似对服务器没什么用的,我查看服务器访问日志的时候发现始终服务器看到的都是我的真实IP,但是如果对方的网站是在程序里面判断的,而且是调用的非绿色的那个参数值的IP来验证的话,那么伪造IP就没问题,完全通过了。我小说站做的采集也就是这么用的,貌似都没有问题啊,一直正常运行的。大家可以去试试吧!
- 上一篇:PHP伪造referer实例
- 下一篇:如何改变或伪造HTTP-REFERER






