R3Con1Z3R代码及功能分析

栏目: 编程工具 · 发布时间: 5年前

内容简介:所以想从代码的角度去解读这个工具,并将它每一部分的功能分析一下。最后,我将它这个脚本进行了修改,可以单独取出里面的部分功能去执行。

*本文作者:ERFZE,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

前言

之前Alpha_h4ck分享了一个工具R3Con1Z3R,觉得很不错,虽然代码很简短,但是功能很强大,而且跨平台,同时支持Pyhthon2与 Python 3。

所以想从代码的角度去解读这个工具,并将它每一部分的功能分析一下。最后,我将它这个脚本进行了修改,可以单独取出里面的部分功能去执行。

另外,此文章主要面向新手及小白,大佬请自行绕过,勿喷。

脚本结构(大致如下图):

R3Con1Z3R代码及功能分析

源代码解读

1. 打印Banner部分

if sys.platform.startswith('win'):
    R, B, Y, C, W = '\033[1;31m', '\033[1;37m', '\033[93m', '\033[1;30m', '\033[0m'
    try:
        import win_unicode_console, colorama
        win_unicode_console.enable()
        colorama.init()
    except:
        print('[+] Error: Coloring libraries not installed')
        R, B, Y, C, W = '', '', '', '', ''
else:
    R, B, Y, C, W = '\033[1;31m', '\033[1;37m', '\033[93m', '\033[1;30m', '\033[0m'
# Banner Printing
def header():
    print('''%s
 _____    ____     _____    ___    _   _   __   ______  ____    _____  
|  __ \  |___ \   / ____|  / _ \  | \ | | /_ | |___  / |___ \  |  __ \ 
| |__) |   __) | | |      | | | | |  \| |  | |    / /    __) | | |__) |
|  _  /   |__ <  | |      | | | | | . ` |  | |   / /    |__ <  |  _  / 
| | \ \   ___) | | |____  | |_| | | |\  |  | |  / /__   ___) | | | \ \ 
|_|  \_\ |____/   \_____|  \___/  |_| \_|  |_| /_____| |____/  |_|  \_\  
                                                            
         %sBy https://github.com/abdulgaphy - @mrgaphy%s    >|%s       #GAPHY %s
        '''%(R, B, R, C, W))

这一部分代码没什么可看的,只是设置颜色及打印Banner,效果可以见下图:

R3Con1Z3R代码及功能分析

我的环境是Linux,Windows环境没有测试。

2. 检测参数部分

这一部分是我不太满意的地方,在我的修改版本中会有所体现。

if len(sys.argv) < 2 or len(sys.argv) > 2:
    header()
    print('{}Usage: python3 r3con1z3r.py [domain.com]\n'.format(Y, C))
    print('{}Example: python3 r3con1z3r.py google.com\n'.format(Y, C))
    print('{}[!] Please specify a domain'.format(Y, C))
    sys.exit()
else:
    url = str(sys.argv[1])

这一部分检测是否提供了domain参数,如果没有,会给出下图所示的提示:

R3Con1Z3R代码及功能分析

3. 各种API

获取HTTP头部分:

def httpHeader():
	baseApi = "http://api.hackertarget.com/httpheaders/?q=" + url
	base = requests.get(baseApi).text
	return base

该函数功能是获取响应头部分,下面的结果分别是我测试google.com及 www.baidu.com 得到的。

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Wed, 30 Jan 2019 10:53:05 GMT
Expires: Fri, 01 Mar 2019 10:53:05 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: Keep-Alive
Content-Length: 277
Content-Type: text/html
Date: Thu, 31 Jan 2019 12:14:10 GMT
Etag: 575e1f6f-115
Last-Modified: Mon, 13 Jun 2016 02:50:23 GMT
Pragma: no-cache
Server: bfe/1.0.8.18

进行反向IP查询部分:

def reverseHackTarget():

baseApi = " http://api.hackertarget.com/reverseiplookup/?q= " + url

base = requests.get(baseApi).text

return base

反向IP查找可返回单个IP上托管的域名,我在 hackertarget 的网站上进行了下面的查询:

R3Con1Z3R代码及功能分析

结果可想而知了,多得数不胜数。

路径查询部分:

def traceRoute():

