寫一個小CTF平臺

0x00.前言

  協會要舉辦信息安全大賽了,初賽的web+crypto+misc主要由我來出題,註冊、比賽的平臺也都要由我來寫php

    上週日完成了註冊頁面的後端(前端由另外一個女生寫的),前天下午大概完成了比賽平臺的全部基本功能(前端也是由我寫的...)前端

    獨立寫完比賽平臺,有些收穫打算寫在這裏,先留個坑,等比賽完了再填坑mysql

  後端:PHPweb

  數據庫:MySQLsql

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平臺應該具有些什麼基礎的功能?session

    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']."&nbsp;&nbsp;&nbsp;".$row['member1']."&nbsp;&nbsp;&nbsp;".$row['member2']."</td>
          <td class='d'>".$row['score']."</td>
          </tr>";
        $num++;
    }
}

 

0x05.答題頁面

   因爲前端不太會..js也不太會,不知道怎麼寫出ctfd那樣的效果,只好用table來裝各個題了...

  效果是這樣的

  

  由於沒寫後臺,因此這些題都是直接在源代碼裏添加修改

  在題目旁邊會檢查隊伍是否已作出該題

  

if(@$_SESSION['web1']=='1'){
    echo '&nbsp;&nbsp;&nbsp;&nbsp;<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.缺陷

   缺陷就有不少了,好比,

  代碼冗長,無後臺管理界面,對隊伍相關信息的操做修改也不方便,出新題也不方便等等,這些也就只有慢慢優化改善這個平臺了

相關文章
相關標籤/搜索