<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    WebScarab如何進行腳本化插件編寫

    腳本功能有兩種不同的實現方式,取決于使用它的位置。

    在代理中-> BeanShell插件和搜索插件使用直接嵌入到插件中的BeanShell解釋器。腳本管理器和腳本化插件使用Apache Bean腳本框架。理論上,您應該能夠在這兩個地方使用BSF支持的任何語言,假設您調整類路徑以適當地包含正確的腳本jar。

    好吧,你應該看看腳本管理器中存在的hooks的完整列表,但主要是修改代理對話(代理-> BeanShell或腳本管理器->攔截{請求|響應}),或者使用腳本插件提交你自己的請求。

    使用代理>BeanShell修改對話

    這是在代理中默認安裝的標準腳本->BeanShell插件。

    import org.owasp.webscarab.model.Request;
    import org.owasp.webscarab.model.Response;
    import org.owasp.webscarab.httpclient.HTTPClient;
    import java.io.IOException;
    
    public Response fetchResponse(HTTPClient nextPlugin, Request request) throws IOException {
       response = nextPlugin.fetchResponse(request);
       return response;
    }

    如您所見,您可以使用任意的Java類(只需導入它們)。

    默認腳本顯然什么也不做。當然,您可以很容易地更改它!只需使用為請求和響應對象定義的方法(您必須使用源代碼)。

    例如,您可能想將GET更改為POST。這個未經測試的腳本勾勒出你可能如何做到這一點:

    import org.owasp.webscarab.model.Request;
    import org.owasp.webscarab.model.Response;
    import org.owasp.webscarab.httpclient.HTTPClient;
    import org.owasp.webscarab.model.HttpUrl;
    import java.io.IOException;
    
    public Response fetchResponse(HTTPClient nextPlugin, Request request) throws IOException {
       // check if we have parameters
       String query = request.getURL().getQuery();
       if (query != null) {
    
          // Construct a new HttpUrl object, since they are immutable
          // This is a bit of a cheat!
          String url = request.getURL().toString();
          url = url.substring(0,url.indexOf('?'));
          request.setURL(new HttpUrl(url));
    
          // now put the original query in the body
          // we need to update a couple of headers, too
          request.setMethod("POST");
          request.setHeader("Content-Type", "application/x-www-form-urlencoded");
          request.setHeader("Content-Length", "0");
          // the setContent method automatically updates the Content-Length header IF it exists
          request.setContent(query.getBytes());
       }
       response = nextPlugin.fetchResponse(request);
       return response;
    }

    如您所見,只需幾行代碼就可以完成很多工作。

    使用腳本管理器修改對話

    腳本管理器接口與代理> BeanShell接口有些不同。首先,截取對話分為兩部分,截取請求和截取響應。

    該接口提供了一些基本的指令。例如,“Intercept Request”表示“在瀏覽器提交新請求時調用”。使用connection.getRequest()和connection.setRequest(請求)來執行更改”。

    這里是以上腳本重寫的腳本管理器接口:

    import org.owasp.webscarab.model.Request;
    import org.owasp.webscarab.model.Response;
    import org.owasp.webscarab.httpclient.HTTPClient;
    import java.io.IOException;
    
     // NB: This is only a COPY! See below
     Request request = connection.getRequest();
    
     // check if we have parameters
     String query = request.getURL().getQuery();
     if (query != null) {
    
        // Construct a new HttpUrl object, since they are immutable
        // This is a bit of a cheat!
        String url = request.getURL().toString();
        url = url.substring(0,url.indexof('?'));
        request.setURL(new HttpUrl(url));
    
        // now put the original query in the body
        // we need to update a couple of headers, too
        request.setHeader("Content-Type", "application/x-www-form-urlencoded");
        request.setHeader("Content-Length", "0");
        // the setContent method automatically updates the Content-Length header IF it exists
        request.setContent(query.getBytes());
    
        // You have to use connection.setRequest() to make any changes take effect!
        connection.setRequest(request);
     }

    腳本插件有什么用呢?

    需要注意的重要變化是“connection”對象的使用,以及您獲得的請求對象只是實際請求的一個副本這一事實。必須調用connection.setRequest()才能使更改有效。

    腳本化插件非常適合執行一系列可以計算的請求。例如,brute使用用戶名和密碼字典來強制登錄頁面。根據對現有或不存在帳戶的不同響應列出站點的用戶。在使用弱會話標識符的站點上查找現有會話。偵察一個形式。從本質上說,這個列表受限于你自己的想象力。

    那么為什么使用這個而不是bash和netcat呢?

    腳本插件提供了一個很好的OO接口來創建請求和分析響應,這在bash中是沒有的。但最令人信服的原因可能是:

    • 它是多線程的(目前有4個并發線程,但是可以很容易地更改)。這在shell中是不容易做到的,甚至在Perl(例如libwhisker)中也是如此
    • 您可以對有趣的響應進行歸檔,以便稍后查看。只需調用“script . addconversation (response)”將其添加到摘要中。

    使用腳本插件的方法非常簡單。使用默認腳本作為模板,并修改它以適應。這個默認腳本提供了一個子程序來一次或并行地獲取響應。最簡單的方法是創建一個模板請求,可能基于摘要中的請求(例如request = script . getrequest(17)將返回request #17的副本)。然后修改模板以適應。

    然后修改
    boolean hasMoreRequests()
    當沒有更多的請求需要獲取時,返回false
    Request getNextRequest()

    返回要發送的下一個請求。

    最后,修改fetchSequentially()或fetchParallel(),以便分析返回的響應。是的,這可能也應該放在一個方法中,例如analyseResponse(Response Response)。

    做完了。單擊Start執行腳本,然后觀察它的運行。

    如果您使用的是-installer版本,那么在scripts目錄中有幾個示例,這些示例可能會給您一些啟發。

    下面是經過處理的示例腳本。最值得注意的是,已經添加了printRequest和printResponse方法,這樣您就可以輕松訪問所有數據,而不需要太多額外的編碼。也有一些地方可以打印長格式的時間。如果您正在執行某種類型的計時攻擊或分析,這是很好的。只需用此代碼替換腳本化部分中的代碼,然后編輯代碼底部的信息。

    import org.owasp.webscarab.model.HttpUrl;
    import org.owasp.webscarab.model.Request;
    import org.owasp.webscarab.model.Response;
    
    // define subroutines BEFORE the main part of the script executes,
    // otherwise they won't be found
    
    void printRequest(Request request){
    out.println("====<REQUEST>====");
    out.println(request.getMethod());
    out.println(request.getURL());
    out.println(request.getVersion());
    String[] headers=request.getHeaderNames();
    for(String header : headers){
    out.println(header+" : " + request.getHeader(header));
    }
    out.println("====</REQUEST>====");
    }
    
    void printResponse(Response response){
    out.println("====<RESPONSE>====");
    out.println(response.getStatus());
    out.println(response.getMessage());
    //print the headers
    String[] headers=response.getHeaderNames();
    for(String header : headers){
    out.println(header+" : " + response.getHeader(header));
    }
    out.println("");
    //print the content
    byte[] data=response.getContent();
    String data_response=new String(data);
    out.println(data_response);
    
    out.println("====</RESPONSE>====");
    }
    // call this to fetch the requests one after another
    void fetchSequential() {
    out.println("===================================");
    while (hasMoreRequests()) {
    request = getNextRequest();
    printRequest(request);
    response = scripted.fetchResponse(request);
    printResponse(response);
    
    //Print the time
    Date now = new Date();
    long nowLong = now.getTime();
    out.println("Current Time " + nowLong);
    out.println("");
    }
    //Print the time now that we're done
    Date now = new Date();
    long nowLong = now.getTime();
    out.println("Done - Current Time " + nowLong);
    out.println("");
    out.println("");
    }
    
    // call this to fetch them in parallel
    // the number of simultaneous connections is controlled by the Scripting plugin 
    // It is currently fixed at 4 simultaneous requests
    void fetchParallel() {
    while (hasMoreRequests() || scripted.isAsyncBusy()) {
    while (scripted.hasAsyncCapacity() && hasMoreRequests()) {
    request = getNextRequest();
    scripted.submitAsyncRequest(request);
    printRequest(request);
    }
    
    if (scripted.hasAsyncResponse()) {
    while (scripted.hasAsyncResponse()) {
    response = scripted.getAsyncResponse();
    request = response.getRequest();    
    
    }
    } else Thread.sleep(100);
    }
    }
    
    // a counter, so we can know when to stop
    int i=0;
    int TotalRequests;
    boolean hasMoreRequests() {
    return i<TotalRequests;
    }
    
    /******************************************************************************
    ***************** USER EDITABLE SCRIPT STARTS HERE ***************************
    *                                                                            *
    * Of course, you can modify the bits above, but you shouldn't need           *
    * to, if you follow the algorithm suggested below.                           *
    *                                                                            *
    ******************************************************************************/
    //====Set the number below equal to the total number of requests====
    TotalRequests=3;
    
    // modify this routine to construct the next request - no changes needed
    Request getNextRequest() {
    // create a new request copied from the template
    Request request = new Request(template);
    i++;  //need to increment the counter
    return request;
    }
    
    //====Edit this section====
    // create a template that contains the basics
    Request template = new Request();
    template.setMethod("GET");
    template.setURL(new HttpUrl("http://www.google.com"));  
    template.setVersion("HTTP/1.0");
    template.setHeader("User-Agent","WebScarab");
    template.setHeader("Host","www.google.com:80");
    template.setHeader("Accept"," text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
    template.setHeader("Accept-Language"," en-us,en;q=0.5");
    template.setHeader("Accept-Encoding"," gzip,deflate");
    template.setHeader("Accept-Charset"," ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    template.setHeader("Keep-Alive"," 300");
    template.setHeader("Proxy-Connection"," keep-alive");
    //template.setHeader("Cookie"," Some cookie values here");
    
    //====Choose Sequential or Parallel Requests====
    // Choose how to submit the requests, sequentially, or in parallel
    fetchSequential();
    //fetchParallel();

    Search插件

    搜索插件在基于任意標準的對話識別方面提供了很大的靈活性。基本上,您所需要做的就是編寫一個腳本,對于“interesting”對話返回true,對于其他對話返回false。

    通常你會使用一個簡單的表達,例如:
    request.getMethod().equals("POST")

    只顯示POSTs。

    然而,您實際上可以創建任意復雜的腳本。

    String method = request.getMethod();
    return "POST".equals(method);

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类