baseApi = " http://api.hackertarget.com/mtr/?q= " + url

base = requests.get(baseApi).text

这一部分功能再明显不过了,路由跟踪,在 Linux 下用traceroute,在windows则是tracert都能实现此功能。

WHOIS部分:

def whoIs():

baseApi = " http://api.hackertarget.com/whois/?q= " + url

base = requests.get(baseApi).text

return base

下面是对google.com进行WHOIS查询的结果:

Domain Name: GOOGLE.COM
   Registry Domain ID: 2138514_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.markmonitor.com
   Registrar URL: http://www.markmonitor.com
   Updated Date: 2018-02-21T18:36:40Z
   Creation Date: 1997-09-15T04:00:00Z
   Registry Expiry Date: 2020-09-14T04:00:00Z
   Registrar: MarkMonitor Inc.
   Registrar IANA ID: 292
   Registrar Abuse Contact Email: abusecomplaints@markmonitor.com
   Registrar Abuse Contact Phone: +1.2083895740
   Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
   Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
   Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
   Domain Status: serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited
   Domain Status: serverTransferProhibited https://icann.org/epp#serverTransferProhibited
   Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
   Name Server: NS1.GOOGLE.COM
   Name Server: NS2.GOOGLE.COM
   Name Server: NS3.GOOGLE.COM
   Name Server: NS4.GOOGLE.COM
   DNSSEC: unsigned
   URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2019-01-30T10:53:11Z <<<

For more information on Whois status codes, please visit https://icann.org/epp



The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars.

DNS查询部分:

def dns():

baseApi = " http://api.hackertarget.com/dnslookup/?q= " + url

base = requests.get(baseApi).text

return base

结果中的A、MX、NS、TXT可以参考下图(来自TCP/IP详解卷1):

R3Con1Z3R代码及功能分析

反向DNS查询部分:

(这一部分没有出现在输出的结果中,不知是不是作者忘记写了)

def reverseDns():

baseApi = " http://api.hackertarget.com/reversedns/?q= " + url

base = requests.get(baseApi).text

return base

hackertarget 网站给出的描述:这一项查找可以通过单个IP 8.8.8.8或是某个范围内的IP 127.0.0.1-10 或是CIDR形式127.0.0.1/27。你也同样可以使用主机名比如 example.com。

根据IP获取地理位置部分:

(这一部分也没有出现在输出的结果中, hackertarget 指出此项查询目前处于测试阶段,不保证准确性)

def geoIp():

baseApi = " http://api.hackertarget.com/geoip/?q= " + url

base = requests.get(baseApi).text

return base

我对这一部分功能进行的测试发现,执行后会明显感觉到耗费时间增加。所以如果无此需求,建议使用我修改的脚本时也尽量不要使用此项功能。

nmap部分:

def nmap():

baseApi = " http://api.hackertarget.com/nmap/?q= " + url

base = requests.get(baseApi).text

return base

nmap的功能就不用多说了,不过 hackertarget 上给出的这个API接口是使用了-sV参数,而且只扫描21,22,23,25,80,110,143,443,445,3389这10个端口:

R3Con1Z3R代码及功能分析

只能购买会员后才能够使用高级功能,作为“贫农”的我自然是没钱买的了,只能看看:

R3Con1Z3R代码及功能分析

不过这些都不重要,最重要的是朋友使用后告诉我 它的扫描结果存在误报,我测试了一波,果然是这样,各位师傅可以自行测试一下。

另外,我感觉它这个功能写在脚本里有些鸡肋。

查询指向同一DNS服务器部分:

def findSharedServer():

baseApi = " http://api.hackertarget.com/findshareddns/?q= " + url

base = requests.get(baseApi).text

return base

获取页面中的链接部分:

def pageLinks():

baseApi = " http://api.hackertarget.com/pagelinks/?q= " + url

base = requests.get(baseApi).text

return base

更准确的说应该是将页面中的链接提取出来。

4. 生成及保存HTML文件

生成HTML文件部分:

