update image and tcp

master
兔子 5 days ago
parent 5b0b3834bb
commit 32c6e7b534

@ -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

@ -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=

@ -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

@ -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=目标端单向RSTreverse=对端反向RSTboth=双向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,35 +556,176 @@ 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) {

@ -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=目标端单向RSTreverse=对端反向RSTboth=双向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,33 +336,149 @@ func (n *Libpcap) handlePacket(p gopacket.Packet) {
}
}
func RealSendRST(p *pcap.Handle, info bcap.PacketInfo, target string, number int) {
for i := 0; i < number; i++ {
if target == "both" || target == "target" {
SendRST(p, info.SrcMac, info.DstMac, info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpSeq()+(uint32(i)*uint32(info.TcpWindow())))
//SendRST(p, info.DstMac, info.SrcMac, info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpSeq()+(uint32(i)*uint32(info.TcpWindow())))
}
if target == "both" || target == "reverse" {
SendRST(p, info.DstMac, info.SrcMac, info.DstIP, info.DstPort, info.SrcIP, info.SrcPort, info.TcpAck()+(uint32(i)*uint32(info.TcpWindow())))
//SendRST(p, info.SrcMac, info.DstMac, info.DstIP, info.DstPort, info.SrcIP, info.SrcPort, info.TcpAck()+(uint32(i)*uint32(info.TcpWindow())))
}
}
}
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 RealSendRST(p *pcap.Handle, info bcap.PacketInfo, target string, number int) {
for i := 0; i < number; i++ {
if target == "both" || target == "target" {
SendRST(p, info.SrcMac, info.DstMac, info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpSeq()+(uint32(i)*uint32(info.TcpWindow())))
//SendRST(p, info.DstMac, info.SrcMac, info.SrcIP, info.SrcPort, info.DstIP, info.DstPort, info.TcpSeq()+(uint32(i)*uint32(info.TcpWindow())))
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 target == "both" || target == "reverse" {
SendRST(p, info.DstMac, info.SrcMac, info.DstIP, info.DstPort, info.SrcIP, info.SrcPort, info.TcpAck()+(uint32(i)*uint32(info.TcpWindow())))
//SendRST(p, info.SrcMac, info.DstMac, info.DstIP, info.DstPort, info.SrcIP, info.SrcPort, info.TcpAck()+(uint32(i)*uint32(info.TcpWindow())))
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 {

@ -1,3 +1,3 @@
package version
var Version = "2.1.0.beta.15"
var Version = "2.1.0.beta.16"

Loading…
Cancel
Save