Cendertron,動態爬蟲與敏感信息泄露檢測

Cendertron,動態爬蟲與敏感信息泄露檢測

Cendertron = Crawler + Rendertronphp

Cendertron https://url.wx-coder.cn/HinPM 是基於 Puppeteer 的 Web 2.0 動態爬蟲與敏感信息泄露檢測工具。其依託於 xe-crawler 的通用爬蟲、調度與緩存模型,新增了 Monkey Test 以及 Request Intercept 等特性,以期儘量多地挖掘頁面與請求。同時針對滲透測試的場景,Cendertron 內置了目錄掃描、敏感文件掃描的能力,可以模擬用戶實際在瀏覽器登陸狀態下的自定義字典爆破。Cendertron 在大量實踐的基礎上設置了自身的去重策略,可以儘量地避免重複爬取,加快掃描速度。Cendertron 同時也是正在閉源開發的 Chaos-Scanner 模塊化安全掃描解決方案的一部分,爲基礎掃描與智能掃描提供前置輸入。git

Usage | 使用

Locally Development | 本地開發

在本地開發中,咱們只須要如正常的 Node 項目同樣啓動,其會使用 Puppeteer 內置的 Headless Chrome 來執行界面渲染操做:github

$ git clone https://github.com/wx-chevalier/Chaos-Scanner
$ cd cendertron
$ yarn install
$ npm run dev
複製代碼

啓動以後能夠按提示打開瀏覽器界面:web

這裏咱們能夠以 DVWA 做爲測試目標,在輸入框內輸入 http://localhost:8082/ 而後執行爬取,便可獲得以下結果:算法

{
  "isFinished": true,
  "metrics": {
    "executionDuration": 116177,
    "spiderCount": 51,
    "depth": 4
  },
  "spiderMap": {
    "http://localhost:8082/vulnerabilities/csrf/": [
      {
        "url": "http://localhost:8082/vulnerabilities/view_source.php?id=csrf&security=low",
        "parsedUrl": {
          "host": "localhost:8082",
          "pathname": "/vulnerabilities/view_source.php",
          "query": {
            "id": "csrf",
            "security": "low"
          }
        },
        "hash": "localhost:8082#/vulnerabilities/view_source.php#idsecurity",
        "resourceType": "document"
      }
      // ...
    ]
  }
}
複製代碼

須要說明的是,由於 DVWA 是須要登陸後爬取,所以若是想進行完整的測試請參考下文的 POST 方式建立任務。chrome

Deploy in Docker | 部署在 Docker 中

# build image
$ docker build -t cendertron .

# run as contaner
$ docker run -it --rm -p 3033:3000 --name cendertron-instance cendertron

# run as container, fix with Jessie Frazelle seccomp profile for Chrome.
$ wget https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json -O ~/chrome.json
$ docker run -it -p 3033:3000 --security-opt seccomp=$HOME/chrome.json --name cendertron-instance cendertron

# or
$ docker run -it -p 3033:3000 --cap-add=SYS_ADMIN --name cendertron-instance cendertron

# use network and mapping logs
$ docker run -d -p 3033:3000 --cap-add=SYS_ADMIN --name cendertron-instance --network wsat-network cendertron
複製代碼

Deploy as FC | 以函數式計算方式部署

Install cendertron from NPM:docker

# set not downloading chromium
$ PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true

$ yarn add cendertron
# or
$ npm install cendertron -S
複製代碼

Import Crawler and use in your code:npm

const crawler = new Crawler(browser, {
  onFinish: () => {
    callback(crawler.spidersRequestMap);
  }
});

let pageUrl =
  evtStr.length !== 0 && evtStr.indexOf('{') !== 0
    ? evtStr
    : 'https://www.aliyun.com';

crawler.start(pageUrl);
複製代碼

If you want to use it in Alibaba Function Computing Service, cendertron-fc provides simple template.json

Strategy | 策略

Cendertron 的內部架構以下所示:瀏覽器

Crawler Scheduler 會負責按期重啓 Headless Chrome 以控制緩存,而且針對待爬取的請求返回已緩存的內容。Crawler Scheduler 會爲每一個無緩存的目標建立 Crawler,Crawler 會根據策略建立不一樣的 Spider,每一個 Spider 依次執行而且將結果推送到 Crawler 中;Crawler 在所有 Spider 執行完畢後會將結果推送到緩存而且通知 Crawler Scheduler:

export interface CrawlerOption {
  // 爬取深度,若是設置爲 1 就是單頁面爬蟲
  depth: number;
  // 爬蟲的惟一編號
  uuid?: string;
  // 爬蟲緩存
  crawlerCache?: CrawlerCache;

  // 單頁面爬取出的最多的子節點數
  maxPageCount: number;
  // 總站點的總延時
  timeout: number;
  // 單頁面的延時
  pageTimeout: number;

  // 是否僅爬取同站內容
  isSameOrigin: boolean;
  // 是否忽略媒體資源
  isIgnoreAssets: boolean;
  // 是否設置爲移動模式
  isMobile: boolean;
  // 是否開啓緩存
  useCache: boolean;
  // 是否使用弱口令掃描
  useWeakfile: boolean;

  // 頁面 Cookie
  cookie: string;
  // 頁面的 localStorage
  localStorage: object;
}
複製代碼

