1. 程式人生 > 其它 >ofaReporter-子域名報告生成工具

ofaReporter-子域名報告生成工具

OneforallReporter

作者:Mi2ac1e

部落格:https://www.cnblogs.com/tysec/

最近一直在看Key師傅的星球,偶然發現他曾經寫了一個專案,在視訊中叫"Subdscan",但是似乎在網上的專案叫"SubDRepoter",在我眼中的亮點就是:生成的HTML報告可以直接看到網站的截圖,這省了我大量的時間。於是就想著鍛鍊一下自己,模仿著寫一個出來。(而且該專案在Key師傅的Github上似乎沒有了...)

由於目前子域名收集我覺得不錯的專案就是Oneforall,所以省略了自己再寫一個子域名收集的功能了,用Oneforall真的太香了。

基於上述,我將該專案命名為Oneforall Reporter

0x01工具概述

能夠針對Oneforall的json格式的結果生成一份報告,該報告包含:網站的截圖,網站的標題,網站的域名(還可以直接點選就能開啟),網站的IP,網站的狀態

0x02程式架構

這裡有一處寫錯了,儲存url的txt檔名應該是與json的檔名一致

0x03程式碼實現

你可以使用Oneforall的 --fmt json 來指定Oneforall輸出為JSON格式,方便工具工作

1.建立專案目錄

rname=input("[input]Named your Project,Don't use any symbol such as xx.com:")
pwd=os.getcwd()
os.mkdir(pwd+'/'+rname)
os.makedirs(pwd+'/'+rname+'/'+'Screen')
print("[info]The project has been established")

此處用了getcwd來獲取當前路徑,之後使用mkdir來建立第一層目錄

之後使用makedirs來建立第二層目錄:Screen用以儲存螢幕截圖

2.讀取JSON中的URL

為了能夠多個專案一起執行,修改了之前的程式碼,json檔名由使用者輸入:

import json
json_name=input("[input]Input your json file name such as:tysec Do not include suffixes: ")
def urlwrite():
    with open(json_name+'.json','r',encoding='utf-8')as fp:
        json_data=json.load(fp)
    # print(json_data)

        for urls in json_data:
            f=open(json_name+'.txt','a+')
            f.write(urls['url']+'\n')

urlwrite()
print("[info]Urls has been writen")

在這裡我遇到了之前沒了解的內容

首先載入json使用了:

json_data=json.load(fp) 此時json_data的資料型別為:list

即這種型別:[{'url':'https://www.target.com'},{'url':'https://target.com'}]

現在需要從字典當中取出url對應的值

所以需要使用:

for urls in json_data

此時的urls型別就是字典了

{'url':'https://www.target.com'}

於是就可以使用urls['url']來取值,最後不要忘記:每個url換行:'\n'

3.讀取

讀取由第二步建立的$json_name$.txt

url_list=[]
f=open(json_name+'.txt','r')
for lines in f:
   url_list.append(lines)
f.close()
print("[info]url list has been loaded")
url_list_lengh=len(url_list)

4.截圖功能

網站截圖功能作為本專案的最關鍵的地方,也算是耗時不少。首先就是這個ChromeDriver.exe 我的天...簡直要命,嘗試了網際網路上的很多方法後,終於呼叫成功了:我將它放在了python安裝目錄,即可呼叫

程式碼如下:

from selenium import webdriver
from time import sleep
from selenium.webdriver.chrome.options import Options
def ChromeDriverNOBrowser():
   chrome_options = Options()
   chrome_options.add_argument('--headless')
   chrome_options.add_argument('--disable-gpu')
"""
在我把這個ofaReporter移植到我的攻擊平臺的時,他出現了這樣的提示:
cannot find Chrome binary
你可以指定你的Chrome安裝路徑:
chrome_options.binary_location = "C:\Program Files\Google\Chrome\Application\chrome.exe"
你需要自己更改一下你的Chrome安裝目錄
"""
   driverChrome = webdriver.Chrome(options=chrome_options)
   return driverChrome

