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压缩
并不能加密,可以使用以下算法加密JSaaencode
jjencode
JS Fuck
- 短信推送更方便