首页 > 编程 > Golang > 正文

go语言制作端口扫描器

2020-04-01 19:15:10
字体:
来源:转载
供稿:网友

本文给大家分享的是使用go语言编写的TCP端口扫描器,可以选择IP范围,扫描的端口,以及多线程,有需要的小伙伴可以参考下。

GO语言编写的TCP端口扫描器,本人的第一个GO程序。

Git@OSC:http://git.oschina.net/youshusoft/GoScanner

使用命令:

Scanner startIp [endIp] port thread

参数说明:

startIp 开始IP

endIp 结束IP,可选,不输入表示只扫描startIp

port 扫描端口,单个端口:3389;多个端口:1433,3389;连续端口:135-3389

thread 最大并发线程数,最高2048

扫描结果保存在同目录下的 result.txt 中,每次启动都会清掉之前的内容。

例子一:

Scanner 58.96.172.22 58.96.172.220 80 512

扫描58.96.172.22到58.96.172.220中的80端口,最大并发线程512。

例子二:

Scanner 58.96.172.22 58.96.172.220 21,5631 512

扫描58.96.172.22到58.96.172.220中的21和5631端口,最大并发线程512。

例子三:

Scanner 58.96.172.22 58.96.172.220 1-520 512

扫描58.96.172.22到58.96.172.220中的1到520端口,最大并发线程512。

例子四:

Scanner 58.96.172.22 1-520 512

