现在已经存在很多python版本或者其他语言版本的端口扫描器,那go语言有什么优势呢?
首先是python,
python的socket模块可以创建套接字,创建tcp的三次握手连接,以此探测目标端口是否存活.本篇将使用socket模块编写tcp端口扫描器和syn端口扫描器,对比差异.
#! -*- coding:utf-8 -*-
import time
import socket
socket_timeout = 0.1#根据需要调整timeout
def tcp_scan(ip,port):
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(socket_timeout)
c=s.connect_ex((ip,port))
if c==0:
print "%s:%s is open" % (ip,port)
else:
# print "%s:%s is not open" % (ip,port)
pass
except Exception,e:
print e
s.close()
if __name__=="__main__":
s_time = time.time()
ip = "10.0.0.1"#ip地址
for port in range(0,1024):#随手写了个1024
''' 此处可用协作 '''
tcp_scan(ip,port)
e_time = time.time()
print "scan time is ",e_time-s_time
# -*- coding: UTF-8 -*-
import time
import random
import socket
import sys
from struct import *
'''
Warning:must run it as root
yum install python-devel libpcap-devel
pip install pcap
'''
def checksum(msg):
''' Check Summing '''
s = 0
for i in range(0,len(msg),2):
w = (ord(msg[i]) << 8) + (ord(msg[i+1]))
s = s+w
s = (s>>16) + (s & 0xffff)
s = ~s & 0xffff
return s
def CreateSocket(source_ip,dest_ip):
''' create socket connection '''
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
except socket.error, msg:
print 'Socket create error: ',str(msg[0]),'message: ',msg[1]
sys.exit()
''' Set the IP header manually '''
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
return s
def CreateIpHeader(source_ip, dest_ip):
''' create ip header '''
# packet = ''
# ip header option
headerlen = 5
version = 4
tos = 0
tot_len = 20 + 20
id = random.randrange(18000,65535,1)
frag_off = 0
ttl = 255
protocol = socket.IPPROTO_TCP
check = 10
saddr = socket.inet_aton ( source_ip )
daddr = socket.inet_aton ( dest_ip )
hl_version = (version << 4) + headerlen
ip_header = pack('!BBHHHBBH4s4s', hl_version, tos, tot_len, id, frag_off, ttl, protocol, check, saddr, daddr)
return ip_header
def create_tcp_syn_header(source_ip, dest_ip, dest_port):
''' create tcp syn header function '''
source = random.randrange(32000,62000,1) # randon select one source_port
seq = 0
ack_seq = 0
doff = 5
''' tcp flags '''
fin = 0
syn = 1
rst = 0
psh = 0
ack = 0
urg = 0
window = socket.htons (8192) # max windows size
check = 0
urg_ptr = 0
offset_res = (doff << 4) + 0
tcp_flags = fin + (syn<<1) + (rst<<2) + (psh<<3) + (ack<<4) + (urg<<5)
tcp_header = pack('!HHLLBBHHH', source, dest_port, seq, ack_seq, offset_res, tcp_flags, window, check, urg_ptr)
''' headers option '''
source_address = socket.inet_aton( source_ip )
dest_address = socket.inet_aton( dest_ip )
placeholder = 0
protocol = socket.IPPROTO_TCP
tcp_length = len(tcp_header)
psh = pack('!4s4sBBH', source_address, dest_address, placeholder, protocol, tcp_length);
psh = psh + tcp_header;
tcp_checksum = checksum(psh)
''' Repack the TCP header and fill in the correct checksum '''
tcp_header = pack('!HHLLBBHHH', source, dest_port, seq, ack_seq, offset_res, tcp_flags, window, tcp_checksum, urg_ptr)
return tcp_header
def syn_scan(source_ip, dest_ip, des_port) :
s = CreateSocket(source_ip, dest_ip)
ip_header = CreateIpHeader(source_ip, dest_ip)
tcp_header = create_tcp_syn_header(source_ip, dest_ip, des_port)
packet = ip_header + tcp_header
s.sendto(packet, (dest_ip, 0))
data = s.recvfrom(1024) [0][0:]
ip_header_len = (ord(data[0]) & 0x0f) * 4
# ip_header_ret = data[0: ip_header_len - 1]
tcp_header_len = (ord(data[32]) & 0xf0)>>2
tcp_header_ret = data[ip_header_len:ip_header_len+tcp_header_len - 1]
''' SYN/ACK flags '''
if ord(tcp_header_ret[13]) == 0x12:
print "%s:%s is open" % (dest_ip,des_port)
else:
print "%s:%s is not open" % (dest_ip,des_port)
if __name__=="__main__":
t_s = time.time()
source_ip = '' # 填写本机ip
dest_ip = '10.0.0.1'#目标ip
for des_port in range(1024):
syn_scan(source_ip, dest_ip, des_port)
t_e = time.time()
print "time is ",(t_e-t_s)
tcp-syn-portscan
代码
#! -*- coding:utf-8 -*-
import time
from scapy.all import *
ip = "10.0.0.1"
TIMEOUT = 0.5#自由设定timeout值
threads = 500#线程数
port_range = 1024#随手一个1024
retry = 1
def is_up(ip):
""" Tests if host is up """
icmp = IP(dst=ip)/ICMP()
resp = sr1(icmp, timeout=TIMEOUT)
if resp == None:
return False
else:
return True
def reset_half_open(ip, ports):
# Reset the connection to stop half-open connections from pooling up
sr(IP(dst=ip)/TCP(dport=ports, flags='AR'), timeout=TIMEOUT)
def is_open(ip, ports):
to_reset = []
results = []
p = IP(dst=ip)/TCP(dport=ports, flags='S') # Forging SYN packet
answers, un_answered = sr(p, verbose=False, retry=retry ,timeout=TIMEOUT) # Send the packets
for req, resp in answers:
if not resp.haslayer(TCP):
continue
tcp_layer = resp.getlayer(TCP)
if tcp_layer.flags == 0x12:
# port is open
to_reset.append(tcp_layer.sport)
results.append(tcp_layer.sport)
elif tcp_layer.flags == 0x14:
# port is open
pass
reset_half_open(ip, to_reset)
return results
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
if __name__ == '__main__':
start_time = time.time()
open_port_list = []
for ports in chunks(list(range(port_range)), threads):
results = is_open(ip, ports)
if results:
open_port_list += results
end_time = time.time()
print "%s %s" % (ip,open_port_list)
print "%s Scan Completed in %fs" % (ip, end_time-start_time)
#! -*- coding:utf-8 -*-
'''
pip install python-nmap
直接调用即可
'''
import nmap
nm =nmap.PortScanner()
def scan(ip,port,arg):
try:
nm.scan(ip, arguments=arg+str(port))
except nmap.nmap.PortScannerError:
print "Please run -O method for root privileges"
else:
for host in nm.all_hosts():
for proto in nm[host].all_protocols():
lport = nm[host][proto].keys()
lport.sort()
for port in lport:
print ('port : %s\tstate : %s' % (port, nm[host][proto][port]['state']))
if __name__=="__main__":
port="80,443,22,21"
scan(ip="14.215.177.38",port=port,arg="-sS -Pn -p")
# tcp scan -sT
# tcp syn scan -sS
package main
// port tcp scan
import (
"fmt"
"net"
"os"
"runtime"
"strconv"
"sync"
"time"
)
func loop(inport chan int, startport, endport int) {
for i := startport; i <= endport; i++ {
inport <- i
}
close(inport)
}
type ScanSafeCount struct {
// 结构体
count int
mux sync.Mutex
}
var scanCount ScanSafeCount
func scanner(inport int, outport chan int, ip string, endport int) {
// 扫描函数
in := inport // 定义要扫描的端口号
// fmt.Printf(" %d ", in) // 输出扫描的端口
host := fmt.Sprintf("%s:%d", ip, in) // 类似(ip,port)
tcpAddr, err := net.ResolveTCPAddr("tcp4", host) // 根据域名查找ip
if err != nil {
// 域名解析ip失败
outport <- 0
} else {
conn, err := net.DialTimeout("tcp", tcpAddr.String(), 10*time.Second) //建立tcp连接
if err != nil {
// tcp连接失败
outport <- 0
} else {
// tcp连接成功
outport <- in // 将端口写入outport信号
fmt.Printf("\n *************( %d 可以 )*****************\n", in)
conn.Close()
}
}
// 线程锁
scanCount.mux.Lock()
scanCount.count = scanCount.count - 1
if scanCount.count <= 0 {
close(outport)
}
scanCount.mux.Unlock()
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) // 设置最大可使用的cpu核数
// 定义变量
inport := make(chan int) // 信号变量,类似python中的queue
outport := make(chan int)
collect := []int{} // 定义一个切片变量,类似python中的list
// fmt.Println(os.Args, len(os.Args)) // 获取命令行参数并输出
if len(os.Args) != 4 {
// 命令行参数个数有误
fmt.Println("使用方式: port_scanner IP startport endport")
os.Exit(0)
}
s_time := time.Now().Unix()
// fmt.Println("扫描开始:") // 获取当前时间
ip := string(os.Args[1]) // 获取参数中的ip
startport, _ := strconv.Atoi(os.Args[2]) // 获取参数中的启始端口
endport, _ := strconv.Atoi(os.Args[3]) // 获取参数中的结束端口
if startport > endport {
fmt.Println("Usage: scanner IP startport endport")
fmt.Println("Endport must be larger than startport")
os.Exit(0)
} else {
// 定义scanCount变量为ScanSafeCount结构体,即计算扫描的端口数量
scanCount = ScanSafeCount{count: (endport - startport + 1)}
}
fmt.Printf("扫描 %s:%d----------%d\n", ip, startport, endport)
go loop(inport, startport, endport) // 执行loop函数将端口写入input信号
for v := range inport {
// 开始循环input
go scanner(v, outport, ip, endport)
}
// 输出结果
for port := range outport {
if port != 0 {
collect = append(collect, port)
}
}
fmt.Println("--")
fmt.Println(collect)
e_time := time.Now().Unix()
fmt.Println("扫描时间:", e_time-s_time)
}
测试代码运行,
go run go-tcp-portscan.go 10.0.0.1 0 1024
package main
// port tcp syn scan
import (
"bytes"
"encoding/binary"
"flag"
"fmt"
"log"
"math/rand"
"net"
"os"
"strconv"
"strings"
"time"
"errors"
)
//TCPHeader test
type TCPHeader struct {
SrcPort uint16
DstPort uint16
SeqNum uint32
AckNum uint32
Flags uint16
Window uint16
ChkSum uint16
UrgentPointer uint16
}
//TCPOption test
type TCPOption struct {
Kind uint8
Length uint8
Data []byte
}
type scanResult struct {
Port uint16
Opened bool
}
type scanJob struct {
Laddr string
Raddr string
SPort uint16
DPort uint16
Stop uint8
}
var stopFlag = make(chan uint8, 1)
func main() {
rate := time.Second / 400
throttle := time.Tick(rate)
jobs := make(chan *scanJob, 65536)
results := make(chan *scanResult, 1000)
for w := 0; w < 10; w++ {
go worker(w, jobs, throttle, results)
}
// 获取命令行参数
ifaceName := flag.String("i", "eth0", "Specify network")
remote := flag.String("r", "", "remote address")
portRange := flag.String("p", "1-1024", "port range: -p 1-1024")
flag.Parse()
// ifaceName := &interfaceName_
// remote := &remote_
// portRange := &portRange_
s_time := time.Now().Unix()
laddr := interfaceAddress(*ifaceName) //
raddr := *remote
minPort , maxPort := portSplit(portRange)
// fmt.Println(laddr, raddr) // 输出源ip地址,目标ip地址
go func(num int){
for i := 0; i < num; i++ {
recvSynAck(laddr, raddr, results)
}
}(10)
go func(jobLength int) {
for j := minPort; j < maxPort + 1; j++ {
s := scanJob{
Laddr: laddr,
Raddr: raddr,
SPort: uint16(random(10000, 65535)),
DPort: uint16(j + 1),
}
jobs <- &s
}
jobs <- &scanJob{Stop: 1}
}(1024)
for {
select {
case res := <-results:
fmt.Println("扫描到开放的端口:",res.Port)
case <-stopFlag:
e_time := time.Now().Unix()
fmt.Println("总共用了多少时间(s):",e_time-s_time)
os.Exit(0)
}
}
}
func worker(id int, jobs <-chan *scanJob, th <-chan time.Time, results chan<- *scanResult) {
for j := range jobs {
if j.Stop != 1 {
sendSyn(j.Laddr, j.Raddr, j.SPort, j.DPort)
} else {
stopFlag <- j.Stop
}
<-th
}
}
func checkError(err error) {
// 错误check
if err != nil {
log.Println(err)
}
}
//CheckSum test
func CheckSum(data []byte, src, dst [4]byte) uint16 {
pseudoHeader := []byte{
src[0], src[1], src[2], src[3],
dst[0], dst[1], dst[2], dst[3],
0,
6,
0,
byte(len(data)),
}
totalLength := len(pseudoHeader) + len(data)
if totalLength%2 != 0 {
totalLength++
}
d := make([]byte, 0, totalLength)
d = append(d, pseudoHeader...)
d = append(d, data...)
return ^mySum(d)
}
func mySum(data []byte) uint16 {
var sum uint32
for i := 0; i < len(data)-1; i += 2 {
sum += uint32(uint16(data[i])<<8 | uint16(data[i+1]))
}
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return uint16(sum)
}
func sendSyn(laddr, raddr string, sport, dport uint16) {
conn, err := net.Dial("ip4:tcp", raddr)
checkError(err)
defer conn.Close()
op := []TCPOption{
TCPOption{
Kind: 2,
Length: 4,
Data: []byte{0x05, 0xb4},
},
TCPOption{
Kind: 0,
},
}
tcpH := TCPHeader{
SrcPort: sport,
DstPort: dport,
SeqNum: rand.Uint32(),
AckNum: 0,
Flags: 0x8002,
Window: 8192,
ChkSum: 0,
UrgentPointer: 0,
}
buff := new(bytes.Buffer)
err = binary.Write(buff, binary.BigEndian, tcpH)
checkError(err)
for i := range op {
binary.Write(buff, binary.BigEndian, op[i].Kind)
binary.Write(buff, binary.BigEndian, op[i].Length)
binary.Write(buff, binary.BigEndian, op[i].Data)
}
binary.Write(buff, binary.BigEndian, [6]byte{})
data := buff.Bytes()
checkSum := CheckSum(data, ipstr2Bytes(laddr), ipstr2Bytes(raddr))
//fmt.Printf("CheckSum 0x%X\n", checkSum)
tcpH.ChkSum = checkSum
buff = new(bytes.Buffer)
binary.Write(buff, binary.BigEndian, tcpH)
for i := range op {
binary.Write(buff, binary.BigEndian, op[i].Kind)
binary.Write(buff, binary.BigEndian, op[i].Length)
binary.Write(buff, binary.BigEndian, op[i].Data)
}
binary.Write(buff, binary.BigEndian, [6]byte{})
data = buff.Bytes()
//fmt.Printf("% X\n", data)
_, err = conn.Write(data)
checkError(err)
}
func recvSynAck(laddr, raddr string, res chan<- *scanResult) error {
listenAddr, err := net.ResolveIPAddr("ip4", laddr) // 解析域名为ip
checkError(err)
conn, err := net.ListenIP("ip4:tcp", listenAddr)
defer conn.Close()
checkError(err)
for {
buff := make([]byte, 1024)
_, addr, err := conn.ReadFrom(buff)
if err != nil {
continue
}
if addr.String() != raddr || buff[13] != 0x12 {
continue
}
var port uint16
binary.Read(bytes.NewReader(buff), binary.BigEndian, &port)
res <- &scanResult{
Port: port,
Opened: true,
}
}
}
func ipstr2Bytes(addr string) [4]byte {
s := strings.Split(addr, ".")
b0, _ := strconv.Atoi(s[0])
b1, _ := strconv.Atoi(s[1])
b2, _ := strconv.Atoi(s[2])
b3, _ := strconv.Atoi(s[3])
return [4]byte{byte(b0), byte(b1), byte(b2), byte(b3)}
}
func random(min, max int) int {
return rand.Intn(max-min) + min
}
func interfaceAddress(ifaceName string ) string {
iface, err:= net.InterfaceByName(ifaceName)
if err != nil {
panic(err)
}
addr, err := iface.Addrs()
if err != nil {
panic(err)
}
addrStr := strings.Split(addr[0].String(), "/")[0]
return addrStr
}
func portSplit(portRange *string) (uint16, uint16) {
ports := strings.Split(*portRange, "-")
minPort, err := strconv.ParseUint(ports[0], 10, 16)
if err !=nil {
panic(err)
}
maxPort, err := strconv.ParseUint(ports[1], 10, 16)
if err != nil {
panic(err)
}
if minPort > maxPort {
panic(errors.New("minPort must greater than maxPort"))
}
return uint16(minPort), uint16(maxPort)
}
代码运行结果:
go run go-syn-portscan.go -r 1.1.1.1 -p 1-1024
这里我想了两种方案,第一种将go语言打包成.so动态连接库,利用python的ctypes模块可以调用;第二种是go写成接口,提供python调用。写成接口的方式相对简单一些,因此这里不介绍了,说说如何打包go,即如何利用python调用go的方法或者说函数。
将上诉go-syn-portscan.go改版一下
代码
package main
// port tcp syn scan
import (
"C"
"os"
"bytes"
"encoding/binary"
"fmt"
"log"
"math/rand"
"net"
"strconv"
"strings"
"time"
"errors"
)
//TCPHeader test
type TCPHeader struct {
SrcPort uint16
DstPort uint16
SeqNum uint32
AckNum uint32
Flags uint16
Window uint16
ChkSum uint16
UrgentPointer uint16
}
//TCPOption test
type TCPOption struct {
Kind uint8
Length uint8
Data []byte
}
type scanResult struct {
Port uint16
Opened bool
}
type scanJob struct {
Laddr string
Raddr string
SPort uint16
DPort uint16
Stop uint8
}
var stopFlag = make(chan uint8, 1)
//export Scan
func Scan(remote_ *C.char, portRange_ *C.char, interfaceName_ *C.char) {
rate := time.Second / 400
throttle := time.Tick(rate)
jobs := make(chan *scanJob, 65536)
results := make(chan *scanResult, 1000)
for w := 0; w < 10; w++ {
go worker(w, jobs, throttle, results)
}
// 获取命令行参数
// ifaceName := flag.String("i", "eth0", "Specify network")
// remote := flag.String("r", "", "remote address")
// portRange := flag.String("p", "1-1024", "port range: -p 1-1024")
// flag.Parse()
interfaceName_1 := C.GoString(interfaceName_)
remote_1 := C.GoString(remote_)
portRange_1 := C.GoString(portRange_)
ifaceName := &interfaceName_1
remote := &remote_1
portRange := &portRange_1
s_time := time.Now().Unix()
laddr := interfaceAddress(*ifaceName) //
raddr := *remote
minPort , maxPort := portSplit(portRange)
fmt.Println(laddr, raddr) // 输出源ip地址,目标ip地址
go func(num int){
for i := 0; i < num; i++ {
recvSynAck(laddr, raddr, results)
}
}(10)
go func(jobLength int) {
for j := minPort; j < maxPort + 1; j++ {
s := scanJob{
Laddr: laddr,
Raddr: raddr,
SPort: uint16(random(10000, 65535)),
DPort: uint16(j + 1),
}
jobs <- &s
}
jobs <- &scanJob{Stop: 1}
}(1024)
for {
select {
case res := <-results:
fmt.Println("扫描到开放的端口:",res.Port) //输出开放的端口号
case <-stopFlag:
e_time := time.Now().Unix()
fmt.Println("本次扫描总共耗时(s):",e_time-s_time)
os.Exit(0)
}
}
}
func worker(id int, jobs <-chan *scanJob, th <-chan time.Time, results chan<- *scanResult) {
for j := range jobs {
if j.Stop != 1 {
sendSyn(j.Laddr, j.Raddr, j.SPort, j.DPort)
} else {
stopFlag <- j.Stop
}
<-th
}
}
func checkError(err error) {
// 错误check
if err != nil {
log.Println(err)
}
}
//CheckSum test
func CheckSum(data []byte, src, dst [4]byte) uint16 {
pseudoHeader := []byte{
src[0], src[1], src[2], src[3],
dst[0], dst[1], dst[2], dst[3],
0,
6,
0,
byte(len(data)),
}
totalLength := len(pseudoHeader) + len(data)
if totalLength%2 != 0 {
totalLength++
}
d := make([]byte, 0, totalLength)
d = append(d, pseudoHeader...)
d = append(d, data...)
return ^mySum(d)
}
func mySum(data []byte) uint16 {
var sum uint32
for i := 0; i < len(data)-1; i += 2 {
sum += uint32(uint16(data[i])<<8 | uint16(data[i+1]))
}
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return uint16(sum)
}
func sendSyn(laddr, raddr string, sport, dport uint16) {
conn, err := net.Dial("ip4:tcp", raddr)
checkError(err)
defer conn.Close()
op := []TCPOption{
TCPOption{
Kind: 2,
Length: 4,
Data: []byte{0x05, 0xb4},
},
TCPOption{
Kind: 0,
},
}
tcpH := TCPHeader{
SrcPort: sport,
DstPort: dport,
SeqNum: rand.Uint32(),
AckNum: 0,
Flags: 0x8002,
Window: 8192,
ChkSum: 0,
UrgentPointer: 0,
}
buff := new(bytes.Buffer)
err = binary.Write(buff, binary.BigEndian, tcpH)
checkError(err)
for i := range op {
binary.Write(buff, binary.BigEndian, op[i].Kind)
binary.Write(buff, binary.BigEndian, op[i].Length)
binary.Write(buff, binary.BigEndian, op[i].Data)
}
binary.Write(buff, binary.BigEndian, [6]byte{})
data := buff.Bytes()
checkSum := CheckSum(data, ipstr2Bytes(laddr), ipstr2Bytes(raddr))
//fmt.Printf("CheckSum 0x%X\n", checkSum)
tcpH.ChkSum = checkSum
buff = new(bytes.Buffer)
binary.Write(buff, binary.BigEndian, tcpH)
for i := range op {
binary.Write(buff, binary.BigEndian, op[i].Kind)
binary.Write(buff, binary.BigEndian, op[i].Length)
binary.Write(buff, binary.BigEndian, op[i].Data)
}
binary.Write(buff, binary.BigEndian, [6]byte{})
data = buff.Bytes()
//fmt.Printf("% X\n", data)
_, err = conn.Write(data)
checkError(err)
}
func recvSynAck(laddr, raddr string, res chan<- *scanResult) error {
listenAddr, err := net.ResolveIPAddr("ip4", laddr) // 解析域名为ip
checkError(err)
conn, err := net.ListenIP("ip4:tcp", listenAddr)
defer conn.Close()
checkError(err)
for {
buff := make([]byte, 1024)
_, addr, err := conn.ReadFrom(buff)
if err != nil {
continue
}
if addr.String() != raddr || buff[13] != 0x12 {
continue
}
var port uint16
binary.Read(bytes.NewReader(buff), binary.BigEndian, &port)
res <- &scanResult{
Port: port,
Opened: true,
}
}
}
func ipstr2Bytes(addr string) [4]byte {
s := strings.Split(addr, ".")
b0, _ := strconv.Atoi(s[0])
b1, _ := strconv.Atoi(s[1])
b2, _ := strconv.Atoi(s[2])
b3, _ := strconv.Atoi(s[3])
return [4]byte{byte(b0), byte(b1), byte(b2), byte(b3)}
}
func random(min, max int) int {
return rand.Intn(max-min) + min
}
func interfaceAddress(ifaceName string ) string {
iface, err:= net.InterfaceByName(ifaceName)
if err != nil {
panic(err)
}
addr, err := iface.Addrs()
if err != nil {
panic(err)
}
addrStr := strings.Split(addr[0].String(), "/")[0]
return addrStr
}
func portSplit(portRange *string) (uint16, uint16) {
ports := strings.Split(*portRange, "-")
minPort, err := strconv.ParseUint(ports[0], 10, 16)
if err !=nil {
panic(err)
}
maxPort, err := strconv.ParseUint(ports[1], 10, 16)
if err != nil {
panic(err)
}
if minPort > maxPort {
panic(errors.New("minPort must greater than maxPort"))
}
return uint16(minPort), uint16(maxPort)
}
func main() { }
go bulid -buildmode=c-shared -o go-syn-portscan2so.so go-syn-portscan2so.go
打包后会得到一个go-syn-portscan2so.so和一个.h文件。然后利用下面的python代码就可以调用Go代码中的Scan()函数了,创建一个final-portscan-with-pygo.py文件
#! -*- coding:utf-8 -*-
from ctypes import *
#其实也可以直接模仿kunpeng的写法,但是没必要.爽了就行.
lib = cdll.LoadLibrary(u'./scan.so')
lib.Scan("10.0.0.1","1-1024","eth0") # ip,端口范围,网卡
运行及结果: