溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

從escapeshellcmd bypass說起到寬字節(jié)注入

發(fā)布時(shí)間:2020-06-06 14:57:12 來源:網(wǎng)絡(luò) 閱讀:1364 作者:shengqi158 欄目:web開發(fā)

1 php 多字節(jié)繞過escapeshellcmd

escapeshellcmd()對shell元字符過濾加反斜杠; 
反斜線(\)會在以下字符之前插入: #&;`|*?~<>^()[]{}$, \x0A 和 \xFF,但在php5.2.5及之前存在通過輸入多字節(jié)繞過escapeshellcmd的問題。5.2.6 已經(jīng)修復(fù)了該問題。

執(zhí)行 escapeshellcmd("echo ".chr(0xc0).";id"); 
加上反斜杠之后,也就是echo \xc0\x5c;id,在中文環(huán)境中\(zhòng)xc0\x5c是會被認(rèn)為是gbk字符的。


  1. >>> hex(ord('\\'))

  2. '0x5c'

  3. >>> s='\xc0\x5c'

  4. >>> print s.decode('gbk').encode('utf8')

  5. >>> s.decode('gbk').encode('utf8')

  6. '\xe7\xb9\xba'

\被吃掉之后于是就變成了echo 繺;id 了。 
gbk是寬字節(jié),兩個(gè)字節(jié),gbk字符范圍:8140-FEFE,首字節(jié)在81-FE直接,尾字節(jié)在40-FE之間,顯然5C在尾字節(jié)中??紤]0xbf;id,escape之后就變成了0xbf5c;id,0xbf5c是一個(gè)合法的GBK編碼,那就變成了[0xbf5c];id了。而utf8表示中文一般三個(gè)字節(jié)。 
同樣受影響的還有escapeshellarg(),源碼中的處理是一個(gè)字節(jié)一個(gè)字節(jié)來處理的。這種漏洞應(yīng)該有一定普遍性,在當(dāng)時(shí)來說。下面我們看下修復(fù)的源代碼:


  1. char *php_escape_shell_cmd(char *str) {

  2. register int x, y, l;

  3. char *cmd;

  4. char *p = NULL;

  5. TSRMLS_FETCH();

  6. l = strlen(str);

  7. cmd = safe_emalloc(2, l, 1); //申請了2倍字符

  8. for (x = 0, y = 0; x < l; x++) {

  9. int mb_len = php_mblen(str + x, (l - x));

  10. //這一段是5.2.6新加的,就是在處理多字節(jié)符號的時(shí)候,當(dāng)多字節(jié)字符小于0的時(shí)候不處理,大于1的時(shí)候跳過,等于1的時(shí)候執(zhí)行過濾動作

  11. /* skip non-valid multibyte characters */

  12. if (mb_len < 0) {

  13. continue;

  14. } else if (mb_len > 1) {

  15. memcpy(cmd + y, str + x, mb_len);

  16. y += mb_len;

  17. x += mb_len - 1;

  18. continue;

  19. }

  20. switch (str[x]) {

  21. case '"':

  22. case '\'':

  23. #ifndef PHP_WIN32

  24. if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) {

  25. /* noop */

  26. } else if (p && *p == str[x]) {

  27. p = NULL;

  28. } else {

  29. cmd[y++] = '\\';

  30. }

  31. cmd[y++] = str[x];

  32. break;

  33. #endif

  34. case '#': /* This is character-set independent */

  35. case '&':

  36. case ';':

  37. case '`':

  38. case '|':

  39. case '*':

  40. case '?':

  41. case '~':

  42. case '<':

  43. case '>':

  44. case '^':

  45. case '(':

  46. case ')':

  47. case '[':

  48. case ']':

  49. case '{':

  50. case '}':

  51. case '$':

  52. case '\\':

  53. case '\x0A': /* excluding these two */

  54. case '\xFF':

  55. #ifdef PHP_WIN32

  56. /* since Windows does not allow us to escape these chars, just remove them */

  57. case '%':

  58. cmd[y++] = ' ';

  59. break;

  60. #endif

  61. cmd[y++] = '\\';

  62. /* fall-through */

  63. default:

  64. cmd[y++] = str[x];

  65. }

  66. }

  67. cmd[y] = '\0';

  68. return cmd;

  69. }

這個(gè)bypass已經(jīng)成為過去時(shí)了,但是還是有很大的借鑒意義,就是寬字節(jié)注入,這種情況不僅僅發(fā)生命令注入時(shí),更多的時(shí)候在sql注入,下面來分析一下寬字節(jié)注入如下三種情況,都是由于寬字節(jié)的問題導(dǎo)致的。

2 寬字節(jié)sql注入

1,一種情況 iconv轉(zhuǎn)換,addslashes之后從gbk轉(zhuǎn)到utf8


  1. $user = $_POST[ 'username' ];

  2. $user = addslashes($user);

  3. $user = iconv("gbk", 'utf8', $user);

  4. $pass = $_POST[ 'password' ];

  5. $pass = md5( $pass );

  6. $qry = "SELECT * FROM `users` WHERE user='$user' AND password='$pass';";

  7. print_r($qry);

  8. $result = @mysql_query($qry) or die('<pre>' . mysql_error() . '</pre>' );

  9. var_dump($result);

處理過程如下: 
%bf%27----(addslashes)->%bf%5c%27-----(utf8)---->縗' 這樣單引號就放出來了,大體流程是%bf%27經(jīng)過addslashes之后變成了%bf%5c%27,再經(jīng)過iconv從gbk轉(zhuǎn)換為utf8的時(shí)候,變成了%e7%b8%97%27,也就是縗'。利用的前提是設(shè)置了set names utf8。

2,在php中使用mysql_query('set names gbk'),指定了客戶端,連接層,結(jié)果為gbk編碼。構(gòu)造數(shù)據(jù)%bf%27,過程和第一種情況類似 
%bf%27---(addslashes)-->%bf%5c%27---(set names gbk)--->縗'

3,iconv轉(zhuǎn)換從utf8到gbk,set names字符集為gbk,構(gòu)造數(shù)據(jù)如下%e9%8c%a6帶入反斜杠,注釋掉單引號 
大體數(shù)據(jù)流程:%e9%8c%a6-----(utf8)----%e5%5c----(addslashes)--->%e5%5c%5c


  1. >>> s = '\xe9\x8c\xa6'

  2. >>> s.decode('utf8')

  3. u'\u9326'

  4. >>> s.decode('utf8').encode('gbk')

  5. '\xe5\\'

總之一條,都是打的%5c的注意,要么轉(zhuǎn)義后轉(zhuǎn)utf8吃掉%5c,要么轉(zhuǎn)utf8后再轉(zhuǎn)義放出%5c

參考: 
http://seclists.org/bugtraq/2008/May/61 
http://www.sektioneins.de/en/advisories/advisory-032008-php-multibyte-shell-command-escaping-bypass-vulnerability.html 
http://php.net/ChangeLog-5.php 
http://php.net/releases/


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI