tighten scan session and HTTP paths

This commit is contained in:
ZacharyZcR
2026-05-23 07:46:53 +08:00
parent 1a714f6a0c
commit 3c7823355d
7 changed files with 89 additions and 66 deletions
+9 -11
View File
@@ -27,15 +27,14 @@ func NewElasticsearchPlugin() *ElasticsearchPlugin {
func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
state := session.State
target := info.Target()
if config.DisableBrute {
return p.identifyService(ctx, info, config, state)
return p.identifyService(ctx, info, session)
}
// 首先检测未授权访问
if p.testCredential(ctx, info, Credential{Username: "", Password: ""}, config, state) {
if p.testCredential(ctx, info, Credential{Username: "", Password: ""}, session) {
common.LogVuln(i18n.Tr("elasticsearch_unauth", target))
return &ScanResult{
Success: true,
@@ -56,7 +55,7 @@ func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, s
}
for _, cred := range credentials {
if p.testCredential(ctx, info, cred, config, state) {
if p.testCredential(ctx, info, cred, session) {
common.LogVuln(i18n.Tr("elasticsearch_credential", target, cred.Username, cred.Password))
return &ScanResult{
Success: true,
@@ -75,7 +74,8 @@ func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, s
}
}
func (p *ElasticsearchPlugin) testCredential(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) bool {
func (p *ElasticsearchPlugin) testCredential(ctx context.Context, info *common.HostInfo, cred Credential, session *common.ScanSession) bool {
config := session.Config
client := &http.Client{
Timeout: config.Timeout,
Transport: &http.Transport{
@@ -100,12 +100,10 @@ func (p *ElasticsearchPlugin) testCredential(ctx context.Context, info *common.H
req.Header.Set("Authorization", "Basic "+auth)
}
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
return false
}
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 {
@@ -121,15 +119,15 @@ func (p *ElasticsearchPlugin) testCredential(ctx context.Context, info *common.H
return false
}
func (p *ElasticsearchPlugin) identifyService(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
func (p *ElasticsearchPlugin) identifyService(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
target := info.Target()
if p.testCredential(ctx, info, Credential{Username: "", Password: ""}, config, state) {
if p.testCredential(ctx, info, Credential{Username: "", Password: ""}, session) {
banner := "Elasticsearch"
common.LogSuccess(i18n.Tr("elasticsearch_service", target, banner))
return &ScanResult{
Success: true,
Type: plugins.ResultTypeService,
Type: plugins.ResultTypeService,
Service: "elasticsearch",
Banner: banner,
}
+14 -18
View File
@@ -27,15 +27,14 @@ func NewNeo4jPlugin() *Neo4jPlugin {
func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
state := session.State
target := info.Target()
if config.DisableBrute {
return p.identifyService(ctx, info, config, state)
return p.identifyService(ctx, info, session)
}
// 先测试未授权访问
if result := p.testUnauthorizedAccess(ctx, info, config, state); result != nil && result.Success {
if result := p.testUnauthorizedAccess(ctx, info, session); result != nil && result.Success {
common.LogVuln(i18n.Tr("neo4j_unauth", target))
return result
}
@@ -50,7 +49,7 @@ func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, session *
}
// 使用公共框架进行并发凭据测试
authFn := p.createAuthFunc(info, config, state)
authFn := p.createAuthFunc(info, session)
testConfig := DefaultConcurrentTestConfigWithTarget(config, info)
result := TestCredentialsConcurrently(ctx, credentials, authFn, "neo4j", testConfig)
@@ -63,14 +62,15 @@ func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, session *
}
// createAuthFunc 创建Neo4j认证函数
func (p *Neo4jPlugin) createAuthFunc(info *common.HostInfo, config *common.Config, state *common.State) AuthFunc {
func (p *Neo4jPlugin) createAuthFunc(info *common.HostInfo, session *common.ScanSession) AuthFunc {
return func(ctx context.Context, cred Credential) *AuthResult {
return p.doNeo4jAuth(ctx, info, cred, config, state)
return p.doNeo4jAuth(ctx, info, cred, session)
}
}
// doNeo4jAuth 执行Neo4j认证
func (p *Neo4jPlugin) doNeo4jAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
func (p *Neo4jPlugin) doNeo4jAuth(ctx context.Context, info *common.HostInfo, cred Credential, session *common.ScanSession) *AuthResult {
config := session.Config
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
client := &http.Client{Timeout: config.Timeout}
@@ -87,16 +87,14 @@ func (p *Neo4jPlugin) doNeo4jAuth(ctx context.Context, info *common.HostInfo, cr
req.SetBasicAuth(cred.Username, cred.Password)
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
return &AuthResult{
Success: false,
ErrorType: classifyNeo4jErrorType(err),
Error: err,
}
}
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 {
@@ -147,7 +145,8 @@ func classifyNeo4jErrorType(err error) ErrorType {
return ClassifyError(err, neo4jAuthErrors, CommonNetworkErrors)
}
func (p *Neo4jPlugin) testUnauthorizedAccess(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
func (p *Neo4jPlugin) testUnauthorizedAccess(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
client := &http.Client{Timeout: config.Timeout}
@@ -157,12 +156,10 @@ func (p *Neo4jPlugin) testUnauthorizedAccess(ctx context.Context, info *common.H
return nil
}
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
return nil
}
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 {
@@ -177,7 +174,8 @@ func (p *Neo4jPlugin) testUnauthorizedAccess(ctx context.Context, info *common.H
return nil
}
func (p *Neo4jPlugin) identifyService(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
func (p *Neo4jPlugin) identifyService(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
target := info.Target()
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
@@ -192,16 +190,14 @@ func (p *Neo4jPlugin) identifyService(ctx context.Context, info *common.HostInfo
}
}
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
return &ScanResult{
Success: false,
Service: "neo4j",
Error: err,
}
}
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
var banner string
+12 -18
View File
@@ -28,7 +28,6 @@ func NewRabbitMQPlugin() *RabbitMQPlugin {
func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
state := session.State
target := info.Target()
if config.DisableBrute {
@@ -36,7 +35,7 @@ func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, sessio
}
// 先检测未授权访问
if result := p.testUnauthorizedAccess(ctx, info, config, state); result != nil && result.Success {
if result := p.testUnauthorizedAccess(ctx, info, session); result != nil && result.Success {
common.LogSuccess(i18n.Tr("rabbitmq_service", target, result.Banner))
return result
}
@@ -51,7 +50,7 @@ func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, sessio
}
// 使用公共框架进行并发凭据测试
authFn := p.createAuthFunc(info, config, state)
authFn := p.createAuthFunc(info, session)
testConfig := DefaultConcurrentTestConfigWithTarget(config, info)
result := TestCredentialsConcurrently(ctx, credentials, authFn, "rabbitmq", testConfig)
@@ -64,14 +63,15 @@ func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, sessio
}
// createAuthFunc 创建RabbitMQ认证函数
func (p *RabbitMQPlugin) createAuthFunc(info *common.HostInfo, config *common.Config, state *common.State) AuthFunc {
func (p *RabbitMQPlugin) createAuthFunc(info *common.HostInfo, session *common.ScanSession) AuthFunc {
return func(ctx context.Context, cred Credential) *AuthResult {
return p.doRabbitMQAuth(ctx, info, cred, config, state)
return p.doRabbitMQAuth(ctx, info, cred, session)
}
}
// doRabbitMQAuth 执行RabbitMQ认证
func (p *RabbitMQPlugin) doRabbitMQAuth(ctx context.Context, info *common.HostInfo, cred Credential, config *common.Config, state *common.State) *AuthResult {
func (p *RabbitMQPlugin) doRabbitMQAuth(ctx context.Context, info *common.HostInfo, cred Credential, session *common.ScanSession) *AuthResult {
config := session.Config
// 对于AMQP端口,使用HTTP管理接口
port := info.Port
if port == 5672 || port == 5671 {
@@ -96,16 +96,14 @@ func (p *RabbitMQPlugin) doRabbitMQAuth(ctx context.Context, info *common.HostIn
req.SetBasicAuth(cred.Username, cred.Password)
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
return &AuthResult{
Success: false,
ErrorType: classifyRabbitMQErrorType(err),
Error: err,
}
}
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 {
@@ -157,7 +155,8 @@ func classifyRabbitMQErrorType(err error) ErrorType {
}
// testUnauthorizedAccess 测试RabbitMQ未授权访问
func (p *RabbitMQPlugin) testUnauthorizedAccess(ctx context.Context, info *common.HostInfo, config *common.Config, state *common.State) *ScanResult {
func (p *RabbitMQPlugin) testUnauthorizedAccess(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
port := info.Port
if port == 5672 || port == 5671 {
port = 15672
@@ -172,11 +171,9 @@ func (p *RabbitMQPlugin) testUnauthorizedAccess(ctx context.Context, info *commo
return nil
}
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
} else {
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 {
@@ -193,7 +190,7 @@ func (p *RabbitMQPlugin) testUnauthorizedAccess(ctx context.Context, info *commo
guestReq, err := http.NewRequestWithContext(ctx, "GET", baseURL+"/api/overview", nil)
if err == nil {
guestReq.SetBasicAuth("guest", "guest")
guestResp, guestErr := client.Do(guestReq)
guestResp, guestErr := session.HTTPDo(client, guestReq)
if guestErr == nil {
defer func() { _ = guestResp.Body.Close() }()
if guestResp.StatusCode == 200 {
@@ -263,7 +260,6 @@ func (p *RabbitMQPlugin) identifyService(ctx context.Context, info *common.HostI
func (p *RabbitMQPlugin) testManagementInterface(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
config := session.Config
state := session.State
target := info.Target()
baseURL := fmt.Sprintf("http://%s:%d", info.Host, info.Port)
@@ -278,16 +274,14 @@ func (p *RabbitMQPlugin) testManagementInterface(ctx context.Context, info *comm
}
}
resp, err := client.Do(req)
resp, err := session.HTTPDo(client, req)
if err != nil {
state.IncrementTCPFailedPacketCount()
return &ScanResult{
Success: false,
Service: "rabbitmq",
Error: err,
}
}
state.IncrementTCPSuccessPacketCount()
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == 200 || resp.StatusCode == 401 {