def generateHTML():
create = """<!DOCTYPE html>
<html>
<head>
  <title>R3C0N1Z3R Report</title>
</head>
<body>
 <center> <h1>R3C0N1Z3R Report - [{}]</h1></center>
 <strong>HTTP header information</strong>
<pre>{}</pre>
    <strong>Trace Route</strong>
    <pre>{}</pre> 
  <strong>Whois Information</strong>
<pre>{}</pre>
<strong>DNS server record</strong>
<pre>{}</pre>
<strong><Nmap- running services/strong>
<pre>{}</pre>
<strong>Website on the same server</strong>
<pre>{}</pre>
<strong>Reverse IP Address</strong>
<pre>{}</pre>
<strong>Page Links</strong>
<pre>{}</pre><hr>
<center> All Rights Reserved © <strong>R3CON1Z3R</strong></center>
 
</body>
</html>
    """.format(url,httpHeader(),traceRoute(),whoIs(),dns(),nmap(),findSharedServer(),reverseHackTarget(),pageLinks())
return create

它的页面效果是这样的,很简单:

R3Con1Z3R代码及功能分析

保存HTML文件:

def saveHTML():
saveFile = open(url + '.html', 'w')
saveFile.write(generateHTML())
saveFile.close()
print('{}[+] HTML Report Successfully Generated{}'.format(Y, C))
print('{}[+] File saved as {}{}.html{}'.format(Y, R, url, C))
print('{}[+] R3CON1Z3R Operation Completed!{}'.format(Y, W))

将结果以domain.html的文件名保存在同一目录下。

修改版本v1.7

#!/usr/bin/env python

# coding: utf-8

# Original Author: Raji Abdulgafar

# Twitter: @mrgaphy

# Mender:ERFZE

# R3CON1Z3R v1.7

import sys

import requests

import argparse

import re

# OS Compatibility : Coloring

if sys.platform.startswith('win'):

R, B, Y, C, W = '\033[1;31m', '\033[1;37m', '\033[93m', '\033[1;30m', '\033[0m'

try:

import win_unicode_console, colorama

win_unicode_console.enable()

colorama.init()

except:

print('[+] Error: Coloring libraries not installed')

R, B, Y, C, W = '', '', '', '', ''

else:

R, B, Y, C, W = '\033[1;31m', '\033[1;37m', '\033[93m', '\033[1;30m', '\033[0m'

# Banner Printing

def header():

print('''%s

_____    ____     _____    ___    _   _   __   ______  ____    _____

|  __ \  |___ \   / ____|  / _ \  | \ | | /_ | |___  / |___ \  |  __ \

| |__) |   __) | | |      | | | | |  \| |  | |    / /    __) | | |__) |

|  _  /   |__ <  | |      | | | | | . ` |  | |   / /    |__ <  |  _  /

| | \ \   ___) | | |____  | |_| | | |\  |  | |  / /__   ___) | | | \ \

|_|  \_\ |____/   \_____|  \___/  |_| \_|  |_| /_____| |____/  |_|  \_\

%sv1.0 By https://github.com/abdulgaphy - @mrgaphy%s    >|%s       #GAPHY %s

%sv1.7 By ERFZE

'''%(R, B, R, C, W,B))

# Api : functionalities

#WEB Tools

def httpHeader():

if args.web or args.all:

baseApi = " http://api.hackertarget.com/httpheaders/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

def pageLinks():

if args.web or args.all:

baseApi = " http://api.hackertarget.com/pagelinks/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

#nmap

def nmap():

if args.nmap or args.all:

baseApi = " http://api.hackertarget.com/nmap/?q= " + url

result=requests.get(baseApi).text

char_index=result.index('SERVICE\n')+8

nmap_title=result[:char_index]

union_string=re.sub(r'\d{2,4}/[a-zA-Z]{3,5}.*?filtered.*?\n',"",result)

base=nmap_title+union_string

return base

else:

return 'NO Result!'

#IP Address

def reverseHackTarget():

if args.address or args.all:

baseApi = " http://api.hackertarget.com/reverseiplookup/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

def geoIp():

if args.address or args.all:

baseApi = " http://api.hackertarget.com/geoip/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

#traceRoute

def traceRoute():

if args.trace or args.all:

baseApi = " http://api.hackertarget.com/mtr/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

#WHOIS

def whoIs():

if args.whois or args.all:

baseApi = " http://api.hackertarget.com/whois/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

#DNS Queries

def dns():

if args.queries or args.all:

