0x01 简述
云南招考频道是高考查分,录取查询的平台,每年高考分数均在此处查询,由于查询时是通过考号与查询密码生成口令后访问服务器页面,此方法通过利用漏洞生成口令提前查询高考分数,避免放榜后大量流量导致服务器卡顿,以及提前知高考成绩
0x02 入口
入口均为静态页面,此处截图已进行修改屏蔽,截图中的域名实际不存在
云南招考频道:https://www.ynzs.cn/

高考查分入口:https://www.ynzs.cn/{高考年份}gkcf/web.html

考生成绩报告:https://gk.ynzs.cn/{年份}/gkcf/{a}/{b}.html

0x03 操作过程
此处将使用2019高考查分页面查询2020的考生高考成绩
打开2019查分地址:https://www.ynzs.cn/2019gkcf/web.html

输入2020考生的准考证号,查询密码

点击查询,跳转错误页面

点击地址栏,将2019改为2020
[-] https://gk.ynzs.cn/2019/gkcf/xx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.html [+] https://gk.ynzs.cn/2020/gkcf/xx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.html查询完毕

0x04 代码分析
2019的查询代码:https://www.ynzs.cn/2019gkcf/js/web.js
$(document).ready(function(){
	
	$("#user").focus();
	$("input:text,textarea,input:password").focus(function() {
		$(this).addClass("cur_select");
    });
    $("input:text,textarea,input:password").blur(function() {
		$(this).removeClass("cur_select");
    });
	
	$("#btn").click(function(){
		var user = $.trim($("#user").val());
		var pass = $.trim($("#pass").val());
		if(user==""){
			$(".sub").html("<b>准考证号不能为空!</b>");
			$("#user").focus();
			return false;
		}
		
		if(user.length !=9){
			$(".sub").html("<b>准考证号应为9位!</b>");
			$("#user").focus();
			return false;
	   	}
		
		if(pass==""){
			$(".sub").html("<b>查询密码不能为空!</b>");
			$("#pass").focus();
			return false;
		}
		
		$.ajax({
			type: "POST",
			url: "check.php?action=query",
			timeout : 3000,
			dataType: "json",
			data: {"user":user,"pass":pass},
			beforeSend: function(){
				$(".sub").html("<b>正在查询,请稍候!</b>");
			},
			success: function(json){
				if(json.success==1){
					window.location.href=json.url;
				}else{
					alert(json.msg);
					return false;
				}
			},
			complete : function(XMLHttpRequest,status){ 
		    if(status=='timeout'){
				  $(".sub").html("<b>查询超时,请重试!</b>");
		    }
		  }
		});
	});
});
作用:
方法:     POST
数据类型:  JSON
数据内容:  {"user":user,"pass":pass}
地址:     https://www.ynzs.cn/2019gkcf/check.php?action=query
2020的查询代码:https://www.ynzs.cn/2020gkcf/js/wait.min.js
var isOpen = !1,
    querytime = 12954714e5;
$(document).ready(function () {
    function a(a, b) {
        return "" == a ? ($(".sub").html("<b>\u51C6\u8003\u8BC1\u53F7\u4E0D\u80FD\u4E3A\u7A7A!</b>"), $("#user")
            .focus(), !1) : 9 == a.length ? "" != b || ($(".sub").html(
            "<b>\u67E5\u8BE2\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A!</b>"), $("#pass").focus(), !1) : ($(
            ".sub").html("<b>\u51C6\u8003\u8BC1\u53F7\u5E94\u4E3A9\u4F4D!</b>"), $("#user").focus(), !1)
    }
    function b(a, b) {
        $("#qurey").hide(), $("#waitdiv").show(), $("#rewaitdiv").hide();
        var d = 3 + 10 * Math.random(),
            e = parseInt(1 + 9 * Math.random());
        setTimeout(function () {
            e >= 1 ? c(a, b) : ($("#qurey").hide(), $("#waitdiv").hide(), $("#rewaitdiv").show())
        }, 1e3 * 5)
    }
    function c(a, b) {
        $.ajax({
            type: "POST",
            url: "check.php?action=query",
            timeout: 3e3,
            dataType: "json",
            data: {
                user: a,
                pass: b
            },
            success: function (a) {
                return 1 == a.success ? void(window.location.href = a.url) : (alert(a.msg), !1)
            },
            complete: function (a, b) {
                "timeout" == b && ($("#qurey").show(), $("#rewaitdiv").hide(), $("#waitdiv").hide(),
                    $(".sub").html("<b>\u67E5\u8BE2\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5!</b>"))
            },
            error: function () {
                $("#qurey").hide(), $("#rewaitdiv").show(), $("#waitdiv").hide()
            }
        })
    }
    $("#user").focus(), $("input:text,textarea,input:password").focus(function () {
        $(this).addClass("cur_select")
    }), $("input:text,textarea,input:password").blur(function () {
        $(this).removeClass("cur_select")
    }), $("#btn").click(function () {
        var d = $.trim($("#user").val()),
            e = $.trim($("#pass").val());
        if (a(d, e)) {
            var f = new Date,
                g = f.getTime();
            g <= querytime ? $(".sub").html(
                    "<b>\u5F53\u524D\u8FD8\u672A\u5F00\u653E\u9AD8\u8003\u67E5\u5206!</b>") : isOpen ?
                b(d, e) : c(d, e)
        }
    }), $("#btnreload").click(function () {
        var c = $.trim($("#user").val()),
            d = $.trim($("#pass").val());
        a(c, d) && b(c, d)
    })
});
解密后,其中变量名称被压缩
var isOpen = !1,
    querytime = 12954714e5;
