ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

搞个工具来偷懒-Python+端口扫描+CSV

2021-11-05 19:33:40  阅读:136  来源: 互联网

标签:name 端口扫描 ip Python 搞个 result file csv data


目录

写在前面

纯为了自己能多偷一会懒而弄的简易工具, 我并不是专业开发, 写这个完全是业余, 代码上会有很明显的冗余, 还望各位看官指点批评

为啥要搞工具

很简单,因为我懒
要批量扫描IP, 扫C段, 扫指定端口, 汇总表格, 这套程序下来我的文档编辑能力又提高了不少, 但这不是我想要的
经过四处求助和百度,得到了两个扫描脚本.

ip_number=`cat ip.txt|wc -l`
split -l 500 ip.txt -d -a 3 ip__  
i=0
ls |grep ip__|while read ip_line
do
	i=$[$i+1]
	masscan  -iL $ip_line -p0-65535 -oX $i.xml --rate 800
	cat $i.xml|grep addr|awk -F '"' '{print $4":"$10}' >>dk.txt
	sleep 30s
done

nmap.py

def nmap1(host,portlist,t_numb):
    t_numb.acquire()
    Nmap = nmap.PortScanner()  # 生成nmap
    np = Nmap.scan(hosts=host, ports=portlist, arguments='-n -Pn')
    for host, values in np['scan'].items():
        scan_raw_result[host] = values
    t_numb.release()

def write_file(what_file, file_name):
    index = 1 
    data = xlwt.Workbook()
    sheet_result = data.add_sheet('result', cell_overwrite_ok=True)
    sheet_result.write(0, 0, "IP")
    sheet_result.write(0, 1, "端口")
    sheet_result.write(0, 2, "主机端口")
    sheet_result.write(0, 3, "协议")
    sheet_result.write(0, 4, "state")
    sheet_result.write(0, 5, "服务")
    try:
        for ip in what_file:
            for name, vars in scan_raw_result[ip].items():
                if "tcp" in name: 
                    for port, tvalues in scan_raw_result[ip]['tcp'].items():
                        #print(tvalues)
                        sheet_result.write(index, 0, ip)
                        sheet_result.write(index, 1, port)
                        sheet_result.write(index, 2, str(ip)+':'+str(port))
                        sheet_result.write(index, 3, 'tcp')
                        sheet_result.write(index, 4, tvalues['state'])
                        sheet_result.write(index, 5, tvalues['name'])
                        index += 1
                if "udp" in name:
                    for port, tvalues in scan_raw_result[ip]['udp'].items():
                        sheet_result.write(index, 0, ip)
                        sheet_result.write(index, 1, port)
                        sheet_result.write(index, 2, str(ip)+':'+str(port))
                        sheet_result.write(index, 3, 'udp')
                        sheet_result.write(index, 4, tvalues['state'])
                        sheet_result.write(index, 5, tvalues['name'])
                        index += 1
        data.save('save.xlsx')
        print(file_name+'写入完成')
    except Exception as e:
        print(e)

分析

masscan.sh比较简单,最起码我看懂了,就是给一个带IP的txt然后给返回个ip:port形式的txt
在将这个txt传递给nmap.py获取端口的指纹和状态. 到也不是很难

遇到问题

由于我要汇总的结果由三个部分组成:批量IP+C段+临时端口扫描
nmap.py运行结束后每次都是覆盖结果,导致我需要手动改名,单独保存xlsx,这令我很不爽,作为一个懒人,这不高效

解决思路

三个扫描使用追加a+写到同一个xlsx里面, 好像比较简单,就把w+缓存a+就好了, 看了半天代码,脚本好像用的不是这个.
研究了一下xlsx,引起了一些不太愉快的回忆, 上一次用python玩xlsx玩到人疯掉了.
那么, 找一中表格格式替换xlsx, CSV.
简单尝试了一下CSV, 真是令我心情愉悦
在这里插入图片描述
这还有什么好说的, 查看也方便, 又可以用表格打开, 一个文件两用, 为什么我之前没发现这么好用的东西

测试之路

CSV读写

确定了python3+csv, 先找来几段代码来看看效果
(找不到参考的哪个文章了)

def ReadFromCSV():
    with open(csv_file, encoding='utf-8') as f:
        reader = csv.reader(f)
        header = next(reader)
        print(header)
        for row in reader:
            print(row)

def Write2CSV():
    header = ['name', 'password', 'status']

    data = [
        ['abc', '123456', 'PASS'],
        ['张五', '123#456', 'PASS'],
        ['张#abc123\n123', '123456', 'PASS'],
        ['666', '123456', 'PASS'],
        ['a b', '123456', 'PASS']
    ]

    with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(header)
        writer.writerows(data)

CSV数据追加

