Skip to content

Commit

Permalink
feat 优化Security Copilot 显示;其他优化
Browse files Browse the repository at this point in the history
  • Loading branch information
yhy0 committed May 7, 2024
1 parent d975ba3 commit 52d5e14
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.idea
logs
data
scan/bbscan/rules/personal_rules.txt
.DS_Store
test.go
# Test binary, built with `go test -c`
Expand Down
2 changes: 1 addition & 1 deletion Jie_config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: 1.0.4

parallel: 10 #同时运行几个插件
parallel: 10 # 同时扫描的最大 url 个数

# 全局 http 发包配置
http:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ import (
"github.com/yhy0/Jie/SCopilot"
"github.com/yhy0/Jie/conf"
"github.com/yhy0/Jie/crawler"
"github.com/yhy0/Jie/pkg/mode"
"github.com/yhy0/Jie/pkg/output"
"github.com/yhy0/logging"
"net/url"
Expand Down Expand Up @@ -306,6 +307,7 @@ Config.WebScan.Craw = "k"
logging.Logger.Infoln(aurora.Red(v.PrintScreen()).String())
}
}()
mode.Active("http://testphp.vulnweb.com/", nil)
}
```

Expand Down
3 changes: 3 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ import (
"github.com/yhy0/Jie/SCopilot"
"github.com/yhy0/Jie/conf"
"github.com/yhy0/Jie/crawler"
"github.com/yhy0/Jie/pkg/mode"
"github.com/yhy0/Jie/pkg/output"
"github.com/yhy0/logging"
"net/url"
Expand Down Expand Up @@ -302,6 +303,8 @@ func lib() {
logging.Logger.Infoln(aurora.Red(v.PrintScreen()).String())
}
}()

mode.Active("http://testphp.vulnweb.com/", nil)
}
```

Expand Down
94 changes: 89 additions & 5 deletions SCopilot/templates/SCopilot.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,19 @@ <h4 class="card-title">端口信息</h4>
</ul>
<div class="p-3 tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">
{{ if .data.InfoPlugin }}
<div class="card border-primary mb-3">
<div class="card-body">
{{ range $plugin, $cnt := .data.InfoPlugin }}
<button id="msgPluginData" type="button" class="btn btn-outline-success btn-sm" data-plugin="{{ $plugin }}">{{ $plugin }}<span class="badge badge text-danger" style="font-size: 14px">{{ $cnt }}</span></button>
{{ end }}
</div>
</div>
{{ end }}

<ul class="list-group position-relative">
{{ range $index, $info := .data.InfoMsg }}
<li class="list-group-item ">
<li class="list-group-item msg-plugin-ul" data-plugin="{{ $info.Plugin }}">
{{ $info.Url }}
<span class="badge rounded-pill bg-primary"> {{ $info.Plugin }}</span>
{{ if $info.Result }}<p><span class="badge bg-warning">{{ $info.Result }}</span></p>{{ end }}
Expand Down Expand Up @@ -198,16 +208,26 @@ <h4 class="card-title">端口信息</h4>
</div>

<div class="tab-pane fade" id="vuln-tab-pane" role="tabpanel" aria-labelledby="vuln-tab" tabindex="0">
{{ if .data.InfoPlugin }}
<div class="card border-primary mb-3">
<div class="card-body">
{{ range $plugin, $cnt := .data.VulPlugin }}
<button id="vulPluginData" type="button" class="btn btn-outline-success btn-sm" data-plugin="{{ $plugin }}">{{ $plugin }}<span class="badge badge text-danger" style="font-size: 14px">{{ $cnt }}</span></button>
{{ end }}
</div>
</div>
{{ end }}

<ul class="list-group">
{{ range $index, $message := .data.VulMessage }}
<li class="list-group-item">
<li class="list-group-item vul-plugin-ul" data-plugin="{{ $message.Plugin }}">
<div class="vuln-card mb-3 {{ $message.Level }}">
<div class="d-flex justify-content-between align-items-center">
<h4 class="level mb-0">
{{ if $message.VulnData.VulnType }} {{ $message.VulnData.VulnType }} - {{ end }}{{ $message.VulnData.Target }}
</h4>
<span class="toggle-switch btn btn-primary">Toggle Details</span>
</div>
<span class="toggle-switch btn btn-primary btn-sm">Toggle Details</span>
<p class="level">{{ $message.Level }} <span class="badge rounded-pill bg-danger"> {{ $message.Plugin }}</span></p>
{{ if $message.VulnData.Ip }}<p>IP: {{ $message.VulnData.Ip }}</p>{{ end }}
{{ if $message.VulnData.CreateTime }}<p>Create Time: {{ $message.VulnData.CreateTime }}</p>{{ end }}
Expand Down Expand Up @@ -424,13 +444,77 @@ <h4 class="level mb-0">
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
var toggleSwitches = document.querySelectorAll(".toggle-switch");
const toggleSwitches = document.querySelectorAll(".toggle-switch");
toggleSwitches.forEach(function (toggleSwitch) {
toggleSwitch.addEventListener("click", function () {
var vulnDetails = this.closest(".vuln-card").querySelector(".vuln-details");
const vulnDetails = this.closest(".vuln-card").querySelector(".vuln-details");
vulnDetails.classList.toggle("show");
});
});