$(document).ready(function() {
    function a(a, b) {
        return "" == a ? ($(".sub").html("<b>准考证号不能为空!</b>"), $("#user")
            .focus(), !1) : 9 == a.length ? "" != b || ($(".sub").html(
            "<b>查询密码不能为空!</b>"), $("#pass").focus(), !1) : ($(
            ".sub").html("<b>准考证号应为9位!</b>"), $("#user").focus(), !1)
    }
    function b(a, b) {
        $("#qurey").hide(), $("#waitdiv").show(), $("#rewaitdiv").hide();
        var d = 3 + 10 * Math.random(),
            e = parseInt(1 + 9 * Math.random());
        setTimeout(function() {
            e >= 1 ? c(a, b) : ($("#qurey").hide(), $("#waitdiv").hide(), $("#rewaitdiv").show())
        }, 1e3 * 5)
    }
    function c(a, b) {
        $.ajax({
            type: "POST",
            url: "check.php?action=query",
            timeout: 3e3,
            dataType: "json",
            data: {
                user: a,
                pass: b
            },
            success: function(a) {
                return 1 == a.success ? void(window.location.href = a.url) : (alert(a.msg), !1)
            },
            complete: function(a, b) {
                "timeout" == b && ($("#qurey").show(), $("#rewaitdiv").hide(), $("#waitdiv").hide(),
                    $(".sub").html("<b>查询超时,请重试!</b>"))
            },
            error: function() {
                $("#qurey").hide(), $("#rewaitdiv").show(), $("#waitdiv").hide()
            }
        })
    }
    $("#user").focus(), $("input:text,textarea,input:password").focus(function() {
        $(this).addClass("cur_select")
    }), $("input:text,textarea,input:password").blur(function() {
        $(this).removeClass("cur_select")
    }), $("#btn").click(function() {
        var d = $.trim($("#user").val()),
            e = $.trim($("#pass").val());
        if (a(d, e)) {
            var f = new Date,
                g = f.getTime();
            g <= querytime ? $(".sub").html("<b>当前还未开放高考查分!</b>") : isOpen ?
                b(d, e) : c(d, e)
        }
    }), $("#btnreload").click(function() {
        var c = $.trim($("#user").val()),
            d = $.trim($("#pass").val());
        a(c, d) && b(c, d)
    })
});
作用分析:
方法:     POST
数据类型:  JSON
数据内容:  {"user":a,"pass":b}
地址:     https://www.ynzs.cn/2020gkcf/check.php?action=query
由数据可以推断:
check.php不返回数据,而是直接重定向check.php的口令获取算法相同,口令考虑为MD5计算而来
0x05 总结反思
- 总结
- 口令使用
md5(准考证号 + 查询密码)获得 - 口令与年份无关
 - 口令生成方法未知
 
 - 口令使用
 - 反思
- 在设计查询时,使用模板+数据渲染,不保存实体图片
 - 增加页面
token,防止越权 - 简单的
unicode压缩并不能加密,可以使用以下算法加密JSaaencodejjencodeJS Fuck
 - 短信推送更方便
 
 

 