新增--filter与--match参数, 可以自定义过滤与匹配函数

This commit is contained in:
M09Ic 2022-11-21 20:44:02 +08:00
parent 04d8a5d0e7
commit cd0ede7e1c
9 changed files with 142 additions and 42 deletions

3
go.mod
View File

@ -6,13 +6,14 @@ require (
github.com/chainreactors/files v0.2.4 github.com/chainreactors/files v0.2.4
github.com/chainreactors/go-metrics v0.0.0-20220926021830-24787b7a10f8 github.com/chainreactors/go-metrics v0.0.0-20220926021830-24787b7a10f8
github.com/chainreactors/gogo/v2 v2.9.5-0.20221110124606-bb8c89742d4d github.com/chainreactors/gogo/v2 v2.9.5-0.20221110124606-bb8c89742d4d
github.com/chainreactors/ipcs v0.0.13
github.com/chainreactors/logs v0.6.2 github.com/chainreactors/logs v0.6.2
github.com/chainreactors/parsers v0.2.7 github.com/chainreactors/parsers v0.2.7
github.com/chainreactors/words v0.1.1 github.com/chainreactors/words v0.1.1
) )
require ( require (
github.com/chainreactors/ipcs v0.0.13 github.com/antonmedv/expr v1.9.0
github.com/go-dedup/simhash v0.0.0-20170904020510-9ecaca7b509c github.com/go-dedup/simhash v0.0.0-20170904020510-9ecaca7b509c
github.com/gosuri/uiprogress v0.0.1 github.com/gosuri/uiprogress v0.0.1
github.com/jessevdk/go-flags v1.5.0 github.com/jessevdk/go-flags v1.5.0

20
go.sum
View File

@ -1,6 +1,9 @@
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/M09ic/go-ntlmssp v1.2.9/go.mod h1:yMNEF6ulbFipt3CakMhcmcNVACshPRG4Ap4l00V+mMs= github.com/M09ic/go-ntlmssp v1.2.9/go.mod h1:yMNEF6ulbFipt3CakMhcmcNVACshPRG4Ap4l00V+mMs=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/antonmedv/expr v1.9.0 h1:j4HI3NHEdgDnN9p6oI6Ndr0G5QryMY0FNxT4ONrFDGU=
github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8=
github.com/chainreactors/files v0.2.0/go.mod h1:/Xa9YXhjBlaC33JTD6ZTJFig6pcplak2IDcovf42/6A= github.com/chainreactors/files v0.2.0/go.mod h1:/Xa9YXhjBlaC33JTD6ZTJFig6pcplak2IDcovf42/6A=
github.com/chainreactors/files v0.2.3/go.mod h1:/Xa9YXhjBlaC33JTD6ZTJFig6pcplak2IDcovf42/6A= github.com/chainreactors/files v0.2.3/go.mod h1:/Xa9YXhjBlaC33JTD6ZTJFig6pcplak2IDcovf42/6A=
github.com/chainreactors/files v0.2.4 h1:R0iCqjWLcwwLoSi87FpgUlpxZAd+W4ZLQF3lkoLWZi0= github.com/chainreactors/files v0.2.4 h1:R0iCqjWLcwwLoSi87FpgUlpxZAd+W4ZLQF3lkoLWZi0=
@ -20,9 +23,12 @@ github.com/chainreactors/parsers v0.2.7 h1:3iEuluL7gSDrElZWyf1KEiTgddgcoZC0IaIHb
github.com/chainreactors/parsers v0.2.7/go.mod h1:Z9weht+lnFCk7UcwqFu6lXpS7u5vttiy0AJYOAyCCLA= github.com/chainreactors/parsers v0.2.7/go.mod h1:Z9weht+lnFCk7UcwqFu6lXpS7u5vttiy0AJYOAyCCLA=
github.com/chainreactors/words v0.1.1 h1:Zw4HKFtYcIH5SfuCV0X6kj/A5sN99jrQD2ChUonLOV8= github.com/chainreactors/words v0.1.1 h1:Zw4HKFtYcIH5SfuCV0X6kj/A5sN99jrQD2ChUonLOV8=
github.com/chainreactors/words v0.1.1/go.mod h1:jRcFgafTKqdkd1+StzPCTJG1ESrZHluXEO2eERdHBMQ= github.com/chainreactors/words v0.1.1/go.mod h1:jRcFgafTKqdkd1+StzPCTJG1ESrZHluXEO2eERdHBMQ=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5 h1:4U+x+EB1P66zwYgTjxWXSOT8vF+651Ksr1lojiCZnT8= github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5 h1:4U+x+EB1P66zwYgTjxWXSOT8vF+651Ksr1lojiCZnT8=
github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5/go.mod h1:poR/Cp00iqtqu9ltFwl6C00sKC0HY13u/Gh05ZBmP54= github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5/go.mod h1:poR/Cp00iqtqu9ltFwl6C00sKC0HY13u/Gh05ZBmP54=
github.com/go-dedup/simhash v0.0.0-20170904020510-9ecaca7b509c h1:mucYYQn+sMGNSxidhleonzAdwL203RxhjJGnxQU4NWU= github.com/go-dedup/simhash v0.0.0-20170904020510-9ecaca7b509c h1:mucYYQn+sMGNSxidhleonzAdwL203RxhjJGnxQU4NWU=
@ -38,14 +44,24 @@ github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo=
github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE= github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
github.com/panjf2000/ants/v2 v2.6.0 h1:xOSpw42m+BMiJ2I33we7h6fYzG4DAlpE1xyI7VS2gxU= github.com/panjf2000/ants/v2 v2.6.0 h1:xOSpw42m+BMiJ2I33we7h6fYzG4DAlpE1xyI7VS2gxU=
github.com/panjf2000/ants/v2 v2.6.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE= github.com/panjf2000/ants/v2 v2.6.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/tview v0.0.0-20200219210816-cd38d7432498/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
@ -64,6 +80,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -77,10 +95,12 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -51,7 +51,7 @@ func NewCheckPool(ctx context.Context, config *pkg.Config) (*CheckPool, error) {
if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge { if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge {
pool.failedCount++ pool.failedCount++
bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, Err: reqerr.Error(), Reason: ErrRequestFailed.Error()} bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, ErrString: reqerr.Error(), Reason: ErrRequestFailed.Error()}
} else { } else {
bl = pkg.NewBaseline(req.URI(), req.Host(), resp) bl = pkg.NewBaseline(req.URI(), req.Host(), resp)
bl.Collect() bl.Collect()

View File

@ -2,6 +2,7 @@ package internal
import ( import (
"fmt" "fmt"
"github.com/antonmedv/expr"
"github.com/chainreactors/logs" "github.com/chainreactors/logs"
"github.com/chainreactors/spray/pkg" "github.com/chainreactors/spray/pkg"
"github.com/chainreactors/words/mask" "github.com/chainreactors/words/mask"
@ -38,13 +39,13 @@ type InputOptions struct {
} }
type OutputOptions struct { type OutputOptions struct {
Matches map[string]string `long:"match" description:"String, "` Match string `long:"match" description:"String, "`
Filters map[string]string `long:"filter" description:"String, "` Filter string `long:"filter" description:"String, "`
Extracts []string `long:"extract" description:"String, "` Extracts []string `long:"extract" description:"String, "`
OutputFile string `short:"f" description:"String, output filename"` OutputFile string `short:"f" description:"String, output filename"`
FuzzyFile string `long:"fuzzy-file" description:"String, fuzzy output filename"` FuzzyFile string `long:"fuzzy-file" description:"String, fuzzy output filename"`
Fuzzy bool `long:"fuzzy" description:"String, open fuzzy output"` Fuzzy bool `long:"fuzzy" description:"String, open fuzzy output"`
OutputProbe string `long:"probe" description:"String, output format"` OutputProbe string `long:"probe" description:"String, output format"`
} }
type RequestOptions struct { type RequestOptions struct {
@ -261,6 +262,23 @@ func (opt *Option) PrepareRunner() (*Runner, error) {
}) })
} }
logs.Log.Importantf("Loaded %d dictionaries and %d decorators", len(opt.Dictionaries), len(r.Fns)) logs.Log.Importantf("Loaded %d dictionaries and %d decorators", len(opt.Dictionaries), len(r.Fns))
if opt.Match != "" {
exp, err := expr.Compile(opt.Match)
if err != nil {
return nil, err
}
r.MatchExpr = exp
}
if opt.Filter != "" {
exp, err := expr.Compile(opt.Filter)
if err != nil {
return nil, err
}
r.FilterExpr = exp
}
// prepare header // prepare header
for _, h := range opt.Headers { for _, h := range opt.Headers {
i := strings.Index(h, ":") i := strings.Index(h, ":")

View File

@ -3,12 +3,15 @@ package internal
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/vm"
"github.com/chainreactors/logs" "github.com/chainreactors/logs"
"github.com/chainreactors/spray/pkg" "github.com/chainreactors/spray/pkg"
"github.com/chainreactors/spray/pkg/ihttp" "github.com/chainreactors/spray/pkg/ihttp"
"github.com/chainreactors/words" "github.com/chainreactors/words"
"github.com/panjf2000/ants/v2" "github.com/panjf2000/ants/v2"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"strconv"
"sync" "sync"
"time" "time"
) )
@ -81,15 +84,22 @@ func NewPool(ctx context.Context, config *pkg.Config) (*Pool, error) {
if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge { if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge {
pool.failedCount++ pool.failedCount++
bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, Err: reqerr.Error(), Reason: ErrRequestFailed.Error()} bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, ErrString: reqerr.Error(), Reason: ErrRequestFailed.Error()}
pool.failedBaselines = append(pool.failedBaselines, bl) pool.failedBaselines = append(pool.failedBaselines, bl)
} else { } else {
if err = pool.PreCompare(resp); unit.source != WordSource || err == nil { if unit.source != WordSource {
// 通过预对比跳过一些无用数据, 减少性能消耗
bl = pkg.NewBaseline(req.URI(), req.Host(), resp) bl = pkg.NewBaseline(req.URI(), req.Host(), resp)
pool.addFuzzyBaseline(bl)
} else { } else {
bl = pkg.NewInvalidBaseline(req.URI(), req.Host(), resp, err.Error()) if unit.source != WordSource || pool.MatchExpr != nil {
// 如果非wordsource, 或自定义了match函数, 则所有数据送入tempch中
bl = pkg.NewBaseline(req.URI(), req.Host(), resp)
} else if err = pool.PreCompare(resp); err == nil {
// 通过预对比跳过一些无用数据, 减少性能消耗
bl = pkg.NewBaseline(req.URI(), req.Host(), resp)
pool.addFuzzyBaseline(bl)
} else {
bl = pkg.NewInvalidBaseline(req.URI(), req.Host(), resp, err.Error())
}
} }
} }
@ -104,8 +114,8 @@ func NewPool(ctx context.Context, config *pkg.Config) (*Pool, error) {
pool.initwg.Done() pool.initwg.Done()
return return
case CheckSource: case CheckSource:
if bl.Err != "" { if bl.ErrString != "" {
logs.Log.Warnf("[check.error] maybe ip had banned by waf, break (%d/%d), error: %s", pool.failedCount, pool.BreakThreshold, bl.Err) logs.Log.Warnf("[check.error] maybe ip had banned by waf, break (%d/%d), error: %s", pool.failedCount, pool.BreakThreshold, bl.ErrString)
pool.failedBaselines = append(pool.failedBaselines, bl) pool.failedBaselines = append(pool.failedBaselines, bl)
} else if i := pool.base.Compare(bl); i < 1 { } else if i := pool.base.Compare(bl); i < 1 {
if i == 0 { if i == 0 {
@ -139,14 +149,27 @@ func NewPool(ctx context.Context, config *pkg.Config) (*Pool, error) {
pool.pool = p pool.pool = p
go func() { go func() {
for bl := range pool.tempCh { for bl := range pool.tempCh {
if pool.customCompare != nil { var status bool
if pool.customCompare(bl) { if pool.MatchExpr != nil {
pool.OutputCh <- bl if pool.CompareWithExpr(pool.MatchExpr, bl) {
status = true
} }
} else { } else {
pool.BaseCompare(bl) if pool.BaseCompare(bl) {
pool.wg.Done() status = true
}
} }
if status {
if pool.FilterExpr != nil && pool.CompareWithExpr(pool.FilterExpr, bl) {
bl.Reason = ErrCustomFilter.Error()
bl.IsValid = false
}
} else {
bl.IsValid = false
}
pool.OutputCh <- bl
pool.wg.Done()
} }
pool.analyzeDone = true pool.analyzeDone = true
@ -171,7 +194,6 @@ type Pool struct {
analyzeDone bool analyzeDone bool
genReq func(s string) (*ihttp.Request, error) genReq func(s string) (*ihttp.Request, error)
check func() check func()
customCompare func(*pkg.Baseline) bool
worder *words.Worder worder *words.Worder
wg sync.WaitGroup wg sync.WaitGroup
initwg sync.WaitGroup // 初始化用, 之后改成锁 initwg sync.WaitGroup // 初始化用, 之后改成锁
@ -185,11 +207,11 @@ func (p *Pool) Init() error {
// todo 分析baseline // todo 分析baseline
// 检测基本访问能力 // 检测基本访问能力
if p.base.Err != "" { if p.base.ErrString != "" {
return fmt.Errorf(p.base.String()) return fmt.Errorf(p.base.String())
} }
if p.index.Err != "" { if p.index.ErrString != "" {
return fmt.Errorf(p.index.String()) return fmt.Errorf(p.index.String())
} }
@ -275,11 +297,11 @@ func (p *Pool) PreCompare(resp *ihttp.Response) error {
return nil return nil
} }
func (p *Pool) BaseCompare(bl *pkg.Baseline) { func (p *Pool) BaseCompare(bl *pkg.Baseline) bool {
if !bl.IsValid { if !bl.IsValid {
// precompare 确认无效数据直接送入管道 // precompare 确认无效数据直接送入管道
p.OutputCh <- bl p.OutputCh <- bl
return return false
} }
var status = -1 var status = -1
base, ok := p.baselines[bl.Status] // 挑选对应状态码的baseline进行compare base, ok := p.baselines[bl.Status] // 挑选对应状态码的baseline进行compare
@ -293,31 +315,56 @@ func (p *Pool) BaseCompare(bl *pkg.Baseline) {
ok = true ok = true
base = p.index base = p.index
} }
} }
if ok { if ok {
if status = base.Compare(bl); status == 1 { if status = base.Compare(bl); status == 1 {
p.PutToInvalid(bl, ErrCompareFailed.Error()) bl.Reason = ErrCompareFailed.Error()
return return false
} }
} }
bl.Collect() bl.Collect()
for _, f := range bl.Frameworks { for _, f := range bl.Frameworks {
if f.Tag == "waf/cdn" { if f.Tag == "waf/cdn" {
p.PutToInvalid(bl, ErrWaf.Error()) bl.Reason = ErrWaf.Error()
return return false
} }
} }
if ok && status == 0 && base.FuzzyCompare(bl) { if ok && status == 0 && base.FuzzyCompare(bl) {
p.PutToInvalid(bl, ErrFuzzyCompareFailed.Error()) bl.Reason = ErrFuzzyCompareFailed.Error()
p.PutToFuzzy(bl) p.PutToFuzzy(bl)
return return false
} }
p.OutputCh <- bl return true
}
func (p *Pool) CompareWithExpr(exp *vm.Program, other *pkg.Baseline) bool {
params := map[string]interface{}{
"index": p.index,
"base": p.base,
"current": other,
}
for _, status := range FuzzyStatus {
if bl, ok := p.baselines[status]; ok {
params["bl"+strconv.Itoa(status)] = bl
} else {
params["bl"+strconv.Itoa(status)] = &pkg.Baseline{}
}
}
res, err := expr.Run(exp, params)
if err != nil {
logs.Log.Warn(err.Error())
}
if res == true {
return true
} else {
return false
}
} }
func (p *Pool) addFuzzyBaseline(bl *pkg.Baseline) { func (p *Pool) addFuzzyBaseline(bl *pkg.Baseline) {
@ -330,7 +377,6 @@ func (p *Pool) addFuzzyBaseline(bl *pkg.Baseline) {
func (p *Pool) PutToInvalid(bl *pkg.Baseline, reason string) { func (p *Pool) PutToInvalid(bl *pkg.Baseline, reason string) {
bl.IsValid = false bl.IsValid = false
bl.Reason = reason
p.OutputCh <- bl p.OutputCh <- bl
} }

View File

@ -3,6 +3,7 @@ package internal
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/antonmedv/expr/vm"
"github.com/chainreactors/files" "github.com/chainreactors/files"
"github.com/chainreactors/logs" "github.com/chainreactors/logs"
"github.com/chainreactors/spray/pkg" "github.com/chainreactors/spray/pkg"
@ -32,6 +33,8 @@ type Runner struct {
Wordlist []string Wordlist []string
Headers http.Header Headers http.Header
Fns []func(string) string Fns []func(string) string
FilterExpr *vm.Program
MatchExpr *vm.Program
Threads int Threads int
PoolSize int PoolSize int
Pools *ants.PoolWithFunc Pools *ants.PoolWithFunc
@ -66,6 +69,8 @@ func (r *Runner) PrepareConfig() *pkg.Config {
CheckPeriod: r.CheckPeriod, CheckPeriod: r.CheckPeriod,
ErrPeriod: r.ErrPeriod, ErrPeriod: r.ErrPeriod,
BreakThreshold: r.BreakThreshold, BreakThreshold: r.BreakThreshold,
MatchExpr: r.MatchExpr,
FilterExpr: r.FilterExpr,
} }
if config.Mod == pkg.PathSpray { if config.Mod == pkg.PathSpray {
config.ClientType = ihttp.FAST config.ClientType = ihttp.FAST

View File

@ -10,6 +10,8 @@ const (
ErrRedirect ErrRedirect
ErrCompareFailed ErrCompareFailed
ErrFuzzyCompareFailed ErrFuzzyCompareFailed
ErrCustomCompareFailed
ErrCustomFilter
) )
func (e ErrorType) Error() string { func (e ErrorType) Error() string {
@ -28,6 +30,10 @@ func (e ErrorType) Error() string {
return "compare failed" return "compare failed"
case ErrFuzzyCompareFailed: case ErrFuzzyCompareFailed:
return "fuzzy compare failed" return "fuzzy compare failed"
case ErrCustomCompareFailed:
return "custom compare failed"
case ErrCustomFilter:
return "custom filtered"
default: default:
return "unknown error" return "unknown error"
} }

View File

@ -72,7 +72,7 @@ type Baseline struct {
Title string `json:"title"` Title string `json:"title"`
Frameworks Frameworks `json:"frameworks"` Frameworks Frameworks `json:"frameworks"`
Extracteds Extracteds `json:"extracts"` Extracteds Extracteds `json:"extracts"`
Err string `json:"error"` ErrString string `json:"error"`
Reason string `json:"reason"` Reason string `json:"reason"`
IsValid bool `json:"valid"` IsValid bool `json:"valid"`
IsFuzzy bool `json:"fuzzy"` IsFuzzy bool `json:"fuzzy"`
@ -189,9 +189,9 @@ func (bl *Baseline) Format(probes []string) string {
line.WriteString(" ,") line.WriteString(" ,")
line.WriteString(bl.Reason) line.WriteString(bl.Reason)
} }
if bl.Err != "" { if bl.ErrString != "" {
line.WriteString(" ,err: ") line.WriteString(" ,err: ")
line.WriteString(bl.Err) line.WriteString(bl.ErrString)
return line.String() return line.String()
} }
@ -216,9 +216,9 @@ func (bl *Baseline) String() string {
line.WriteString(bl.Reason) line.WriteString(bl.Reason)
line.WriteString("]") line.WriteString("]")
} }
if bl.Err != "" { if bl.ErrString != "" {
line.WriteString(" [err: ") line.WriteString(" [err: ")
line.WriteString(bl.Err) line.WriteString(bl.ErrString)
line.WriteString("]") line.WriteString("]")
return line.String() return line.String()
} }

View File

@ -1,6 +1,7 @@
package pkg package pkg
import ( import (
"github.com/antonmedv/expr/vm"
"net/http" "net/http"
) )
@ -31,6 +32,9 @@ type Config struct {
Headers http.Header Headers http.Header
ClientType int ClientType int
Fns []func(string) string Fns []func(string) string
OutputCh chan *Baseline MatchExpr *vm.Program
FuzzyCh chan *Baseline FilterExpr *vm.Program
OutputCh chan *Baseline
FuzzyCh chan *Baseline
} }