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

python

为了偷懒, 我复制四方代码, 改写了一个基于python的nmap 端口扫描工具.....

目录

  • 写在前面
      • 为啥要搞工具
      • 分析
      • 遇到问题
      • 解决思路
      • 测试之路
        • CSV读写
        • CSV数据追加
        • CSV数据查询
        • CSV数据删除
  • 必要元素集结完毕
  • 代码部分

写在前面

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

为啥要搞工具

很简单,因为我懒

要批量扫描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+就好了, 看了半天代码,nmap扫描的脚本好像用的不是这种方法.

研究了一下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)

以上是 搞个工具来偷懒-Python+端口扫描+CSV 的全部内容, 来源链接: utcz.com/z/388693.html

回到顶部