Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ require (
github.com/projectdiscovery/dsl v0.8.20
github.com/projectdiscovery/fasttemplate v0.0.2
github.com/projectdiscovery/gcache v0.0.0-20241015120333-12546c6e3f4c
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb
github.com/projectdiscovery/goflags v0.1.75
github.com/projectdiscovery/goja v0.0.0-20260618133720-acb73e419534
github.com/projectdiscovery/goja_nodejs v0.0.0-20260618132410-8519f75f703d
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -849,8 +849,6 @@ github.com/projectdiscovery/freeport v0.0.7 h1:Q6uXo/j8SaV/GlAHkEYQi8WQoPXyJWxys
github.com/projectdiscovery/freeport v0.0.7/go.mod h1:cOhWKvNBe9xM6dFJ3RrrLvJ5vXx2NQ36SecuwjenV2k=
github.com/projectdiscovery/gcache v0.0.0-20241015120333-12546c6e3f4c h1:s+lLAlrOrgwlPZQ9DFqNw+kia2nteKnJZ2Ek313yoUc=
github.com/projectdiscovery/gcache v0.0.0-20241015120333-12546c6e3f4c/go.mod h1:rN35/D3lVx2YDeENFFz06uj8j3XIqK1Ym9XcISF5fzg=
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb h1:rutG906Drtbpz4DwU5mhGIeOhRcktDH4cGQitGUMAsg=
github.com/projectdiscovery/go-smb2 v0.0.0-20240129202741-052cc450c6cb/go.mod h1:FLjF1DmZ+POoGEiIQdWuYVwS++C/GwpX8YaCsTSm1RY=
github.com/projectdiscovery/goflags v0.1.75 h1:njEBnyueQaFa2ptWxbyl9zX0OClNdlN2AzZveNHiBOs=
github.com/projectdiscovery/goflags v0.1.75/go.mod h1:7nAP1r2Dqgn/rwmOE3EWbZWUCEJKNIhVSBGpuzJAIns=
github.com/projectdiscovery/goja v0.0.0-20260618133720-acb73e419534 h1:hYd1zQA/dxO2ASyQ6Re73TcJkW1LjLQvt4+86Hxefz8=
Expand Down
103 changes: 103 additions & 0 deletions pkg/js/generated/ts/dcerpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,67 @@ export class Client {
public SamrEnumerateUsers(): DomainUser[] | null {
return null;
}

/**
* EnumServices lists Win32 services on the target via SVCCTL
* (nmap: smb-enum-services).
* @example
* ```javascript
* const c = new dcerpc.Client('dc01.acme.local', 'acme.local', 'admin', 'P@ssw0rd');
* const services = c.EnumServices();
* for (const s of services) {
* if (s.State === 'RUNNING') { log(s.Name + ' => ' + s.DisplayName); }
* }
* ```
*/
public EnumServices(): ServiceEntry[] | null {
return null;
}

/**
* EnumSessions lists SMB sessions known to the server via SRVSVC
* (nmap: smb-enum-sessions).
* @example
* ```javascript
* const c = new dcerpc.Client('fs01.acme.local', 'acme.local', 'admin', 'P@ssw0rd');
* const sessions = c.EnumSessions();
* for (const s of sessions) {
* log(s.Username + '@' + s.Client + ' active=' + s.Active + 's');
* }
* ```
*/
public EnumSessions(): SessionEntry[] | null {
return null;
}

/**
* EnumProcesses lists running processes via the Terminal Services Legacy API
* (nmap smb-enum-processes analogue).
* @example
* ```javascript
* const c = new dcerpc.Client('dc01.acme.local', 'acme.local', 'admin', 'P@ssw0rd');
* const procs = c.EnumProcesses();
* for (const p of procs) {
* log(p.PID + ' ' + p.Name + ' session=' + p.SessionID);
* }
* ```
*/
public EnumProcesses(): ProcessEntry[] | null {
return null;
}

/**
* EnumLoggedOnUsers lists users known to the workstation service (WKSSVC).
* @example
* ```javascript
* const c = new dcerpc.Client('ws01.acme.local', 'acme.local', 'admin', 'P@ssw0rd');
* const users = c.EnumLoggedOnUsers();
* for (const u of users) { log(u.LogonDomain + '\\' + u.Username); }
* ```
*/
public EnumLoggedOnUsers(): LoggedOnUser[] | null {
return null;
}


/**
Expand Down Expand Up @@ -295,6 +356,48 @@ export interface FileEntry {
IsDir?: boolean,
}

/**
* ServiceEntry is a flat SVCCTL service record (nmap smb-enum-services).
*/
export interface ServiceEntry {
Name?: string,
DisplayName?: string,
State?: string,
StateCode?: number,
Controls?: number,
}

/**
* SessionEntry is a flat SRVSVC session record (nmap smb-enum-sessions).
*/
export interface SessionEntry {
Client?: string,
Username?: string,
Active?: number,
Idle?: number,
}

/**
* ProcessEntry is a running process (nmap smb-enum-processes analogue via WinStation).
*/
export interface ProcessEntry {
Name?: string,
PID?: number,
SessionID?: number,
WorkingSetSize?: number,
SID?: string,
}

/**
* LoggedOnUser is a WKSSVC workstation user record.
*/
export interface LoggedOnUser {
Username?: string,
LogonDomain?: string,
OthDomains?: string,
LogonServer?: string,
}



/**
Expand Down
92 changes: 88 additions & 4 deletions pkg/js/generated/ts/smb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

/**
* SMBClient is a client for SMB servers.
* Internally client uses github.com/zmap/zgrab2/lib/smb/smb driver.
* github.com/projectdiscovery/go-smb2 driver
* Unauthenticated discovery uses zgrab2 / fingerprintx.
* Authenticated share I/O uses goimpacket via smbsession.
* @example
* ```javascript
* const smb = require('nuclei/smb');
Expand Down Expand Up @@ -66,10 +66,69 @@ export class SMBClient {
* }
* ```
*/
public ListShares(host: string, port: number, user: string): string[] | null {
public ListShares(host: string, port: number, user: string, password: string): string[] | null {
return null;
}

/**
* ListDir lists files and directories under path on the given share
* (nmap smb-ls). path may be empty or "." for the share root.
* user may be "DOMAIN\\user" or "user@domain".
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.SMBClient();
* const entries = client.ListDir('acme.com', 445, 'user', 'pass', 'backup', '.');
* for (const e of entries) { log(e.Name + (e.IsDir ? '/' : '')); }
* ```
*/
public ListDir(host: string, port: number, user: string, password: string, share: string, dir: string): ShareEntry[] | null {
return null;
}

/**
* ReadFile reads a file from share/path into a string, capped at 10 MiB.
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.SMBClient();
* const body = client.ReadFile('acme.com', 445, 'user', 'pass', 'backup', 'creds.txt');
* log(body);
* ```
*/
public ReadFile(host: string, port: number, user: string, password: string, share: string, filePath: string): string | null {
return null;
}

/**
* ListTree recursively lists files under path on share up to a fixed depth
* and entry budget. Entry names are share-relative paths.
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.SMBClient();
* const tree = client.ListTree('acme.com', 445, 'user', 'pass', 'backup', '.');
* for (const e of tree) { log(e.Name); }
* ```
*/
public ListTree(host: string, port: number, user: string, password: string, share: string, dir: string): ShareEntry[] | null {
return null;
}

/**
* ListProtocols discovers which SMB dialects/capabilities the server
* exposes (nmap smb-protocols).
* @example
* ```javascript
* const smb = require('nuclei/smb');
* const client = new smb.SMBClient();
* const info = client.ListProtocols('acme.com', 445);
* log(to_json(info));
* ```
*/
public ListProtocols(host: string, port: number): ProtocolInfo | null {
return null;
}


/**
* DetectSMBGhost tries to detect SMBGhost vulnerability
Expand All @@ -88,6 +147,31 @@ export class SMBClient {

}

/**
* ShareEntry is a single file or directory on an SMB share.
*/
export interface ShareEntry {
Name?: string,
Size?: number,
IsDir?: boolean,
ModTime?: string,
}

/**
* ProtocolInfo summarises dialects and capabilities discovered during
* SMB negotiation (nmap smb-protocols style).
*/
export interface ProtocolInfo {
SMB1Supported?: boolean,
SMB2Supported?: boolean,
Version?: string,
Dialect?: string,
HasNTLM?: boolean,
NativeOS?: string,
NTLM?: string,
GroupName?: string,
}



/**
Expand Down
48 changes: 25 additions & 23 deletions pkg/js/libs/dcerpc/dcerpc.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
// Package dcerpc exposes a small subset of the Mzack9999/goimpacket DCE/RPC
// stack to nuclei javascript templates. It is the entry point for AD attack
// templates that need to talk EPMAPPER / SAMR / LSARPC / SVCCTL / TSCH / WINREG
// to a domain controller or member server.
// / SRVSVC to a domain controller or member server.
//
// Capability map overlapping nmap SMB scripts (issue #4707):
//
// smb-enum-users → Client.SamrEnumerateUsers
// smb-enum-services → Client.EnumServices
// smb-enum-sessions → Client.EnumSessions
// smb-enum-processes → Client.EnumProcesses (WinStation LegacyAPI)
// smb-psexec → Client.SmbExec (also nuclei/goexec, nuclei/scmr)
// smb-ls / cat → Client.SmbLs / SmbCat (prefer nuclei/smb for new templates)
// (logged-on users) → Client.EnumLoggedOnUsers (WKSSVC; not in nmap list)
//
// Not implemented here (by design — do not add):
//
// smb-flood — DoS; harmful, no scanner value (nmap categories: dos)
// smb-mbenum — Master Browser / mailslots; obsolete NetBIOS surface
// smb-print-text — writes to printer spooler; intrusive niche
// smb-protocols / unauth discovery — nuclei/smb
//
// All host arguments are validated against the per-execution network policy
// before any traffic is sent. The actual TCP dial is performed via goimpacket's
Expand All @@ -28,6 +45,7 @@ import (
gpsmbexec "github.com/Mzack9999/goimpacket/pkg/smbexec"
"github.com/projectdiscovery/goja"

"github.com/projectdiscovery/nuclei/v3/pkg/js/libs/smbsession"
"github.com/projectdiscovery/nuclei/v3/pkg/js/utils"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
Expand Down Expand Up @@ -399,11 +417,12 @@ func (c *Client) SmbListShares() ([]string, error) {
if err := c.connect(); err != nil {
return nil, err
}
return c.smb.ListShares()
return smbsession.FromClient(c.smb).ListShares()
}

// SmbCat reads the contents of a single file from the given share. The path
// is interpreted relative to the share root (use forward slashes).
// Prefer nuclei/smb.ReadFile for new templates; this remains for dcerpc sessions.
//
// @example
// ```javascript
Expand All @@ -417,43 +436,26 @@ func (c *Client) SmbCat(share, file string) (string, error) {
if err := c.connect(); err != nil {
return "", err
}
if err := c.smb.UseShare(share); err != nil {
return "", fmt.Errorf("use share %s: %w", share, err)
}
return c.smb.Cat(file)
return smbsession.FromClient(c.smb).ReadFile(share, file, smbsession.DefaultMaxReadBytes)
}

// SmbLs lists files under dir on the given share. dir = "" lists the root.
// Prefer nuclei/smb.ListDir for new templates.
//
// @example
// ```javascript
// const c = new dcerpc.Client('dc01', 'acme.local', 'admin', 'P@ss');
// const entries = c.SmbLs('backup', '');
// for (const e of entries) { log(e.Name + (e.IsDir ? '/' : '')); }
// ```
type FileEntry struct {
Name string `json:"name"`
Size int64 `json:"size"`
IsDir bool `json:"is_dir"`
}
type FileEntry = smbsession.Entry

func (c *Client) SmbLs(share, dir string) ([]FileEntry, error) {
c.nj.Require(share != "", "share cannot be empty")
if err := c.connect(); err != nil {
return nil, err
}
if err := c.smb.UseShare(share); err != nil {
return nil, fmt.Errorf("use share %s: %w", share, err)
}
infos, err := c.smb.Ls(dir)
if err != nil {
return nil, err
}
out := make([]FileEntry, 0, len(infos))
for _, fi := range infos {
out = append(out, FileEntry{Name: fi.Name(), Size: fi.Size(), IsDir: fi.IsDir()})
}
return out, nil
return smbsession.FromClient(c.smb).ListDir(share, dir)
}

// LsaLookupSids resolves an array of SIDs to (domain, name, type) triples
Expand Down
Loading
Loading