0x00
±³¾°
Ò»°ãͨÓÃweb³ÌÐòÊÇÈç¹ûÏëÖªµÀÍøÕ¾ÓòÃû²»ÊÇÒ»¼þ¼òµ¥µÄÊÂÇ飬Èç¹ûÓÃÒ»¸ö¹Ì¶¨µÄURIÀ´×÷ΪÓòÃû»áÓи÷ÖÖÂé·³¡£¿ª·¢ÈËÔ±Ò»°ãÊÇÒÀÀµHTTP
Host header£¨±ÈÈçÔÚphpÀïÊÇ_SERVER["HTTP_HOST"] £©£¬¶øÕâ¸öheaderºÜ¶àÇé¿öÏÂÊÇ¿¿²»×¡µÄ¡£¶øºÜ¶àÓ¦ÓÃÊÇÖ±½Ó°ÑÕâ¸öÖµ²»×öhtml±àÂë±ãÊä³öµ½ÁËÒ³ÃæÖУ¬±ÈÈ磺
<link href="http://_SERVER['HOST']" (Joomla) |
»¹Óеĵط½»¹°üº¬ÓÐsecret keyºÍtoken£¬
<link href="http://_SERVER['HOST']" (Joomla) |
ÕâÑù´¦ÀíÎÊÌâÒ»°ã»áºÜÈÝÒ×ÔâÓöµ½Á½ÖÖ³£¼ûµÄ¹¥»÷£º»º´æÎÛȾºÍÃÜÂëÖØÖ᣻º´æÎÛȾÊÇÖ¸¹¥»÷Õßͨ¹ý¿ØÖÆÒ»¸ö»º´æÏµÍ³À´½«Ò»¸ö¶ñÒâÕ¾µãµÄÒ³Ãæ·µ»Ø¸øÓû§¡£ÃÜÂëÖØÖÃÕâÖÖ¹¥»÷Ö÷ÒªÊÇÒòΪ·¢Ë͸øÓû§µÄÄÚÈÝÊÇ¿ÉÒÔÎÛȾµÄ£¬Ò²¾ÍÊÇ˵¿ÉÒÔ¼ä½ÓµÄ½Ù³ÖÓʼþ·¢ËÍÄÚÈÝ¡£
0x01 ÃÜÂëÖØÖÃÎÛȾ¹¥»÷
Äà Gallery Õâ¸öÕ¾À´×öÀý×Ó¡£µ±ÎÒÃǽøÐÐÃÜÂëÖØÖõÄʱºò£¬ÍøÕ¾»á¸øÎÒÃÇ·¢ËÍÒ»¸öËæ»úµÄkey£º
$user -> hash = random::hash() ; $message -> confirm_url = url::abs_site("password/do_reset?key=$user->hash") |
µ±Óû§µã»÷ÖØÖÃÃÜÂëµÄÁ´½Óʱ£¬¿Ï¶¨¿ÉÒÔ˵Ã÷µãµÄÊÇ×Ô¼ºµÄÕË»§¡£

