背景:
“北京交警APP”可以网上办理进京证,但是最近每次在该APP办理进京证,总会提示“排队人数过多”。很是苦恼,想一探究竟,到底是真的排队过多,偶有成功,还是总会弹出该错误提示?
前期准备——抓包:
1.利用fiddler对手机进行抓包,看到一个addcartype接口的302响应和一个错误页面的200响应,这是进入申请进京证排队20秒的那个接口,直接跳到错误页面。如下
2.详细分析addcartype接口,这是导致错误页面的关键。如下
php实现一个简单的灌水程序
1. 每隔一秒访问该接口,如果HTTP响应码为302,则继续灌它。
2. 每隔一小时统计接口302访问次数
3. 如果状态码为200,则记录返回数据。好进行申请进京证的下一步。
代码见下,开发这个灌水纯粹是脑子一热,逻辑如有纰漏请指正。
<?php
/**
* Created by PhpStorm.
* User: wanghejun_iwm
* Date: 2017/6/2
* Time: 15:56
*/
set_time_limit(0);
$url = "https://api.jinjingzheng.zhongchebaolian.com/enterbj/platform/enterbj/addcartype";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
//设置header
$header = array();
$header[] = "Content-Type: application/x-www-form-urlencoded";
$header[] = "Origin: https://api.jinjingzheng.zhongchebaolian.com";
$header[] = "Cookie: JSESSIONID=03451CCEFCA2975A892618509F49EB2A; CNZZDATA1260761932=1447194544-1489704663-https%253A%252F%252Fapi.jinjingzheng.zhongchebaolian.com%252F%7C1494198185; UM_distinctid=15ab66a50aa19-0ebf95ce9e49a4-2e5e056a-3d10d-15ab66a50ab7c";
$header[] = "Content-Length: 182";
$header[] = "Connection: keep-alive";
$header[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$header[] = "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89";
$header[] = "Referer: https://api.jinjingzheng.zhongchebaolian.com/enterbj/jsp/enterbj/index.jsp";
$header[] = "Accept-Language: zh-cn";
$header[] = "Accept-Encoding: gzip, deflate";
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
$data = 'applyid=&carid=马赛克&userid=马赛克&gpslon=116.314587&gpslat=40.044848&imei=&imsi=&licenseno=%E5%86%马赛克&appsource=&hiddentime=2017-06-02+15%3A29%3A52';
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //data with URLEncode
$ret = curl_exec($ch);
$httpCode = 302;
$n = 0;
$currentTime = intval(date("d") . date("H"));
while ($httpCode == 302) {
$n++;
sleep(1);
$ret = curl_exec($ch);
$httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);
$data = curl_multi_getcontent($ch);
$now = intval(date("d") . date("H"));
if ($now > $currentTime) {
$currentTime = $now;
//记录当前为止302次数
$time = date("Y-m-d H:i:s");
error_log("\n 截止到$time ,请求次数 : $n\n" , 3, '/tmp/jinjingzheng');
}
if ($httpCode == 200) {
error_log("\n 截止到成功 ,请求次数 : $n\n" , 3, '/tmp/jinjingzheng');
error_log("\n 返回信息 : \n" . print_r($data, true), 3, '/tmp/jinjingzheng');
}
}
curl_close($ch);
后台运行灌水小程序
php JinjingEnter.php &
后续改进
1. 对/enterbj/platform/enterbj/addcartype进行灌水,得到返回信息,查看是乱码。
原因:返回信息未进行gzip解码,需要在代码中加入一行
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); //解释gzip内容
2. 乱码问题解决,返回信息为一个页面,down下来 本地打开,发现样式、图片都加载不到,如下图
原因:查看html源码,发现未进行资源替换。里面的样式文件以及url请求都用的uri段形式,如下
/enterbj/static_resources/enterbj/images/img_cz.jpg
所以需要爬虫代码继续改造,替换起始段位 /enterbj/ 为 https://api.jinjingzheng.zhongchebaolian.com/enterbj/
line58代码改成如下,并注入到一个html文件中。
$data = preg_replace('/(\'|\")\/enterbj/', '$1https://api.jinjingzheng.zhongchebaolian.com/enterbj', $data);
error_log($data, 3, '/tmp/jinjing.html');
以下为得到的二级页面,核验环保等级页面。由于已转换成web页面,我们可以通过chrome 调试查看请求。
点击“核验环保等级”Button,请求信息如下
发现在这一层又是遇到麻烦了,直接抛出无情的404.后转换成get直接请求该链接。发现该接口不支持get请求,所以说更加断定是对方服务器动了手脚,处理请求的时候直接甩出404
所以说这个接口也需要灌水,直到没有404,得到正确返回信息。综合,改造代码如下
首先封装一个http请求函数
/**
* 发送http/https请求
* @param string $url 请求url
* @param array $header 数组header
* @param $body 请求体
* @param int $trueCode 特判正确码
* @param bool $isPost 是否post请求
* @param bool $isHttps 是否https请求
*/
function sendHttp($url = " ", array $header, $body = null, $trueCode = 200, $isPost = true, $isHttps = true) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
if (true == $isHttps) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名
}
if (true == $isPost) {
curl_setopt($ch, CURLOPT_POST, true);
if (!is_null($body)) {
$data = is_array($body) ? http_build_query($body) : $body;
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
$httpCode = 0;
$n = 0;
while ($httpCode != $trueCode) {
$n++;
sleep(1);
$ret = curl_exec($ch);
$httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);
$data = curl_multi_getcontent($ch);
if ($httpCode == 200) {
error_log("\n 截止到成功 ,$url 请求次数 : $n\n" , 3, '/tmp/jinjingzheng');
echo "\n";
$data = preg_replace('/(\'|\")\/enterbj/', '$1https://api.jinjingzheng.zhongchebaolian.com/enterbj', $data);
$filename = "/tmp/" . end(explode('/', $url)) . ".html";
if (file_exists($filename)) {
unlink($filename);
}
file_put_contents($filename, $data);
} else {
error_log("\n $url 请求次数 : $n ,返回码 :$httpCode\n " , 3, '/tmp/jinjingzheng');
}
}
curl_close($ch);
return true;
}
其次,对核验环保等级接口灌水
$header2 = array();
$header2[] = 'Accept:application/json, text/javascript, */*; q=0.01';
$header2[] = 'Accept-Encoding:gzip, deflate, br';
$header2[] = 'Accept-Language:zh-CN,zh;q=0.8';
$header2[] = 'Connection:keep-alive';
$header2[] = 'Content-Length:137';
$header2[] = 'Content-Type:application/x-www-form-urlencoded; charset=UTF-8';
$header2[] = 'Host:api.jinjingzheng.zhongchebaolian.com';
$header2[] = 'Origin:null';
$header2[] = 'User-Agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36';
$url2 = 'https://api.jinjingzheng.zhongchebaolian.com/enterbj/platform/enterbj/checkenvgrade';
$body2 = '马赛克';
sendHttp($url2, $header2, $body2);