const msgs = document.querySelectorAll("#msgPluginData");
msgs.forEach(function(button) {
button.addEventListener("click", function() {
const pluginName = button.getAttribute("data-plugin"); // 获取按钮上的 data-plugin 属性值
// 获取所有的 ul
const allUls = document.querySelectorAll(".msg-plugin-ul");

// 判断是否已经显示了所有 ul
const isAllDisplayed = Array.from(allUls).every(function(ul) {
return ul.style.display === ""; // 检查是否所有 ul 都是显示状态
});

console.log(isAllDisplayed);
// 切换显示状态
if (isAllDisplayed) {
// 如果所有 ul 都是显示状态,则只显示对应 plugin 的 ul
allUls.forEach(function(ul) {
if (ul.getAttribute("data-plugin") === pluginName) {
ul.style.display = ""; // 显示对应 plugin 的 ul
} else {
ul.style.display = "none"; // 隐藏其他不相关的 ul
}
});
} else {
// 如果有 ul 是隐藏状态,则显示所有
allUls.forEach(function(ul) {
ul.style.display = "";
});
}
});
});

const vuls = document.querySelectorAll("#vulPluginData");
vuls.forEach(function(button) {
button.addEventListener("click", function() {
const pluginName = button.getAttribute("data-plugin"); // 获取按钮上的 data-plugin 属性值
// 获取所有的 ul
const allUls = document.querySelectorAll(".vul-plugin-ul");

// 判断是否已经显示了所有 ul
const isAllDisplayed = Array.from(allUls).every(function(ul) {
return ul.style.display === ""; // 检查是否所有 ul 都是显示状态
});

console.log(isAllDisplayed);
// 切换显示状态
if (isAllDisplayed) {
// 如果所有 ul 都是显示状态,则只显示对应 plugin 的 ul
allUls.forEach(function(ul) {
if (ul.getAttribute("data-plugin") === pluginName) {
ul.style.display = ""; // 显示对应 plugin 的 ul
} else {
ul.style.display = "none"; // 隐藏其他不相关的 ul
}
});
} else {
// 如果有 ul 是隐藏状态,则显示所有
allUls.forEach(function(ul) {
ul.style.display = "";
});
}
});
});
});
</script>

Expand Down
1 change: 0 additions & 1 deletion SCopilot/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ <h1 class="modal-title fs-5" id="exampleModalLabel">清空所有数据</h1>
const listItems = document.querySelectorAll('.list-item');

