为了上班摸鱼,我写了个工具帮我扫描

haofang   ·   发表于 2021-11-26 17:24:23   ·   闲聊灌水区

[toc]

需求

扫描C段
扫描指定IP
汇总到表格
发邮件

写在前面

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

为啥要搞工具

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

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

nmap.py

  1. def nmap1(host,portlist,t_numb):
  2. t_numb.acquire()
  3. Nmap = nmap.PortScanner() # 生成nmap
  4. np = Nmap.scan(hosts=host, ports=portlist, arguments='-n -Pn')
  5. for host, values in np['scan'].items():
  6. scan_raw_result[host] = values
  7. t_numb.release()
  8. def write_file(what_file, file_name):
  9. index = 1
  10. data = xlwt.Workbook()
  11. sheet_result = data.add_sheet('result', cell_overwrite_ok=True)
  12. sheet_result.write(0, 0, "IP")
  13. sheet_result.write(0, 1, "端口")
  14. sheet_result.write(0, 2, "主机端口")
  15. sheet_result.write(0, 3, "协议")
  16. sheet_result.write(0, 4, "state")
  17. sheet_result.write(0, 5, "服务")
  18. try:
  19. for ip in what_file:
  20. for name, vars in scan_raw_result[ip].items():
  21. if "tcp" in name:
  22. for port, tvalues in scan_raw_result[ip]['tcp'].items():
  23. #print(tvalues)
  24. sheet_result.write(index, 0, ip)
  25. sheet_result.write(index, 1, port)
  26. sheet_result.write(index, 2, str(ip)+':'+str(port))
  27. sheet_result.write(index, 3, 'tcp')
  28. sheet_result.write(index, 4, tvalues['state'])
  29. sheet_result.write(index, 5, tvalues['name'])
  30. index += 1
  31. if "udp" in name:
  32. for port, tvalues in scan_raw_result[ip]['udp'].items():
  33. sheet_result.write(index, 0, ip)
  34. sheet_result.write(index, 1, port)
  35. sheet_result.write(index, 2, str(ip)+':'+str(port))
  36. sheet_result.write(index, 3, 'udp')
  37. sheet_result.write(index, 4, tvalues['state'])
  38. sheet_result.write(index, 5, tvalues['name'])
  39. index += 1
  40. data.save('save.xlsx')
  41. print(file_name+'写入完成')
  42. except Exception as e:
  43. 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, 先找来几段代码来看看效果
(找不到参考的哪个文章了)

  1. def ReadFromCSV():
  2. with open(csv_file, encoding='utf-8') as f:
  3. reader = csv.reader(f)
  4. header = next(reader)
  5. print(header)
  6. for row in reader:
  7. print(row)
  8. def Write2CSV():
  9. header = ['name', 'password', 'status']
  10. data = [
  11. ['abc', '123456', 'PASS'],
  12. ['张五', '123#456', 'PASS'],
  13. ['张#abc123\n123', '123456', 'PASS'],
  14. ['666', '123456', 'PASS'],
  15. ['a b', '123456', 'PASS']
  16. ]
  17. with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
  18. writer = csv.writer(f)
  19. writer.writerow(header)
  20. writer.writerows(data)

CSV数据追加

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

  1. def ReadCSV(*args):
  2. data_list = []
  3. try:
  4. csv_file = args[0]
  5. with open(csv_file, encoding='utf-8') as f:
  6. try:
  7. reader = csv.reader(f)
  8. header = next(reader)
  9. except StopIteration as e:
  10. header_flag = False # 无header
  11. return False, '' # 无数据
  12. else:
  13. data_list.append(header)
  14. for row in reader:
  15. data_list.append(row)
  16. header_flag = True
  17. return header_flag, data_list
  18. except FileNotFoundError as e:
  19. open(csv_file, 'w+')
  20. def Write2CSV(*args):
  21. csv_file = args[0]
  22. header = args[1]
  23. data = args[2]
  24. flag = ReadCSV(csv_file)[0]
  25. csv_data = ReadCSV(csv_file)[1]
  26. if flag == True:
  27. with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
  28. writer = csv.writer(f)
  29. # 写入二维数组
  30. writer.writerows(data)
  31. pass
  32. if flag == False:
  33. with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
  34. writer = csv.writer(f)
  35. writer.writerow(header)
  36. # 写入二维数组
  37. 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博客

  1. class Solution:
  2. # array 二维列表
  3. def Find(self, target, array):
  4. # write code here
  5. if not array or not array[0] or target is None:
  6. return False
  7. if array[0][0] > target or array[-1][-1] < target:
  8. return False
  9. rows, cols = len(array), len(array[0])
  10. r, c = 0, cols - 1
  11. while r < rows and c >= 0:
  12. if array[r][c] == target:
  13. return True
  14. if array[r][c] < target:
  15. r += 1
  16. else:
  17. c -= 1
  18. return array[r][c] == target

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

  1. def Find(self, target, array):
  2. find_list =[]
  3. if not array or not array[0] or target is None:
  4. return False,''
  5. rows, cols = len(array), len(array[0])
  6. r, c = 0, 0
  7. for r in range(rows):
  8. for c in range(cols):
  9. try:
  10. if array[r][c] == target:
  11. find_list.append(r)
  12. except IndexError as e:
  13. break
  14. else:
  15. continue

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

CSV数据删除

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

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

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

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

必要元素集结完毕

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

代码部分

csv_delete.py

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

