一.CTF
ctf简介
CTF(Capture The Flag,夺旗赛)CTF 的前身是传统黑客之间的网络技术比拼游戏,起源于 1996 年第四届 DEFCON,以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。 CTF是一种流行的信息安全竞赛形式,其英文名可直译为“夺得Flag”,也可意译为“夺旗赛”。其大致流程是,参赛团队之间通过进行攻防对抗、程序分析等形式,率先从主办方给出的比赛环境中得到一串具有一定格式的字符串
或其他内容,并将其提交给主办方,从而夺得分数。为了方便称呼,我们把这样的内容称之为“Flag”。 flag所表示的为目标服务器上存储的一些敏感机密
的信息, 这些信息正常情况下是不能对外暴露的。选手利用目标的一些漏洞,获取到flag,其表示的即为在真实的黑客攻击中窃取到的机密信息。 一般情况下flag拥有固定格式为flag{xxxxx}
通常来说CTF是以团队为单位进行参赛。每个团队3-5人(具体根据主办方要求决定),在整个比赛过程中既要每个选手拥有某个方向的漏洞挖掘能力,也要同队选手之间的相互配合
取自 ctfhub
ctf题目类型
在CTF中主要包含以下5个大类的题目,有些比赛会根据自己的侧重点单独添加某个分类,例如移动设备(Mobile)
, 电子取证(Forensics)
等,近年来也会出来混合类型的题目,例如在Web中存在一个二进制程序,需要选手先利用Web的漏洞获取到二进制程序,之后通过逆向或是Pwn等方式获得最终flag
Web
Web类题目大部分情况下和网、Web、HTTP等相关技能有关。主要考察选手对于Web攻防的一些知识技巧。诸如SQL注入
、XSS
、代码执行
、代码审计
等等都是很常见的考点。一般情况下Web题目只会给出一个能够访问的URL。部分题目会给出附件
Pwn
Pwn类题目重点考察选手对于二进制漏洞的挖掘和利用
能力,其考点也通常在堆栈溢出
、格式化漏洞
、UAF
、Double Free
等常见二进制漏洞上。选手需要根据题目中给出的二进制可执行文件进行逆向分析,找出其中的漏洞并进行利用,编写对应的漏洞攻击脚本(Exploit
),进而对主办方给出的远程服务器进行攻击并获取flag通常来说Pwn类题目给出的远程服务器信息为nc IP_ADDRESS PORT
,例如nc 1.2.3.4 4567
这种形式,表示在1.2.3.4
这个IP的4567
端口上运行了该题目
Reverse
Re类题目考察选手逆向工程
能力。题目会给出一个可执行二进制文件,有些时候也可能是Android的APK安装包。选手需要逆向给出的程序,分析其程序工作原理。最终根据程序行为等获得flag
Crypto
Crypto类题目考察选手对密码学
相关知识的了解程度,诸如RSA
、AES
、DES
等都是密码学题目的常客。有些时候也会给出一个加密脚本和密文,根据加密流程逆推出明文。
Misc
Misc意为杂项,即不包含在以上分类的题目都会放到这个分类。题目会给出一个附件。选手下载该附件进行分析,最终得出flag
常见的题型有图片隐写、视频隐写、文档隐写、流量分析、协议分析、游戏、IoT相关等等。五花八门,种类繁多tfhub
比赛形式
线上
选手通过主办方搭建的比赛平台在线注册,在线做题并提交flag,线上比赛多为解题模式,攻防模式较为少见。通常来说对于长时间未解出的题目,主办方会酌情给出提示(Hint
)来帮助选手做题。
线下
选手前往比赛所在地,现场接入比赛网络进行比赛,线下多为AWD模式,近年来随着比赛赛制的不断革新,线下赛也会出现多种模式混合进行,例如结合解题+AWD,解题+RW 等等
AWD:Attack with Defense(AwD)全称攻防模式,在攻防模式CTF赛制中,参赛队伍连接到同一个网络空间。主办方会预先为每个参赛队分配要防守的主机,该主机称之为
GameBox
,每个队伍之间的GameBox配置及漏洞是完全一致
的,选手需要防护自己的GameBox不被攻击的同时挖掘漏洞并攻击对手服务来得分。在AwD中主办方会运行一个名为Checker
的程序定时检测选手的GameBox的运行状态。若检测到状态不对则判定该GameBox宕机,按照规则扣除一定分数。攻防模式CTF赛制可以实时通过得分反映出比赛情况,最终也以得分直接分出胜负,是一种竞争激烈,具有很强观赏性和高度透明性的网络安全赛制。在这种赛制中,不仅仅是比参赛队员的智力和技术,也比体力(因为比赛一般都会持续24至48小时左右),同时也比团队之间的分工配合与合作。 AwD通常仅包含Web
及Pwn
两种类型的题目。每个队伍可能会分到多个GameBox,随着比赛的进行,最早的GameBox可能会下线,同时会上线新的GameBox。
RW:Real World(RW) 首次于2018年
长亭科技
主办的RealWorldCTF中出现,该赛制着重考察选手在面对真实的环境下的漏洞挖掘与利用能力。通常RW模式出题也会围绕着能够应用于真实渗透攻击当中的漏洞,一般来说RW常见题型为VM/Docker逃逸、针对浏览器的攻击、针对IoT/Car等设备的攻击,Web类攻击等等 在RW赛制中会有一个Show Time
,当选手认为自己已经可以完成题目时,选手可以在比赛平台上提交展示申请,由工作人员根据申请先后顺序进行展示排期。选手展示之前需要上台并连接相关网络,同时现场大屏会切换至目标的正常页面。选手确认连接并测试OK之后开始计时。一般情况下上台攻击的时间为5分钟
,选手一旦完成攻击现场大屏幕会实时看到攻击的效果,此时裁判会根据效果是否符合题目要求来判定该题是否完成。如5在攻击时间内依然未能看到展示效果则认为本次攻击失败。现如今为了防止选手恶意排期。通常会有一个队伍总展示次数(例如在2019年数字经济云安全公测大赛中每个队伍只允许上台展示30次),选手也需要尽可能保证上台之后攻击的成功率 举个例子。题目要求需要攻击位于比赛网络中的某个网站并将首页替换为包含队伍名称的页面。题目给出该网站的一些信息(源代码/数据库等等),选手经过本地挖掘漏洞之后,提交展示申请,排期到了之后进行上台展示。注意,因为RW模式是以展示效果来作为题目是否完成的准则,所以在RW模式中并不存在Flag
。
ctf平台:
https://ctf.show/challenges
https://www.xctf.org.cn/xctf/2020/
https://buuoj.cn/login?next=%2Fchallenges%3F
https://ctf.bugku.com/
https://www.jarvisoj.com/login
https://www.ctfhub.com/#/index
安全论坛
https://xz.aliyun.com/
https://www.anquanke.com/
https://www.ichunqiu.com/
https://www.freebuf.com/
https://bbs.pediy.com/
https://www.hetianlab.com/
https://www.52pojie.cn/
意义
二.php
解释性语言
基础语法
PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。
注释
(一) 以//开始.
(二) 以#开始.
(三) 多行注释有一种以/*开始以 */结束
php中单引号与双引号的区别?
1. 双引号的变量是解析并输出,而单引号的变量不解析。
2. 单引号的解析速度比双引号的快
演示:
$age = 22;
$str1 = '他今年 $age 岁'; //''原样输出
$str2 = "他今年 $age 岁"; //""要解析里面的`变量 即输出22
echo $str1;
变量, 常量
数组
$c=["zhangsan","lisi"];
echo $c[1];
三.ctf中php tricks
3.1 强弱类型比较
== 是弱类型比较,两个不同类型比较时,会自动转换成相同类型后再比较值
===是强比较,需要比较值和类型
<?php
if("admin"==0) //true
if("1admin"==1)//true
if("admin1"==1)//false
if("0e12324"=="0e1324")//true
php弱类型比较中,数字和字符串比较中,字符串转换成数字的过程中,会取字符串前面数字的值作为整个字符串转换成数字的值,比较“1admin”,转换成数字就是1,所以"admin1"的话,因为字符串没有数字,只能转换成0了,所以第一个才会是true。 而最后一个则是被php当成科学计数法的,计算,所以结果都是0,比较时会相等。
md5弱比较绕过(==)
== 会将两个变量变为同类型比较,所以寻找两个明文不同但md5值为"0exxxxx"的字符串,因为0exxxx会被看成科学计数法,所以0exxxx都为0,所以相等。
0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
............
md5强类型比较(===)
数组绕过
源码
<?php
error_reporting(0);
include 'flag.php';
$a = $_GET['a'];
$b = $_GET['b'];
if($a!= $b && md5($a) == md5($b)){
echo $flag;
}
?>
3.2 strcmp函数的绕过
strcmp()函数用于比较两个字符串
strcmp( string$ str1, string$ str2)
参数str1第一个字符串.str2第二个字符串。如果str1小于str2返回<0;如果str1大于str2返回> 0;如果两者相等返回0(注意相等返回0这个特性)
但是如果此函数参数中有一个不合法的参数(对象,数组等),就会报错并返回0(在php 5.2版本之前,利用strcmp函数将数组与字符串进行比较会返回-1,但是从5.3开始,会返回0)
源码
<?php
error_reporting(0);
include "flag.php";
if(isset($_GET['password']))
if (strcmp($_GET['password'],$flag)==0)
die('Flag: '.$flag);
else
print 'Invalid password';
?>
3.3 Eregi匹配
注意:php版本=5.3
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。
1.数组
ereg是处理字符串,传入数组之后,ereg是返回NULL
2.%00截断 sadasd%00wwww
源码
<?php
error_reporting(0);
if(ereg("zut",$_GET['a']))
{
echo 'success';
}
else
{
echo 'failure';
}
3.4 intval()函数
php intval 返回值是int
源码
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}
数组绕过
intval('4476.0')===4476 小数点
intval('+4476.0')===4476 正负号
intval('4476e0')===4476 科学计数法
intval('0x117c')===4476 16进制
intval('010574')===4476 8进制
intval(' 010574')===4476 8进制+空格
3.5 is_numeric()函数
这个函数用来判断传入的值是否是一个数字,这个函数判断的范围比较广,返回值为ture或false,
is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以,查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,接着后面的判断!
源码
<?php
include "flag.php";
$num=$_GET['num'];
if(!is_numeric($num))
{
//echo "数值为:".$num;
echo "<br/>";
if($num==123)
echo $flag;
}
else
echo "他不能是数字哦";
?>
3.6 extract变量覆盖
extract() 该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
源码
<?php
error_reporting(0);
include 'flag.php';
extract($_GET);
if (isset($y))
{
$content = trim(file_get_contents($x));
if ($y == $content)
{
echo $flag; }
else
{
echo 'Oh..';} }
?>
拓展: 伪协议
php 伪协议
a=999&b=data://,999
拓展:$$变量覆盖题目
$a = 'abc';
$$a = 789;
echo $abc;