update image and tcp
This commit is contained in:
parent
5b0b3834bb
commit
32c6e7b534
4
go.mod
4
go.mod
@ -4,12 +4,12 @@ go 1.20
|
||||
|
||||
require (
|
||||
b612.me/bcap v0.0.4
|
||||
b612.me/notify v1.2.6
|
||||
b612.me/notify v0.0.0-20240818092352-85803f75dfa0
|
||||
b612.me/sdk/whois v0.0.0-20240816133027-129514a15991
|
||||
b612.me/starcrypto v0.0.5
|
||||
b612.me/stario v0.0.10
|
||||
b612.me/starlog v1.3.4
|
||||
b612.me/starmap v1.2.4
|
||||
b612.me/starmap v0.0.0-20240818092703-ae61140c5062
|
||||
b612.me/starnet v0.2.1
|
||||
b612.me/staros v1.1.8
|
||||
b612.me/starssh v0.0.2
|
||||
|
13
go.sum
13
go.sum
@ -1,21 +1,18 @@
|
||||
b612.me/bcap v0.0.4 h1:iY2Oz+uyG/mue6a/dJiU82ci5Xwkj4xHhre/q0O8G60=
|
||||
b612.me/bcap v0.0.4/go.mod h1:tpus+4iMpsnxb98Pck70s87Zt4sIWuRZjK23MmmzmoY=
|
||||
b612.me/notify v1.2.5/go.mod h1:GTnAdC6v9krGxtC8Gkn8TcyUsYnHSiHjRAXsONPiLpI=
|
||||
b612.me/notify v1.2.6 h1:fY+0ccP6cJCDvnfRilmPlDK+J8xTYBpYNwf7jaC2IIE=
|
||||
b612.me/notify v1.2.6/go.mod h1:awcFq3bvbkf3hdviUtOW16Io0IEJXkNPgno7IRe7B9g=
|
||||
b612.me/notify v0.0.0-20240818092352-85803f75dfa0 h1:PaLuNLMM0HBM7qPdk4igtNvqT2CDgdm52sL+KA9I3so=
|
||||
b612.me/notify v0.0.0-20240818092352-85803f75dfa0/go.mod h1:YyaYF4jj5ygIC/QbCMyhBWnsmmTL8kVs6UlHMGVKiY8=
|
||||
b612.me/sdk/whois v0.0.0-20240816133027-129514a15991 h1:+eXeVqkoi4s9sNoY9eGt4ieSbr1+Deos8fC8wMfOCNI=
|
||||
b612.me/sdk/whois v0.0.0-20240816133027-129514a15991/go.mod h1:PB9QpUoQEip0MB3st8H5hmnDTcDsR0RGV0BfpUr5XDg=
|
||||
b612.me/starcrypto v0.0.3/go.mod h1:pF5A16p8r/h1G0x7ZNmmAF6K1sdIMpbCUxn2WGC8gZ0=
|
||||
b612.me/starcrypto v0.0.5 h1:Aa4pRDO2lBH2Aw+vz8NuUtRb73J8z5aOa9SImBY5sq4=
|
||||
b612.me/starcrypto v0.0.5/go.mod h1:pF5A16p8r/h1G0x7ZNmmAF6K1sdIMpbCUxn2WGC8gZ0=
|
||||
b612.me/stario v0.0.9/go.mod h1:x4D/x8zA5SC0pj/uJAi4FyG5p4j5UZoMEZfvuRR6VNw=
|
||||
b612.me/stario v0.0.0-20240818091810-d528a583f4b2/go.mod h1:1Owmu9jzKWgs4VsmeI8YWlGwLrCwPNM/bYpxkyn+MMk=
|
||||
b612.me/stario v0.0.10 h1:+cIyiDCBCjUfodMJDp4FLs+2E1jo7YENkN+sMEe6550=
|
||||
b612.me/stario v0.0.10/go.mod h1:1Owmu9jzKWgs4VsmeI8YWlGwLrCwPNM/bYpxkyn+MMk=
|
||||
b612.me/starlog v1.3.4 h1:XuVYo6NCij8F4TGSgtEuMhs1WkZ7HZNnYUgQ3nLTt84=
|
||||
b612.me/starlog v1.3.4/go.mod h1:37GMgkWQMOAjzKs49Hf2i8bLwdXbd9QF4zKhUxFDoSk=
|
||||
b612.me/starmap v1.2.4 h1:gfAyBtzW3KKCIyI14I2pEqGsR/u2E+3tkH0xRqtWb4E=
|
||||
b612.me/starmap v1.2.4/go.mod h1:EhOUzkItc5IcyBmr1C7/vmZBbW3GgCWs63hGn7WhuMc=
|
||||
b612.me/starnet v0.1.8/go.mod h1:k862Kf8DiVWTqdX6PHTFb6NoT+3G3Y74n8NCyNhuP0Y=
|
||||
b612.me/starmap v0.0.0-20240818092703-ae61140c5062 h1:ImKEWAxzBYsS/YbqdVOPdUdv6b+i/lSGpipUGueXk7w=
|
||||
b612.me/starmap v0.0.0-20240818092703-ae61140c5062/go.mod h1:PhtO9wFrwPIHpry2CEdnVNZkrNOgfv77xrE0ZKQDkLM=
|
||||
b612.me/starnet v0.2.1 h1:17n3wa2QgBYbO1rqDLAhyc2DfvbBc23GSp1v42Pvmiw=
|
||||
b612.me/starnet v0.2.1/go.mod h1:6q+AXhYeXsIiKV+hZZmqAMn8S48QcdonURJyH66rbzI=
|
||||
b612.me/staros v1.1.8 h1:5Bpuf9q2nH75S2ekmieJuH3Y8LTqg/voxXCOiMAC3kk=
|
||||
|
190
image/image.go
190
image/image.go
@ -1,15 +1,31 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"sort"
|
||||
|
||||
"b612.me/starlog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var useHex bool
|
||||
var useAlpha bool
|
||||
var useCount int
|
||||
var ckt uint8
|
||||
var fromRgb string
|
||||
var toRgb string
|
||||
|
||||
func init() {
|
||||
Cmd.AddCommand(imgMirrorCmd)
|
||||
Cmd.AddCommand(imgMirrorCmd, imgRgbCountCmd, imgReplaceCmd, imgReverseCmd)
|
||||
imgRgbCountCmd.Flags().BoolVarP(&useHex, "hex", "x", false, "使用十六进制表示")
|
||||
imgRgbCountCmd.Flags().BoolVarP(&useAlpha, "alpha", "a", false, "统计alpha通道")
|
||||
imgRgbCountCmd.Flags().IntVarP(&useCount, "count", "c", 10, "显示数量")
|
||||
imgReplaceCmd.Flags().Uint8VarP(&ckt, "ckt", "k", 30, "颜色比较阈值")
|
||||
imgReplaceCmd.Flags().StringVarP(&fromRgb, "from", "f", "dfdfdf", "需要替换的颜色")
|
||||
imgReplaceCmd.Flags().StringVarP(&toRgb, "to", "t", "ffffff", "替换为的颜色")
|
||||
}
|
||||
|
||||
var Cmd = &cobra.Command{
|
||||
@ -80,3 +96,175 @@ var imgAlpha = &cobra.Command{
|
||||
fmt.Println("任务完成!")
|
||||
},
|
||||
}
|
||||
|
||||
var imgRgbCountCmd = &cobra.Command{
|
||||
Use: "rgbcount",
|
||||
Short: "统计最多的rgb值",
|
||||
Long: "统计最多的RGB值",
|
||||
Run: func(this *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
starlog.Errorln("请指定需要统计的图像!")
|
||||
return
|
||||
}
|
||||
for _, v := range args {
|
||||
img, err := OpenImage(v)
|
||||
if err != nil {
|
||||
starlog.Errorln(err, v)
|
||||
continue
|
||||
}
|
||||
size := img.Bounds()
|
||||
colorMap := make(map[string]int)
|
||||
for x := 0; x < size.Dx(); x++ {
|
||||
for y := 0; y < size.Dy(); y++ {
|
||||
color := img.At(x, y)
|
||||
r, g, b, a := color.RGBA()
|
||||
var key string
|
||||
if useAlpha {
|
||||
if !useHex {
|
||||
key = fmt.Sprintf("%d,%d,%d,%d", uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8))
|
||||
} else {
|
||||
key = fmt.Sprintf("%x%x%x%x", uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8))
|
||||
}
|
||||
} else {
|
||||
if !useHex {
|
||||
key = fmt.Sprintf("%d,%d,%d", uint8(r>>8), uint8(g>>8), uint8(b>>8))
|
||||
} else {
|
||||
key = fmt.Sprintf("%x%x%x", uint8(r>>8), uint8(g>>8), uint8(b>>8))
|
||||
}
|
||||
}
|
||||
if _, ok := colorMap[key]; ok {
|
||||
colorMap[key]++
|
||||
} else {
|
||||
colorMap[key] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
colorSlice := make([]struct {
|
||||
string
|
||||
int
|
||||
}, 0, len(colorMap))
|
||||
for k, v := range colorMap {
|
||||
colorSlice = append(colorSlice, struct {
|
||||
string
|
||||
int
|
||||
}{k, v})
|
||||
}
|
||||
sort.Slice(colorSlice, func(i, j int) bool {
|
||||
return colorSlice[i].int > colorSlice[j].int
|
||||
})
|
||||
fmt.Println(v)
|
||||
for i := 0; i < useCount && i < len(colorSlice); i++ {
|
||||
fmt.Printf("%d. %s: %d\n", i+1, colorSlice[i].string, colorSlice[i].int)
|
||||
}
|
||||
fmt.Println("----------------")
|
||||
}
|
||||
fmt.Println("任务完成!")
|
||||
},
|
||||
}
|
||||
|
||||
var imgReplaceCmd = &cobra.Command{
|
||||
Use: "replace",
|
||||
Short: "图像RGB替换",
|
||||
Long: "图像RGB替换",
|
||||
Run: func(this *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
starlog.Errorln("请指定需要转换的图像!")
|
||||
return
|
||||
}
|
||||
r, g, b, err := HexToRGB(fromRgb)
|
||||
if err != nil {
|
||||
starlog.Errorln(err)
|
||||
return
|
||||
}
|
||||
nr, ng, nb, err := HexToRGB(toRgb)
|
||||
if err != nil {
|
||||
starlog.Errorln(err)
|
||||
return
|
||||
}
|
||||
for _, v := range args {
|
||||
img, err := OpenImage(v)
|
||||
if err != nil {
|
||||
starlog.Errorln(err, v)
|
||||
continue
|
||||
}
|
||||
size := img.Bounds()
|
||||
nimg := image.NewRGBA(size)
|
||||
for x := 0; x < size.Dx(); x++ {
|
||||
for y := 0; y < size.Dy(); y++ {
|
||||
mR, mG, mB, ma := img.At(x, y).RGBA()
|
||||
mr, mg, mb := uint8(mR>>8), uint8(mG>>8), uint8(mB>>8)
|
||||
nimg.Set(x, y, img.At(x, y))
|
||||
if mr-r < ckt || r-mr < ckt {
|
||||
if mg-g < ckt || g-mg < ckt {
|
||||
if mb-b < ckt || b-mb < ckt {
|
||||
nimg.Set(x, y, color.NRGBA{nr, ng, nb, uint8(ma >> 8)})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := SavePhoto("new-"+v, nimg); err != nil {
|
||||
starlog.Errorln(err, v)
|
||||
continue
|
||||
} else {
|
||||
fmt.Println(v, "转换已完成!")
|
||||
}
|
||||
}
|
||||
fmt.Println("任务完成!")
|
||||
},
|
||||
}
|
||||
|
||||
func HexToRGB(hexStr string) (uint8, uint8, uint8, error) {
|
||||
// 检查输入长度是否为6
|
||||
if len(hexStr) != 6 {
|
||||
return 0, 0, 0, fmt.Errorf("invalid hex color string: %s", hexStr)
|
||||
}
|
||||
|
||||
// 将16进制字符串解码为字节数组
|
||||
decoded, err := hex.DecodeString(hexStr)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("failed to decode hex string: %v", err)
|
||||
}
|
||||
|
||||
// 解码结果应该有3个字节
|
||||
if len(decoded) != 3 {
|
||||
return 0, 0, 0, fmt.Errorf("invalid hex color format: %s", hexStr)
|
||||
}
|
||||
|
||||
// 返回三个通道值
|
||||
return decoded[0], decoded[1], decoded[2], nil
|
||||
}
|
||||
|
||||
var imgReverseCmd = &cobra.Command{
|
||||
Use: "reverse",
|
||||
Short: "图像反色",
|
||||
Long: "图像反色",
|
||||
Run: func(this *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
starlog.Errorln("请指定需要转换的图像!")
|
||||
return
|
||||
}
|
||||
for _, v := range args {
|
||||
img, err := OpenImage(v)
|
||||
if err != nil {
|
||||
starlog.Errorln(err, v)
|
||||
continue
|
||||
}
|
||||
size := img.Bounds()
|
||||
nimg := image.NewRGBA(size)
|
||||
for x := 0; x < size.Dx(); x++ {
|
||||
for y := 0; y < size.Dy(); y++ {
|
||||
r, g, b, a := img.At(x, y).RGBA()
|
||||
nimg.Set(x, y, color.NRGBA{uint8(255 - r>>8), uint8(255 - g>>8), uint8(255 - b>>8), uint8(a >> 8)})
|
||||
}
|
||||
}
|
||||
if err := SavePhoto("reverse-"+v, nimg); err != nil {
|
||||
starlog.Errorln(err, v)
|
||||
continue
|
||||
} else {
|
||||
fmt.Println(v, "转换已完成!")
|
||||
}
|
||||
}
|
||||
fmt.Println("任务完成!")
|
||||
},
|
||||
}
|
||||
|
@ -34,7 +34,9 @@ func init() {
|
||||
Cmd.Flags().StringVarP(&mg.Tareget, "output", "o", "", "输出文件名")
|
||||
Cmd.Flags().IntVarP(&mg.BufferSize, "buffer", "b", 8192, "缓冲区大小")
|
||||
Cmd.Flags().IntVarP(&mg.Thread, "thread", "t", 8, "线程数")
|
||||
Cmd.Flags().IntVarP(&mg.RedoRPO, "safe", "s", 1048576, "安全校验点")
|
||||
Cmd.Flags().BoolVarP(&mg.NoWriteRedo, "no-redo", "N", false, "不写入redo文件")
|
||||
Cmd.Flags().IntVarP(&mg.RedoRPO, "safe", "s", 0, "安全校验点,0意味自动调整")
|
||||
Cmd.Flags().IntVarP(&mg.RedoMinSaveSec, "redo-min-sec", "m", 2, "redo文件最短写入间隔(秒)")
|
||||
Cmd.Flags().StringSliceVarP(&headers, "header", "H", []string{}, "自定义请求头,格式: key=value")
|
||||
Cmd.Flags().StringVarP(&proxy, "proxy", "P", "", "代理地址")
|
||||
Cmd.Flags().StringVarP(&ua, "user-agent", "U", "", "自定义User-Agent")
|
||||
@ -140,7 +142,9 @@ func Run(cmd *cobra.Command, args []string) {
|
||||
starlog.Infoln("User Interrupted")
|
||||
mg.fn()
|
||||
time.Sleep(time.Second)
|
||||
mg.Redo.Save()
|
||||
if !mg.NoWriteRedo {
|
||||
mg.Redo.Save()
|
||||
}
|
||||
os.Exit(3)
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ type Redo struct {
|
||||
avgSpeed float64
|
||||
total uint64
|
||||
isRedo bool
|
||||
lastCallSave time.Time
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
@ -128,18 +129,20 @@ func (r *Redo) AverageSpeed() float64 {
|
||||
}
|
||||
|
||||
func (r *Redo) Save() error {
|
||||
//defer recover()
|
||||
var err error
|
||||
err = r.reform()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.lastCallSave = time.Now()
|
||||
if r.Filename != "" {
|
||||
data, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
return os.WriteFile(r.Filename+".bgrd", data, 0644)
|
||||
}
|
||||
return nil
|
||||
|
27
mget/wget.go
27
mget/wget.go
@ -23,7 +23,10 @@ type Mget struct {
|
||||
//本地文件大小
|
||||
TargetSize int64
|
||||
//redo文件最大丢数据量
|
||||
RedoRPO int
|
||||
RedoRPO int
|
||||
NoWriteRedo bool
|
||||
RedoAutoRpo bool
|
||||
RedoMinSaveSec int
|
||||
//单个buffer大小
|
||||
BufferSize int
|
||||
//并发下载线程数
|
||||
@ -231,7 +234,9 @@ func (w *Mget) Run() error {
|
||||
continue
|
||||
}
|
||||
if w.writeError != nil {
|
||||
err = w.Redo.Save()
|
||||
if !w.NoWriteRedo {
|
||||
err = w.Redo.Save()
|
||||
}
|
||||
return fmt.Errorf("write error: %w %v", w.writeError, err)
|
||||
}
|
||||
break
|
||||
@ -252,10 +257,13 @@ func (w *Mget) Run() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(r) == 0 {
|
||||
return os.Remove(w.Tareget + ".bgrd")
|
||||
if !w.NoWriteRedo {
|
||||
if len(r) == 0 {
|
||||
return os.Remove(w.Tareget + ".bgrd")
|
||||
}
|
||||
return w.Redo.Save()
|
||||
}
|
||||
return w.Redo.Save()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Mget) dispatch(idx int) error {
|
||||
@ -393,6 +401,10 @@ func (w *Mget) WriteServer() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if w.RedoRPO == 0 {
|
||||
w.RedoAutoRpo = true
|
||||
w.RedoRPO = 1024 * 1024 * 1024
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-w.ctx.Done():
|
||||
@ -413,9 +425,12 @@ func (w *Mget) WriteServer() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if currentRange-lastUpdateRange >= w.RedoRPO {
|
||||
if !w.NoWriteRedo && currentRange-lastUpdateRange >= w.RedoRPO && time.Now().After(w.Redo.lastCallSave.Add(time.Second*time.Duration(w.RedoMinSaveSec))) {
|
||||
w.tf.Sync()
|
||||
go w.Redo.Save()
|
||||
if w.RedoAutoRpo {
|
||||
w.RedoRPO = int(w.Redo.Speed()) * 2
|
||||
}
|
||||
lastUpdateRange = currentRange
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +31,11 @@ func init() {
|
||||
Cmd.Flags().IntVarP(&nf.packetDelay, "packet-delay-num", "n", 0, "触发封禁关键词后,延迟n个包再封禁")
|
||||
Cmd.Flags().BoolVarP(&nf.useRST, "rst", "r", false, "触发封禁关键词后,同步发送RST报文")
|
||||
Cmd.Flags().StringVarP(&nf.rstMode, "rstmode", "R", "reverse", "RST报文发送模式,可选值:both,target,reverse")
|
||||
Cmd.Flags().BoolVarP(&nf.fastMode, "fastmode", "f", false, "快速模式,仅在模拟延迟或丢包时使用")
|
||||
Cmd.Flags().BoolVarP(&nf.fastMode, "fastmode", "F", false, "快速模式,仅在模拟延迟或丢包时使用")
|
||||
Cmd.Flags().IntVarP(&nf.NFQNums, "nfqueue-num", "q", 2, "nfqueue队列号")
|
||||
Cmd.Flags().BoolVarP(&nf.allowRandomAck, "random-ack", "A", false, "允许并行乱序处理报文,如果需要模拟延迟,此选项需开启,但封禁功能可能受到乱序影响")
|
||||
Cmd.Flags().BoolVarP(&nf.onlyDropblackwordPacket, "only-drop-blackword-packet", "o", false, "只封禁包含关键词的报文,此模式下,packetDelay会失效")
|
||||
Cmd.Flags().BoolVarP(&nf.singlePacketMode, "signle-packet", "o", false, "仅对匹配到的单报文操作,此模式下,packetDelay会失效")
|
||||
Cmd.Flags().StringSliceVarP(&nf.cuePktMethod, "cue-pkt-method", "O", []string{}, "单报文匹配下,执行的报文操作,可选值:drop,delay ms,allow,reset")
|
||||
Cmd.Flags().StringSliceVarP(&nf.Flags, "flags", "f", nil, "tcp flags匹配,如:SYN,ACK")
|
||||
Cmd.Flags().IntVarP(&nf.CapFileCacheNum, "write-cache", "W", 0, "命中匹配写入文件报文缓存,如果为0 ,则忽略匹配条件")
|
||||
}
|
||||
|
@ -29,5 +29,7 @@ func init() {
|
||||
Cmd.Flags().StringVarP(&nf.eth, "eth", "e", "", "监听网卡名,如eth0")
|
||||
Cmd.Flags().StringVarP(&nf.bpf, "bpf", "b", "tcp", "BPF过滤,如tcp port 80")
|
||||
Cmd.Flags().StringVarP(&nf.host, "host", "i", "", "监听主机名,如127.0.0.1")
|
||||
Cmd.Flags().StringSliceVarP(&nf.Flags, "flags", "f", nil, "tcp flags匹配,如:SYN,ACK")
|
||||
Cmd.Flags().IntVarP(&nf.CapFileCacheNum, "write-cache", "W", 0, "命中匹配写入文件报文缓存,如果为0 ,则忽略匹配条件")
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"b612.me/bcap/nfq"
|
||||
"b612.me/stario"
|
||||
"b612.me/starlog"
|
||||
"b612.me/starmap"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@ -63,18 +64,21 @@ type NfCap struct {
|
||||
// 触发封禁词后,使用RST重置链路
|
||||
useRST bool
|
||||
// RST模式,target=目标端单向RST,reverse=对端反向RST,both=双向RST
|
||||
rstMode string
|
||||
fastMode bool //自探测
|
||||
printColor []*starlog.Color
|
||||
logCache chan loged
|
||||
monitorPort int
|
||||
cache []string
|
||||
NFQNums int
|
||||
ctx context.Context
|
||||
fn context.CancelFunc
|
||||
requests chan *handler
|
||||
allowRandomAck bool
|
||||
onlyDropblackwordPacket bool
|
||||
rstMode string
|
||||
fastMode bool //自探测
|
||||
printColor []*starlog.Color
|
||||
logCache chan loged
|
||||
monitorPort int
|
||||
cache []string
|
||||
NFQNums int
|
||||
ctx context.Context
|
||||
fn context.CancelFunc
|
||||
requests chan *handler
|
||||
allowRandomAck bool
|
||||
singlePacketMode bool
|
||||
cuePktMethod []string
|
||||
CapFileCacheNum int
|
||||
Flags []string
|
||||
}
|
||||
|
||||
type loged struct {
|
||||
@ -205,7 +209,7 @@ func (t *NfCap) Run() error {
|
||||
|
||||
func NewNfCap() *NfCap {
|
||||
var nf = new(NfCap)
|
||||
nf.packetCache = make(chan gopacket.Packet, 2048)
|
||||
nf.packetCache = make(chan gopacket.Packet, 8192)
|
||||
nf.logCache = make(chan loged, 2048)
|
||||
nf.printColor = []*starlog.Color{
|
||||
starlog.NewColor(starlog.FgWhite), //0=unknown
|
||||
@ -233,7 +237,7 @@ func NewNfCap() *NfCap {
|
||||
}
|
||||
nf.cap = bcap.NewPackets()
|
||||
nf.ctx, nf.fn = context.WithCancel(context.Background())
|
||||
nf.requests = make(chan *handler, 2048)
|
||||
nf.requests = make(chan *handler, 8192)
|
||||
return nf
|
||||
}
|
||||
func (t *NfCap) handleNfResult() {
|
||||
@ -246,8 +250,10 @@ func (t *NfCap) handleNfResult() {
|
||||
continue
|
||||
}
|
||||
if t.allowRandomAck {
|
||||
go info.p.SetVerdict(info.id, <-info.fin)
|
||||
continue
|
||||
go func() {
|
||||
info.p.SetVerdict(info.id, <-info.fin)
|
||||
}()
|
||||
break
|
||||
}
|
||||
info.p.SetVerdict(info.id, <-info.fin)
|
||||
}
|
||||
@ -344,6 +350,21 @@ func (n *NfCap) strInRange(str string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *NfCap) strInRangeIdx(str string) int {
|
||||
if len(n.targetCmd) == 0 {
|
||||
return -1
|
||||
}
|
||||
for k, v := range n.targetCmd {
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(str, v) {
|
||||
return k
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (n *NfCap) handlePacket(info bcap.PacketInfo, nfp nfq.Packet) int {
|
||||
p := nfp.Packet
|
||||
n.count++
|
||||
@ -427,6 +448,9 @@ func (n *NfCap) handlePacket(info bcap.PacketInfo, nfp nfq.Packet) int {
|
||||
case 14:
|
||||
dec = "TCP Keepalive"
|
||||
}
|
||||
if len(n.Flags) > 0 && !n.writerMatch(p, true) {
|
||||
return nfqueue.NfAccept
|
||||
}
|
||||
if n.showAll || n.ipInRange(info.SrcIP) || n.ipInRange(info.DstIP) {
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("%s %v:%v -> %v:%v %s seq=%v ack=%v win=%v len=%v\n", time.Now().Format("2006-01-02 15:04:05.000000"), info.SrcIP, info.SrcPort,
|
||||
@ -451,6 +475,21 @@ func (n *NfCap) handlePacket(info bcap.PacketInfo, nfp nfq.Packet) int {
|
||||
}
|
||||
}
|
||||
}
|
||||
if res := n.cuePacket(info, layer); res != -1 {
|
||||
return res
|
||||
}
|
||||
if shouldDisallow {
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("Block(loss) TCP %v:%v -> %v:%v,LEN=%d\n", info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpPayloads()),
|
||||
stateLevel: 0,
|
||||
logLevel: "warning",
|
||||
}
|
||||
return nfqueue.NfDrop
|
||||
}
|
||||
return nfqueue.NfAccept
|
||||
}
|
||||
|
||||
func (n *NfCap) cuePacket(info bcap.PacketInfo, layer gopacket.Layer) int {
|
||||
if info.Comment() != "" || n.cap.Key(info.ReverseKey).Comment() != "" {
|
||||
tmp := info.Comment()
|
||||
if tmp == "" {
|
||||
@ -478,39 +517,32 @@ func (n *NfCap) handlePacket(info bcap.PacketInfo, nfp nfq.Packet) int {
|
||||
n.cap.SetComment(info.ReverseKey, strconv.Itoa(pkg-1))
|
||||
}
|
||||
}
|
||||
if len(n.targetCmd) > 0 && (n.ipInRange(info.SrcIP) || n.ipInRange(info.DstIP)) && n.strInRange(string(layer.LayerPayload())) {
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("%s:%s -> %s:%s !!Match Keyword,will block!!\n", info.SrcIP, info.SrcPort,
|
||||
info.DstIP, info.DstPort),
|
||||
stateLevel: 0,
|
||||
logLevel: "warning",
|
||||
}
|
||||
if n.onlyDropblackwordPacket {
|
||||
if n.useRST && info.StateDescript() == 13 {
|
||||
return nfqueue.NfAccept
|
||||
}
|
||||
if len(n.targetCmd) > 0 && (n.ipInRange(info.SrcIP) || n.ipInRange(info.DstIP)) {
|
||||
if idx := n.strInRangeIdx(string(layer.LayerPayload())); idx >= 0 {
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("Block TCP %v:%v -> %v:%v,LEN=%d\n", info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpPayloads()),
|
||||
str: fmt.Sprintf("%s:%s -> %s:%s !!Match Keyword,will block!!\n", info.SrcIP, info.SrcPort,
|
||||
info.DstIP, info.DstPort),
|
||||
stateLevel: 0,
|
||||
logLevel: "warning",
|
||||
}
|
||||
return nfqueue.NfDrop
|
||||
}
|
||||
if n.packetDelay > 0 && info.Comment() == "" {
|
||||
n.cap.SetComment(info.Key, strconv.Itoa(n.packetDelay))
|
||||
n.cap.SetComment(info.ReverseKey, strconv.Itoa(n.packetDelay))
|
||||
} else {
|
||||
if n.useRST {
|
||||
RealSendRST(info, n.rstMode, 3)
|
||||
if n.singlePacketMode {
|
||||
return n.singlePacket(info, idx)
|
||||
}
|
||||
if n.ipInRange(info.SrcIP) {
|
||||
n.blockMap.Store(info.SrcIP, true)
|
||||
if n.packetDelay > 0 && info.Comment() == "" {
|
||||
n.cap.SetComment(info.Key, strconv.Itoa(n.packetDelay))
|
||||
n.cap.SetComment(info.ReverseKey, strconv.Itoa(n.packetDelay))
|
||||
} else {
|
||||
n.blockMap.Store(info.DstIP, true)
|
||||
if n.useRST {
|
||||
RealSendRST(info, n.rstMode, 3)
|
||||
}
|
||||
if n.ipInRange(info.SrcIP) {
|
||||
n.blockMap.Store(info.SrcIP, true)
|
||||
} else {
|
||||
n.blockMap.Store(info.DstIP, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, ok1 := n.blockMap.Load(info.DstIP)
|
||||
_, ok2 := n.blockMap.Load(info.SrcIP)
|
||||
if ok1 || ok2 {
|
||||
@ -524,37 +556,178 @@ func (n *NfCap) handlePacket(info bcap.PacketInfo, nfp nfq.Packet) int {
|
||||
}
|
||||
return nfqueue.NfDrop
|
||||
}
|
||||
if shouldDisallow {
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("Block(loss) TCP %v:%v -> %v:%v,LEN=%d\n", info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpPayloads()),
|
||||
stateLevel: 0,
|
||||
logLevel: "warning",
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (n *NfCap) singlePacket(info bcap.PacketInfo, idx int) int {
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("Handle TCP %v:%v -> %v:%v,LEN=%d\n", info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpPayloads()),
|
||||
stateLevel: 0,
|
||||
logLevel: "warning",
|
||||
}
|
||||
if len(n.cuePktMethod) == 0 {
|
||||
return nfqueue.NfDrop
|
||||
}
|
||||
task := n.cuePktMethod[idx]
|
||||
for _, v := range strings.Split(task, ";") {
|
||||
v = strings.TrimSpace(v)
|
||||
tasks := strings.Fields(v)
|
||||
switch strings.ToLower(tasks[0]) {
|
||||
case "delay":
|
||||
if len(tasks) < 2 {
|
||||
continue
|
||||
}
|
||||
tmp, err := strconv.Atoi(tasks[1])
|
||||
if err != nil {
|
||||
fmt.Printf("输入延迟无效:%v\n", err)
|
||||
continue
|
||||
}
|
||||
time.Sleep(time.Millisecond * time.Duration(tmp))
|
||||
case "drop":
|
||||
return nfqueue.NfDrop
|
||||
case "allow":
|
||||
return nfqueue.NfAccept
|
||||
case "reset":
|
||||
RealSendRST(info, n.rstMode, 3)
|
||||
default:
|
||||
starlog.Warningf("未知命令:%s\n", v)
|
||||
}
|
||||
}
|
||||
return nfqueue.NfAccept
|
||||
}
|
||||
|
||||
func (n *NfCap) pcapWriter(stopCtx context.Context, fp *os.File) error {
|
||||
w := pcapgo.NewWriter(fp)
|
||||
err := w.WriteFileHeader(65535, layers.LinkTypeRaw)
|
||||
err := w.WriteFileHeader(65535, layers.LinkTypeEthernet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := starmap.NewStarChanStack(uint64(n.CapFileCacheNum))
|
||||
avail := 0
|
||||
for {
|
||||
select {
|
||||
case <-stopCtx.Done():
|
||||
return nil
|
||||
case p := <-n.packetCache:
|
||||
w.WritePacket(gopacket.CaptureInfo{
|
||||
Timestamp: time.Now(),
|
||||
CaptureLength: len(p.Data()),
|
||||
Length: len(p.Data()),
|
||||
}, p.Data())
|
||||
if n.CapFileCacheNum == 0 {
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
continue
|
||||
}
|
||||
if avail > 0 {
|
||||
avail--
|
||||
if n.writerMatch(p, false) {
|
||||
avail = n.CapFileCacheNum
|
||||
}
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
continue
|
||||
}
|
||||
if buf.Free() == 0 {
|
||||
buf.Pop()
|
||||
}
|
||||
if !n.writerMatch(p, false) {
|
||||
buf.Push(p)
|
||||
continue
|
||||
}
|
||||
for buf.Len() > 0 {
|
||||
hp, err := buf.Pop()
|
||||
if err == nil {
|
||||
w.WritePacket(hp.(gopacket.Packet).Metadata().CaptureInfo, hp.(gopacket.Packet).Data())
|
||||
}
|
||||
}
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
avail = n.CapFileCacheNum
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NfCap) writerMatch(pkt gopacket.Packet, onlyFlags bool) bool {
|
||||
tcpLayer := pkt.Layer(layers.LayerTypeTCP)
|
||||
if !onlyFlags {
|
||||
var src, dst string
|
||||
if nw := pkt.NetworkLayer(); nw != nil {
|
||||
srcp, dstp := nw.NetworkFlow().Endpoints()
|
||||
src = srcp.String()
|
||||
dst = dstp.String()
|
||||
}
|
||||
if !(n.ipInRange(src) || n.ipInRange(dst)) {
|
||||
return false
|
||||
}
|
||||
if tcpLayer == nil {
|
||||
if len(n.targetCmd) != 0 && !n.strInRange(string(pkt.TransportLayer().LayerPayload())) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
if len(n.targetCmd) != 0 && !n.strInRange(string(tcpLayer.LayerPayload())) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(n.Flags) == 0 {
|
||||
return true
|
||||
}
|
||||
if tcpLayer == nil {
|
||||
return false
|
||||
}
|
||||
tl := tcpLayer.(*layers.TCP)
|
||||
for _, seq := range n.Flags {
|
||||
notMatch := false
|
||||
bkfor:
|
||||
for _, v := range strings.Split(strings.ToUpper(seq), ",") {
|
||||
switch strings.TrimSpace(v) {
|
||||
case "SYN":
|
||||
if !tl.SYN {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "ACK":
|
||||
if !tl.ACK {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "FIN":
|
||||
if !tl.FIN {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "RST":
|
||||
if !tl.RST {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "CWR":
|
||||
if !tl.CWR {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "ECE":
|
||||
if !tl.ECE {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "NS":
|
||||
if !tl.NS {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "PSH":
|
||||
if !tl.PSH {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "URG":
|
||||
if !tl.URG {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
}
|
||||
}
|
||||
if !notMatch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func RealSendRST(info bcap.PacketInfo, target string, number int) {
|
||||
for i := 0; i < number; i++ {
|
||||
if target == "both" || target == "target" {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"b612.me/bcap"
|
||||
"b612.me/bcap/libpcap"
|
||||
"b612.me/starlog"
|
||||
"b612.me/starmap"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@ -52,16 +53,18 @@ type Libpcap struct {
|
||||
// 触发封禁词后,使用RST重置链路
|
||||
useRST bool
|
||||
// RST模式,target=目标端单向RST,reverse=对端反向RST,both=双向RST
|
||||
rstMode string
|
||||
printColor []*starlog.Color
|
||||
logCache chan loged
|
||||
ctx context.Context
|
||||
fn context.CancelFunc
|
||||
bpf string
|
||||
eth string
|
||||
host string
|
||||
handle *libpcap.NetCatch
|
||||
blockMap sync.Map
|
||||
rstMode string
|
||||
printColor []*starlog.Color
|
||||
logCache chan loged
|
||||
ctx context.Context
|
||||
fn context.CancelFunc
|
||||
bpf string
|
||||
eth string
|
||||
host string
|
||||
handle *libpcap.NetCatch
|
||||
blockMap sync.Map
|
||||
CapFileCacheNum int
|
||||
Flags []string
|
||||
}
|
||||
|
||||
type loged struct {
|
||||
@ -297,6 +300,9 @@ func (n *Libpcap) handlePacket(p gopacket.Packet) {
|
||||
if !n.showAll && !n.ipInRange(info.SrcIP) && !n.ipInRange(info.DstIP) {
|
||||
return
|
||||
}
|
||||
if len(n.Flags) > 0 && !n.writerMatch(p, true) {
|
||||
return
|
||||
}
|
||||
n.logCache <- loged{
|
||||
str: fmt.Sprintf("%s %v:%v -> %v:%v %s seq=%v ack=%v win=%v len=%v\n", time.Now().Format("2006-01-02 15:04:05.000000"), info.SrcIP, info.SrcPort,
|
||||
info.DstIP, info.DstPort, dec, info.TcpSeq(), info.TcpAck(), info.TcpWindow(), info.TcpPayloads()),
|
||||
@ -330,22 +336,6 @@ func (n *Libpcap) handlePacket(p gopacket.Packet) {
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Libpcap) pcapWriter(stopCtx context.Context, fp *os.File) error {
|
||||
w := pcapgo.NewWriter(fp)
|
||||
err := w.WriteFileHeader(65535, layers.LinkTypeEthernet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-stopCtx.Done():
|
||||
return nil
|
||||
case p := <-n.packetCache:
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RealSendRST(p *pcap.Handle, info bcap.PacketInfo, target string, number int) {
|
||||
for i := 0; i < number; i++ {
|
||||
if target == "both" || target == "target" {
|
||||
@ -359,6 +349,138 @@ func RealSendRST(p *pcap.Handle, info bcap.PacketInfo, target string, number int
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Libpcap) pcapWriter(stopCtx context.Context, fp *os.File) error {
|
||||
w := pcapgo.NewWriter(fp)
|
||||
err := w.WriteFileHeader(65535, layers.LinkTypeEthernet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := starmap.NewStarChanStack(uint64(n.CapFileCacheNum))
|
||||
avail := 0
|
||||
for {
|
||||
select {
|
||||
case <-stopCtx.Done():
|
||||
return nil
|
||||
case p := <-n.packetCache:
|
||||
if n.CapFileCacheNum == 0 {
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
continue
|
||||
}
|
||||
if avail > 0 {
|
||||
avail--
|
||||
if n.writerMatch(p, false) {
|
||||
avail = n.CapFileCacheNum
|
||||
}
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
continue
|
||||
}
|
||||
if buf.Free() == 0 {
|
||||
buf.Pop()
|
||||
}
|
||||
if !n.writerMatch(p, false) {
|
||||
buf.Push(p)
|
||||
continue
|
||||
}
|
||||
for buf.Len() > 0 {
|
||||
hp, err := buf.Pop()
|
||||
if err == nil {
|
||||
w.WritePacket(hp.(gopacket.Packet).Metadata().CaptureInfo, hp.(gopacket.Packet).Data())
|
||||
}
|
||||
}
|
||||
w.WritePacket(p.Metadata().CaptureInfo, p.Data())
|
||||
avail = n.CapFileCacheNum
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Libpcap) writerMatch(pkt gopacket.Packet, onlyFlags bool) bool {
|
||||
tcpLayer := pkt.Layer(layers.LayerTypeTCP)
|
||||
if !onlyFlags {
|
||||
var src, dst string
|
||||
if nw := pkt.NetworkLayer(); nw != nil {
|
||||
srcp, dstp := nw.NetworkFlow().Endpoints()
|
||||
src = srcp.String()
|
||||
dst = dstp.String()
|
||||
}
|
||||
if !(n.ipInRange(src) || n.ipInRange(dst)) {
|
||||
return false
|
||||
}
|
||||
if tcpLayer == nil {
|
||||
if len(n.targetCmd) != 0 && !n.strInRange(string(pkt.TransportLayer().LayerPayload())) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
if len(n.targetCmd) != 0 && !n.strInRange(string(tcpLayer.LayerPayload())) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(n.Flags) == 0 {
|
||||
return true
|
||||
}
|
||||
if tcpLayer == nil {
|
||||
return false
|
||||
}
|
||||
tl := tcpLayer.(*layers.TCP)
|
||||
for _, seq := range n.Flags {
|
||||
notMatch := false
|
||||
bkfor:
|
||||
for _, v := range strings.Split(strings.ToUpper(seq), ",") {
|
||||
switch strings.TrimSpace(v) {
|
||||
case "SYN":
|
||||
if !tl.SYN {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "ACK":
|
||||
if !tl.ACK {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "FIN":
|
||||
if !tl.FIN {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "RST":
|
||||
if !tl.RST {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "CWR":
|
||||
if !tl.CWR {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "ECE":
|
||||
if !tl.ECE {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "NS":
|
||||
if !tl.NS {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "PSH":
|
||||
if !tl.PSH {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
case "URG":
|
||||
if !tl.URG {
|
||||
notMatch = true
|
||||
break bkfor
|
||||
}
|
||||
}
|
||||
}
|
||||
if !notMatch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func SendRST(p *pcap.Handle, srcMac, dstMac []byte, srcIP, srcPort, dstIP, dstPort string, seq uint32) error {
|
||||
if net.ParseIP(dstIP).To4() != nil {
|
||||
return sendIPv4(p, srcMac, dstMac, srcIP, srcPort, dstIP, dstPort, seq, false)
|
||||
|
@ -1,3 +1,3 @@
|
||||
package version
|
||||
|
||||
var Version = "2.1.0.beta.15"
|
||||
var Version = "2.1.0.beta.16"
|
||||
|
Loading…
x
Reference in New Issue
Block a user