csv_find.py

  1. class Solution:
  2. def Find(self, target, array):
  3. find_list =[]
  4. if not array or not array[0] or target is None:
  5. return False,''
  6. rows, cols = len(array), len(array[0])
  7. r, c = 0, 0
  8. for r in range(rows):
  9. for c in range(cols):
  10. try:
  11. if array[r][c] == target:
  12. find_list.append(r)
  13. except IndexError as e:
  14. break
  15. else:
  16. continue
  17. if len(find_list) == 0:
  18. return False,''
  19. else :
  20. return True,find_list

csv_save.py

  1. def ReadCSV(*args):
  2. data_list = []
  3. try:
  4. csv_file = args[0]
  5. with open(csv_file, encoding='utf-8') as f:
  6. try:
  7. reader = csv.reader(f)
  8. header = next(reader)
  9. except StopIteration as e:
  10. header_flag = False
  11. return False, ''
  12. else:
  13. data_list.append(header)
  14. for row in reader:
  15. data_list.append(row)
  16. header_flag = True
  17. return header_flag, data_list
  18. except FileNotFoundError as e:
  19. open(csv_file, 'w+')
  20. def Write2CSV(*args):
  21. csv_file = args[0]
  22. header = args[1]
  23. data = args[2]
  24. delete_list = []
  25. cfs = cf.Solution()
  26. flag = ReadCSV(csv_file)[0]
  27. csv_data = ReadCSV(csv_file)[1]
  28. csv_line = len(csv_data)
  29. for a in data:
  30. target = a[2]
  31. find = cfs.Find(target, csv_data)
  32. if find[0] == True:
  33. for x in find[1]:
  34. x = x-1
  35. delete_list.append(x)
  36. else:
  37. break
  38. try:
  39. cd.CSVDelete(csv_file, delete_list)
  40. except:
  41. pass
  42. if flag == True:
  43. with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
  44. writer = csv.writer(f)
  45. writer.writerows(data)
  46. pass
  47. if flag == False:
  48. with open(csv_file, 'a+', encoding='utf-8', newline='') as f:
  49. writer = csv.writer(f)
  50. writer.writerow(header)
  51. writer.writerows(data)

csv_main.py

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

nmap.py

  1. cachefile = './data/cache.txt'
  2. ip_txt = './data/ip_port.txt'
  3. result_lixt = './result_list.txt'
  4. csv_name = (time.strftime("%Y-%m-%d", time.localtime()))
  5. result_file = './'+ csv_name +'.csv'
  6. scan_raw_result = {}
  7. header = ['IP', '端口', '主机端口', '协议', 'state', '服务']
  8. def nmap1(host, portlist, t_numb):
  9. t_numb.acquire()
  10. Nmap = nmap.PortScanner() # 生成nmap
  11. print(host, portlist)
  12. np = Nmap.scan(hosts=host, ports=portlist, arguments='-n -Pn')
  13. for host, values in np['scan'].items():
  14. scan_raw_result[host] = values
  15. t_numb.release()
  16. def write_file(what_file, file_name): # 写文件到excel
  17. flag = 1
  18. try:
  19. for ip in what_file:
  20. for name, vars in scan_raw_result[ip].items():
  21. if "tcp" in name: # tcp协议
  22. for port, tvalues in scan_raw_result[ip]['tcp'].items():
  23. # ip
  24. # port
  25. ip_port = str(ip) + ':' + str(port)
  26. agree = 'tcp'
  27. port_status = tvalues['state']
  28. server_name = tvalues['name']
  29. # CSV
  30. if tvalues['name'] == '':
  31. server_name = 'unknown'
  32. # else:
  33. # server_name == tvalues['name']
  34. tmp_data = [ip, port, ip_port, agree,
  35. port_status, server_name]
  36. Write2CSV(tmp_data)
  37. if "udp" in name: # udp协议
  38. for port, tvalues in scan_raw_result[ip]['udp'].items():
  39. # ip
  40. # port
  41. ip_port = ip + ':' + port
  42. agree = 'udp'
  43. port_status = tvalues['state']
  44. server_name = tvalues['name']
  45. # CSV
  46. if tvalues['name'] == '':
  47. server_name = 'unknown'
  48. # else:
  49. # server_name == tvalues['name']
  50. tmp_data = [ip, port, ip_port, agree,
  51. port_status, server_name]
  52. Write2CSV(tmp_data)
  53. flag += 1
  54. except Exception as e:
  55. raise
  56. print(e)
  57. def DataFormat(*args):
  58. dir = {}
  59. data = []
  60. t_list = []
  61. file = open(readfile, encoding='utf-8')
  62. data = file.readlines()
  63. t_numb = threading.Semaphore(20)
  64. for line in data:
  65. pattern = r'\-|\(|\)|<|\"'
  66. pattern_ip_port = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{0,5}'
  67. line = line.strip()
  68. ip_port = line.split(":")
  69. if ip_port[0] not in dir:
  70. dir[ip_port[0]] = []
  71. if ip_port[1] not in dir[ip_port[0]]:
  72. dir[ip_port[0]].append(ip_port[1])
  73. for ip, value in dir.items():
  74. ports = ','.join(str(port) for port in value)
  75. t = threading.Thread(target=nmap1, args=(ip, ports, t_numb,))
  76. t_list.append(t)
  77. for t in t_list:
  78. t.start()
  79. for t in t_list:
  80. t.join()
  81. pass
  82. key1 = list(set(scan_raw_result.keys()))
  83. if __name__ == '__main__':
  84. params = sys.argv
  85. if len(params) == 1:
  86. readfile = './ip.txt'
  87. if len(params) == 2:
  88. readfile = params[1]
  89. Clear()
  90. DataFormat(readfile)

投到灌水区 看官凭喜好点评

打赏我,让我更有动力~

0 条回复   |  直到 2021-11-26 | 953 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.