php escapeshellcmd¶à×Ö½Ú±àÂ멶´½âÎö¼°ÑÓÉì

ZDNet °²È«ÆµµÀƵµÀ ¸üÐÂʱ¼ä£º2008-06-26 ×÷Õߣº À´Ô´£ºSohuIT

±¾ÎĹؼü´Ê£ºphp ×Ö½Ú escapeshellcmd

¡¡¡¡Ò»Ð©ÔÊÐíÈçGBK£¬EUC-KR, SJISµÈ¿í×Ö½Ú×Ö·û¼¯µÄϵͳ¶¼¿ÉÄÜÊÜ´ËÓ°Ï죬ӰÏ컹ÊǷdz£´óµÄ£¬¹úÄÚµÄÐéÄâÖ÷»úÓ¦¸ÃÊÇͨɱµÄ£¬ÔÚ²âÊÔÍêÕâ¸ö©¶´Ö®ºó£¬·¢ÏÖ»¹ÊÇÊ®·ÖÓÐÒâ˼µÄ£¬ÒÔÇ°Ò²Óйý¶ÔÕâÖÖÀàÐÍ°²È«Â©¶´µÄÑо¿£¬ÓÚÊǾͰÑÏà¹ØµÄ©¶´½âÊͺÍһЩ×Ô¼ºµÄÏë·¨¶¼Ð´³öÀ´£¬Ò²Ï£Íû¹úÄÚµÄһЩÓЩ¶´µÄƽ̨ÄÜѸËÙ×ö³öÏìÓ¦£¬ÐÞ²¹Â©¶´¡£

¡¡¡¡Õâ¸ö©¶´³öÔÚphpµÄÓÃÀ´×ªÒåÃüÁîÐÐ×Ö·û´®µÄº¯ÊýÉÏ£¬ÕâЩº¯Êýµ×²ãÊÇÓõÄphp_escape_shell_cmdÕâ¸öº¯ÊýµÄ£¬ÎÒÃÇÏÈÀ´¿´¿´ËûµÄ´¦Àí¹ý³Ì£º

¡¡¡¡/* {{{ php_escape_shell_cmd

¡¡¡¡Escape all chars that could possibly be used to

¡¡¡¡break out of a shell command

¡¡¡¡This function emalloc¡¯s a string and returns the pointer.

¡¡¡¡Remember to efree it when done with it.

¡¡¡¡*NOT* safe for binary strings

¡¡¡¡*/