baseApi = " http://api.hackertarget.com/dnslookup/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

def reverseDns():

if args.queries or args.all:

baseApi = " http://api.hackertarget.com/reversedns/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

def findSharedServer():

if args.queries or args.all:

baseApi = " http://api.hackertarget.com/findshareddns/?q= " + url

base = requests.get(baseApi).text

return base

else:

return 'NO Result!'

# Generating reports in HTML format

def generateHTML():

create = """<!DOCTYPE html>

<html>

<head>

<title>R3C0N1Z3R Report</title>

</head>

<body>

<center> <h1>R3C0N1Z3R Report - [{}]</h1></center>

<strong>HTTP header information</strong>

<pre>{}</pre>

<strong>Page Links</strong>

<pre>{}</pre>

<strong>Namp</strong>

<strong><Nmap- running services/strong>

<pre>{}</pre>

<strong>Reverse IP Address</strong>

<pre>{}</pre>

<strong>IP Location Lookup</strong>

<pre>{}</pre>

<strong>Trace Route</strong>

<pre>{}</pre>

<strong>Whois Information</strong>

<pre>{}</pre>

<strong>DNS server record</strong>

<pre>{}</pre>

<strong>Reverse DNS Lookup</strong>

<pre>{}</pre>

<strong>Website on the same server</strong>

<pre>{}</pre><hr>

<center> All Rights Reserved &copy; <strong>R3CON1Z3R</strong></center>

</body>

</html>

""".format(url,httpHeader(),pageLinks(),nmap(),reverseHackTarget(),geoIp(),traceRoute(),whoIs(),dns(),reverseDns(),findSharedServer())

return create

# Saving the report

def saveHTML():

saveFile = open(url + '.html', 'w')

saveFile.write(generateHTML())

saveFile.close()

print('{}[+] HTML Report Successfully Generated{}'.format(Y, C))

print('{}[+] File saved as {}{}.html{}'.format(Y, R, url, C))

print('{}[+] R3CON1Z3R Operation Completed!{}'.format(Y, W))

if __name__ == '__main__':

parser=argparse.ArgumentParser()

parser.add_argument('-d','--domain',help='domain')

parser.add_argument('-a','--all',action="store_true",help='ALL functions')

parser.add_argument('-w','--web',action="store_true",help='WEB Tools(httpHeader AND pageLinks)')

parser.add_argument('-n','--nmap',action="store_true",help='nmap')

parser.add_argument('-i','--address',action="store_true",help='IP Address')

parser.add_argument('-t','--trace',action="store_true",help='traceRoute')

parser.add_argument('-s','--whois',action="store_true",help='WHOIS')

parser.add_argument('-q','--queries',action="store_true",help='DNS Queries(dnslookup AND reversedns AND findshareddns)')

args=parser.parse_args()

if args.domain:

header()

url = args.domain

saveHTML()

else:

header()

print('{}[!] Please specify a domain'.format(Y, C))

sys.exit()

这是我修改后的代码,主要改动如下:

a. 使用argparse模块,增加参数,使得用户可以选择部分功能执行。

R3Con1Z3R代码及功能分析

b. 将nmap结果中的filtered的项剔除,不出现到最后的HTML中。(虽然这个功能很鸡肋,但是还是留下了它)

R3Con1Z3R代码及功能分析

结语

我已经将我修改的v1.7发给了原作者(一个非洲帅哥),如果后期还有改动的话,我会第一时间将代码放到评论区。等到最终它完全修改完成后,会上传到Github。

*本文作者:ERFZE,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

点石成金

点石成金

[美] 史蒂夫·克鲁克 / De Dream' / 机械工业出版社 / 2006-8 / 39.00元

可用性设计是Web设计中最重要也是最困难的一项任务。《点石成金》的作者根据自己多年从业的经验,剖析用户的心理,在用户使用的模式、为浏览进行设计、导航设计、主页布局、可用性测试等方面提出了许多独特的观点,并给出了大量简单、易行的可用性设计的建议。这本书短小精悍,语言轻松诙谐,书中穿插大量色彩丰富的屏幕截图、趣味丛生的卡通插图以及包含大量信息的图表,使枯燥的设计原理变得平易近人。 此书适合从事W......一起来看看 《点石成金》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具