web-dev-qa-db-ja.com

悪用可能なPHP関数

任意のコードの実行に使用できる関数のリストを作成しようとしています。目的は、ブラックリストに登録するか、許可しない機能をリストすることではありません。むしろ、侵入先のサーバーでバックドアを検索するときに便利なred-flagキーワードのgrep- ableリストが必要です。

アイデアは、多目的の悪意のあるPHPスクリプト(c99やr57などの「Webシェル」スクリプトなど)を作成する場合、1つ以上を使用する必要があるということです。ユーザーが任意のコードを実行できるようにするために、ファイル内のどこかにある比較的小さな関数のセット。これらの関数を検索すると、何万ものPHPファイルの干し草の山を、より詳細な調査が必要な比較的小さなスクリプトセットにすばやく絞り込むことができます。

たとえば、明らかに、次のいずれかが悪意のある(またはひどいコーディング)と見なされます。

<? eval($_GET['cmd']); ?>

<? system($_GET['cmd']); ?>

<? preg_replace('/.*/e',$_POST['code']); ?>

などなど。

先日、侵害されたWebサイトを検索しても、preg_replaceフラグ(を使用することで/eが危険にさらされる可能性があることに気付かなかったため、悪意のあるコードに気付きませんでした。 ?なぜそこにも?)。私が逃した他のものはありますか?

これまでの私のリストは次のとおりです。

シェル実行

  • system
  • exec
  • popen
  • backtick operator
  • pcntl_exec