扫描58.96.172.22中的1到520端口,最大并发线程512。

 

 
  1. package main 
  2. import ( 
  3. "fmt" 
  4. "strconv" 
  5. "flag" 
  6. "strings" 
  7. "net" 
  8. "os" 
  9. /** 
  10. 扫描地址 
  11. */ 
  12. var ipAddrs chan string = make(chan string) 
  13. //扫描结果 
  14. var result chan string = make(chan string) 
  15. //线程数 
  16. var thread chan int = make(chan int
  17. var nowThread int
  18. //关闭程序 
  19. var clo chan bool = make(chan bool) 
  20. //保存结果 
  21. func writeResult(){ 
  22. fileName := "result.txt" 
  23. fout,err := os.Create(fileName) 
  24. if err != nil{ 
  25. //文件创建失败 
  26. fmt.Println(fileName + " create error"
  27. defer fout.Close() 
  28. s,ok := <- result 
  29. for ;ok;{ 
  30. fout.WriteString(s + "/r/n"
  31. s,ok = <- result 
  32. //通知进程退出 
  33. clo <- true;  
  34. //根据线程参数启动扫描线程 
  35. func runScan(){ 
  36. t,ok := <- thread 
  37. nowThread = t; 
  38. if ok{ 
  39. for i := 0;i < nowThread;i++{ 
  40. go scan(strconv.Itoa(i)) 
  41. //等待线程终止 
  42. for;<-thread == 0;{ 
  43. nowThread-- 
  44. if nowThread == 0{ 
  45. //全部线程已终止,关闭结果写入,退出程序 
  46. close(result) 
  47. break 
  48. /** 
  49. 扫描线程 
  50. */ 
  51. func scan(threadId string){ 
  52. s,ok := <-ipAddrs 
  53. for;ok;{ 
  54. fmt.Println("[thread-" + threadId + "] scan:" + s) 
  55. _,err := net.Dial("tcp",s) 
  56. if err == nil{ 
  57. //端口开放 
  58. result <- s  
  59. s,ok = <-ipAddrs 
  60. fmt.Println("[thread-" + threadId + "] end"
  61. thread <- 0; 
  62. //获取下一个IP 
  63. func nextIp(ip string) string{ 
  64. ips := strings.Split(ip,"."
  65. var i int
  66. for i = len(ips) - 1;i >= 0;i--{ 
  67. n,_ := strconv.Atoi(ips[i]) 
  68. if n >= 255{ 
  69. //进位 
  70. ips[i] = "1" 
  71. }else
  72. //+1 
  73. n++ 
  74. ips[i] = strconv.Itoa(n) 
  75. break 
  76. if i == -1{ 
  77. //全部IP段都进行了进位,说明此IP本身已超出范围 
  78. return ""
  79. ip = "" 
  80. leng := len(ips) 
  81. for i := 0;i < leng;i++{ 
  82. if i == leng -1{ 
  83. ip += ips[i] 
  84. }else
  85. ip += ips[i] + "." 
  86. return ip 
  87. //生成IP地址列表 
  88. func processIp(startIp,endIp string) []string{ 
  89. var ips = make([]string,0) 
  90. for ;startIp != endIp;startIp = nextIp(startIp){ 
  91. if startIp != ""
  92. ips = append(ips,startIp) 
  93. ips = append(ips,startIp) 
  94. return ips 
  95. //处理参数 
  96. func processFlag(arg []string){ 
  97. //开始IP,结束IP 
  98. var startIp,endIp string 
  99. //端口 
  100. var ports []int = make([]int,0) 
  101. index := 0 
  102. startIp = arg[index] 
  103. si := net.ParseIP(startIp) 
  104. if si == nil{ 
  105. //开始IP不合法 
  106. fmt.Println("'startIp' Setting error"
  107. return 
  108. index++ 
  109. endIp = arg[index] 
  110. ei := net.ParseIP(endIp) 
  111. if(ei == nil){ 
  112. //未指定结束IP,即只扫描一个IP 
  113. endIp = startIp 
  114. }else
  115. index++ 
  116. tmpPort := arg[index] 
  117. if strings.Index(tmpPort,"-") != -1{ 
  118. //连续端口 
  119. tmpPorts := strings.Split(tmpPort,"-"
  120. var startPort,endPort int 
  121. var err error 
  122. startPort,err = strconv.Atoi(tmpPorts[0]) 
  123. if err != nil || startPort < 1 || startPort > 65535{ 
  124. //开始端口不合法 
  125. return 
  126. if len(tmpPorts) >= 2{ 
  127. //指定结束端口 
  128. endPort,err = strconv.Atoi(tmpPorts[1]) 
  129. if err != nil || endPort < 1 || endPort > 65535 || endPort < startPort{ 
  130. //结束端口不合法 
  131. fmt.Println("'endPort' Setting error"
  132. return 
  133. }else
  134. //未指定结束端口 
  135. endPort = 65535 
  136. for i := 0;startPort + i <= endPort;i++{ 
  137. ports = append(ports,startPort + i) 
  138. }else
  139. //一个或多个端口 
  140. ps := strings.Split(tmpPort,","
  141. for i := 0;i < len(ps);i++{ 
  142. p,err := strconv.Atoi(ps[i]) 
  143. if err != nil{ 
  144. //端口不合法 
  145. fmt.Println("'port' Setting error"
  146. return 
  147. ports = append(ports,p) 
  148. index++ 
  149. t,err := strconv.Atoi(arg[index]) 
  150. if(err != nil){ 
  151. //线程不合法 
  152. fmt.Println("'thread' Setting error"
  153. return 
  154. //最大线程2048 
  155. if t < 1{ 
  156. t = 1; 
  157. }else if t > 2048{ 
  158. t = 2048; 
  159. //传送启动线程数 
  160. thread <- t 
  161. //生成扫描地址列表 
  162. ips := processIp(startIp,endIp) 
  163. il := len(ips) 
  164. for i := 0; i < il;i++{ 
  165. pl := len(ports) 
  166. for j := 0;j < pl;j++{ 
  167. ipAddrs <- ips[i] + ":" + strconv.Itoa(ports[j])  
  168. close(ipAddrs) 
  169. func main(){ 
  170. flag.Parse() 
  171. if flag.NArg() != 3 && flag.NArg() != 4{ 
  172. //参数不合法 
  173. fmt.Println("Parameter error"
  174. return 
  175. //获取参数 
  176. args := make([]string,0,4) 
  177. for i := 0;i < flag.NArg();i++{ 
  178. args = append(args,flag.Arg(i)) 
  179. //启动扫描线程 
  180. go runScan() 
  181. //启动结果写入线程 
  182. go writeResult() 
  183. //参数处理 
  184. processFlag(args) 
  185. //等待退出指令 
  186. <- clo; 
  187. fmt.Println("Exit"

以上所述就是本文的全部内容了,希望大家能够喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表