0x00.前言
协会要举办信息安全大赛了,初赛的web+crypto+misc主要由我来出题,注册、比赛的平台也都要由我来写
上周日完成了注册页面的后端(前端由另一个女生写的),前天下午大概完成了比赛平台的所有基本功能(前端也是由我写的...)
独立写完比赛平台,有些收获打算写在这里,先留个坑,等比赛完了再填坑
后端:PHP
数据库:MySQL
0x01.登录页面
登录界面的前端是直接找的一个比较简朴的框架。
后端检验用户的输入,队伍名是只允许出现中英文、数字及下划线的,我用的preg_match()进行正则匹配
if(!preg_match('/^(?!_)[A-Za-z0-9_x{4e00}-x{9fa5}]+$/u',$_POST['team'])) { echo "<h2 align='center'><font color='#FF00000'>队名只能包含中英文、数字及下划线!</h2>"; }
验证合法后,连接MySQL,采用php里mysqli扩展的预编译执行SQL语句(防注入),查询队伍是否存在
1 //数据库连接 2 $con = new mysqli('localhost',username,password,database); 3 if ($con->connect_error) { 4 die("连接失败: " . $con->connect_error); 5 } 6 // 预处理及绑定 7 $stmt = $con->prepare("SELECT team,pwd FROM teams WHERE team=? AND pwd=?"); 8 $stmt->bind_param("ss", $team,$pwd); 9 // 执行成功 10 if($stmt->execute()){ 11 $stmt->store_result(); //取回结果 12 if(($stmt->num_rows())==1){ 13 $_SESSION['team'] = $team; //记录一个Session 14 header("Refresh:0;url=index.php"); //登陆成功跳转至主页 15 }else{ 16 echo "<h2 align='center'><font color='#FF00000'>队名或密码错误!</h1>"; 17 } 18 }
0x02.功能框架
思考:一个CTF平台应该具备些什么基础的功能?
1.发公告的首页
2.队伍得分的排行榜
3.比赛做题的界面(重点)
4.注销
以上四点是我觉得一个CTF平台应具备的最基础的功能
另外可扩展的功能有比如:*查看队伍信息(包括成员、做题情况等),*后台管理页面等
由于时间较紧迫,初赛比较小型,所以就没写那么多,以后有时间再多扩展些功能
平台的前端也是找的一个比较清新的导航界面框架
上面的导航栏可以随鼠标向下滑动而上移
0x03.数据库及身份认证
数据库存了队伍的队名、密码、队长+成员、得分、各个题是否已做的信息。由于怕自己写的平台有漏洞,就没有把flag放在数据库中。
值得注意的是,得分的那一个字段需要定义为int类型,不能定义为varchar类型,否则后面按得分排名时会出错
对队伍的身份认证采用Session会话管理,用session记录队名,并且在做题页面中,会先查询队伍做题情况并记入session中。已做的题就会在题旁边显示已做,并且不允许再重复提交flag
平台上的每个界面一开始都要检查用户是否已登录
session_start(); if(!isset($_SESSION['team'])){ $login = false; }else{ $login = true; }
在每个功能页面都包含这段代码,检查$login的值就行
若已登录,导航栏是这样的
未登录是这样的
0x04.排行榜
排行榜比较简单,查询数据库按分数排名,循环打印出来
$sql = "SELECT team,leader,member1,member2,score FROM teams ORDER BY score DESC"; if($res = mysqli_query($con,$sql)){ $num = 1; while($row = mysqli_fetch_assoc($res)){ echo " <tr> <td class='a'>".$num."</td> <td class='b'>".$row['team']."</td> <td class='c'>".$row['leader']." ".$row['member1']." ".$row['member2']."</td> <td class='d'>".$row['score']."</td> </tr>"; $num++; } }
0x05.答题页面
由于前端不太会..js也不太会,不知道怎么写出ctfd那样的效果,只好用table来装各个题了...
效果是这样的
因为没写后台,所以这些题都是直接在源代码里添加修改
在题目旁边会检查队伍是否已做出该题
if(@$_SESSION['web1']=='1'){ echo ' <font color="#32CD32">已解决√'; }
验证flag时,我是将flag以及题目的分值放在一个配置文件里,提交flag时将其包含
检验flag代码如下
if(isset($_POST['web1submit'])){ if(!empty($_POST['web1flag'])){ if($_SESSION['web1']==0){ if(@$_POST['web1flag']===$web1flag){ require("mysqlcon.php"); // 查询队伍当前分数 $sql = "SELECT score FROM teams WHERE team='".$_SESSION["team"]."'"; if($res = mysqli_query($con,$sql)){ while($row = mysqli_fetch_assoc($res)){ $score = $row['score']; } } // 加分 $score += $web1score; // 更新分数 $sql = "UPDATE teams SET score='".$score."' WHERE team='".$_SESSION["team"]."'"; if(mysqli_query($con,$sql)){ // 更改web1列记录已做 $sql = "UPDATE teams SET web1=1 WHERE team='".$_SESSION["team"]."'"; if(mysqli_query($con,$sql)){ echo '<br><font color="#32CD32">正确√'; } } mysqli_close($con); }else{ echo '<br><font color="#FF00000">错误×'; } }else{ echo '<br><font color="#FF00000">请勿重复答题!'; } } }
0x06.细节
1.【单双引号】
通过这次写这个平台,才了解到php中单双引号的使用还是有很大区别的,主要区别在于单引号会把【引号内完全当字符解析】,而双引号会【解析引号内的简单变量】,更厉害的是花括号{}——可以解析更复杂的变量
0x07.缺陷
缺陷就有很多了,比如,
代码冗长,无后台管理界面,对队伍相关信息的操作修改也不方便,出新题也不方便等等,这些也就只有慢慢优化改善这个平台了