一、前言
各个主流CTF平台为防止作弊采用动态FLAG
什么是动态FLAG?也就是说 每个用户一道题目都有一个唯一的FLAG 如果用户提交了别人的FLAG,就会认定为存在抄袭作弊嫌疑
二、流程
三、实现
前台用户打开题目
就会获取到题目所有信息
判断平台是否存在动态FLAG 是否是Docker下发的题目等等信息
也会把FLAG 更新至 Session缓存中 用于对比用户提交是否正确
FLAG生成函数:
# Ti0sCTF 平台使用
# Author:微风飘呀飘
# Mail: Admin@Ti0s.Com
/**
* PS: 根据题目ID生成FLAG
*/
function getFlagAdd($id)
{
$id = intval($id);
global $link;
$sql = $link->query("
SELECT `id`,`type`,`title`,`content`,`seed`,`rand`,`flag`
FROM `ti0sctf_challenges`
WHERE `id`='$id'
AND `hide`='0'
");
$sql or die("SQL_Error!");
$ti0s = $sql->fetch_assoc();
$_SESSION['ques_ID'] = $id;
$_SESSION['ques_Type'] = $ti0s['type'];
# getConfigData 函数为读取系统配置表内信息
# 获取FLAG盐值
$flagHash = getConfigData('flag_hash');
# 获取FLAG头部
$flagHead = getConfigData('flag_head');
# 生成格式FLAG
$flag=md5($flagHash.md5($_SESSION['userToken'].$ti0s['seed']));
$divisionFlag=substr($flag,0,8)."-".substr($flag,8,4)."-".substr($flag,12,4)."-".substr($flag,16,4)."-".substr($flag,20,12);
$_SESSION['flag'] = $ti0s['rand'] ? $flagHead.'{'.$divisionFlag.'}':$ti0s['flag'];
return 'ok';
}
下发Docker函数:
# Ti0sCTF 平台使用
# Author:微风飘呀飘
# Mail: Admin@Ti0s.Com
/**
* PS: 下发Docker容器
*/
function getDocker()
{
global $link;
isset($_SESSION['quesID']) or die('DATA_MISS');
$quseID = $_SESSION['quesID'];
$flag = $_SESSION['flag'];
$token =getConfigData('docker_token');
$url = getConfigData('docker_server')."?token=$token&quseID=$quseID&flag=$flag";
$content = file_get_contents($url);
$port = $content[1]['port'];
$dockerName = $content[1]['dockerName'];
return "ok";
}
FLAG下发脚本:
#!/bin/bash
# Ti0sCTF 平台使用
# Author:微风飘呀飘
# Mail: Admin@Ti0s.Com
# 替换
sed -i "s/flag{ti0sctf}/$1/g" /var/www/html/flag.php
# 数据库
sed -i "s/flag{ti0sctf}/$1/g" /var/www/html/sql.sql
# 根目录
echo $1 > /flag.txt
# ELF文件
sed -i "s/flag{ti0sctf}/$1/g" /flag.c && gcc -o flag flag.c
这样就可以实现 一个人一个容器 并且一个容器内有唯一的FLAG
四、疑问
如果有什么疑问 可以给我留言
如果您有什么更好的建议 可以与我协商
五、平台
练习平台:https://ctf.ti0s.com