模擬操做

Cendertron 內置了 Click Monkey, Gremlins 等多種隨機執行器,會點擊按鈕而且執行一些隨機操做:

function initGermlins() {
  gremlins
    .createHorde()
    .gremlin(gremlins.species.formFiller())
    .gremlin(gremlins.species.clicker().clickTypes(['click']))
    .gremlin(gremlins.species.toucher())
    .gremlin(gremlins.species.scroller())
    .gremlin(function() {
      if ('$' in window) {
        window.$ = function() {};
      }
    })
    .unleash();
}
複製代碼

請求監聽與提取

Cendertron 會監聽打開的頁面與全部的 Ajax 請求:

await page.setRequestInterception(true);

// 設置目標監聽
const targetCreatedListener = (target: puppeteer.Target) => {
  const opener = target.opener();

  if (!opener) {
    return;
  }

  // 記錄全部新打開的界面
  opener.page().then(_page => {
    if (_page === page) {
      target.page().then(_p => {
        if (!_p.isClosed()) {
          openedUrls.push(target.url());
          _p.close();
        }
      });
    }
  });
};

// 監聽全部當前打開的頁面
browser.on('targetcreated', targetCreatedListener);

page.on('request', interceptedRequest => {
  // 屏蔽全部的圖片
  if (isMedia(interceptedRequest.url())) {
    interceptedRequest.abort();
  } else if (
    interceptedRequest.isNavigationRequest() &&
    interceptedRequest.redirectChain().length !== 0
  ) {
    interceptedRequest.continue();
  } else {
    interceptedRequest.continue();
  }

  requests.push(transformInterceptedRequestToRequest(interceptedRequest));

  // 每次調用時候都會回調函數
  cb(requests, openedUrls, [targetCreatedListener]);
});
複製代碼

URL 歸一化與過濾

所謂的 URL 歸一化,就是將同一資源下被隨機串處理的 Path 們泛化成同一個 Pattern,從而減小重複爬取的數目;固然,在安全掃描的場景下咱們須要進行儘量地去重,而在數據爬取的場景下,則每每不須要進行過多的過濾。目前 Cendertron 只是採起了簡單的 UTL 歸一化算法,而且使用 Set 進行過濾,若是你想了解更復雜的 URL 歸一化與聚類算法,能夠參考天然語言處理 https://url.wx-coder.cn/JcINy 或者哈希表實戰 https://url.wx-coder.cn/WfdWP 中的關聯章節。

export function hashUrl(url: string): string {
  // 將 URL 進行格式化提取
  const _parsedUrl = parse(url, url, true);

  let urlHash = '';

  if (!_parsedUrl) {
    return urlHash;
  }

  // 提取出 URL 中的各個部分
  const { host, pathname, query, hash } = _parsedUrl;

  // 判斷是否存在查詢參數
  const queryKeys = Object.keys(query).sort((k1, k2) => (k1 > k2 ? 1 : -1));

  if (queryKeys.length > 0) {
    // 若是存在查詢參數,則默認全路徑加查詢參數進行解析
    urlHash = `${host}#${pathname}#${queryKeys.join('')}`;
  } else {
    // 若是不存在查詢參數,則去除 pathname 的最後一位,而且添加進來
    const pathFragments = pathname.split('/');

    // 判斷路徑是否包含多個項目,若是包含,則將全部疑似 UUID 的替換爲 ID
    if (pathFragments.length > 1) {
      urlHash = `${host}#${pathFragments .filter(frag => frag.length > 0) .map(frag => (maybeUUID(frag) ? 'id' : frag)) .join('')}`;
    } else {
      urlHash = `${host}#${pathname}`;
    }
  }

  if (hash) {
    const hashQueryString = hash.replace('#', '');
    const queryObj = parseQuery(hashQueryString);
    Object.keys(queryObj).forEach(n => {
      if (n) {
        urlHash += n;
      }
    });
  }

  return urlHash;
}
複製代碼

權限認證

以 DVWA 爲例,能夠用 Docker 快速開啓測試環境:docker run --rm -it -p 8082:80 vulnerables/web-dvwa,而後向 /scrape 提交 POST 請求:

{
  "url": "http://localhost:8082/vulnerabilities/csrf/",
  "cookies": "tid=xx; PHPSESSID=xx; security=low"
}
複製代碼

在 Cendertron 中,其會使用以下方式設置 Cookie:

const puppeteer = require('puppeteer');

let rockIt = async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  var cookie = [
    // cookie exported by google chrome plugin editthiscookie
    {
      domain: 'httpbin.org',
      expirationDate: 1597288045,
      hostOnly: false,
      httpOnly: false,
      name: 'key',
      path: '/',
      sameSite: 'no_restriction',
      secure: false,
      session: false,
      storeId: '0',
      value: 'value!',
      id: 1
    }
  ];
  await page.setCookie(...cookie);
  await page.goto('https://httpbin.org/headers');
  console.log(await page.content());
  await page.close();
  await browser.close();
};
rockIt();
複製代碼

將來也會支持 localStorage 等存儲方式:

await page.evaluate(() => {
  localStorage.setItem('token', 'example-token');
});
複製代碼
相關文章
相關標籤/搜索