fixing logic

This commit is contained in:
Mzack9999 2025-09-25 22:46:40 +02:00
parent 61bd0828dc
commit cb2d93174a
4 changed files with 107 additions and 110 deletions

View File

@ -1,26 +0,0 @@
id: rdp-enc-check
info:
name: RDP Enc - Detection
author: pussycat0x
severity: info
metadata:
verified: true
max-request: 1
shodan-query: port:"3389"
tags: js,network,rdp,info,enum
javascript:
- code: |
let m = require('nuclei/rdp');
let response = m.CheckRDPEncryption(Host,Port);
Export(response);
args:
Host: "{{Host}}"
Port: "3389"
extractors:
- type: dsl
dsl:
- response

View File

@ -71,19 +71,18 @@ export interface CheckRDPAuthResponse {
* ``` * ```
*/ */
export interface RDPEncryptionResponse { export interface RDPEncryptionResponse {
SecurityLayer: { // Security Layer Protocols
NativeRDP: boolean; NativeRDP: boolean;
SSL: boolean; SSL: boolean;
CredSSP: boolean; CredSSP: boolean;
RDSTLS: boolean; RDSTLS: boolean;
CredSSPWithEarlyUserAuth: boolean; CredSSPWithEarlyUserAuth: boolean;
};
EncryptionLevel: { // Encryption Levels
RC4_40bit: boolean; RC4_40bit: boolean;
RC4_56bit: boolean; RC4_56bit: boolean;
RC4_128bit: boolean; RC4_128bit: boolean;
FIPS140_1: boolean; FIPS140_1: boolean;
};
} }
/** /**

View File

@ -40,11 +40,11 @@ func memoizedcheckRDPAuth(executionId string, host string, port int) (CheckRDPAu
return CheckRDPAuthResponse{}, errors.New("could not convert cached result") return CheckRDPAuthResponse{}, errors.New("could not convert cached result")
} }
func memoizedcheckRDPEncryption(host string, port int) (RDPEncryptionResponse, error) { func memoizedcheckRDPEncryption(executionId string, host string, port int) (RDPEncryptionResponse, error) {
hash := "checkRDPEncryption" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) hash := "checkRDPEncryption" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) { v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
return checkRDPEncryption(host, port) return checkRDPEncryption(executionId, host, port)
}) })
if err != nil { if err != nil {
return RDPEncryptionResponse{}, err return RDPEncryptionResponse{}, err

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"net" "net"
"strconv"
"time" "time"
"github.com/praetorian-inc/fingerprintx/pkg/plugins" "github.com/praetorian-inc/fingerprintx/pkg/plugins"
@ -129,6 +130,29 @@ func checkRDPAuth(executionId string, host string, port int) (CheckRDPAuthRespon
return resp, nil return resp, nil
} }
type (
SecurityLayer string
)
const (
SecurityLayerNativeRDP = "NativeRDP"
SecurityLayerSSL = "SSL"
SecurityLayerCredSSP = "CredSSP"
SecurityLayerRDSTLS = "RDSTLS"
SecurityLayerCredSSPWithEarlyUserAuth = "CredSSPWithEarlyUserAuth"
)
type (
EncryptionLevel string
)
const (
EncryptionLevelRC4_40bit = "RC4_40bit"
EncryptionLevelRC4_56bit = "RC4_56bit"
EncryptionLevelRC4_128bit = "RC4_128bit"
EncryptionLevelFIPS140_1 = "FIPS140_1"
)
type ( type (
// RDPEncryptionResponse is the response from the CheckRDPEncryption function. // RDPEncryptionResponse is the response from the CheckRDPEncryption function.
// This is returned by CheckRDPEncryption function. // This is returned by CheckRDPEncryption function.
@ -139,19 +163,18 @@ type (
// log(toJSON(encryption)); // log(toJSON(encryption));
// ``` // ```
RDPEncryptionResponse struct { RDPEncryptionResponse struct {
SecurityLayer struct { // Protocols
NativeRDP bool NativeRDP bool
SSL bool SSL bool
CredSSP bool CredSSP bool
RDSTLS bool RDSTLS bool
CredSSPWithEarlyUserAuth bool CredSSPWithEarlyUserAuth bool
}
EncryptionLevel struct { // EncryptionLevels
RC4_40bit bool RC4_40bit bool
RC4_56bit bool RC4_56bit bool
RC4_128bit bool RC4_128bit bool
FIPS140_1 bool FIPS140_1 bool
}
} }
) )
@ -163,76 +186,89 @@ type (
// const encryption = rdp.CheckRDPEncryption('acme.com', 3389); // const encryption = rdp.CheckRDPEncryption('acme.com', 3389);
// log(toJSON(encryption)); // log(toJSON(encryption));
// ``` // ```
func CheckRDPEncryption(host string, port int) (RDPEncryptionResponse, error) { func CheckRDPEncryption(ctx context.Context, host string, port int) (RDPEncryptionResponse, error) {
return memoizedcheckRDPEncryption(host, port) executionId := ctx.Value("executionId").(string)
return memoizedcheckRDPEncryption(executionId, host, port)
} }
// @memo // @memo
func checkRDPEncryption(host string, port int) (RDPEncryptionResponse, error) { func checkRDPEncryption(executionId string, host string, port int) (RDPEncryptionResponse, error) {
dialer := protocolstate.GetDialersWithId(executionId)
if dialer == nil {
return RDPEncryptionResponse{}, fmt.Errorf("dialers not initialized for %s", executionId)
}
resp := RDPEncryptionResponse{} resp := RDPEncryptionResponse{}
timeout := 5 * time.Second defaultTimeout := 5 * time.Second
// Test different security protocols // Test different security protocols
protocols := map[string]int{ protocols := map[SecurityLayer]int{
"NativeRDP": 0, SecurityLayerNativeRDP: 0,
"SSL": 1, SecurityLayerSSL: 1,
"CredSSP": 3, SecurityLayerCredSSP: 3,
"RDSTLS": 4, SecurityLayerRDSTLS: 4,
"CredSSPWithEarlyUserAuth": 8, SecurityLayerCredSSPWithEarlyUserAuth: 8,
} }
for name, value := range protocols { for name, value := range protocols {
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", fmt.Sprintf("%s:%d", host, port)) ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
conn, err := dialer.Fastdialer.Dial(ctx, "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
if err != nil { if err != nil {
continue continue
} }
defer conn.Close() defer func() {
_ = conn.Close()
}()
// Test protocol // Test protocol
isRDP, err := testRDPProtocol(conn, timeout, value) isRDP, err := testRDPProtocol(conn, value)
if err == nil && isRDP { if err == nil && isRDP {
switch name { switch SecurityLayer(name) {
case "NativeRDP": case SecurityLayerNativeRDP:
resp.SecurityLayer.NativeRDP = true resp.NativeRDP = true
case "SSL": case SecurityLayerSSL:
resp.SecurityLayer.SSL = true resp.SSL = true
case "CredSSP": case SecurityLayerCredSSP:
resp.SecurityLayer.CredSSP = true resp.CredSSP = true
case "RDSTLS": case SecurityLayerRDSTLS:
resp.SecurityLayer.RDSTLS = true resp.RDSTLS = true
case "CredSSPWithEarlyUserAuth": case SecurityLayerCredSSPWithEarlyUserAuth:
resp.SecurityLayer.CredSSPWithEarlyUserAuth = true resp.CredSSPWithEarlyUserAuth = true
} }
} }
} }
// Test different encryption levels // Test different encryption levels
ciphers := map[string]int{ ciphers := map[EncryptionLevel]int{
"RC4_40bit": 1, EncryptionLevelRC4_40bit: 1,
"RC4_56bit": 8, EncryptionLevelRC4_56bit: 8,
"RC4_128bit": 2, EncryptionLevelRC4_128bit: 2,
"FIPS140_1": 16, EncryptionLevelFIPS140_1: 16,
} }
for name, value := range ciphers { for encryptionLevel, value := range ciphers {
conn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", fmt.Sprintf("%s:%d", host, port)) ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
conn, err := dialer.Fastdialer.Dial(ctx, "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
if err != nil { if err != nil {
continue continue
} }
defer conn.Close() defer func() {
_ = conn.Close()
}()
// Test cipher // Test cipher
isRDP, err := testRDPCipher(conn, timeout, value) isRDP, err := testRDPCipher(conn, value)
if err == nil && isRDP { if err == nil && isRDP {
switch name { switch encryptionLevel {
case "RC4_40bit": case EncryptionLevelRC4_40bit:
resp.EncryptionLevel.RC4_40bit = true resp.RC4_40bit = true
case "RC4_56bit": case EncryptionLevelRC4_56bit:
resp.EncryptionLevel.RC4_56bit = true resp.RC4_56bit = true
case "RC4_128bit": case EncryptionLevelRC4_128bit:
resp.EncryptionLevel.RC4_128bit = true resp.RC4_128bit = true
case "FIPS140_1": case EncryptionLevelFIPS140_1:
resp.EncryptionLevel.FIPS140_1 = true resp.FIPS140_1 = true
} }
} }
} }
@ -241,13 +277,7 @@ func checkRDPEncryption(host string, port int) (RDPEncryptionResponse, error) {
} }
// testRDPProtocol tests RDP with a specific security protocol // testRDPProtocol tests RDP with a specific security protocol
func testRDPProtocol(conn net.Conn, timeout time.Duration, protocol int) (bool, error) { func testRDPProtocol(conn net.Conn, protocol int) (bool, error) {
// Set connection timeout
_ = conn.SetDeadline(time.Now().Add(timeout))
defer func() {
_ = conn.SetDeadline(time.Time{})
}()
// Send RDP connection request with specific protocol // Send RDP connection request with specific protocol
// This is a simplified version - in reality you'd need to implement the full RDP protocol // This is a simplified version - in reality you'd need to implement the full RDP protocol
// including the negotiation phase with the specified protocol // including the negotiation phase with the specified protocol
@ -280,13 +310,7 @@ func testRDPProtocol(conn net.Conn, timeout time.Duration, protocol int) (bool,
} }
// testRDPCipher tests RDP with a specific encryption level // testRDPCipher tests RDP with a specific encryption level
func testRDPCipher(conn net.Conn, timeout time.Duration, cipher int) (bool, error) { func testRDPCipher(conn net.Conn, cipher int) (bool, error) {
// Set connection timeout
_ = conn.SetDeadline(time.Now().Add(timeout))
defer func() {
_ = conn.SetDeadline(time.Time{})
}()
// Send RDP connection request with specific cipher // Send RDP connection request with specific cipher
// This is a simplified version - in reality you'd need to implement the full RDP protocol // This is a simplified version - in reality you'd need to implement the full RDP protocol
// including the negotiation phase with the specified cipher // including the negotiation phase with the specified cipher