¡¡¡¡char *php_escape_shell_cmd(char *str) {

¡¡¡¡register int x, y, l;

¡¡¡¡char *cmd;

¡¡¡¡char *p = NULL;

¡¡¡¡l = strlen(str);

¡¡¡¡cmd = safe_emalloc(2, l, 1);

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

¡¡¡¡switch (str[x]) {

¡¡¡¡case ¡¯"¡¯:

¡¡¡¡case ¡¯¡¯¡¯:

¡¡¡¡#ifndef PHP_WIN32

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

¡¡¡¡/* noop */

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

¡¡¡¡p = NULL;

¡¡¡¡} else {

¡¡¡¡cmd[y++] = ¡¯¡¯;

¡¡¡¡}

¡¡¡¡cmd[y++] = str[x];

¡¡¡¡break;

¡¡¡¡#endif

¡¡¡¡case ¡¯#¡¯: /* This is character-set independent */

¡¡¡¡case ¡¯&¡¯:

¡¡¡¡case ¡¯;¡¯:

¡¡¡¡case ¡¯`¡¯:

¡¡¡¡case ¡¯|¡¯:

¡¡¡¡case ¡¯*¡¯:

¡¡¡¡case ¡¯?¡¯:

¡¡¡¡case ¡¯~¡¯:

¡¡¡¡case ¡¯<¡¯:

¡¡¡¡case ¡¯>¡¯:

¡¡¡¡case ¡¯^¡¯:

¡¡¡¡case ¡¯(¡¯:

¡¡¡¡case ¡¯)¡¯:

¡¡¡¡case ¡¯[¡¯:

¡¡¡¡case ¡¯]¡¯:

¡¡¡¡case ¡¯{¡¯:

¡¡¡¡case ¡¯}¡¯:

¡¡¡¡case ¡¯$¡¯:

¡¡¡¡case ¡¯¡¯:

¡¡¡¡case ¡¯x0A¡¯: /* excluding these two */

¡¡¡¡case ¡¯xFF¡¯:

¡¡¡¡#ifdef PHP_WIN32

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

¡¡¡¡case ¡¯%¡¯:

¡¡¡¡cmd[y++] = ¡¯ ¡¯;

¡¡¡¡break;

¡¡¡¡#endif

¡¡¡¡cmd[y++] = ¡¯¡¯;

¡¡¡¡/* fall-through */

¡¡¡¡default:

¡¡¡¡cmd[y++] = str[x];

¡¡¡¡}

¡¡¡¡}

¡¡¡¡cmd[y] = ¡¯¡¯;

¡¡¡¡return cmd;

¡¡¡¡}

¡¡¡¡/* }}} */

¡¡¡¡¿ÉÒÔ¿´µ½£¬phpͨ¹ý½«",¡¯,#,&,;.....µÈµÈÔÚshellÃüÁîÐÐÀïÓÐÌØÊâÒâÒåµÄ×Ö·û¶¼Í¨¹ýÔÚÇ°Ãæ¼ÓÉϱä³É".¡¯,#,&,;......À´½øÐÐתÒ壬ʹµÃÓû§µÄÊäÈë±»¹ýÂË£¬À´±ÜÃâ²úÉúcommand injection©¶´¡£ÔÚphp¿´À´£¬Ö»Òª¹ýÂËÁËÕâЩ×Ö·û£¬ËÍÈëµ½systemµÈº¯ÊýÖÐʱ£¬²ÎÊý¾Í»áÊÇ°²È«µÄ£¬phpÊÖ²áÖиø³öµÄÀûÓÃÀý×ÓÈçÏ£º

¡¡¡¡

$e = escapeshellcmd($userinput);

// here we don¡¯t care if $e has spaces

system("echo $e");

$f = escapeshellcmd($filename);

// and here we do, so we use quotes

system("touch "/tmp/$f"; ls -l "/tmp/$f"");

?>¡¡¡¡$e = escapeshellcmd($userinput);

¡¡¡¡// here we don¡¯t care if $e has spaces

¡¡¡¡system("echo $e");

¡¡¡¡$f = escapeshellcmd($filename);

¡¡¡¡// and here we do, so we use quotes

¡¡¡¡system("touch "/tmp/$f"; ls -l "/tmp/$f"");

¡¡¡¡>

¡¡¡¡ºÜÃ÷ÏÔ£¬Èç¹ûûÓо­¹ýescapeshellcmdµÄ´¦Àí£¬Óû§ÊäÈëhello;idµÄ»°£¬×îºósystemÖ´ÐеĻáÊÇ£º

¡¡¡¡echo hello;id

¡¡¡¡ÔÚshellÀïÊÇ·Ö¸îÃüÁîµÄ×÷Óã¬ÕâÑù²»½ö½ö»áecho hello,»¹»áÖ´ÐÐidÕâ¸öÃüÁµ¼ÖÂÃüÁî×¢È멶´¡£ÓÃescapeshellcmd´¦ÀíÖ®ºóÃüÁî±ä³É£º

¡¡¡¡echo hello;id

¡¡¡¡ÕâÑùÖ´ÐеÄÃüÁî¾ÍÖ»»áÊÇecho£¬ÆäËûµÄ¶¼±ä³ÉechoµÄ²ÎÊý£¬ºÜ°²È«¡£

¡¡¡¡ÊÂʵÉÏÊÇÕâÑùô£¿phpÔÚ´¦ÀíÍê²ÎÊýËÍÈësystemÖ®ºóËü¾Íʲô¶¼²»¹ÜÁË£¬ºóÃæµÄ¹¤×÷ʵ¼ÊÉ϶¼ÊÇÓÉlinuxÀ´Íê³ÉµÄ£¬ÄÇôlinuxÔÚ´¦ÀíÕâЩ²ÎÊýµÄʱºòÊÇÔõôÑùµÄÄØ£¿linuxÔÚÖ´ÐÐÃüÁîµÄʱºò»áÓÐһЩµÄ±íʾ¹¤×÷»·¾³µÄ»·¾³±äÁ¿£¬Æ©ÈçPWD´ú±íµ±Ç°µÄ¹¤×÷»·¾³£¬UID´ú±íÁËÄãµÄÉí·Ý£¬BASH´ú±íÃüÁî½âÊÍÆ÷µÈµÈ......¶øÔÚlinuxϵͳִÐÐÃüÁîµÄʱºò£¬»¹ÓÐÒ»¸ö·Ç³£ÖØÒªµÄ²ÎÊý£¬LANG£¬Õâ¸ö²ÎÊý¾ö¶¨ÁËlinux shellÈçºÎ´¦ÀíÄãµÄÊäÈ룬ÕâÑù¾Í¿ÉÒÔµ±ÄãÊäÈëһЩÖÐÎÄ×Ö·ûµÄʱºò£¬linuxÄÜÈÏʶËû£¬²»ÖÁÓÚ³öÏÖÈËÓëϵͳ֮¼ä³öÏÖÀí½âÉϵĴíÎó¡£Ä¬ÈÏÇé¿öÏ£¬linuxµÄLANGÊÇen_US.UTF-8£¬UTF-8ÊÇÒ»¸öºÜ°²È«µÄ×Ö·û¼¯£¬ÆäϵÁÐÖаüº¬ÓжÔ×ÔÉíµÄУÑ飬ËùÒÔ²»»á³öÏÖ´íÎ󣬻Ṥ×÷Á¼ºÃ¡£Ò»Ð©ÏµÍ³Ö§³Ö¶à×Ö½Ú×Ö·û¼¯ÈçGBKµÄʱºò£¬ÕâÒ²ÕýÊǹúÄڵĶàÊýÇé¿ö£¬Äã¿ÉÒÔÉèÖÃLANG=zh_CN.GBK£¬ÕâÑùÄãµÄÊäÈ붼»á±»µ±×÷GBK±àÂë´¦Àí£¬¶øGBKÊÇË«×ֽڵģ¬ºÏ·¨µÄGBK±àÂë»á±»ÈÏΪÊÇÒ»¸ö×Ö·û¡£

¡¡¡¡´ó¼Ò¿ÉÒÔ¿´µ½£¬ÔÚphpµÄ´¦Àí¹ý³ÌÖУ¬ËüÊǵ¥×Ö½Ú´¦ÀíµÄ£¬ËüÖ»°ÑÊäÈëµ±×÷Ò»¸ö×Ö½ÚÁ÷£¬¶øÔÚlinuxÉèÖÃÁËGBK×Ö·û¼¯µÄʱºò£¬ËüµÄ´¦ÀíÊÇË«×ֽڵģ¬´ó¼ÒµÄÀí½âºÜÃ÷ÏԵز»Ò»Ö¡£ÎÒÃDzéÏÂGBKµÄ×Ö·û¼¯·¶Î§Îª8140-FEFE£¬Ê××Ö½ÚÔÚ 81-FE Ö®¼ä£¬Î²×Ö½ÚÔÚ 40-FE Ö®¼ä£¬¶øÒ»¸ö·Ç³£ÖØÒªµÄ×Ö·ûµÄ±àÂëΪ5c£¬ÔÚGBKµÄβ×Ö½Ú·¶Î§Ö®ÄÚ£¬ÕâÑùÎÒÃÇ¿¼ÂÇÒ»¸öÌØÊâµÄÊäÈ룺

¡¡¡¡0xbf;id

¡¡¡¡»ò 0xbf¡¯id

¡¡¡¡¾­¹ýphpµÄescapeshellcmdµ¥×Ö½ÚתÂëÖ®ºó½«»áÊÇ

¡¡¡¡0xbf5c;id

¡¡¡¡0xbf5c¡¯id

¡¡¡¡×¢Òâ0xbf5cÊÇÒ»¸öºÏ·¨µÄGBK±àÂ룬ÄÇôÔÚlinuxÖ´ÐеÄʱºò£¬»áÈÏΪÊäÈëÊÇ

¡¡¡¡[0xbfbc];id

¡¡¡¡ºÜºÃ£¬ºóÃæµÄid½«»á±»Ö´ÐС£¿ÉÒÔ×ö¸ö¼òµ¥µÄʵÑ飬ÈçÏ£º

¡¡¡¡[loveshell@Loveshell tmp]$Content$nbsp;echo ¿

¡¡¡¡>

¡¡¡¡

¡¡¡¡[loveshell@Loveshell tmp]$Content$nbsp;set|grep -i lang

¡¡¡¡LANG=zh_CN.GB2312

¡¡¡¡LANGVAR=en_US.UTF-8

¡¡¡¡[loveshell@Loveshell tmp]$Content$nbsp;export LANG=zh_CN.GBK

¡¡¡¡[loveshell@Loveshell tmp]$Content$nbsp;echo ¿

¡¡¡¡¿

¡¡¡¡[loveshell@Loveshell tmp]$Content$nbsp;set|grep -i lang

¡¡¡¡LANG=zh_CN.GBK

¡¡¡¡LANGVAR=en_US.UTF-8

¡¡¡¡[loveshell@Loveshell tmp]$Content$nbsp;

¡¡¡¡ÆäÖпµÄ±àÂëΪ0xbf5c£¬¿ÉÒÔ¿´µ½ÔÚ²»ÉèÖÃLANGΪGBKµÄʱºò¿ÊÇÒ»¸ö·Ç·¨µÄgb2312±àÂ룬ËùÒԻᱻÈÏΪÊÇÁ½¸ö×Ö·û£¬ËùÒÔÆäÖк¬ÓеÄ0x5cÆð×÷Ó㬱»ÈÏΪÃüÁîû½áÊø¡£È»ºóÎÒÃÇÉèÖñàÂëΪGBK£¬¿¾Í»á±»ÈÏΪÊÇÒ»¸ö×Ö·ûÀ´echoÁË¡£

¡¡¡¡ÄÇÎÒÃÇÈçºÎÀ´Ö¤Ã÷phpµÄ©¶´ÄØ£¬ÄÃ

¡¡¡¡×÷ΪÀý×Ó£¬Õý³£Çé¿öÏÂÉÏÃæµÄ´úÂ빤×÷ºÜºÃ£¬ÎÒÃÇÌá½»

¡¡¡¡exp.php?c=loveshell%bf;id

¡¡¡¡½á¹û·µ»Ø

¡¡¡¡loveshell?id

¡¡¡¡ÎÒÃÇÔÙÀ´ÉÔ΢¸ÄÏÂÉÏÃæµÄ´úÂë

¡¡¡¡phpµÄputenvº¯ÊýÓÃÓÚÐÞ¸ÄphpµÄÔËÐÐʱµÄ»·¾³±äÁ¿£¬ÉÏÃæÐÞ¸ÄÍêLANGÖ®ºó£¬ÔÙÌá½»ÉÏÃæµÄ²ÎÊý¾Í¿ÉÒÔ¿´µ½£º

¡¡¡¡loveshell¿ uid=99(nobody) gid=4294967295 groups=4294967295

¡¡¡¡ÃüÁî±»³É¹¦Ö´ÐÐÁË£¬ÕâÀïÐèÒª×Ô¼ºÉèÖû·¾³±äÁ¿£¬µ±È»Ò²¿ÉÄÜijЩ»úÆ÷ÒѾ­ÉèÖÃÁËLANGΪGBK£¬ÓÚÊÇһЩ²ÉÓÃescapeshellcmd¹ýÂËÊäÈëµÄ¾Í»á³öÎÊÌâÁË¡£ÕâÀï±¾ÖÊÊÇlinuxºÍphp¶Ô²ÎÊýµÄÀí½â²»Ò»Ö£¬¶øphpµÄmailº¯ÊýÔڵײ㻹ÊÇÒÀ¿¿ÏµÍ³À´Ö´ÐÐsendmailÃüÁîµÄ£¬²¢ÇÒÖ§³Ö¶ÔsendmailÃüÁî¼Ó²ÎÊý£¬²»¹ý²ÎÊý±»¹ýÂËÁË£¬µ«ÊÇÀûÓÃÕâÀï˵µ½µÄÎÊÌ⣬ÎÒÃǾͿÉÒÔÔÚ¶à×Ö½Ú±àÂë»úÆ÷ÉÏbypass¹ýÂË¡£

¡¡¡¡mailº¯ÊýһЩ´úÂëƬ¶ÎÈçÏ£º

¡¡¡¡......

¡¡¡¡if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) {

¡¡¡¡php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect. The fifth parameter is disabled in SAFE MODE.");

¡¡¡¡RETURN_FALSE;

¡¡¡¡}

¡¡¡¡if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss",

¡¡¡¡&to, &to_len,

¡¡¡¡&subject, &subject_len,

¡¡¡¡&message, &message_len,

¡¡¡¡&headers, &headers_len,

¡¡¡¡&extra_cmd, &extra_cmd_len

¡¡¡¡) == FAILURE) {

¡¡¡¡return;

¡¡¡¡}

¡¡¡¡......

¡¡¡¡if (force_extra_parameters) {

¡¡¡¡extra_cmd = estrdup(force_extra_parameters);

¡¡¡¡} else if (extra_cmd) {

¡¡¡¡extra_cmd = php_escape_shell_cmd(extra_cmd);

¡¡¡¡}

¡¡¡¡if (php_mail(to_r, subject_r, message, headers, extra_cmd TSRMLS_CC)) {

¡¡¡¡RETVAL_TRUE;

¡¡¡¡} else {

¡¡¡¡RETVAL_FALSE;

¡¡¡¡}

¡¡¡¡.....

¡¡¡¡ÕâÀïÈç¹û²»ÊÇ°²È«Ä£Ê½¾Í»áÔÊÐíµÚÎå¸ö²ÎÊý£¬µÚÎå¸ö²ÎÊý×÷Ϊextra_cmd¾­¹ýphp_escape_shell_cmd¹ýÂ˺ó×÷ΪµÚÎå¸ö²ÎÊýËÍÈëphp_mailº¯Êý£¬ÔÚphp_mailÖÐƬ¶ÎÈçÏ£º

¡¡¡¡......

¡¡¡¡if (extra_cmd != NULL) {

¡¡¡¡sendmail_cmd = emalloc (strlen (sendmail_path) + strlen (extra_cmd) + 2);

¡¡¡¡strcpy (sendmail_cmd, sendmail_path);

¡¡¡¡strcat (sendmail_cmd, " ");

¡¡¡¡strcat (sendmail_cmd, extra_cmd);

¡¡¡¡} else {

¡¡¡¡sendmail_cmd = sendmail_path;

¡¡¡¡}

¡¡¡¡#ifdef PHP_WIN32

¡¡¡¡sendmail = popen(sendmail_cmd, "wb");

¡¡¡¡#else

¡¡¡¡/* Since popen() doesn¡¯t indicate if the internal fork() doesn¡¯t work

¡¡¡¡* (e.g. the shell can¡¯t be executed) we explicitely set it to 0 to be

¡¡¡¡* sure we don¡¯t catch any older errno value. */

¡¡¡¡errno = 0;

¡¡¡¡sendmail = popen(sendmail_cmd, "w");

¡¡¡¡......

¡¡¡¡extra_cmd±»¸½×ÅÔÚsendmail·¾¶ºóÃæ×÷Ϊ²ÎÊýÁË£¬ÕâÀïÎÒÃǾͿÉÒÔÀûÓÃÕâ¸ö©¶´À´ÔÚһЩ½ûÖ¹µôsystemµÈΣÏÕº¯ÊýµÄ»·¾³ÏÂÖ´ÐÐÃüÁîÁË£¬

¡¡¡¡¿ÉÒÔÔÚÖ§³ÖGBKµÄ»úÆ÷ÉÏÔËÐУ¬ÆäËû×Ö·û¼¯Ó¦¸ÃÒ²Ò»Ñù£¬ÉÔ΢ÐÞ¸ÄÏÂÒ²¾Í¿ÉÒÔÓá£ÖÁÓÚÐÞ²¹£¬ÎÒÏ뻹ÊǾ¡¿ìÉý¼¶µ½Ð°棬»òÕß½«mailº¯ÊýÀ­ÈëÄãµÄºÚÃûµ¥Ö®ÁС£

¡¡¡¡Õâ¸ö©¶´µÄ±¾ÖÊÊÇÔÚÓÚ´¦ÀíÊý¾ÝµÄʱºòÀí½â²»Ò»ÖÂÔì³ÉµÄ£¬ÉÔ΢°ÑÒÔÇ°µÄһЩÎÊÌâ½áºÏÆðÀ´ºÜÈÝÒ×·¢ÏÖÕâ·½ÃæµÄÓ°×Ó¡£phpÓëMysql´¦Àí²»Ò»Öµ¼ÖÂ×¢É䣬³ÌÐò´¦ÀíºÍä¯ÀÀÆ÷´¦Àíhtml²»Ò»Öµ¼ÖÂxss£¬´¦Àíxml²»Ò»Öµ¼ÖÂxml×¢Éä....ÕâÀïÓÖ¿´µ½ÔÚlinux shell´¦ÀíÉÏ»¹Óв»Ò»ÖµÄʱºòµ¼ÖÂÃüÁî×¢Éä¡£¿ÉÒÔÔ¤ÁÏ£¬ÔÚperlµÈÆäËû½Å±¾ÓïÑÔÀÉæ¼°×Ö·û¼¯´¦ÀíµÄµØ·½Ò»Ñù»á²úÉúÕâÑùµÄÎÊÌâ¡£×Ö·û¼¯´ú±íÁËϵͳÊÇÈçºÎ¶Ô´ýÊäÈëµÄÊý¾Ý£¬×Ö·û¼¯²»Ò»Ñù£¬ÏµÍ³µÃµ½µÄÐÅÏ¢¾Í²»Ò»Ñù£¬ÔÚһЩ×Ö·û¼¯ÖУ¬Ö»Òª,¡¯,|ÕâЩÌØÊâ×Ö·ûÂäÔÚ¿í×Ö½ÚµÚ¶þ¸ö×Ö½Ú·¶Î§Ö®ÖеÄʱºò¾Í»áµ¼ÖÂÎÊÌ⣬ƩÈç

¡¡¡¡SJIS

¡¡¡¡[x20-x7e]|[xa1-xdf]|([x81-x9f]|[xe0-xef])([x40-x7e]|[x80-xfc])

¡¡¡¡x40-x7e¾Í°üÀ¨ÁËx5c£¬µ¼ÖÂÎÊÌâ³öÏÖ¡£ÎÒÃÇÔÚÉè¼Æ³ÌÐòÔÚ´¦ÀíÓëÆäËû²ãÃæµÄ³ÌÐò»òÕßЭÒé´ò½»µÀµÄʱºò¾ÍÒª¿¼ÂǺÃÕâ¸öÒòËØ£¬×öºÃ´¦ÀíµÄÒ»Ö£¬±ÜÃâ³öÏÖÎÊÌâ¡£ÔÙ´ÎÏòStefan EsserÖ£¬Stefan Esser is my hero! £º£©

°²È«ÆµµÀ php ×îб¨µÀ

°²È«ÆµµÀ ×Ö½Ú ×îб¨µÀ

[an error occurred while processing this directive]