Add files via upload

This commit is contained in:
公明
2026-07-10 16:46:26 +08:00
committed by GitHub
parent 25a76a8c97
commit 0ff8c58fbd
18 changed files with 1461 additions and 122 deletions
+45 -11
View File
@@ -15,6 +15,7 @@ import (
"cyberstrike-ai/internal/audit"
"cyberstrike-ai/internal/database"
"cyberstrike-ai/internal/security"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
@@ -144,13 +145,13 @@ func normalizeWindowsCmdPath(p string) string {
return strings.ReplaceAll(s, "/", "\\")
}
// quotePsSingle 把字符串按 PowerShell 单引号字符串规则转义(内部 ' → '')。
// quotePsSingle 把字符串按 PowerShell 单引号字符串规则转义(内部 ' → )。
// 供 PowerShell 脚本参数使用,全脚本只用单引号,外层 cmd 再用双引号包裹即可安全传递。
func quotePsSingle(s string) string {
return "'" + strings.ReplaceAll(s, "'", "''") + "'"
}
// quoteShellSinglePosix 把路径按 POSIX sh 单引号规则转义(内部 ' → '\''
// quoteShellSinglePosix 把路径按 POSIX sh 单引号规则转义(内部 ' → '\
func quoteShellSinglePosix(p string) string {
if p == "" {
return "."
@@ -379,7 +380,8 @@ func (h *WebShellHandler) ListConnections(c *gin.Context) {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "database not available"})
return
}
list, err := h.db.ListWebshellConnections()
session, _ := security.CurrentSession(c)
list, err := h.db.ListWebshellConnectionsForAccess(session.UserID, session.Scope)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
@@ -434,6 +436,10 @@ func (h *WebShellHandler) CreateConnection(c *gin.Context) {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if session, ok := security.CurrentSession(c); ok {
_ = h.db.SetResourceOwner("webshell", conn.ID, session.UserID)
_ = h.db.AssignResourceToUser(session.UserID, "webshell", conn.ID)
}
if h.audit != nil {
host := req.URL
if u, err := url.Parse(req.URL); err == nil {
@@ -659,14 +665,15 @@ func (h *WebShellHandler) ListAIConversations(c *gin.Context) {
// ExecRequest 执行命令请求(前端传入连接信息 + 命令)
type ExecRequest struct {
URL string `json:"url" binding:"required"`
Password string `json:"password"`
Type string `json:"type"` // php, asp, aspx, jsp, custom
Method string `json:"method"` // GET 或 POST,空则默认 POST
CmdParam string `json:"cmd_param"` // 命令参数名,如 cmd/xxx,空则默认 cmd
Encoding string `json:"encoding"` // 响应编码:auto / utf-8 / gbk / gb18030,空则 auto
OS string `json:"os"` // 目标操作系统:auto / linux / windows,当前 exec 不用它,保留字段便于未来扩展
Command string `json:"command" binding:"required"`
URL string `json:"url" binding:"required"`
Password string `json:"password"`
Type string `json:"type"` // php, asp, aspx, jsp, custom
Method string `json:"method"` // GET 或 POST,空则默认 POST
CmdParam string `json:"cmd_param"` // 命令参数名,如 cmd/xxx,空则默认 cmd
Encoding string `json:"encoding"` // 响应编码:auto / utf-8 / gbk / gb18030,空则 auto
OS string `json:"os"` // 目标操作系统:auto / linux / windows,当前 exec 不用它,保留字段便于未来扩展
ConnectionID string `json:"connection_id,omitempty"`
Command string `json:"command" binding:"required"`
}
// ExecResponse 执行命令响应
@@ -714,6 +721,10 @@ func (h *WebShellHandler) Exec(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "url and command are required"})
return
}
if !h.webshellConnectionRequestAllowed(c, req.ConnectionID, req.URL) {
c.JSON(http.StatusForbidden, gin.H{"error": "无权访问该资源"})
return
}
parsed, err := url.Parse(req.URL)
if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") {
@@ -807,6 +818,10 @@ func (h *WebShellHandler) FileOp(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "url and action are required"})
return
}
if !h.webshellConnectionRequestAllowed(c, req.ConnectionID, req.URL) {
c.JSON(http.StatusForbidden, gin.H{"error": "无权访问该资源"})
return
}
parsed, err := url.Parse(req.URL)
if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") {
@@ -883,6 +898,25 @@ func (h *WebShellHandler) FileOp(c *gin.Context) {
})
}
func (h *WebShellHandler) webshellConnectionRequestAllowed(c *gin.Context, connectionID, requestURL string) bool {
connectionID = strings.TrimSpace(connectionID)
if connectionID == "" {
return true
}
if h.db == nil {
return false
}
session, ok := security.CurrentSession(c)
if !ok || !h.db.UserCanAccessResource(session.UserID, session.Scope, "webshell", connectionID) {
return false
}
conn, err := h.db.GetWebshellConnection(connectionID)
if err != nil || conn == nil {
return false
}
return strings.TrimSpace(conn.URL) == strings.TrimSpace(requestURL)
}
// ExecWithConnection 在指定 WebShell 连接上执行命令(供 MCP/Agent 等非 HTTP 调用)
func (h *WebShellHandler) ExecWithConnection(conn *database.WebShellConnection, command string) (output string, ok bool, errMsg string) {
if conn == nil {