mirror of
https://github.com/Li4n0/revsuit.git
synced 2026-09-25 16:11:53 +08:00
Compare commits
1
Commits
v0.1-beta
...
v0.1.1-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc6e3962f8 |
@@ -41,6 +41,7 @@ jobs:
|
|||||||
CGO_ENABLE: 1
|
CGO_ENABLE: 1
|
||||||
run: |
|
run: |
|
||||||
GOARCH="amd64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
|
GOARCH="amd64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
|
||||||
|
GOARCH="arm64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
|
||||||
- name: Upload the artifacts
|
- name: Upload the artifacts
|
||||||
uses: li4n0/upload-release-action@v2
|
uses: li4n0/upload-release-action@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-6db702b8],html[data-v-6db702b8]{height:100%;margin:0}.fade-transform-enter-active[data-v-6db702b8],.fade-transform-leave-active[data-v-6db702b8]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-6db702b8],.fade-transform-leave[data-v-6db702b8]{opacity:0}.fade-transform-enter-to[data-v-6db702b8]{opacity:0}.ant-menu-item>span>a[data-v-6db702b8]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-6db702b8]{color:#fff}#nav[data-v-6db702b8]{height:100%}#nav .trigger[data-v-6db702b8]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#nav .trigger[data-v-6db702b8]:hover{color:#1890ff}#nav .logo[data-v-6db702b8]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-6db702b8]{color:#888;text-align:right;margin-right:1rem}
|
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-171364ce],html[data-v-171364ce]{height:100%;margin:0}.fade-transform-enter-active[data-v-171364ce],.fade-transform-leave-active[data-v-171364ce]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-171364ce],.fade-transform-leave[data-v-171364ce]{opacity:0}.fade-transform-enter-to[data-v-171364ce]{opacity:0}.ant-menu-item>span>a[data-v-171364ce]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-171364ce]{color:#fff}#nav[data-v-171364ce]{height:100%}#nav .trigger[data-v-171364ce]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#nav .trigger[data-v-171364ce]:hover{color:#1890ff}#nav .logo[data-v-171364ce]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-171364ce]{color:#888;text-align:right;margin-right:1rem}
|
||||||
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
#add-rule[data-v-e8e0136c]{margin-bottom:10px}
|
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
#add-rule[data-v-f1cd719a]{margin-bottom:10px}
|
||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>RevSuit Control Panel</title><link href="css/chunk-012c9c90.css" rel="prefetch"><link href="css/chunk-0155152b.css" rel="prefetch"><link href="css/chunk-1da7f23b.css" rel="prefetch"><link href="css/chunk-2e835d68.css" rel="prefetch"><link href="css/chunk-330a7e95.css" rel="prefetch"><link href="css/chunk-3d13e56e.css" rel="prefetch"><link href="css/chunk-d4730ae2.css" rel="prefetch"><link href="css/chunk-e00d17cc.css" rel="prefetch"><link href="css/chunk-e039e75a.css" rel="prefetch"><link href="css/chunk-fef965c2.css" rel="prefetch"><link href="js/chunk-012c9c90.js" rel="prefetch"><link href="js/chunk-0155152b.js" rel="prefetch"><link href="js/chunk-08f9fbe8.js" rel="prefetch"><link href="js/chunk-1da7f23b.js" rel="prefetch"><link href="js/chunk-2e835d68.js" rel="prefetch"><link href="js/chunk-330a7e95.js" rel="prefetch"><link href="js/chunk-3d13e56e.js" rel="prefetch"><link href="js/chunk-b241c712.js" rel="prefetch"><link href="js/chunk-d4730ae2.js" rel="prefetch"><link href="js/chunk-e00d17cc.js" rel="prefetch"><link href="js/chunk-e039e75a.js" rel="prefetch"><link href="js/chunk-fef965c2.js" rel="prefetch"><link href="css/app.css" rel="preload" as="style"><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="js/app.js" rel="preload" as="script"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link href="css/app.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but revsuit-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.js"></script><script src="js/app.js"></script></body></html>
|
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>RevSuit Control Panel</title><link href="css/chunk-0155152b.css" rel="prefetch"><link href="css/chunk-1da7f23b.css" rel="prefetch"><link href="css/chunk-2e835d68.css" rel="prefetch"><link href="css/chunk-330a7e95.css" rel="prefetch"><link href="css/chunk-3d13e56e.css" rel="prefetch"><link href="css/chunk-5840ae94.css" rel="prefetch"><link href="css/chunk-d4730ae2.css" rel="prefetch"><link href="css/chunk-e00d17cc.css" rel="prefetch"><link href="css/chunk-e039e75a.css" rel="prefetch"><link href="css/chunk-fef965c2.css" rel="prefetch"><link href="js/chunk-0155152b.js" rel="prefetch"><link href="js/chunk-08f9fbe8.js" rel="prefetch"><link href="js/chunk-1da7f23b.js" rel="prefetch"><link href="js/chunk-2e835d68.js" rel="prefetch"><link href="js/chunk-330a7e95.js" rel="prefetch"><link href="js/chunk-3d13e56e.js" rel="prefetch"><link href="js/chunk-5840ae94.js" rel="prefetch"><link href="js/chunk-b241c712.js" rel="prefetch"><link href="js/chunk-d4730ae2.js" rel="prefetch"><link href="js/chunk-e00d17cc.js" rel="prefetch"><link href="js/chunk-e039e75a.js" rel="prefetch"><link href="js/chunk-fef965c2.js" rel="prefetch"><link href="css/app.css" rel="preload" as="style"><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="js/app.js" rel="preload" as="script"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link href="css/app.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but revsuit-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.js"></script><script src="js/app.js"></script></body></html>
|
||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+14
-6
@@ -2,8 +2,9 @@
|
|||||||
<a-layout id="nav">
|
<a-layout id="nav">
|
||||||
<a-layout-sider v-model="collapsed" :trigger="null" collapsible>
|
<a-layout-sider v-model="collapsed" :trigger="null" collapsible>
|
||||||
<div class="logo"><b>R</b><span v-if="!collapsed"><b>ev</b>Suit</span></div>
|
<div class="logo"><b>R</b><span v-if="!collapsed"><b>ev</b>Suit</span></div>
|
||||||
<a-menu theme="dark" mode="inline" :selectedKeys="[this.$route.path]" :open-keys.sync='openKeys'>
|
<a-menu theme="dark" mode="inline" :selectedKeys="[this.$route.path]" :openKeys.sync="openKeys">
|
||||||
<!-- <a-menu-item key="/">-->
|
<!-- <a-menu-item key="
|
||||||
|
/">-->
|
||||||
<!-- <router-link to="/">-->
|
<!-- <router-link to="/">-->
|
||||||
<!-- <a-icon type="dashboard"/>-->
|
<!-- <a-icon type="dashboard"/>-->
|
||||||
<!-- <span>Dashboard</span>-->
|
<!-- <span>Dashboard</span>-->
|
||||||
@@ -48,8 +49,7 @@
|
|||||||
<a-menu-item key="/settings">
|
<a-menu-item key="/settings">
|
||||||
<router-link to="/settings">
|
<router-link to="/settings">
|
||||||
<a-icon type="setting"/>
|
<a-icon type="setting"/>
|
||||||
Settings
|
<span>Settings</span></router-link>
|
||||||
</router-link>
|
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
|
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
|
||||||
@click="() => (collapsed = !collapsed)"
|
@click="() => (collapsed = !collapsed)"
|
||||||
/>
|
/>
|
||||||
<div v-if="isLogMode" style="float: right; min-width:50% ;padding: 12px 0;line-height: 24px;">
|
<div v-if="isLogMode" style="float: right; min-width:60% ;padding: 12px 0;line-height: 24px;">
|
||||||
<a-row :gutter="24" type="flex">
|
<a-row :gutter="24" type="flex">
|
||||||
<a-col :span="21">
|
<a-col :span="21">
|
||||||
<a-form-model v-show="showSettings" ref="settings" layout="inline">
|
<a-form-model v-show="showSettings" ref="settings" layout="inline">
|
||||||
@@ -123,7 +123,7 @@ export default {
|
|||||||
pageSize: store.pageSize,
|
pageSize: store.pageSize,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
showSettings: false,
|
showSettings: false,
|
||||||
openKeys: ['logs'],
|
openKeys: [],
|
||||||
version: "",
|
version: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -153,6 +153,14 @@ export default {
|
|||||||
}
|
}
|
||||||
this.GetVersion()
|
this.GetVersion()
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
let unwatch = this.$watch('$route', function (to, from) {
|
||||||
|
if (from.path === "/" && this.openKeys.length === 0) {
|
||||||
|
this.openKeys.push(to.path.split("/")[1])
|
||||||
|
unwatch()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
clearInterval(this.timer)
|
clearInterval(this.timer)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
<a-form-model-item :rules="rules.flagFormat" prop="flag_format">
|
<a-form-model-item :rules="rules.flagFormat" prop="flag_format">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
Flag Format
|
Flag Format
|
||||||
<a-tooltip title="Basic usage:
|
<a-tooltip :title="`Basic usage:
|
||||||
1. Only when the request contains content that satisfies the flag format, the request will be captured.
|
1. Only when the request's ${flagField} contains content that satisfies the flag format, the request will be captured.
|
||||||
2. Use regular expression syntax.
|
2. Use regular expression syntax.
|
||||||
3. The character '*' means to capture all requests.
|
3. The character '*' means to capture all requests.
|
||||||
Advanced usage:
|
Advanced usage:
|
||||||
1. When the regex uses grouping without group name, the platform will only notify the user or push to the client when the first group appears for the first time.
|
1. When the regex uses grouping without group name, the platform will only notify the user or push to the client when the first group appears for the first time.
|
||||||
2. When the regex uses grouping with group name, you can get these submatches through template variables and use them in other fields of the rule.">
|
2. When the regex uses grouping with group name, you can get these submatches through template variables and use them in other fields of the rule.`">
|
||||||
<a-icon type="question-circle-o"/>
|
<a-icon type="question-circle-o"/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</span>
|
</span>
|
||||||
@@ -97,7 +97,7 @@ export default {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: ['form', 'readOnly']
|
props: ['form', 'readOnly', 'flagField']
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
@close="closeDrawer"
|
@close="closeDrawer"
|
||||||
>
|
>
|
||||||
<a-form-model :model="form" ref="form" layout="vertical" @submit="handleSubmit">
|
<a-form-model :model="form" ref="form" layout="vertical" @submit="handleSubmit">
|
||||||
<BasicRule :form="form" :readOnly="formReadOnly"/>
|
<BasicRule :form="form" :readOnly="formReadOnly" :flagField="'user or schema'"/>
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-model-item label="Files" :rules="rules.files">
|
<a-form-model-item label="Files" :rules="rules.files">
|
||||||
@@ -31,7 +31,8 @@
|
|||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<div class="ant-form-item-label">
|
<div class="ant-form-item-label">
|
||||||
<label for="exploit-jdbc-client">Exploit Jdbc Client
|
<label for="exploit-jdbc-client">Exploit Jdbc Client
|
||||||
<a-tooltip placement="topLeft" title="Whether test to exploit jdbc client.">
|
<a-tooltip placement="topLeft"
|
||||||
|
title="Whether test to exploit jdbc client.">
|
||||||
<a-icon type="question-circle"/>
|
<a-icon type="question-circle"/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</label>
|
</label>
|
||||||
@@ -41,8 +42,13 @@
|
|||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-model-item label="Payload">
|
<a-form-model-item>
|
||||||
<a-input-group compact v-for="payloadKey in payloadKeys" :key="payloadKey">
|
<label for="payload">Payload
|
||||||
|
<a-tooltip placement="topLeft" title="Need to set ${payload} variable by flag format first. Payload which key is same as ${payload} will be used.">
|
||||||
|
<a-icon type="question-circle"/>
|
||||||
|
</a-tooltip>
|
||||||
|
</label>
|
||||||
|
<a-input-group id="payload" compact v-for="payloadKey in payloadKeys" :key="payloadKey">
|
||||||
<a-input v-model="form['Key-'+payloadKey]"
|
<a-input v-model="form['Key-'+payloadKey]"
|
||||||
style="width: 47%;margin-bottom: 5px"
|
style="width: 47%;margin-bottom: 5px"
|
||||||
v-decorator="['Key-'+payloadKey,]"
|
v-decorator="['Key-'+payloadKey,]"
|
||||||
@@ -256,7 +262,7 @@ export default {
|
|||||||
onShowSizeChange: (current, size) => {
|
onShowSizeChange: (current, size) => {
|
||||||
store.pageSize = size
|
store.pageSize = size
|
||||||
}
|
}
|
||||||
}, filters: {},
|
}, filters: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
columns,
|
columns,
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ const banner = `
|
|||||||
/ _, _/ __/ |/ /___/ / /_/ / / /_
|
/ _, _/ __/ |/ /___/ / /_/ / / /_
|
||||||
/_/ |_|\___/|___//____/\__,_/_/\__/
|
/_/ |_|\___/|___//____/\__,_/_/\__/
|
||||||
v%s
|
v%s
|
||||||
https://revsuit.pro`
|
https://revsuit.pro
|
||||||
|
`
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func init() {
|
|||||||
log.Warn("Download qqwry.dat failed, caused by:%v, recommend to download it by yourself otherwise the `IpArea` will be null", err)
|
log.Warn("Download qqwry.dat failed, caused by:%v, recommend to download it by yourself otherwise the `IpArea` will be null", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if time.Until(info.ModTime()) > 5*24*time.Hour {
|
} else if -time.Until(info.ModTime()) > 5*24*time.Hour {
|
||||||
log.Info("Updating qqwry.dat...")
|
log.Info("Updating qqwry.dat...")
|
||||||
err := download()
|
err := download()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+23
-20
@@ -126,29 +126,32 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
|||||||
}
|
}
|
||||||
log.Info("DNS record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
log.Info("DNS record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
||||||
|
|
||||||
//only send to client when this connection recorded first time.
|
//only send to client or notify user when this connection recorded first time.
|
||||||
if _rule.PushToClient {
|
var count int64
|
||||||
if flagGroup != "" {
|
if flagGroup != "" {
|
||||||
var count int64
|
database.DB.Where("rule_name=? and domain like ?", _rule.Name, "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
||||||
database.DB.Where("rule_name=? and domain like ?", _rule.Name, "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
}
|
||||||
if count <= 1 {
|
if count <= 1 {
|
||||||
r.PushToClient()
|
if _rule.PushToClient {
|
||||||
log.Trace("DNS record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.PushToClient()
|
r.PushToClient()
|
||||||
log.Trace("DNS record[id:%d, flag:%s] has been put to client message queue", r.ID, flag)
|
if flagGroup != "" {
|
||||||
|
log.Trace("DNS record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
||||||
|
} else {
|
||||||
|
log.Trace("DNS record[id:%d] has been put to client message queue", r.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//send notice
|
||||||
|
if _rule.Notice {
|
||||||
|
go func() {
|
||||||
|
r.Notice()
|
||||||
|
if flagGroup != "" {
|
||||||
|
log.Trace("DNS record[id:%d, flagGroup:%s] notice has been sent", r.ID, flagGroup)
|
||||||
|
} else {
|
||||||
|
log.Trace("DNS record[id:%d] notice has been sent", r.ID)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//send notice
|
|
||||||
if _rule.Notice {
|
|
||||||
go func() {
|
|
||||||
r.Notice()
|
|
||||||
log.Trace("DNS record[id:%d] notice has been sent", r.ID)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _rule.Value != "" {
|
if _rule.Value != "" {
|
||||||
value := rule.CompileTpl(_rule.Value, vars)
|
value := rule.CompileTpl(_rule.Value, vars)
|
||||||
_type := _rule.Type
|
_type := _rule.Type
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Rule struct {
|
type Rule struct {
|
||||||
rule.BaseRule `yaml:""`
|
rule.BaseRule `yaml:",inline"`
|
||||||
Type newdns.Type `gorm:"default:1" form:"type" json:"type"`
|
Type newdns.Type `gorm:"default:1" form:"type" json:"type"`
|
||||||
Value string `form:"value" json:"value"`
|
Value string `form:"value" json:"value"`
|
||||||
TTL time.Duration `gorm:"ttl;default:10" form:"ttl" json:"ttl"`
|
TTL time.Duration `gorm:"ttl;default:10" form:"ttl" json:"ttl"`
|
||||||
|
|||||||
+23
-19
@@ -156,26 +156,30 @@ func createRecord(_rule *Rule, flag, flagGroup, user, password, method, path, fi
|
|||||||
}
|
}
|
||||||
log.Info("FTP record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
log.Info("FTP record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
||||||
|
|
||||||
//only send to client when this connection recorded first time.
|
//only send to client or notify user when this connection recorded first time.
|
||||||
if _rule.PushToClient {
|
var count int64
|
||||||
if flagGroup != "" {
|
if flagGroup != "" {
|
||||||
var count int64
|
database.DB.Where("rule_name=? and (user like ? or password like ?)", _rule.Name, "%"+flagGroup+"%", "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
||||||
database.DB.Where("rule_name=? and (user like ? or password like ?)", _rule.Name, "%"+flagGroup+"%", "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
}
|
||||||
if count <= 1 {
|
if count <= 1 {
|
||||||
r.PushToClient()
|
if _rule.PushToClient {
|
||||||
log.Trace("FTP record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.PushToClient()
|
r.PushToClient()
|
||||||
log.Trace("FTP record[id:%d, flag:%s] has been put to client message queue", r.ID, flag)
|
if flagGroup != "" {
|
||||||
|
log.Trace("FTP record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
||||||
|
} else {
|
||||||
|
log.Trace("FTP record[id:%d] has been put to client message queue", r.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//send notice
|
||||||
|
if _rule.Notice {
|
||||||
|
go func() {
|
||||||
|
r.Notice()
|
||||||
|
if flagGroup != "" {
|
||||||
|
log.Trace("FTP record[id:%d, flagGroup:%s] notice has been sent", r.ID, flagGroup)
|
||||||
|
} else {
|
||||||
|
log.Trace("FTP record[id:%d] notice has been sent", r.ID)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//send notice
|
|
||||||
if _rule.Notice {
|
|
||||||
go func() {
|
|
||||||
r.Notice()
|
|
||||||
log.Trace("FTP record[id:%d] notice has been sent", r.ID)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-34
@@ -68,11 +68,10 @@ func (s *Server) NewConnection(c *vmysql.Conn) {
|
|||||||
user = c.User
|
user = c.User
|
||||||
schema = c.SchemaName
|
schema = c.SchemaName
|
||||||
validated bool
|
validated bool
|
||||||
flag string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, _rule := range s.getRules() {
|
for _, _rule := range s.getRules() {
|
||||||
flag, _, _ = _rule.Match(user)
|
flag, flagGroup, vars := _rule.Match(user)
|
||||||
if flag == "" {
|
if flag == "" {
|
||||||
flag, _, _ = _rule.Match(schema)
|
flag, _, _ = _rule.Match(schema)
|
||||||
}
|
}
|
||||||
@@ -82,6 +81,9 @@ func (s *Server) NewConnection(c *vmysql.Conn) {
|
|||||||
log.Trace("MySQL connection[id: %d] matched rule[rule_name: %s, flag: %s]", c.ConnectionID, _rule.Name, flag)
|
log.Trace("MySQL connection[id: %d] matched rule[rule_name: %s, flag: %s]", c.ConnectionID, _rule.Name, flag)
|
||||||
s.connRulePool.Store(c.ConnectionID, _rule)
|
s.connRulePool.Store(c.ConnectionID, _rule)
|
||||||
validated = true
|
validated = true
|
||||||
|
c.Flag = flag
|
||||||
|
c.FlagGroup = flagGroup
|
||||||
|
c.Vars = vars
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !validated {
|
if !validated {
|
||||||
@@ -103,7 +105,6 @@ func (s *Server) ConnectionClosed(c *vmysql.Conn) {
|
|||||||
var clientName, clientOS, flag, flagGroup string
|
var clientName, clientOS, flag, flagGroup string
|
||||||
|
|
||||||
user := c.User
|
user := c.User
|
||||||
schema := c.SchemaName
|
|
||||||
supportLoadLocalData := c.SupportLoadDataLocal
|
supportLoadLocalData := c.SupportLoadDataLocal
|
||||||
|
|
||||||
cr, ok := s.connRulePool.Load(c.ConnectionID)
|
cr, ok := s.connRulePool.Load(c.ConnectionID)
|
||||||
@@ -113,13 +114,6 @@ func (s *Server) ConnectionClosed(c *vmysql.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_rule := cr.(*Rule)
|
_rule := cr.(*Rule)
|
||||||
// flag must not be empty
|
|
||||||
for _, s := range []string{user, schema} {
|
|
||||||
flag, flagGroup, _ = _rule.Match(s)
|
|
||||||
if flag != "" {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.ConnAttrs != nil {
|
if c.ConnAttrs != nil {
|
||||||
clientName = c.ConnAttrs["_client_name"] + " " + c.ConnAttrs["_client_version"]
|
clientName = c.ConnAttrs["_client_name"] + " " + c.ConnAttrs["_client_version"]
|
||||||
@@ -143,27 +137,31 @@ func (s *Server) ConnectionClosed(c *vmysql.Conn) {
|
|||||||
}
|
}
|
||||||
log.Info("MySQL record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
log.Info("MySQL record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
||||||
|
|
||||||
//only send to client when this connection recorded first time.
|
//only send to client or notify user when this connection recorded first time.
|
||||||
if _rule.PushToClient {
|
var count int64
|
||||||
if flagGroup != "" {
|
if c.FlagGroup != "" {
|
||||||
var count int64
|
database.DB.Where("rule_name=? and (user like ? or schema like ?)", _rule.Name, "%"+flagGroup+"%", "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
||||||
database.DB.Where("rule_name=? and (user like ? or schema like ?)", _rule.Name, "%"+flagGroup+"%", "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
|
||||||
if count <= 1 {
|
|
||||||
r.PushToClient()
|
|
||||||
log.Trace("MySQL record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.PushToClient()
|
|
||||||
log.Trace("MySQL record[id:%d, flag:%s] has been put to client message queue", r.ID, flag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if count <= 1 {
|
||||||
//send notice
|
if _rule.PushToClient {
|
||||||
if _rule.Notice {
|
r.PushToClient()
|
||||||
go func() {
|
if flagGroup != "" {
|
||||||
r.Notice()
|
log.Trace("MySQL record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
||||||
log.Trace("MySQL record[id: %d] notice has been sent", r.ID)
|
} else {
|
||||||
}()
|
log.Trace("MySQL record[id:%d] has been put to client message queue", r.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//send notice
|
||||||
|
if _rule.Notice {
|
||||||
|
go func() {
|
||||||
|
r.Notice()
|
||||||
|
if flagGroup != "" {
|
||||||
|
log.Trace("MySQL record[id:%d, flagGroup:%s] notice has been sent", r.ID, flagGroup)
|
||||||
|
} else {
|
||||||
|
log.Trace("MySQL record[id: %d] notice has been sent", r.ID)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.connRulePool.Delete(c.ConnectionID)
|
s.connRulePool.Delete(c.ConnectionID)
|
||||||
@@ -203,12 +201,13 @@ func (s *Server) ComQuery(c *vmysql.Conn, query string, callback func(*sqltypes.
|
|||||||
})}
|
})}
|
||||||
|
|
||||||
//choose payload
|
//choose payload
|
||||||
//jdbc:mysql://127.0.0.1:3306/test?connectionAttributes=t:cc7&autoDeserialize=true
|
if c.Vars["payload"] != "" && _rule.Payloads[c.Vars["payload"]] != "" {
|
||||||
if c.ConnAttrs["t"] != "" && _rule.Payloads[c.ConnAttrs["t"]] != "" {
|
payload, _ = base64.StdEncoding.DecodeString(_rule.Payloads[c.Vars["payload"]])
|
||||||
payload, _ = base64.StdEncoding.DecodeString(_rule.Payloads[c.ConnAttrs["t"]])
|
log.Trace("MySQL exploit client [%d] with payload [%s]", c.ConnectionID, c.Vars["payload"])
|
||||||
} else {
|
} else {
|
||||||
for _, v := range _rule.Payloads {
|
for k, v := range _rule.Payloads {
|
||||||
payload, _ = base64.StdEncoding.DecodeString(v)
|
payload, _ = base64.StdEncoding.DecodeString(v)
|
||||||
|
log.Trace("MySQL not found payload variable, exploit client [%d] with payload [%s]", c.ConnectionID, k)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,10 @@ type Conn struct {
|
|||||||
|
|
||||||
ConnAttrs map[string]string
|
ConnAttrs map[string]string
|
||||||
Files map[string][]byte
|
Files map[string][]byte
|
||||||
|
|
||||||
|
Flag string
|
||||||
|
FlagGroup string
|
||||||
|
Vars map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// bufPool is used to allocate and free buffers in an efficient way.
|
// bufPool is used to allocate and free buffers in an efficient way.
|
||||||
|
|||||||
+24
-20
@@ -191,27 +191,31 @@ func (s *Server) Receive(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
log.Info("HTTP record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
log.Info("HTTP record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
||||||
|
|
||||||
//only send to client when this connection recorded first time.
|
//only send to client or notify user when this connection recorded first time.
|
||||||
if _rule.PushToClient {
|
var count int64
|
||||||
if flagGroup != "" {
|
if flagGroup != "" {
|
||||||
var count int64
|
database.DB.Where("rule_name=? and raw_request like ?", _rule.Name, "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
||||||
database.DB.Where("rule_name=? and raw_request like ?", _rule.Name, "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
|
||||||
if count <= 1 {
|
|
||||||
r.PushToClient()
|
|
||||||
log.Trace("HTTP record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.PushToClient()
|
|
||||||
log.Trace("HTTP record[id:%d, flag:%s] has been put to client message queue", r.ID, r.Flag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if count <= 1 {
|
||||||
//send notice
|
if _rule.PushToClient {
|
||||||
if _rule.Notice {
|
r.PushToClient()
|
||||||
go func() {
|
if flagGroup != "" {
|
||||||
r.Notice()
|
log.Trace("HTTP record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
||||||
log.Trace("HTTP record[id:%d] notice has been sent", r.ID)
|
} else {
|
||||||
}()
|
log.Trace("HTTP record[id:%d] has been put to client message queue", r.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//send notice
|
||||||
|
if _rule.Notice {
|
||||||
|
go func() {
|
||||||
|
r.Notice()
|
||||||
|
if flagGroup != "" {
|
||||||
|
log.Trace("HTTP record[id:%d, flagGroup:%s] notice has been sent", r.ID, flagGroup)
|
||||||
|
} else {
|
||||||
|
log.Trace("HTTP record[id:%d] notice has been sent", r.ID)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for header, value := range _rule.ResponseHeaders {
|
for header, value := range _rule.ResponseHeaders {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
|
|
||||||
func auth(c *gin.Context) {
|
func auth(c *gin.Context) {
|
||||||
c.SetSameSite(http.SameSiteLaxMode)
|
c.SetSameSite(http.SameSiteLaxMode)
|
||||||
c.SetCookie("token", c.Request.Header["Token"][0], 0, "/revsuit/api/", c.Request.Host, true, true)
|
c.SetCookie("token", c.Request.Header["Token"][0], 0, "/revsuit/api/", "", false, true)
|
||||||
c.String(200, "pong")
|
c.String(200, "pong")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
log "unknwon.dev/clog/v2"
|
log "unknwon.dev/clog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "Beta0.1"
|
const VERSION = "0.1.1-beta"
|
||||||
|
|
||||||
type Revsuit struct {
|
type Revsuit struct {
|
||||||
config *Config
|
config *Config
|
||||||
@@ -97,7 +97,7 @@ func initLog(level string) (logLevel log.Level) {
|
|||||||
database.DB.Logger.LogMode(logger.Info)
|
database.DB.Logger.LogMode(logger.Info)
|
||||||
logLevel = log.LevelTrace
|
logLevel = log.LevelTrace
|
||||||
case "info":
|
case "info":
|
||||||
gin.SetMode(gin.DebugMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
database.DB.Logger.LogMode(logger.Info)
|
database.DB.Logger.LogMode(logger.Info)
|
||||||
logLevel = log.LevelInfo
|
logLevel = log.LevelInfo
|
||||||
case "warning", "warn":
|
case "warning", "warn":
|
||||||
|
|||||||
Reference in New Issue
Block a user