if (searchTerm.length > 0) {
console.log("11")
listItems.forEach(function (item) {
const itemText = item.textContent || item.innerText;
console.log(itemText.toLowerCase(searchTerm.toLowerCase()))
Expand Down
2 changes: 1 addition & 1 deletion conf/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ var DangerHeaders = []string{
"X-Api-Version",
}

// Parallelism 同时 10 插件运行
// Parallelism 对一个网站同时扫描的最大 url 个数
var Parallelism = 10
2 changes: 1 addition & 1 deletion conf/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var FileName = "Jie_config.yaml"

var defaultConfigYaml = []byte(`version: ` + Version + `
parallel: 10 #同时运行几个插件
parallel: 10 # 同时扫描的最大 url 个数
# 全局 http 发包配置
http:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/beevik/etree v1.3.0
github.com/buger/jsonparser v1.1.1
github.com/gin-gonic/gin v1.9.1
github.com/go-rod/rod v0.114.8 // indirect
github.com/go-rod/rod v0.114.8
github.com/google/go-github v17.0.0+incompatible // indirect
github.com/google/uuid v1.6.0
github.com/json-iterator/go v1.1.12 // indirect
Expand Down
3 changes: 3 additions & 0 deletions lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/yhy0/Jie/SCopilot"
"github.com/yhy0/Jie/conf"
"github.com/yhy0/Jie/crawler"
"github.com/yhy0/Jie/pkg/mode"
"github.com/yhy0/Jie/pkg/output"
"github.com/yhy0/logging"
"net/url"
Expand Down Expand Up @@ -76,4 +77,6 @@ func lib() {
logging.Logger.Infoln(aurora.Red(v.PrintScreen()).String())
}
}()

mode.Active("http://testphp.vulnweb.com/", nil)
}
3 changes: 2 additions & 1 deletion scan/bbscan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
- type_no 返回包 Content-Type 格式不包括
- tag 返回包内容匹配
- root_only 只有主目录下才会存在该路径
- fingprints 网站的指纹, 多种形式以 , 分割 表示或
- fingprints 网站的指纹, 多种形式以 , 分割 表示或

8 changes: 4 additions & 4 deletions scan/bbscan/bbscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func BBscan(u string, root bool, fingprints []string, header map[string]string,
wg.Add(1)
ch <- struct{}{}

go func(t string, r *Rule) {
go func(t string, _path string, r *Rule) {
defer wg.Done()
defer func() { <-ch }()
<-time.After(time.Duration(100) * time.Millisecond)
Expand All @@ -285,7 +285,7 @@ func BBscan(u string, root bool, fingprints []string, header map[string]string,
}

// 黑名单,跳过
if scan_util.IsBlackHtml(res.Body, res.Header["Content-Type"]) {
if scan_util.IsBlackHtml(res.Body, res.Header["Content-Type"], _path) {
return
}

Expand Down Expand Up @@ -377,7 +377,7 @@ func BBscan(u string, root bool, fingprints []string, header map[string]string,
}
}
}
}(target, rule)
}(target, path, rule)

}

Expand Down Expand Up @@ -407,7 +407,7 @@ func SingleScan(targets []string, path string) {
return
}
// 黑名单,跳过
if scan_util.IsBlackHtml(res.Body, res.Header["Content-Type"]) {
if scan_util.IsBlackHtml(res.Body, res.Header["Content-Type"], path) {
return
}

Expand Down
16 changes: 16 additions & 0 deletions scan/bbscan/bbscan_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package bbscan

import (
"fmt"
"testing"
)

/**
@author yhy
@since 2024/4/26
@desc //TODO
**/

func TestBBscan(t *testing.T) {
fmt.Println(Rules["/util/exec_sh?filePath=1"])
}
4 changes: 2 additions & 2 deletions scan/bbscan/rules/go_pprof_debug.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# add golang pprof
/debug/pprof/heap?debug=1 {status=200} {type="text/plain"} {tag="heap profile"}
/pprof/heap?debug=1 {status=200} {type="text/plain"} {tag="heap profile"}
/debug/pprof/goroutine?debug=1 {status=200} {type="text/plain"} {tag="goroutine profile"}
/pprof/goroutine?debug=1 {status=200} {type="text/plain"} {tag="goroutine profile"}
9 changes: 6 additions & 3 deletions scan/gadget/swagger/swagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,16 +441,19 @@ func scanApi(method, baseUrl, path, queryParams, bodyParams string, header map[s
}

func scanSwagger(method, target, bodyParams string, header map[string]string, client *httpx.Client) {
parse, err := url.Parse(target)
if err != nil {
return
}
// util.HttpProxy = "http://127.0.0.1:8080"
if strings.EqualFold(method, "get") {
res, err := client.Request(target, "GET", "", header)
if err != nil {
logging.Logger.Errorf("scanApi(GET %s) err %v", target, err)
return
}

// 可能是未授权, 然后对 200 的进行ssrf、注入测试
if res.StatusCode == 200 && !util2.IsBlackHtml(res.Body, res.Header["Content-Type"]) {
if res.StatusCode == 200 && !util2.IsBlackHtml(res.Body, res.Header["Content-Type"], parse.Path) {
logging.Logger.Infof("Possibly unauthorized access: GET %s", target)

in := &input.CrawlResult{
Expand Down Expand Up @@ -523,7 +526,7 @@ func scanSwagger(method, target, bodyParams string, header map[string]string, cl
return
}

if res.StatusCode == 200 && !util2.IsBlackHtml(res.Body, res.Header["Content-Type"]) { // 可能是未授权
if res.StatusCode == 200 && !util2.IsBlackHtml(res.Body, res.Header["Content-Type"], parse.Path) { // 可能是未授权
payload := fmt.Sprintf("%s %s %s", method, target, bodyParams)
logging.Logger.Infof("Possibly unauthorized access: %s", payload)

Expand Down
9 changes: 7 additions & 2 deletions scan/util/black.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type BlackRule struct {
Rule string
}

func IsBlackHtml(str string, contentType []string) bool {
func IsBlackHtml(str string, contentType []string, uri string) bool {
for _, rule := range BlackLists {
if rule.Type == "text" {
if util.Contains(str, rule.Rule) {
Expand All @@ -40,10 +40,15 @@ func IsBlackHtml(str string, contentType []string) bool {
}

if len(str) < 250 && util.InSliceCaseFold("application/json", contentType) {
reg, _ := regexp.Compile(`(?i)("(status|code|statusCode)"(\s+)?:(\s+)?(400|401|404|502)|"(message|msg)"(\s+)?:(\s+)?.*?(not exist|not found|请求非法)|not found)`)
reg, _ := regexp.Compile(`(?i)("(status|code|statusCode)"(\s+)?:(\s+)?(1\d{2}|400|401|404|5\d{2})|"(message|msg)"(\s+)?:(\s+)?.*?(not exist|not found|请求非法|Not Authorized)|not found)`)
if len(reg.FindStringSubmatch(str)) > 0 {
return true
}

// {"code":500,"msg":"No handler found for GET /assets/.env","data":null} 类似这种也是没啥用的
if strings.Contains(str, uri) {
return true
}
}

return false
Expand Down

0 comments on commit 52d5e14

Please sign in to comment.