driver=ChromeDriverNOBrowser()
driver.set_window_size(1920,1080)
i=0
for i in range(int(url_list_lengh)):
   try:

      driver.get(url_list[i])
      sleep(1)
#網頁截圖並儲存
      driver.get_screenshot_as_file(rname+'/'+'Screen/'+str(i)+'.png')
      print("The"+str(i)+"pictrue has been capture")
   except:
      print("[--Error--]")
print("[info]Screen capture has been Finished")

5.生成報告功能

我使用jinja2來完成

你可以使用:pip3 install jinja2

python生成模板部分如下:

from jinja2 import Environment, FileSystemLoader
def generate_html(body,starttime):
    env = Environment(loader=FileSystemLoader('./'))
    template = env.get_template('template.html')#模板檔案
    with open(rname+'/'+"result.html",'w+') as fout:
        html_content = template.render(start_time=starttime ,
                                        body=body,


                                        )
        fout.write(html_content)

body = []
pic = []
k=0#用來連結圖片

with open(rname+'.json', 'r', encoding='utf-8')as res:
    json_data = json.load(res)
    for mdata in json_data:
        picpath = {'pic_path': 'Screen/' + str(k) + '.png'}
        mdata.update(picpath)
        result=mdata
        body.append(result)

        k = k + 1

generate_html(body,2021)
print("[info]Finished")


在這裡需要解決的就是:將圖片路徑也新增到字典當中,這裡我使用的update來實現將pic_path新增到讀取的字典當中。最後直接將result新增到body列表當中

下面是jinja2的html模板:

懶人福利,直接引用了bootstrap4

<!DOCTYPE html>
<html lang="en">

<head>
    <script type="text/javascript" src="../js/jquery-3.5.1.min.js"></script>
    <script type="text/javascript" src="../js/bootstrap.min.js"></script>
    <script type="text/javascript" src="../js/popper.min.js"></script>
    <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="../css/style.css">
    <title>OneforallReporter</title>
</head>
<body>
<div class="container">

<h1 style="text-align: center">Auth:Mi2ac1e</h1>
<h1 style="text-align: center">Report:{{start_time}}</h1>
</div>
{% for item in body %}
<div class="container">
    <div class="row">
        <div class="col-md-auto">
<img src="{{item.pic_path}}" class="pic">
        </div>
        <div class="col-md-auto">
            <p style="font-size: 30px">{{item.title}}</p>
<a href="{{item.url}}" target="_blank" style="font-size: 25px">{{item.url}}</a><br><br>

<p style="font-size: 25px">IP:{{item.ip}}</p><br>
<p style="font-size: 25px">status:{{item.status}}</p>
        </div>
    </div>
</div>
<br>
{% endfor%}
<p style="text-align: center">本工具想法源自Key師傅曾提到的Subdscan</p>
</body>
</html>

{{start_time}}佔位符,對應python中的:

  html_content = template.render(start_time=starttime , body=body)
   generate_html(body,2021)

即:最終會在{{start_time}}這裡生成2021(後續打算把這個time變成生成專案的時間)

之後你應該用:

{% for item in body %}開始你的body部分

諸如{{item.title}} 這種,都是從前面的mdata字典中取出來的值,其中你的佔位符item.xxx的xxx應該與字典的key值保持一致。

{% endfor%}最後結束你的body部分

這裡有個小細節:我把a標籤添加了target="_blank"他可以使得你點選連結就可以開啟一個新的標籤,而不是在當前選項卡開啟新的網站。

0x04執行截圖



0x05不足

  1. 工具並沒有對狀態碼進行篩選,404的頁面,打不開的頁面統統會被截圖並被呈現到報告當中。

  2. 工具執行速度一般,有一些冗餘程式碼

  3. http,https重複截圖

0x06總結與致謝

感謝Key師傅的之前某一次的分享,讓我知道了這種思路並付諸實踐。期間遇到了些小問題,也學習到了不少知識。當然目前的程式碼只能說停留在"能用,可以實現最基本的功能"當中。但優化並不是很好。下一步肯定需要優化一下程式碼。