Õâ¸öµØ·½µÄ©¶´ÊÇ£º url::abs_site ÕâÒ»²¿·ÖʹÓõÄHost headerÊÇÀ´×ÔÓû§ÖØÖÃÃÜÂëµÄÇëÇó£¬ÄÇô¹¥»÷Õß¿ÉÒÔͨ¹ýÒ»¸öÊÜËû¿ØÖƵÄÁ´½ÓÀ´ÎÛȾÃÜÂëÖØÖõÄÓʼþ¡£
> POST /password/reset HTTP/1.1 > Host: evil.com > ... > csrf=1e8d5c9bceb16667b1b330cc5fd48663&name=admin |
Õâ¸ö©¶´ÔÚDjango£¬Piwik ºÍJoomlaÖж¼´æÔÚ£¬»¹ÓÐһЩÆäËûµÄÓ¦Ó㬿ò¼ÜºÍÀà¿â¡£
µ±È»ÕâÖÖ¹¥»÷·½Ê½Ò»¶¨ÒªÄÜÆÈ¡Óû§µã»÷·ÃÎÊÕâ¸öÊÜÎÛȾµÄÁ´½Ó£¬Èç¹ûÓû§¾¯¾õÁËûÓеã»÷£¬ÄÇô¹¥»÷¾Í»áʧ°Ü¡£µ±È»Äã×Ô¼ºÒ²¿ÉÒÔÅäºÏһЩÉç»á¹¤³ÌѧµÄ·½·¨À´±£Ö¤¹¥»÷µÄ³É¹¦ÂÊ¡£
»¹ÓÐһЩÇé¿ö£¬Host¿ÉÄܻᱻurl±àÂëºóÖ±½Ó·Åµ½emailµÄheaderÀïÃæÔì³Éheader×¢È롣ͨ¹ýÕâ¸ö£¬¹¥»÷Õß¿ÉÒÔºÜÈÝÒ׵ľÍÄܽٳÖÓû§µÄÕË»§¡£
0x02 »º´æÎÛȾ
ͨ¹ýHost headerÀ´ÎÛȾ»º´æµÄ¹¥»÷·½·¨×î³õÊÇCarlos Beuno ÔÚ2008ÄêÌá³öÀ´µÄ¡£µ«ÊÇÔÚÏÖÔÚµÄÍøÂç¼Ü¹¹ÖУ¬ÕâÖÖ¹¥»÷»¹ÊDZȽÏÀ§Äѵģ¬ÒòΪÏÖÔڵĻº´æÉ豸¶¼Äܹ»Ê¶±ðHost¡£±ÈÈç¶ÔÓÚÏÂÃæµÄÕâÁ½ÖÖÇé¿öËûÃǾø¶Ô²»»áŪ»ìÏý£º
> GET /index.html HTTP/1.1 > GET /index.html HTTP/1.1 > Host: example.com > Host: evil.com |
Òò´ËΪÁËÄÜʹ»º´æÄܽ«ÎÛȾºóµÄresponse·µ»Ø¸øÓû§£¬ÎÒÃÇ»¹±ØÐëÈûº´æ·þÎñÆ÷¿´µ½µÄhost header
ºÍÓ¦Óÿ´µ½µÄhost header ²»Ò»Ñù¡£±ÈÈç˵¶ÔÓÚVarnish£¨Ò»¸öºÜÓÐÃûµÄ»º´æ·þÎñÈí¼þ£©£¬¿ÉÒÔʹÓÃÒ»¸ö¸´ÖƵÄHost
header¡£VarnishÊÇͨ¹ý×îÏȵ½´ïµÄÇëÇóµÄhost headerÀ´±æ±ðhostµÄ£¬¶øApacheÔòÊÇ¿´ËùÓÐÇëÇóµÄhost£¬NginxÔòÖ»ÊÇ¿´×îºóÒ»¸öÇëÇóµÄhost¡£Õâ¾ÍÒâζ×ÅÄã¿ÉÒÔͨ¹ýÏÂÃæÕâ¸öÇëÇóÀ´ÆÛÆVarnish´ïµ½ÎÛȾµÄÄ¿µÄ£º
> GET / HTTP/1.1 > Host: example.com > Host: evil.com |
Ó¦Óñ¾ÉíµÄ»º´æÒ²¿ÉÄÜÊܵ½ÎÛȾ¡£±ÈÈçJoomla¾Í½«È¡µÃµÄhostÖµ²»¾html±àÂë±ãд½øÈÎÒâÒ³Ãæ£¬¶øËüµÄ»º´æÔò¶ÔÕâЩûÓÐÈκδ¦Àí¡£±ÈÈç¿ÉÒÔͨ¹ýÏÂÃæµÄÇëÇóÀ´Ð´ÈëÒ»¸ö´æ´¢Ð͵Äxss£º
curl -H "Host: cow\"onerror='alert(1)'rel='stylesheet'" http://example.com/ | fgrep cow\" |
ʵ¼ÊÉϵÄÇëÇóÊÇÕâÑùµÄ£º
> GET / HTTP/1.1 > Host: cow"onerror='alert(1)'rel='stylesheet' |
ÏìÓ¦ÆäʵÒѾÊܵ½ÎÛȾ£º
<link href="http://cow"onerror='alert(1)'rel='stylesheet'/" rel="canonical"/> |
ÕâʱֻÐèÒªä¯ÀÀÊ×Ò³¿´ÊÇ·ñÓе¯´°¾ÍÖªµÀ»º´æÊÇ·ñÒѾ±»ÎÛȾÁË¡£
0x03 °²È«µÄÅäÖÃ
ÔÚÕâÀïÎÒ¼ÙÉèÄã¿ÉÒÔͨ¹ýÈκÎÀàÐ͵ÄÓ¦ÓÃÀ´·¢ÆðÒ»¸öhttpÇëÇ󣬶øhost headerÒ²ÊÇ¿ÉÒÔÈÎÒâ±à¼µÄ¡£ËäÈ»ÔÚÒ»¸öhttpÇëÇóÀhost
headerÊÇÓÃÀ´¸æËßwebserver¸ÃÇëÇóÓ¦¸Ãת·¢¸øÄĸöÕ¾µã£¬µ«ÊÇÊÂʵÉÏ£¬Õâ¸öheaderµÄ×÷ÓûòÕß˵·çÏÕ²¢²»Ö¹Èç´Ë¡£
±ÈÈçÈç¹ûApache½ÓÊÕµ½Ò»¸ö´øÓзǷ¨host headerµÄÇëÇó£¬Ëü»á½«´ËÇëÇóת·¢¸øÔÚ httpd.conf
ÀﶨÒåµÄµÚÒ»¸öÐéÄâÖ÷»ú¡£Òò´Ë£¬ApacheºÜÓпÉÄܽ«´øÓÐÈÎÒâhost headerµÄÇëÇóת·¢¸øÓ¦Ó᣶øDjangoÒѾÒâʶµ½ÁËÕâ¸öȱÏÝ£¬ËùÒÔËü½¨ÒéÓû§ÁíÍ⽨Á¢Ò»¸öĬÈϵÄÐéÄâÖ÷»ú£¬ÓÃÀ´½ÓÊÜÕâЩ´øÓзǷ¨host
headerµÄÇëÇó£¬ÒÔ±£Ö¤Django×Ô¼ºµÄÓ¦Óò»½ÓÊܵ½ÕâЩÇëÇó¡£
²»¹ý¿ÉÒÔͨ¹ýX-Forwarded-Host Õâ¸öheader¾Í¿ÉÒÔÈÆ¹ý¡£Django·Ç³£Çå³þ»º´æÎÛȾµÄ·çÏÕ£¬²¢ÇÒÔÚ2011ÄêµÄ9Ô·ݾÍͨ¹ýĬÈϽûÓÃX-Forwarded-HostÕâ¸öheaderÀ´ÐÞ¸´´ËÎÊÌâ¡£MozillaÈ´ÔÚaddons.mozilla.orgÕ¾µãºöÊÓÁË´ËÎÊÌ⣬ÎÒÔÚ2012ÄêµÄ4Ô·¢ÏÖÁË´ËÎÊÌ⣺
> POST /en-US/firefox/user/pwreset HTTP/1.1 > Host: addons.mozilla.org > X-Forwarded-Host: evil.com |
¼´Ê¹Django¸ø³öÁ˲¹¶¡£¬µ«ÊÇÒÀÈ»´æÔÚ·çÏÕ¡£WebserverÔÊÐíÔÚhost headerÀïÃæÖ¸¶¨¶Ë¿Ú£¬µ«ÊÇËü²¢²»ÄÜͨ¹ý¶Ë¿ÚÀ´Ê¶±ðÇëÇóÊǶÔÓ¦µÄÄĸöÐéÄâÖ÷»ú¡£¿ÉÒÔͨ¹ýÏÂÃæµÄ·½·¨À´Èƹý£º
> POST /en-US/firefox/user/pwreset HTTP/1.1 > Host: addons.mozilla.org:@passwordreset.net |
ÕâÖ±½Ó»áµ¼ÖÂÉú³ÉÒ»¸öÃÜÂëÖØÖÃÁ´½Ó£º
https://addons.mozilla.org:@passwordreset.net/users/pwreset/3f6hp/3ab-9ae3db614fc0d0d036d4
µ±Óû§µã»÷Õâ¸öÁ´½ÓµÄʱºò¾Í»á·¢ÏÖ£¬ÆäʵÕâ¸ökeyÒѾ±»·¢Ë͵½passwordreset.netÕâ¸öÕ¾µãÁË¡£ÔÚÎÒ±¨¸æÁË´ËÎÊÌâºó£¬DjangoÓÖÍÆ³öÁËÒ»¸ö²¹¶¡£ºhttps://www.djangoproject.com/weblog/2012/oct/17/security/
²»ÐÒµÄÊÇ£¬Õâ¸ö²¹¶¡Ö»ÊǼòµ¥µÄͨ¹ýºÚÃûµ¥·½Ê½À´¼òµ¥µÄ¹ýÂ˵ôÁË@ºÍÆäËûһЩ×Ö·û¡£¶øÓÉÓÚÃÜÂëÖØÖÃÁ´½ÓÊÇÒÔ´¿Îı¾¶ø²»ÊÇhtmlµÄ·½Ê½·¢Ë͵ģ¬ËùÒԴ˲¹¶¡Ö»ÐèÒªÌí¼ÓÒ»¸ö¿Õ¸ñ¾Í¿ÉÒÔÈÆ¹ý£º
> POST /en-US/firefox/users/pwreset HTTP/1.1 > Host: addons.mozilla.org: www.securepasswordreset.com |
DjangoµÄºóÐø²¹¶¡¹æ¶¨ÁËhost headerµÄ¶Ë¿Ú²¿·ÖÖ»ÄÜÊǺ¬ÓÐÊý×Ö£¬ÒÔ¹æ±Ü´ËÎÊÌâ¡£µ«ÊÇÔÚRFC2616ÎĵµÖй涨ÁË£¬Èç¹ûÇëÇóURIÊÇÒ»¸ö¾ø¶ÔµÄURI£¬ÄÇôhostÊÇRequest-URIµÄÒ»²¿·Ö¡£ÔÚÇëÇóÖеÄÈκÎHost
headerÖµ±ØÐë±»ºöÂÔ¡£
Ò²¾ÍÊÇ˵£¬ÔÚApacheºÍNginx£¨Ö»ÒªÊÇ×ñÊØ´ËÎĵµµÄwebserver£©ÖУ¬¿ÉÒÔͨ¹ý¾ø¶ÔuriÏòÈÎÒâÓ¦Ó÷¢ËÍÒ»¸ö°üº¬ÓÐÈÎÒâhost
headerµÄÇëÇó£º
> POST https://addons.mozilla.org/en-US/firefox/users/pwreset HTTP/1.1 > Host: evil.com |
Õâ¸öÇëÇóÔÚSERVER_NAMEÀïÃæµÄÖµÊÇaddons.mozilla.org£¬¶ø²»ÊÇhostÀïµÄevil.com¡£Ó¦ÓÿÉÒÔͨ¹ýʹÓÃSERVER_NAME¶ø²»ÊÇhost
headerÀ´¹æ±Ü´Ë·çÏÕ£¬µ«ÊÇÈç¹ûûÓÐÅäºÏÌØÊâÅäÖõÄwebserver£¬Õâ¸ö·çÏÕÒÀÈ»´æÔÚ¡£¿ÉÒÔÔÚÕâÀïhttp://stackoverflow.com/questions/2297403/http-host-vs-server-name/2297421#2297421¿´¿´
HTTP_HOST ºÍSERVER_NAME µÄÇø±ð¡£Django¹Ù·½ÔÚ2013ÄêµÄ¶þÔÂͨ¹ýÇ¿ÖÆÊ¹ÓÃÒ»¸öhost°×Ãûµ¥À´ÐÞ¸´ÁË´ËÎÊÌâ¡£¾¡¹ÜÈç´Ë£¬ÔںܶàÆäËûµÄwenÓ¦ÓÃÉÏ£¬ÕâÖÖ¹¥»÷·½Ê½ÒÀÈ»ÂÅÊÔ²»Ë¬¡£
0x04 ·þÎñÆ÷·½ÃæÐèÒª×öµÄ
ÓÉÓÚhttpÇëÇóµÄÌØµã£¬host headerµÄÖµÆäʵÊDz»¿ÉÐŵġ£Î¨Ò»¿ÉÐŵÄÖ»ÓÐSERVER_NAME£¬Õâ¸öÔÚApacheºÍNginxÀï¿ÉÒÔͨ¹ýÉèÖÃÒ»¸öÐéÄâ»úÀ´¼Ç¼ËùÓеķǷ¨host
header¡£ÔÚNginxÀﻹ¿ÉÒÔͨ¹ýÖ¸¶¨Ò»¸öSERVER_NAMEÃûµ¥£¬ApacheÒ²¿ÉÒÔͨ¹ýÖ¸¶¨Ò»¸öSERVER_NAMEÃûµ¥²¢¿ªÆôUseCanonicalNameÑ¡Ïî¡£½¨ÒéÁ½ÖÖ·½·¨Í¬Ê±Ê¹Óá£
VarnishºÜ¿ì»á·¢²¼Ò»¸ö²¹¶¡¡£ÔÚ¹Ù·½²¹¶¡³öÀ´Ç°£¬¿ÉÒÔͨ¹ýÔÚÅäÖÃÎļþÀï¼ÓÈ룺
import std;
sub vcl_recv {
std.collect(req.http.host);
} |
0x05 Ó¦Óñ¾ÉíÐèÒª×öµÄ
½â¾öÕâ¸öÎÊÌâÆäʵÊǺÜÀ§Äѵģ¬ÒòΪûÓÐÍêÈ«×Ô¶¯»¯µÄ·½·¨À´°ïÖúÕ¾³¤Ê¶±ðÄÄЩhost µÄÖµÊÇÖµµÃÐÅÈεġ£ËäÈ»×öÆðÀ´ÓеãÂé·³£¬µ«ÊÇ×ȫµÄ×ö·¨ÊÇ£ºÐ§·ÂDjangoµÄ·½·¨£¬ÔÚÍøÕ¾°²×°ºÍ³õʼ»¯µÄʱºò£¬ÒªÇó¹ÜÀíÔ±Ìṩһ¸ö¿ÉÐÅÈεÄÓòÃû°×Ãûµ¥¡£Èç¹ûÕâ¸öʵÏÖÆðÀ´±È½ÏÀ§ÄÑ£¬ÄÇÖÁÉÙÒ²Òª±£Ö¤Ê¹ÓÃSERVER_NAME¶ø²»ÊÇhost
header£¬²¢ÇÒ¹ÄÀøÓû§Ê¹Óð²È«ÅäÖÃ×öµÄ±È½ÏºÃµÄÕ¾µã¡£ |