预期的效果这段代码已经达到了, 也是追加模式, 但这个追加会把header也重新写一遍.
改一下代码判断文件有没有header(其实这步很多余,header完全可以在汇总数据的时候用去重处理掉...但我就是玩)
于是, 第二版诞生了


def ReadCSV(*args):
    data_list = []
    try:
        csv_file = args[0]
        with open(csv_file, encoding='utf-8') as f:
            try:
                reader = csv.reader(f)
                header = next(reader)
            except StopIteration as e:
                header_flag = False     # 无header
                return False, ''            # 无数据
            else:
                data_list.append(header)
                for row in reader:
                    data_list.append(row)
                header_flag = True
                return header_flag, data_list
    except FileNotFoundError as e:
        open(csv_file, 'w+')

def Write2CSV(*args):
    csv_file = args[0]
    header = args[1]
    data = args[2]
    flag = ReadCSV(csv_file)[0]
    csv_data = ReadCSV(csv_file)[1]

    if flag == True:
        with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
            writer = csv.writer(f)
            # 写入二维数组
            writer.writerows(data)
        pass

    if flag == False:
        with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(header)
            # 写入二维数组
            writer.writerows(data)

CSV数据查询

就是在写之前先读一下文件看看有没有header存在, 返回个flag标记状态, 这样就可以在不重写header的情况下追加数据了
接下来, 再测试, 另一个问题: 重复数据怎么办
经过时间推进, 有些端口的状态肯定是有变化的, 按照滞后比可以把三个扫描工作排个顺序:临时扫描>批量IP扫描>C段扫描
那么CSV的写入顺序就明了了:临时扫描>批量IP扫描>C段扫描
nmap.py执行顺序:C段结果>批量结果>临时结果
执行哪个result.txt我可以手动控制,但是要保证导入的数据时最新的, 那就把前一个相同的数据删掉好了
整个CSV列表中, 只有ip:port字段是唯一的, 那就可以在追加数据之前先在CSV表中查一遍, 看看有没有这条数据, 有则删除
在删除之前肯定要先查一遍吧, CSV读写数据的基础是二维数组, 查CSV就变成了元素和二维数组之间的较量
找来一个二维数组查询的代码

剑指offer 第二版(Python3)--二维数组中的查找_鲁班七号-CSDN博客

class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        if not array or not array[0] or target is None:
            return False
        if array[0][0] > target or array[-1][-1] < target:
            return False
        rows, cols = len(array), len(array[0])
        r, c = 0, cols - 1
        while r < rows and c >= 0:
            if array[r][c] == target:
                return True
            if array[r][c] < target:
                r += 1
            else:
                c -= 1
        return array[r][c] == target

看了一下, 不太适用我的情况, 改造一下

    def Find(self, target, array):
        find_list =[]
        if not array or not array[0] or target is None:
            return False,''
        rows, cols = len(array), len(array[0])
        r, c = 0, 0
        for r in range(rows):
            for c in range(cols):
                try:
                    if array[r][c] == target:
                        find_list.append(r)
                except IndexError as e:
                    break
                else:
                    continue

这里为什么要把r放到find_list中, 是因为后面删除的时候需要这个r的值. 这里try了一下本来是要回避一中特殊情况的, 但因为太懒, 干脆就先放着不管了. find解决, 下一个

CSV数据删除

python-csv文件删除行或者删除列_秀呀秀的博客-CSDN博客

借助pandas, 先读取数据, 从中删除某行, 在把数据写回去. 说实话这样的效率真的不高, 但我见识有限, 一时想不出其他好的解决办法, 再有就是我在写这个工具上花的时间够多了, 先运行起来降低工作量是关键, 优化后面在考虑.

# 截取一部分下来
import pandas as pd
data = pd.read_csv("./betting.csv")
data_new=data.drop([128,129,130])

这里的drop入参就是list, 这样我可以同时删掉多行, 而不用每删一行重新加载一次文档.
经过反复的改动, 最终完成了这一些列的操作, 新增数据, 查询与删除, 数据替换
我在也不用为汇总发愁了

必要元素集结完毕

在下不才, 在此奉上简陋的代码

代码部分

csv_delete.py

def CSVDelete(*args):
    csv_file = args[0]
    detele_line = args[1]
    data = pd.read_csv(csv_file)
    data_new = data.drop(detele_line)
    data_new.to_csv(csv_file, index=0)

csv_find.py

class Solution:
    def Find(self, target, array):
        find_list =[]
        if not array or not array[0] or target is None:
            return False,''
        rows, cols = len(array), len(array[0])
        r, c = 0, 0
        for r in range(rows):
            for c in range(cols):
                try:
                    if array[r][c] == target:
                        find_list.append(r)
                except IndexError as e:
                    break
                else:
                    continue
        if len(find_list) == 0:              
            return False,''
        else :
            return True,find_list

csv_save.py