PHP実行

  • eval
  • preg_replace/e修飾子付き)
  • create_function
  • include [_once]/require [_once](エクスプロイトの詳細については、マリオの回答を参照してください

ファイルを変更できる機能のリストを用意しておくことも有用かもしれませんが、99%の時間にエクスプロイトコードに上記の機能の少なくとも1つが含まれると思います。ただし、ファイルを編集または出力できるすべての機能のリストがある場合は、投稿してください。ここに記載します。 (そして、私はmysql_executeを数えていません。それは別の種類のエクスプロイトの一部だからです。)

277
tylerl

このリストを作成するために、2つのソースを使用しました。 A色の研究 および ラット 。私も自分の一部をミックスに追加し、このスレッドの人々が助けてくれました。

Edit:このリストを投稿した後、 RIPS の創設者に連絡し、現在このツールはPHPこのリスト内のすべての関数を使用するためのコード。

これらの関数呼び出しのほとんどは、シンクとして分類されます。汚染された変数($ _REQUESTなど)がシンク関数に渡されると、脆弱性が発生します。 RATSRIPS などのプログラムは、grepのような機能を使用して、アプリケーション内のすべてのシンクを識別します。これは、プログラマーがこれらの関数を使用する際に細心の注意を払う必要があることを意味しますが、それらがすべて禁止されている場合、あなたは多くを成し遂げることができません。

"大きな力には大きな責任が伴います。"

-スタン・リー

コマンド実行

exec           - Returns last line of commands output
passthru       - Passes commands output directly to the browser
system         - Passes commands output directly to the browser and returns last line
Shell_exec     - Returns commands output
`` (backticks) - Same as Shell_exec()
popen          - Opens read or write pipe to process of a command
proc_open      - Similar to popen() but greater degree of control
pcntl_exec     - Executes a program

PHPコードの実行

evalとは別に、PHPコードを実行する他の方法があります:include/requireは、 Local File Include および Remote File Include 脆弱性。

eval()
assert()  - identical to eval()
preg_replace('/.*/e',...) - /e does an eval() on the match
create_function()
include()
include_once()
require()
require_once()
$_GET['func_name']($_GET['argument']);
$func = new ReflectionFunction($_GET['func_name']); $func->invoke(); or $func->invokeArgs(array());

コールバックを受け入れる関数のリスト

これらの関数は、攻撃者が選択した関数を呼び出すために使用できる文字列パラメーターを受け入れます。機能に応じて、攻撃者はパラメータを渡すことができる場合とできない場合があります。その場合、phpinfo()のようなInformation Disclosure関数を使用できます。

Function                     => Position of callback arguments
'ob_start'                   =>  0,
'array_diff_uassoc'          => -1,
'array_diff_ukey'            => -1,
'array_filter'               =>  1,
'array_intersect_uassoc'     => -1,
'array_intersect_ukey'       => -1,
'array_map'                  =>  0,
'array_reduce'               =>  1,
'array_udiff_assoc'          => -1,
'array_udiff_uassoc'         => array(-1, -2),
'array_udiff'                => -1,
'array_uintersect_assoc'     => -1,
'array_uintersect_uassoc'    => array(-1, -2),
'array_uintersect'           => -1,
'array_walk_recursive'       =>  1,
'array_walk'                 =>  1,
'assert_options'             =>  1,
'uasort'                     =>  1,
'uksort'                     =>  1,
'usort'                      =>  1,
'preg_replace_callback'      =>  1,
'spl_autoload_register'      =>  0,
'iterator_apply'             =>  1,
'call_user_func'             =>  0,
'call_user_func_array'       =>  0,
'register_shutdown_function' =>  0,
'register_tick_function'     =>  0,
'set_error_handler'          =>  0,
'set_exception_handler'      =>  0,
'session_set_save_handler'   => array(0, 1, 2, 3, 4, 5),
'sqlite_create_aggregate'    => array(2, 3),
'sqlite_create_function'     =>  2,

情報開示

これらの関数呼び出しのほとんどはシンクではありません。むしろ、返されたデータのいずれかが攻撃者に見える場合、それはおそらく脆弱性です。攻撃者がphpinfo()を見ることができる場合、それは間違いなく脆弱性です。

phpinfo
posix_mkfifo
posix_getlogin
posix_ttyname
getenv
get_current_user
proc_get_status
get_cfg_var
disk_free_space
disk_total_space
diskfreespace
getcwd
getlastmo
getmygid
getmyinode
getmypid
getmyuid

その他

extract - Opens the door for register_globals attacks (see study in scarlet).
parse_str -  works like extract if only one argument is given.  
putenv
ini_set
mail - has CRLF injection in the 3rd parameter, opens the door for spam. 
header - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area. 
proc_Nice
proc_terminate
proc_close
pfsockopen
fsockopen
Apache_child_terminate
posix_kill
posix_mkfifo
posix_setpgid
posix_setsid
posix_setuid

ファイルシステム関数

RATSによると、PHPのすべての ファイルシステム関数 は厄介です。これらのいくつかは、攻撃者にとってあまり有用ではないようです。他のものはあなたが思うよりも便利です。たとえば、allow_url_fopen=Onの場合、URLをファイルパスとして使用できるため、copy($_GET['s'], $_GET['d']);の呼び出しを使用して、システム上の任意の場所にPHPスクリプトをアップロードできます。また、サイトがGETを介して送信されたリクエストに対して脆弱である場合、それらのファイルシステム機能のすべてが悪用され、サーバーを介して別のホストにチャネルし、攻撃する可能性があります。

// open filesystem handler
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
// write to filesystem (partially in combination with reading)
chgrp
chmod
chown
copy
file_put_contents
lchgrp
lchown
link
mkdir
move_uploaded_file
rename
rmdir
symlink
tempnam
touch
unlink
imagepng   - 2nd parameter is a path.
imagewbmp  - 2nd parameter is a path. 
image2wbmp - 2nd parameter is a path. 
imagejpeg  - 2nd parameter is a path.
imagexbm   - 2nd parameter is a path.
imagegif   - 2nd parameter is a path.
imagegd    - 2nd parameter is a path.
imagegd2   - 2nd parameter is a path.
iptcembed
ftp_get
ftp_nb_get
// read from filesystem
file_exists
file_get_contents
file
fileatime
filectime
filegroup
fileinode
filemtime
fileowner
fileperms
filesize
filetype
glob
is_dir
is_executable
is_file
is_link
is_readable
is_uploaded_file
is_writable
is_writeable
linkinfo
lstat
parse_ini_file
pathinfo
readfile
readlink
realpath
stat
gzfile
readgzfile
getimagesize
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
ftp_put
ftp_nb_put
exif_read_data
read_exif_data
exif_thumbnail
exif_imagetype
hash_file
hash_hmac_file
hash_update_file
md5_file
sha1_file
highlight_file
show_source
php_strip_whitespace
get_meta_tags
205
rook

Include($ tmp)およびrequire(HTTP_REFERER)および* _onceもスキャンする必要があります。エクスプロイトスクリプトが一時ファイルに書き込むことができる場合、後でそれを含めることができます。基本的には2段階の評価です。

また、次のような回避策を使用して、リモートコードを非表示にすることもできます。

 include("data:text/plain;base64,$_GET[code]");

また、ウェブサーバーが既に侵害されている場合、エンコードされていない悪が常に表示されるとは限りません。多くの場合、悪用シェルはgzipでエンコードされています。ここではinclude("zlib:script2.png.gz");の評価はありませんが、同じ効果があります。

59
mario

これ自体は答えではありませんが、興味深いことがあります。

$y = str_replace('z', 'e', 'zxzc');
$y("malicious code");

同じ精神で、call_user_func_array()を使用して、難読化された関数を実行できます。

48
Aillyn

誰もechoprintをセキュリティの悪用のポイントとして言及していないことに驚いています。

クロスサイトスクリプティング(XSS) は、サーバー側のコード実行エクスプロイトよりもさらに一般的であるため、深刻なセキュリティエクスプロイトです。

20
Bill Karwin

特に、このリストにunserialize()を追加したいと思います。任意のコードの実行、サービス拒否、メモリ情報の漏洩など、さまざまな脆弱性の長い歴史があります。ユーザー提供のデータで呼び出されることはありません。これらのvulの多くは、ここ数年のリリースで修正されていますが、現在の執筆時点ではいまだにいくつかの厄介なvulが残っています。

危険なphp関数/使用法に関するその他の情報については、 Hardened PHP Project およびその勧告を参照してください。最近の Month of PHP Security および2007の Month of PHP Bugs プロジェクト

また、設計上、オブジェクトのシリアル化を解除すると、コンストラクター関数とデストラクター関数が実行されることに注意してください。ユーザー提供のデータで呼び出さないもう1つの理由。

19
Cheekysoft

私のVPSは次の機能を無効にするように設定されています。

root@vps [~]# grep disable_functions /usr/local/lib/php.ini
disable_functions = dl, exec, Shell_exec, system, passthru, popen, pclose, proc_open, proc_Nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, Apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid

PHPには、リストが大きすぎてgrepできないほど十分に潜在的に破壊可能な関数があります。たとえば、PHPにはchmodとchownがあり、これらを使用してWebサイトを単純に非アクティブ化できます。

編集:おそらく、危険(危険な機能、より悪い機能、使用してはならない機能)でグループ化された関数の配列のファイルを検索するbashスクリプトを作成し、危険の相対性を計算することができますファイルがパーセンテージに課すこと。次に、これを各ファイルの横にタグ付けされたパーセンテージでディレクトリのツリーに出力します(30%の危険のしきい値よりも大きい場合)。

17
Josh

また、任意のメモリ位置の読み書きを可能にする「割り込みの脆弱性」のクラスにも注意してください!

これらは、trim()、rtrim()、ltrim()、explode()、strchr()、strstr()、substr()、chunk_split()、strtok()、addcslashes()、str_repeat()などの関数に影響します。これは主に、排他的ではありませんが、言語の呼び出し時の参照渡し機能が10年間廃止されましたが、無効にされていないためです。

詳細については、BlackHat USA 2009での割り込みの脆弱性およびその他の下位レベルPHP問題に関するStefan Esserの講演をご覧ください スライド

このペーパー/プレゼンテーションでは、dl()を使用して任意のシステムコードを実行する方法も示しています。

15
Cheekysoft

プラットフォーム固有の、しかし理論的な実行ベクトル:

  • dotnet_load()
  • new COM( "WScript.Shell")
  • 新しいJava( "Java.lang.Runtime")
  • event_new()-非常に最終的に

そして、さらに多くの変装方法があります。

  • proc_openはpopenのエイリアスです
  • call_user_func_array( "exE" .chr(99)、array( "/ usr/bin/damage"、 "--all"));
  • file_put_contents( "/ cgi-bin/nextinvocation.cgi")&& chmod(...)
  • PharData :: setDefaultStub-.pharファイル内のコードを調べるためのいくつかの作業
  • runkit_function_rename( "exec"、 "innocent_name")またはAPD rename_function
14
mario

eval言語構造とは別に、任意のコード実行を許可する別の関数があります: assert

assert('ex' . 'ec("kill --bill")');
13
NikiC

興味深いエクスプロイトの1つのソースは言及されていません。 PHPを使用すると、文字列に0x00バイトを含めることができます。基になる(libc)関数は、これを文字列の終わりとして扱います。

これにより、PHPの(不完全に実装された)健全性チェックがだまされる可能性があります。次のような状況で:

/// note: proof of principle code, don't use
$include = $_GET['file'];
if ( preg_match("/\\.php$/",$include) ) include($include);

これには、.phpで終わるファイルだけでなく、script.php?file=somefile%00.phpを呼び出すことで、任意のファイルが含まれます。

したがって、PHPの文字列の長さに従わない関数は、何らかの脆弱性につながる可能性があります。

10
mvds

危険な構文要素はどうですか?

" variable variable "($$var)は、$ varという名前で現在のスコープ内の変数を検索します。誤って使用すると、リモートユーザーは現在のスコープ内の変数を変更または読み取ることができます。基本的に、より弱いeval

例:いくつかのコード$$uservar = 1;を記述し、リモートユーザーが$uservarを「admin」に設定すると、現在のスコープで$admin1に設定されます。

ソースファイルを解析しても、すべての可能なエクスプロイトを実際に見つけることはできないと思います。

  • また、ここに本当に素晴らしいリストが提供されている場合、悪用される可能性のある機能を見逃す可能性があります

  • このような「隠された」邪悪なコードがまだある可能性があります

$ myEvilRegex = base64_decode( 'Ly4qL2U =');

preg_replace($ myEvilRegex、$ _POST ['code']);

  • あなたは今、私もこれに一致するようにスクリプトを拡張するだけです

  • しかし、その後、あなたはそのコンテキスト外にあるかもしれない「おそらく悪のコード」を持っているでしょう

  • そのため、(疑似)セキュリティで保護するには、実際に適切なコードを書くおよび既存のすべてのコードを読むを使用する必要があります

6
Andreas Linden

バックティック演算子 PHPマニュアルのバックティック

5
opHASnoNAME

move_uploaded_fileが言及されたことは知っていますが、一般的にファイルのアップロードは非常に危険です。 $_FILESが存在するだけで懸念が生じるはずです。

PHPコードをあらゆるタイプのファイルに埋め込むことはかなり可能です。画像は、テキストコメントでは特に脆弱です。 $_FILESデータ内で見つかった拡張子をそのままコードが受け入れる場合、問題は特に厄介です。

たとえば、ユーザーはPHPコードが「foo.php」として埋め込まれた有効なPNGファイルをアップロードできます。スクリプトが特に素朴な場合、実際にはファイルを「/uploads/foo.php」としてコピーします。サーバーがユーザーアップロードディレクトリでスクリプトの実行を許可するように構成されている場合(多くの場合、ひどい見落とし)、任意のPHPコードを即座に実行できます。 (画像が.pngとして保存されている場合でも、他のセキュリティ上の欠陥を介して実行されるコードを取得できる可能性があります。)

アップロード時に確認する(網羅的ではない)リスト:

  • コンテンツを分析して、アップロードが主張するタイプであることを確認してください
  • 実行されない既知の安全なファイル拡張子でファイルを保存します
  • PHP(およびその他のコード実行)がユーザーアップロードディレクトリで無効になっていることを確認します
5
Matthew

リストにpcntl_signalpcntl_alarmを追加しましょう。

これらの関数を使用して、php.iniまたはスクリプトで作成されたset_time_limit制限を回避できます。

たとえば、このスクリプトはset_time_limit(1);にもかかわらず10秒間実行されます

(クレジットはセバスチャン・バーグマンに送られます Tweet および Gist

<?php
declare(ticks = 1);

set_time_limit(1);

function foo() {
    for (;;) {}
}

class Invoker_TimeoutException extends RuntimeException {}

class Invoker
{
    public function invoke($callable, $timeout)
    {
        pcntl_signal(SIGALRM, function() { throw new Invoker_TimeoutException; }, TRUE);
        pcntl_alarm($timeout);
        call_user_func($callable);
    }
}

try {
    $invoker = new Invoker;
    $invoker->invoke('foo', 1);
} catch (Exception $e) {
    sleep(10);
    echo "Still running despite of the timelimit";
}
5
edorian

これらの関数は、いくつかの厄介な効果もあります。

  • str_repeat()
  • unserialize()
  • register_tick_function()
  • register_shutdown_function()

最初の2つは使用可能なメモリをすべて使い果たし、後者は使い果たされ続けます...

4
Alix Axel

PHP.iniファイルの設定により無効にできるPHPエクスプロイトが多数あります。明らかな例はregister_globalsですが、設定によっては、HTTP経由でリモートマシンからファイルをインクルードまたは開くことも可能です。これは、プログラムがinclude()またはファイル処理関数のいずれかで変数ファイル名を使用する場合に悪用される可能性があります。

PHPでは、変数名の末尾に()を追加することにより、変数関数呼び出しも可能です。たとえば、$myvariable();は、変数で指定された関数名を呼び出します。これは悪用可能です。たとえば、攻撃者がWordの「eval」を含む変数を取得してパラメーターを制御できる場合、プログラムに実際にeval()関数が含まれていなくても、必要なことは何でもできます。

4
Spudley

私の答えは少し否定的かもしれませんが、...

私見、そこにあるすべての機能と方法は、邪悪な目的に使用することができます。悪のトリクルダウン効果と考えてください。変数はユーザーまたはリモート入力に割り当てられ、変数は関数で使用され、関数の戻り値はクラスプロパティで使用され、クラスプロパティはファイル関数で使用され、などなど。覚えておいてください:偽造されたIPアドレスまたは中間者攻撃は、Webサイト全体を悪用する可能性があります。

最善の方法は、$_SERVER$_GET$_POST$_FILE$_COOKIEinclude(some remote file)ifallow_url_fopenがオン)、すべてリモートファイルなどを処理する他の関数/クラス。ユーザーまたはリモートから提供された各値のスタックトレースプロファイルをプログラムで作成します。これは、割り当てられた変数とそれが使用されている関数またはメソッドのすべての繰り返しインスタンスを取得し、それらの関数/メソッドのすべての出現のリストを再帰的にコンパイルするなどしてプログラムで実行できます。それを調べて、最初に、それが触れる他のすべての機能に対して適切なフィルタリングおよび検証機能を通過することを確認します。もちろんこれは手作業による検査です。そうでない場合は、PHP(ユーザー定義を含む)の関数とメソッドの数に等しいcaseスイッチの総数があります。

または、ユーザー入力のみを処理する場合は、allスクリプトの開始時に初期化された静的コントローラークラスを使用します。目的; 2)入力ソース(つまり$_SERVER = null)を消去します。これが少しナジエスクになるところを見ることができます。