def ReadCSV(*args):

    data_list = []
    try:
        csv_file = args[0]
        with open(csv_file, encoding='utf-8') as f:
            try:
                reader = csv.reader(f)
                header = next(reader)
            except StopIteration as e:
                header_flag = False
                return False, ''  
            else:
                data_list.append(header)
                for row in reader:
                    data_list.append(row)
                header_flag = True
                return header_flag, data_list
    except FileNotFoundError as e:
        open(csv_file, 'w+')



def Write2CSV(*args):
    csv_file = args[0]
    header = args[1]
    data = args[2]
    delete_list = []
    cfs = cf.Solution()
    flag = ReadCSV(csv_file)[0]
    csv_data = ReadCSV(csv_file)[1]
    csv_line = len(csv_data)
    for a in data:
        target = a[2]
        find = cfs.Find(target, csv_data)
        if find[0] == True:
            for x in find[1]:
                x = x-1
                delete_list.append(x)
        else:
            break
    try:
        cd.CSVDelete(csv_file, delete_list)
    except:
        pass

    if flag == True:
        with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
            writer = csv.writer(f)
            writer.writerows(data)
        pass

    if flag == False:
        with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(header)
            writer.writerows(data)

csv_main.py

csv_name = (time.strftime("%Y-%m-%d", time.localtime()))
csv_file = './'+ csv_name +'.csv'
header = ['IP', '端口', '主机端口', '协议', 'state', '服务']
data = [
    ['127.0.0.1', '22', '127.0.0.1:22', 'tcp', 'closed', '1234'],
]
cs.Write2CSV(csv_file, header, data)

nmap.py

cachefile = './data/cache.txt'
ip_txt = './data/ip_port.txt'
result_lixt = './result_list.txt'
csv_name = (time.strftime("%Y-%m-%d", time.localtime()))
result_file = './'+ csv_name +'.csv'
scan_raw_result = {}
header = ['IP', '端口', '主机端口', '协议', 'state', '服务']

def nmap1(host, portlist, t_numb):
    t_numb.acquire()
    Nmap = nmap.PortScanner()  # 生成nmap
    print(host, portlist)
    np = Nmap.scan(hosts=host, ports=portlist, arguments='-n -Pn')
    for host, values in np['scan'].items():
        scan_raw_result[host] = values
    t_numb.release()


def write_file(what_file, file_name):          # 写文件到excel
    flag = 1
    try:
        for ip in what_file:
            for name, vars in scan_raw_result[ip].items():
                if "tcp" in name:                          # tcp协议
                    for port, tvalues in scan_raw_result[ip]['tcp'].items():
                        # ip
                        # port
                        ip_port = str(ip) + ':' + str(port)
                        agree = 'tcp'
                        port_status = tvalues['state']
                        server_name = tvalues['name']
                        # CSV
                        if tvalues['name'] == '':
                            server_name = 'unknown'
                        # else:
                        #     server_name == tvalues['name']
                        tmp_data = [ip, port, ip_port, agree,
                                    port_status, server_name]
                        Write2CSV(tmp_data)

                if "udp" in name:                          # udp协议
                    for port, tvalues in scan_raw_result[ip]['udp'].items():
                        # ip
                        # port
                        ip_port = ip + ':' + port
                        agree = 'udp'
                        port_status = tvalues['state']
                        server_name = tvalues['name']
                        # CSV
                        if tvalues['name'] == '':
                            server_name = 'unknown'
                        # else:
                        #     server_name == tvalues['name']
                        tmp_data = [ip, port, ip_port, agree,
                                    port_status, server_name]
                        Write2CSV(tmp_data)
            flag += 1
    except Exception as e:
        raise
        print(e)
def DataFormat(*args):
    dir = {}
    data = []
    t_list = []
    file = open(readfile, encoding='utf-8')
    data = file.readlines()
    t_numb = threading.Semaphore(20)

    for line in data:
        pattern = r'\-|\(|\)|<|\"'
        pattern_ip_port = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{0,5}'

        line = line.strip()
        ip_port = line.split(":")

        if ip_port[0] not in dir:
            dir[ip_port[0]] = []

        if ip_port[1] not in dir[ip_port[0]]:
            dir[ip_port[0]].append(ip_port[1])

    for ip, value in dir.items():
        ports = ','.join(str(port) for port in value)
        t = threading.Thread(target=nmap1, args=(ip, ports, t_numb,))
        t_list.append(t)

    for t in t_list:
        t.start()

    for t in t_list:
        t.join()
    pass
    key1 = list(set(scan_raw_result.keys()))
if __name__ == '__main__':
    params = sys.argv
    if len(params) == 1:
        readfile = './ip.txt'
    if len(params) == 2:
        readfile = params[1]

    Clear()
    DataFormat(readfile)

标签:name,端口扫描,ip,Python,搞个,result,file,csv,data
来源: https://www.cnblogs.com/haofang/p/15514057.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有