2

security.stackexchange.com でこれについての議論が最近ありました

任意のコード実行に使用できる関数

まあそれは少しスコープを縮小します-しかし、 'print'はjavascriptを注入するために使用できます(したがってセッションなどを盗む)ので、それでもややarbitrary意的です。

ブラックリストに登録する必要のある関数をリストすることではありません。むしろ、grep可能なリストが欲しい

それは賢明なアプローチです。

ただし、独自のパーサーを作成することを検討してください-すぐに制御不能になるgrepベースのアプローチを見つけるでしょう(awkの方が少し良いでしょう)。すぐに、ホワイトリストの実装も希望し始めます!

明白なものに加えて、文字列リテラル以外の引数でインクルードするものにフラグを立てることをお勧めします。 __autoload()にも注意してください。

2
symcbean

セキュリティの目的でプロバイダが無効にする機能のリストを次に示します。

  • 幹部
  • dl
  • show_source
  • Apache_note
  • Apache_setenv
  • クローズログ
  • debugger_off
  • debugger_on
  • define_syslog_variables
  • escapeshellarg
  • escapeshellcmd
  • ini_restore
  • openlog
  • パススルー
  • 閉める
  • pcntl_exec
  • ポペン
  • proc_close
  • proc_get_status
  • proc_Nice
  • proc_open
  • proc_terminate
  • Shell_exec
  • syslog
  • システム
  • url_exec
1

コード内の攻撃のほとんどは、複数のアクセスソース、または複数のステップを使用して自分自身を実行します。コードや悪意のあるコードを持つメソッドだけでなく、すべてのメソッド、それを実行または呼び出す関数を検索します。また、最高のセキュリティには、フォームデータの送受信時にエンコードおよび検証することが含まれます。

また、システム変数を定義する際には注意してください。システム変数は、後でコード内の関数またはメソッドから呼び出すことができます。

1
Cninroh

テキストを解釈する4ビット文字関数を使用して、いくつかのバッファオーバーフローが発見されました。 htmlentities()htmlspecialchars()

最上位にあったのは、mb_convert_encoding()を使用して解釈前に単一のエンコードに変換することです。

0
ehime

RIPS /config/sinks.php、静的ソースで、センシティブシンク(エクスプロイト可能なPHP関数)とそのパラメーターの継続的に更新されたリストを見つけることができます。 PHPバックドアも検出するPHPアプリケーションの脆弱性のコードアナライザー。

0
Reiners