diff --git a/pkg/js/compiler/pool.go b/pkg/js/compiler/pool.go index 5af691dd00..3c0ea1e83a 100644 --- a/pkg/js/compiler/pool.go +++ b/pkg/js/compiler/pool.go @@ -31,6 +31,7 @@ import ( _ "github.com/projectdiscovery/nuclei/v3/pkg/js/generated/go/libssh" _ "github.com/projectdiscovery/nuclei/v3/pkg/js/generated/go/libstructs" _ "github.com/projectdiscovery/nuclei/v3/pkg/js/generated/go/libtelnet" + _ "github.com/projectdiscovery/nuclei/v3/pkg/js/generated/go/libutils" _ "github.com/projectdiscovery/nuclei/v3/pkg/js/generated/go/libvnc" "github.com/projectdiscovery/nuclei/v3/pkg/js/global" "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs" diff --git a/pkg/js/devtools/bindgen/generator.go b/pkg/js/devtools/bindgen/generator.go index 764044d4e3..3fa4eb15a3 100644 --- a/pkg/js/devtools/bindgen/generator.go +++ b/pkg/js/devtools/bindgen/generator.go @@ -105,7 +105,11 @@ func CreateTemplateData(directory string, packagePrefix string) (*TemplateData, fmt.Println(directory) fset := token.NewFileSet() - pkgs, err := parser.ParseDir(fset, directory, nil, parser.ParseComments) + // Filter out test files (_test.go) which shouldn't be included in bindings + filter := func(fi os.FileInfo) bool { + return !strings.HasSuffix(fi.Name(), "_test.go") + } + pkgs, err := parser.ParseDir(fset, directory, filter, parser.ParseComments) if err != nil { return nil, errors.Wrap(err, "could not parse directory") } diff --git a/pkg/js/devtools/tsgen/scrape.go b/pkg/js/devtools/tsgen/scrape.go index aac352dfc8..742dcc4b59 100644 --- a/pkg/js/devtools/tsgen/scrape.go +++ b/pkg/js/devtools/tsgen/scrape.go @@ -34,9 +34,11 @@ func (p *EntityParser) scrapeAndCreate(typeName string) error { return errkit.Newf("%v is not a type name", typeName) } // Ensure the type is a named struct type + // Skip interfaces (like net.Conn) - they can't be scraped for fields namedStruct, ok := typeNameObj.Type().Underlying().(*types.Struct) if !ok { - return fmt.Errorf("%s is not a named struct type", typeName) + // Not a struct (could be interface, etc.) - skip silently + return nil } // fmt.Printf("got named struct %v\n", namedStruct) // Iterate over the struct fields diff --git a/pkg/js/generated/go/librdp/rdp.go b/pkg/js/generated/go/librdp/rdp.go index ded295cbde..f8ff4bf975 100644 --- a/pkg/js/generated/go/librdp/rdp.go +++ b/pkg/js/generated/go/librdp/rdp.go @@ -20,11 +20,20 @@ func init() { "IsRDP": lib_rdp.IsRDP, // Var and consts + "EncryptionLevelFIPS140_1": lib_rdp.EncryptionLevelFIPS140_1, + "EncryptionLevelRC4_128bit": lib_rdp.EncryptionLevelRC4_128bit, + "EncryptionLevelRC4_40bit": lib_rdp.EncryptionLevelRC4_40bit, + "EncryptionLevelRC4_56bit": lib_rdp.EncryptionLevelRC4_56bit, + "SecurityLayerCredSSP": lib_rdp.SecurityLayerCredSSP, + "SecurityLayerCredSSPWithEarlyUserAuth": lib_rdp.SecurityLayerCredSSPWithEarlyUserAuth, + "SecurityLayerNativeRDP": lib_rdp.SecurityLayerNativeRDP, + "SecurityLayerRDSTLS": lib_rdp.SecurityLayerRDSTLS, + "SecurityLayerSSL": lib_rdp.SecurityLayerSSL, // Objects / Classes - "CheckRDPAuthResponse": gojs.GetClassConstructor[lib_rdp.CheckRDPAuthResponse](&lib_rdp.CheckRDPAuthResponse{}), - "CheckRDPEncryptionResponse": gojs.GetClassConstructor[lib_rdp.RDPEncryptionResponse](&lib_rdp.RDPEncryptionResponse{}), - "IsRDPResponse": gojs.GetClassConstructor[lib_rdp.IsRDPResponse](&lib_rdp.IsRDPResponse{}), + "CheckRDPAuthResponse": gojs.GetClassConstructor[lib_rdp.CheckRDPAuthResponse](&lib_rdp.CheckRDPAuthResponse{}), + "IsRDPResponse": gojs.GetClassConstructor[lib_rdp.IsRDPResponse](&lib_rdp.IsRDPResponse{}), + "RDPEncryptionResponse": gojs.GetClassConstructor[lib_rdp.RDPEncryptionResponse](&lib_rdp.RDPEncryptionResponse{}), }, ).Register() } diff --git a/pkg/js/generated/go/librsync/rsync.go b/pkg/js/generated/go/librsync/rsync.go index ffc6f0a616..7d1b71b8ee 100644 --- a/pkg/js/generated/go/librsync/rsync.go +++ b/pkg/js/generated/go/librsync/rsync.go @@ -20,8 +20,9 @@ func init() { // Var and consts // Objects / Classes - "IsRsyncResponse": gojs.GetClassConstructor[lib_rsync.IsRsyncResponse](&lib_rsync.IsRsyncResponse{}), - "RsyncClient": gojs.GetClassConstructor[lib_rsync.RsyncClient](&lib_rsync.RsyncClient{}), + "IsRsyncResponse": gojs.GetClassConstructor[lib_rsync.IsRsyncResponse](&lib_rsync.IsRsyncResponse{}), + "RsyncClient": gojs.GetClassConstructor[lib_rsync.RsyncClient](&lib_rsync.RsyncClient{}), + "RsyncListResponse": gojs.GetClassConstructor[lib_rsync.RsyncListResponse](&lib_rsync.RsyncListResponse{}), }, ).Register() } diff --git a/pkg/js/generated/go/libtelnet/telnet.go b/pkg/js/generated/go/libtelnet/telnet.go index a51a54b9c8..45672b4422 100644 --- a/pkg/js/generated/go/libtelnet/telnet.go +++ b/pkg/js/generated/go/libtelnet/telnet.go @@ -2,7 +2,6 @@ package telnet import ( lib_telnet "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/telnet" - telnetmini "github.com/projectdiscovery/nuclei/v3/pkg/utils/telnetmini" "github.com/Mzack9999/goja" "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs" @@ -19,12 +18,23 @@ func init() { "IsTelnet": lib_telnet.IsTelnet, // Var and consts + "DO": lib_telnet.DO, + "DONT": lib_telnet.DONT, + "ECHO": lib_telnet.ECHO, + "ENCRYPT": lib_telnet.ENCRYPT, + "IAC": lib_telnet.IAC, + "NAWS": lib_telnet.NAWS, + "SB": lib_telnet.SB, + "SE": lib_telnet.SE, + "SUPPRESS_GO_AHEAD": lib_telnet.SUPPRESS_GO_AHEAD, + "TERMINAL_TYPE": lib_telnet.TERMINAL_TYPE, + "WILL": lib_telnet.WILL, + "WONT": lib_telnet.WONT, // Objects / Classes - "TelnetClient": gojs.GetClassConstructor[lib_telnet.TelnetClient](&lib_telnet.TelnetClient{}), "IsTelnetResponse": gojs.GetClassConstructor[lib_telnet.IsTelnetResponse](&lib_telnet.IsTelnetResponse{}), + "TelnetClient": gojs.GetClassConstructor[lib_telnet.TelnetClient](&lib_telnet.TelnetClient{}), "TelnetInfoResponse": gojs.GetClassConstructor[lib_telnet.TelnetInfoResponse](&lib_telnet.TelnetInfoResponse{}), - "NTLMInfoResponse": gojs.GetClassConstructor[telnetmini.NTLMInfoResponse](&telnetmini.NTLMInfoResponse{}), }, ).Register() } diff --git a/pkg/js/generated/go/libutils/utils.go b/pkg/js/generated/go/libutils/utils.go new file mode 100644 index 0000000000..c94fa59bb2 --- /dev/null +++ b/pkg/js/generated/go/libutils/utils.go @@ -0,0 +1,29 @@ +package utils + +import ( + lib_utils "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/utils" + + "github.com/Mzack9999/goja" + "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs" +) + +var ( + module = gojs.NewGojaModule("nuclei/utils") +) + +func init() { + module.Set( + gojs.Objects{ + // Functions + + // Var and consts + + // Objects / Classes + "Utils": gojs.GetClassConstructor[lib_utils.Utils](&lib_utils.Utils{}), + }, + ).Register() +} + +func Enable(runtime *goja.Runtime) { + module.Enable(runtime) +} diff --git a/pkg/js/generated/ts/fs.ts b/pkg/js/generated/ts/fs.ts index 234c31d61e..343946b582 100755 --- a/pkg/js/generated/ts/fs.ts +++ b/pkg/js/generated/ts/fs.ts @@ -23,7 +23,7 @@ * const items = fs.ListDir('/tmp'); * ``` */ -export function ListDir(path: string, itemType: string): string[] | null { +export function ListDir(ctx: any, path: string, itemType: string): string[] | null { return null; } @@ -39,7 +39,7 @@ export function ListDir(path: string, itemType: string): string[] | null { * const content = fs.ReadFile('helpers/usernames.txt'); * ``` */ -export function ReadFile(path: string): Uint8Array | null { +export function ReadFile(ctx: any, path: string): Uint8Array | null { return null; } @@ -55,7 +55,7 @@ export function ReadFile(path: string): Uint8Array | null { * const content = fs.ReadFileAsString('helpers/usernames.txt'); * ``` */ -export function ReadFileAsString(path: string): string | null { +export function ReadFileAsString(ctx: any, path: string): string | null { return null; } @@ -72,7 +72,7 @@ export function ReadFileAsString(path: string): string | null { * log(contents); * ``` */ -export function ReadFilesFromDir(dir: string): string[] | null { +export function ReadFilesFromDir(ctx: any, dir: string): string[] | null { return null; } diff --git a/pkg/js/generated/ts/index.ts b/pkg/js/generated/ts/index.ts index a4175a45b9..363ef60654 100755 --- a/pkg/js/generated/ts/index.ts +++ b/pkg/js/generated/ts/index.ts @@ -18,4 +18,5 @@ export * as smtp from './smtp'; export * as ssh from './ssh'; export * as structs from './structs'; export * as telnet from './telnet'; +export * as utils from './utils'; export * as vnc from './vnc'; diff --git a/pkg/js/generated/ts/kerberos.ts b/pkg/js/generated/ts/kerberos.ts index d0af2d0e7e..33202580b9 100755 --- a/pkg/js/generated/ts/kerberos.ts +++ b/pkg/js/generated/ts/kerberos.ts @@ -188,9 +188,9 @@ export class Config { */ export interface AuthorizationDataEntry { - ADData?: Uint8Array, - ADType?: number, + + ADData?: Uint8Array, } @@ -212,9 +212,9 @@ export interface BitString { */ export interface BitString { - Bytes?: Uint8Array, - BitLength?: number, + + Bytes?: Uint8Array, } @@ -236,16 +236,16 @@ export interface Config { */ export interface EncTicketPart { - EndTime?: Date, - - RenewTill?: Date, - CRealm?: string, AuthTime?: Date, StartTime?: Date, + EndTime?: Date, + + RenewTill?: Date, + Flags?: BitString, Key?: EncryptionKey, @@ -318,27 +318,29 @@ export interface HostAddress { */ export interface LibDefaults { - CCacheType?: number, + Forwardable?: boolean, - K5LoginAuthoritative?: boolean, + RDNS?: boolean, - Proxiable?: boolean, + DefaultTGSEnctypes?: string[], - RDNS?: boolean, + DefaultTktEnctypes?: string[], - K5LoginDirectory?: string, + DNSLookupKDC?: boolean, - KDCTimeSync?: number, + ExtraAddresses?: Uint8Array, - VerifyAPReqNofail?: boolean, + UDPPreferenceLimit?: number, - DefaultTGSEnctypes?: string[], + DefaultKeytabName?: string, + + DefaultRealm?: string, DefaultTGSEnctypeIDs?: number[], DNSCanonicalizeHostname?: boolean, - Forwardable?: boolean, + K5LoginAuthoritative?: boolean, /** * time in nanoseconds @@ -346,53 +348,51 @@ export interface LibDefaults { RenewLifetime?: number, + AllowWeakCrypto?: boolean, + + Canonicalize?: boolean, + /** * time in nanoseconds */ - TicketLifetime?: number, - - DefaultClientKeytabName?: string, - - DefaultTktEnctypeIDs?: number[], + Clockskew?: number, DNSLookupRealm?: boolean, - ExtraAddresses?: Uint8Array, - - DefaultRealm?: string, + IgnoreAcceptorHostname?: boolean, - NoAddresses?: boolean, + PermittedEnctypeIDs?: number[], PreferredPreauthTypes?: number[], - PermittedEnctypeIDs?: number[], - RealmTryDomains?: number, - DefaultKeytabName?: string, + K5LoginDirectory?: string, - DefaultTktEnctypes?: string[], + KDCTimeSync?: number, - DNSLookupKDC?: boolean, + NoAddresses?: boolean, - IgnoreAcceptorHostname?: boolean, + PermittedEnctypes?: string[], - AllowWeakCrypto?: boolean, + /** + * time in nanoseconds + */ - Canonicalize?: boolean, + TicketLifetime?: number, - SafeChecksumType?: number, + VerifyAPReqNofail?: boolean, - UDPPreferenceLimit?: number, + DefaultClientKeytabName?: string, - /** - * time in nanoseconds - */ + Proxiable?: boolean, - Clockskew?: number, + CCacheType?: number, - PermittedEnctypes?: string[], + DefaultTktEnctypeIDs?: number[], + + SafeChecksumType?: number, KDCDefaultOptions?: BitString, } @@ -404,9 +404,9 @@ export interface LibDefaults { */ export interface PrincipalName { - NameString?: string[], - NameType?: number, + + NameString?: string[], } @@ -416,10 +416,6 @@ export interface PrincipalName { */ export interface Realm { - Realm?: string, - - AdminServer?: string[], - DefaultDomain?: string, KDC?: string[], @@ -427,6 +423,10 @@ export interface Realm { KPasswdServer?: string[], MasterKDC?: string[], + + Realm?: string, + + AdminServer?: string[], } diff --git a/pkg/js/generated/ts/ldap.ts b/pkg/js/generated/ts/ldap.ts index 02a10075b9..d06587c8c9 100755 --- a/pkg/js/generated/ts/ldap.ts +++ b/pkg/js/generated/ts/ldap.ts @@ -399,8 +399,8 @@ export class Client { * client.Authenticate('user', 'password'); * ``` */ - public Authenticate(username: string): void { - return; + public Authenticate(username: string): boolean { + return false; } @@ -413,8 +413,8 @@ export class Client { * client.AuthenticateWithNTLMHash('pdtm', 'hash'); * ``` */ - public AuthenticateWithNTLMHash(username: string): void { - return; + public AuthenticateWithNTLMHash(username: string): boolean { + return false; } @@ -463,6 +463,21 @@ export class Client { } + /** + * GetVersion returns the LDAP versions being used by the server + * @example + * ```javascript + * const ldap = require('nuclei/ldap'); + * const client = new ldap.Client('ldap://ldap.example.com', 'acme.com'); + * const versions = client.GetVersion(); + * log(versions); + * ``` + */ + public GetVersion(): string[] { + return []; + } + + /** * close the ldap connection * @example diff --git a/pkg/js/generated/ts/mssql.ts b/pkg/js/generated/ts/mssql.ts index 632abaa2ea..ed23cd3975 100755 --- a/pkg/js/generated/ts/mssql.ts +++ b/pkg/js/generated/ts/mssql.ts @@ -26,7 +26,7 @@ export class MSSQLClient { * const connected = client.Connect('acme.com', 1433, 'username', 'password'); * ``` */ - public Connect(host: string, port: number, username: string): boolean | null { + public Connect(ctx: any, host: string, port: number, username: string): boolean | null { return null; } @@ -43,7 +43,7 @@ export class MSSQLClient { * const connected = client.ConnectWithDB('acme.com', 1433, 'username', 'password', 'master'); * ``` */ - public ConnectWithDB(host: string, port: number, username: string): boolean | null { + public ConnectWithDB(ctx: any, host: string, port: number, username: string): boolean | null { return null; } @@ -58,7 +58,7 @@ export class MSSQLClient { * const isMssql = mssql.IsMssql('acme.com', 1433); * ``` */ - public IsMssql(host: string, port: number): boolean | null { + public IsMssql(ctx: any, host: string, port: number): boolean | null { return null; } @@ -74,7 +74,7 @@ export class MSSQLClient { * log(to_json(result)); * ``` */ - public ExecuteQuery(host: string, port: number, username: string): SQLResult | null | null { + public ExecuteQuery(ctx: any, host: string, port: number, username: string): SQLResult | null | null { return null; } diff --git a/pkg/js/generated/ts/mysql.ts b/pkg/js/generated/ts/mysql.ts index 4007f05719..60276c2350 100755 --- a/pkg/js/generated/ts/mysql.ts +++ b/pkg/js/generated/ts/mysql.ts @@ -41,7 +41,7 @@ export class MySQLClient { * const isMySQL = mysql.IsMySQL('acme.com', 3306); * ``` */ - public IsMySQL(host: string, port: number): boolean | null { + public IsMySQL(ctx: any, host: string, port: number): boolean | null { return null; } @@ -58,7 +58,7 @@ export class MySQLClient { * const connected = client.Connect('acme.com', 3306, 'username', 'password'); * ``` */ - public Connect(host: string, port: number, username: string): boolean | null { + public Connect(ctx: any, host: string, port: number, username: string): boolean | null { return null; } @@ -72,7 +72,7 @@ export class MySQLClient { * log(to_json(info)); * ``` */ - public FingerprintMySQL(host: string, port: number): MySQLInfo | null { + public FingerprintMySQL(ctx: any, host: string, port: number): MySQLInfo | null { return null; } @@ -88,7 +88,7 @@ export class MySQLClient { * const connected = client.ConnectWithDSN('username:password@tcp(acme.com:3306)/'); * ``` */ - public ConnectWithDSN(dsn: string): boolean | null { + public ConnectWithDSN(ctx: any, dsn: string): boolean | null { return null; } @@ -106,7 +106,7 @@ export class MySQLClient { * log(to_json(result)); * ``` */ - public ExecuteQueryWithOpts(opts: MySQLOptions, query: string): SQLResult | null | null { + public ExecuteQueryWithOpts(ctx: any, opts: MySQLOptions, query: string): SQLResult | null | null { return null; } @@ -121,7 +121,7 @@ export class MySQLClient { * log(to_json(result)); * ``` */ - public ExecuteQuery(host: string, port: number, username: string): SQLResult | null | null { + public ExecuteQuery(ctx: any, host: string, port: number, username: string): SQLResult | null | null { return null; } @@ -136,7 +136,7 @@ export class MySQLClient { * log(to_json(result)); * ``` */ - public ExecuteQueryOnDB(host: string, port: number, username: string): SQLResult | null | null { + public ExecuteQueryOnDB(ctx: any, host: string, port: number, username: string): SQLResult | null | null { return null; } diff --git a/pkg/js/generated/ts/net.ts b/pkg/js/generated/ts/net.ts index f68846e557..c5b146c0b3 100755 --- a/pkg/js/generated/ts/net.ts +++ b/pkg/js/generated/ts/net.ts @@ -9,7 +9,7 @@ * const conn = net.Open('tcp', 'acme.com:80'); * ``` */ -export function Open(protocol: string): NetConn | null { +export function Open(ctx: any, protocol: string): NetConn | null { return null; } @@ -24,7 +24,7 @@ export function Open(protocol: string): NetConn | null { * const conn = net.OpenTLS('tcp', 'acme.com:443'); * ``` */ -export function OpenTLS(protocol: string): NetConn | null { +export function OpenTLS(ctx: any, protocol: string): NetConn | null { return null; } @@ -215,5 +215,90 @@ export class NetConn { } + /** + * SendBytes sends raw bytes to the connection (accepts []byte from JS) + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.SendBytes([0x48, 0x45, 0x4c, 0x4c, 0x4f]); + * ``` + */ + public SendBytes(data: Uint8Array): void { + return; + } + + + /** + * SendLine sends data with a newline appended + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * conn.SendLine('GET / HTTP/1.1'); + * ``` + */ + public SendLine(data: string): void { + return; + } + + + /** + * RecvUntil receives data until the delimiter is found + * Returns all data including the delimiter + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const data = conn.RecvUntil('\r\n\r\n'); + * ``` + */ + public RecvUntil(delim: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * RecvUntilString receives data until the delimiter string is found + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const data = conn.RecvUntilString('\r\n\r\n'); + * ``` + */ + public RecvUntilString(delim: string): string | null { + return null; + } + + + /** + * RecvLine receives data until a newline is found + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const line = conn.RecvLine(); + * ``` + */ + public RecvLine(): string | null { + return null; + } + + + /** + * RecvN receives exactly N bytes (alias for RecvFull) + * @example + * ```javascript + * const net = require('nuclei/net'); + * const conn = net.Open('tcp', 'acme.com:80'); + * const header = conn.RecvN(16); + * ``` + */ + public RecvN(n: number): Uint8Array | null { + return null; + } + + } diff --git a/pkg/js/generated/ts/oracle.ts b/pkg/js/generated/ts/oracle.ts index 5701a4c513..a8be4d0b99 100755 --- a/pkg/js/generated/ts/oracle.ts +++ b/pkg/js/generated/ts/oracle.ts @@ -1,23 +1,8 @@ -/** - * IsOracleResponse is the response from the IsOracle function. - * this is returned by IsOracle function. - * @example - * ```javascript - * const oracle = require('nuclei/oracle'); - * const client = new oracle.OracleClient(); - * const isOracle = client.IsOracle('acme.com', 1521); - * ``` - */ -export interface IsOracleResponse { - IsOracle?: boolean, - Banner?: string, -} - /** * Client is a client for Oracle database. - * Internally client uses go-ora driver. + * Internally client uses oracle/godror driver. * @example * ```javascript * const oracle = require('nuclei/oracle'); @@ -25,82 +10,106 @@ export interface IsOracleResponse { * ``` */ export class OracleClient { + + // Constructor of OracleClient constructor() {} - /** - * Connect connects to an Oracle database - * @example - * ```javascript - * const oracle = require('nuclei/oracle'); - * const client = new oracle.OracleClient(); - * client.Connect('acme.com', 1521, 'XE', 'user', 'password'); - * ``` - */ - public Connect(host: string, port: number, serviceName: string, username: string, password: string): boolean | null { + * IsOracle checks if a host is running an Oracle server + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const isOracle = oracle.IsOracle('acme.com', 1521); + * log(toJSON(isOracle)); + * ``` + */ + public IsOracle(ctx: any, host: string, port: number): IsOracleResponse | null { return null; } + /** - * ConnectWithDSN connects to an Oracle database using a DSN string - * @example - * ```javascript - * const oracle = require('nuclei/oracle'); - * const client = new oracle.OracleClient(); - * client.ConnectWithDSN('oracle://user:password@host:port/service', 'SELECT @@version'); - * ``` - */ - public ConnectWithDSN(dsn: string): boolean | null { + * Connect connects to an Oracle database + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const client = new oracle.OracleClient; + * client.Connect('acme.com', 1521, 'XE', 'user', 'password'); + * ``` + */ + public Connect(ctx: any, host: string, port: number, serviceName: string, username: string, password: string): boolean | null { return null; } + /** - * IsOracle checks if a host is running an Oracle server - * @example - * ```javascript - * const oracle = require('nuclei/oracle'); - * const isOracle = oracle.IsOracle('acme.com', 1521); - * ``` - */ - public IsOracle(host: string, port: number): IsOracleResponse | null { + * ConnectWithDSN Method + */ + public ConnectWithDSN(ctx: any, dsn: string): boolean | null { return null; } + /** - * ExecuteQuery connects to Oracle database using given credentials and executes a query. - * It returns the results of the query or an error if something goes wrong. - * @example - * ```javascript - * const oracle = require('nuclei/oracle'); - * const client = new oracle.OracleClient(); - * const result = client.ExecuteQuery('acme.com', 1521, 'username', 'password', 'XE', 'SELECT * FROM dual'); - * log(to_json(result)); - * ``` - */ - public ExecuteQuery(host: string, port: number, username: string, password: string, dbName: string, query: string): SQLResult | null { + * ExecuteQuery connects to MS SQL database using given credentials and executes a query. + * It returns the results of the query or an error if something goes wrong. + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const client = new oracle.OracleClient; + * const result = client.ExecuteQuery('acme.com', 1521, 'username', 'password', 'XE', 'SELECT @@version'); + * log(to_json(result)); + * ``` + */ + public ExecuteQuery(ctx: any, host: string, port: number, username: string): SQLResult | null | null { return null; } + /** - * ExecuteQueryWithDSN executes a query on an Oracle database using a DSN - * @example - * ```javascript - * const oracle = require('nuclei/oracle'); - * const client = new oracle.OracleClient(); - * const result = client.ExecuteQueryWithDSN('oracle://user:password@host:port/service', 'SELECT * FROM dual'); - * log(to_json(result)); - * ``` - */ - public ExecuteQueryWithDSN(dsn: string, query: string): SQLResult | null { + * ExecuteQueryWithDSN executes a query on an Oracle database using a DSN + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const client = new oracle.OracleClient; + * const result = client.ExecuteQueryWithDSN('oracle://user:password@host:port/service', 'SELECT @@version'); + * log(to_json(result)); + * ``` + */ + public ExecuteQueryWithDSN(ctx: any, dsn: string, query: string): SQLResult | null | null { return null; } + + } + + +/** + * IsOracleResponse is the response from the IsOracle function. + * this is returned by IsOracle function. + * @example + * ```javascript + * const oracle = require('nuclei/oracle'); + * const isOracle = oracle.IsOracle('acme.com', 1521); + * ``` + */ +export interface IsOracleResponse { + + IsOracle?: boolean, + + Banner?: string, +} + + + /** * SQLResult Interface */ export interface SQLResult { + Count?: number, + Columns?: string[], - Rows?: any[], } + diff --git a/pkg/js/generated/ts/pop3.ts b/pkg/js/generated/ts/pop3.ts index 84de1718a4..0e78e974d1 100755 --- a/pkg/js/generated/ts/pop3.ts +++ b/pkg/js/generated/ts/pop3.ts @@ -9,7 +9,7 @@ * log(toJSON(isPOP3)); * ``` */ -export function IsPOP3(host: string, port: number): IsPOP3Response | null { +export function IsPOP3(ctx: any, host: string, port: number): IsPOP3Response | null { return null; } diff --git a/pkg/js/generated/ts/postgres.ts b/pkg/js/generated/ts/postgres.ts index 31efd44c33..90b0f84326 100755 --- a/pkg/js/generated/ts/postgres.ts +++ b/pkg/js/generated/ts/postgres.ts @@ -24,7 +24,7 @@ export class PGClient { * const isPostgres = postgres.IsPostgres('acme.com', 5432); * ``` */ - public IsPostgres(host: string, port: number): boolean | null { + public IsPostgres(ctx: any, host: string, port: number): boolean | null { return null; } @@ -41,7 +41,7 @@ export class PGClient { * const connected = client.Connect('acme.com', 5432, 'username', 'password'); * ``` */ - public Connect(host: string, port: number, username: string): boolean | null { + public Connect(ctx: any, host: string, port: number, username: string, password: string): boolean | null { return null; } @@ -58,7 +58,7 @@ export class PGClient { * log(to_json(result)); * ``` */ - public ExecuteQuery(host: string, port: number, username: string): SQLResult | null | null { + public ExecuteQuery(ctx: any, host: string, port: number, username: string, password: string, dbName: string, query: string): SQLResult | null | null { return null; } @@ -75,7 +75,7 @@ export class PGClient { * const connected = client.ConnectWithDB('acme.com', 5432, 'username', 'password', 'dbname'); * ``` */ - public ConnectWithDB(host: string, port: number, username: string): boolean | null { + public ConnectWithDB(ctx: any, host: string, port: number, username: string, password: string, dbName: string): boolean | null { return null; } diff --git a/pkg/js/generated/ts/rdp.ts b/pkg/js/generated/ts/rdp.ts index 28a28468a5..70503b2e55 100755 --- a/pkg/js/generated/ts/rdp.ts +++ b/pkg/js/generated/ts/rdp.ts @@ -1,3 +1,32 @@ + + + +export const EncryptionLevelFIPS140_1 = "FIPS140_1"; + + +export const EncryptionLevelRC4_128bit = "RC4_128bit"; + + +export const EncryptionLevelRC4_40bit = "RC4_40bit"; + + +export const EncryptionLevelRC4_56bit = "RC4_56bit"; + + +export const SecurityLayerCredSSP = "CredSSP"; + + +export const SecurityLayerCredSSPWithEarlyUserAuth = "CredSSPWithEarlyUserAuth"; + + +export const SecurityLayerNativeRDP = "NativeRDP"; + + +export const SecurityLayerRDSTLS = "RDSTLS"; + + +export const SecurityLayerSSL = "SSL"; + /** * CheckRDPAuth checks if the given host and port are running rdp server * with authentication and returns their metadata. @@ -9,10 +38,12 @@ * log(toJSON(checkRDPAuth)); * ``` */ -export function CheckRDPAuth(host: string, port: number): CheckRDPAuthResponse | null { +export function CheckRDPAuth(ctx: any, host: string, port: number): CheckRDPAuthResponse | null { return null; } + + /** * CheckRDPEncryption checks the RDP server's supported security layers and encryption levels. * It tests different protocols and ciphers to determine what is supported. @@ -23,10 +54,12 @@ export function CheckRDPAuth(host: string, port: number): CheckRDPAuthResponse | * log(toJSON(encryption)); * ``` */ -export function CheckRDPEncryption(host: string, port: number): RDPEncryptionResponse | null { +export function CheckRDPEncryption(ctx: any, host: string, port: number): RDPEncryptionResponse | null { return null; } + + /** * IsRDP checks if the given host and port are running rdp server. * If connection is successful, it returns true. @@ -39,10 +72,12 @@ export function CheckRDPEncryption(host: string, port: number): RDPEncryptionRes * log(toJSON(isRDP)); * ``` */ -export function IsRDP(host: string, port: number): IsRDPResponse | null { +export function IsRDP(ctx: any, host: string, port: number): IsRDPResponse | null { return null; } + + /** * CheckRDPAuthResponse is the response from the CheckRDPAuth function. * this is returned by CheckRDPAuth function. @@ -60,30 +95,7 @@ export interface CheckRDPAuthResponse { Auth?: boolean, } -/** - * RDPEncryptionResponse is the response from the CheckRDPEncryption function. - * This is returned by CheckRDPEncryption function. - * @example - * ```javascript - * const rdp = require('nuclei/rdp'); - * const encryption = rdp.CheckRDPEncryption('acme.com', 3389); - * log(toJSON(encryption)); - * ``` - */ -export interface RDPEncryptionResponse { - // Security Layer Protocols - NativeRDP: boolean; - SSL: boolean; - CredSSP: boolean; - RDSTLS: boolean; - CredSSPWithEarlyUserAuth: boolean; - - // Encryption Levels - RC4_40bit: boolean; - RC4_56bit: boolean; - RC4_128bit: boolean; - FIPS140_1: boolean; -} + /** * IsRDPResponse is the response from the IsRDP function. @@ -102,16 +114,53 @@ export interface IsRDPResponse { OS?: string, } + + /** - * ServiceRDP Interface + * RDPEncryptionResponse is the response from the CheckRDPEncryption function. + * This is returned by CheckRDPEncryption function. + * @example + * ```javascript + * const rdp = require('nuclei/rdp'); + * const encryption = rdp.CheckRDPEncryption('acme.com', 3389); + * log(toJSON(encryption)); + * ``` */ -export interface ServiceRDP { +export interface RDPEncryptionResponse { - ForestName?: string, + /** + * Protocols + */ - OSFingerprint?: string, + NativeRDP?: boolean, - OSVersion?: string, + SSL?: boolean, + + CredSSP?: boolean, + + RDSTLS?: boolean, + + CredSSPWithEarlyUserAuth?: boolean, + + /** + * EncryptionLevels + */ + + RC4_40bit?: boolean, + + RC4_56bit?: boolean, + + RC4_128bit?: boolean, + + FIPS140_1?: boolean, +} + + + +/** + * ServiceRDP Interface + */ +export interface ServiceRDP { TargetName?: string, @@ -122,5 +171,11 @@ export interface ServiceRDP { DNSComputerName?: string, DNSDomainName?: string, + + ForestName?: string, + + OSFingerprint?: string, + + OSVersion?: string, } diff --git a/pkg/js/generated/ts/redis.ts b/pkg/js/generated/ts/redis.ts index fbab318363..671ad9dad2 100755 --- a/pkg/js/generated/ts/redis.ts +++ b/pkg/js/generated/ts/redis.ts @@ -8,7 +8,7 @@ * const connected = redis.Connect('acme.com', 6379, 'password'); * ``` */ -export function Connect(host: string, port: number, password: string): boolean | null { +export function Connect(ctx: any, host: string, port: number, password: string): boolean | null { return null; } @@ -22,7 +22,7 @@ export function Connect(host: string, port: number, password: string): boolean | * const info = redis.GetServerInfo('acme.com', 6379); * ``` */ -export function GetServerInfo(host: string, port: number): string | null { +export function GetServerInfo(ctx: any, host: string, port: number): string | null { return null; } @@ -36,7 +36,7 @@ export function GetServerInfo(host: string, port: number): string | null { * const info = redis.GetServerInfoAuth('acme.com', 6379, 'password'); * ``` */ -export function GetServerInfoAuth(host: string, port: number, password: string): string | null { +export function GetServerInfoAuth(ctx: any, host: string, port: number, password: string): string | null { return null; } @@ -50,7 +50,7 @@ export function GetServerInfoAuth(host: string, port: number, password: string): * const isAuthenticated = redis.IsAuthenticated('acme.com', 6379); * ``` */ -export function IsAuthenticated(host: string, port: number): boolean | null { +export function IsAuthenticated(ctx: any, host: string, port: number): boolean | null { return null; } @@ -64,7 +64,7 @@ export function IsAuthenticated(host: string, port: number): boolean | null { * const result = redis.RunLuaScript('acme.com', 6379, 'password', 'return redis.call("get", KEYS[1])'); * ``` */ -export function RunLuaScript(host: string, port: number, password: string, script: string): any | null { +export function RunLuaScript(ctx: any, host: string, port: number, password: string, script: string): any | null { return null; } diff --git a/pkg/js/generated/ts/rsync.ts b/pkg/js/generated/ts/rsync.ts index 6cb675b0d6..dbf0a45bd5 100755 --- a/pkg/js/generated/ts/rsync.ts +++ b/pkg/js/generated/ts/rsync.ts @@ -9,10 +9,12 @@ * log(toJSON(isRsync)); * ``` */ -export function IsRsync(host: string, port: number): IsRsyncResponse | null { +export function IsRsync(ctx: any, host: string, port: number): IsRsyncResponse | null { return null; } + + /** * RsyncClient is a client for RSYNC servers. * Internally client uses https://github.com/gokrazy/rsync driver. @@ -24,51 +26,43 @@ export function IsRsync(host: string, port: number): IsRsyncResponse | null { */ export class RsyncClient { + // Constructor of RsyncClient constructor() {} - /** - * Connect establishes a connection to the rsync server with authentication. - * @example - * ```javascript - * const rsync = require('nuclei/rsync'); - * const client = new rsync.RsyncClient(); - * const connected = client.Connect('acme.com', 873, 'username', 'password', 'backup'); - * ``` - */ - public Connect(host: string, port: number, username: string, password: string, module: string): boolean | null { + * ListModules lists the modules of a Rsync server. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * const listModules = client.ListModules('acme.com', 873, 'username', 'password'); + * log(toJSON(listModules)); + * ``` + */ + public ListModules(ctx: any, host: string, port: number, username: string, password: string): RsyncListResponse | null { return null; } + /** - * ListModules lists available modules on the rsync server. - * @example - * ```javascript - * const rsync = require('nuclei/rsync'); - * const client = new rsync.RsyncClient(); - * const modules = client.ListModules('acme.com', 873, 'username', 'password'); - * log(toJSON(modules)); - * ``` - */ - public ListModules(host: string, port: number, username: string, password: string): string[] | null { + * ListShares lists the shares of a Rsync server. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * const listShares = client.ListFilesInModule('acme.com', 873, 'username', 'password', '/'); + * log(toJSON(listShares)); + * ``` + */ + public ListFilesInModule(ctx: any, host: string, port: number, username: string, password: string, module: string): RsyncListResponse | null { return null; } - /** - * ListFilesInModule lists files in a specific module on the rsync server. - * @example - * ```javascript - * const rsync = require('nuclei/rsync'); - * const client = new rsync.RsyncClient(); - * const files = client.ListFilesInModule('acme.com', 873, 'username', 'password', 'backup'); - * log(toJSON(files)); - * ``` - */ - public ListFilesInModule(host: string, port: number, username: string, password: string, module: string): string[] | null { - return null; - } + } + + /** * IsRsyncResponse is the response from the IsRsync function. * this is returned by IsRsync function. @@ -86,3 +80,24 @@ export interface IsRsyncResponse { Banner?: string, } + + +/** + * ListSharesResponse is the response from the ListShares function. + * this is returned by ListShares function. + * @example + * ```javascript + * const rsync = require('nuclei/rsync'); + * const client = new rsync.RsyncClient(); + * const listShares = client.ListShares('acme.com', 873); + * log(toJSON(listShares)); + */ +export interface RsyncListResponse { + + Modules?: string[], + + Files?: string[], + + Output?: string, +} + diff --git a/pkg/js/generated/ts/smb.ts b/pkg/js/generated/ts/smb.ts index c9b769cb5d..0eeb8039c2 100755 --- a/pkg/js/generated/ts/smb.ts +++ b/pkg/js/generated/ts/smb.ts @@ -28,7 +28,7 @@ export class SMBClient { * log(to_json(info)); * ``` */ - public ConnectSMBInfoMode(host: string, port: number): SMBLog | null | null { + public ConnectSMBInfoMode(ctx: any, host: string, port: number): SMBLog | null | null { return null; } @@ -46,7 +46,7 @@ export class SMBClient { * log(to_json(metadata)); * ``` */ - public ListSMBv2Metadata(host: string, port: number): ServiceSMB | null | null { + public ListSMBv2Metadata(ctx: any, host: string, port: number): ServiceSMB | null | null { return null; } @@ -66,7 +66,7 @@ export class SMBClient { * } * ``` */ - public ListShares(host: string, port: number, user: string): string[] | null { + public ListShares(ctx: any, host: string, port: number, user: string): string[] | null { return null; } @@ -81,7 +81,7 @@ export class SMBClient { * const isSMBGhost = smb.DetectSMBGhost('acme.com', 445); * ``` */ - public DetectSMBGhost(host: string, port: number): boolean | null { + public DetectSMBGhost(ctx: any, host: string, port: number): boolean | null { return null; } @@ -113,12 +113,6 @@ export interface HeaderLog { */ export interface NegotiationLog { - SecurityMode?: number, - - DialectRevision?: number, - - ServerGuid?: Uint8Array, - Capabilities?: number, SystemTime?: number, @@ -127,6 +121,12 @@ export interface NegotiationLog { AuthenticationTypes?: string[], + SecurityMode?: number, + + DialectRevision?: number, + + ServerGuid?: Uint8Array, + HeaderLog?: HeaderLog, } @@ -159,16 +159,16 @@ export interface SMBCapabilities { */ export interface SMBLog { - NTLM?: string, - - GroupName?: string, - HasNTLM?: boolean, SupportV1?: boolean, NativeOs?: string, + NTLM?: string, + + GroupName?: string, + Version?: SMBVersions, Capabilities?: SMBCapabilities, @@ -185,13 +185,13 @@ export interface SMBLog { */ export interface SMBVersions { - Major?: number, - - Minor?: number, - Revision?: number, VerString?: string, + + Major?: number, + + Minor?: number, } @@ -201,8 +201,6 @@ export interface SMBVersions { */ export interface ServiceSMB { - OSVersion?: string, - NetBIOSComputerName?: string, NetBIOSDomainName?: string, @@ -216,6 +214,8 @@ export interface ServiceSMB { SigningEnabled?: boolean, SigningRequired?: boolean, + + OSVersion?: string, } diff --git a/pkg/js/generated/ts/ssh.ts b/pkg/js/generated/ts/ssh.ts index 058df03c5b..a658c7c0eb 100755 --- a/pkg/js/generated/ts/ssh.ts +++ b/pkg/js/generated/ts/ssh.ts @@ -40,7 +40,7 @@ export class SSHClient { * const connected = client.Connect('acme.com', 22, 'username', 'password'); * ``` */ - public Connect(host: string, port: number, username: string): boolean | null { + public Connect(ctx: any, host: string, port: number, username: string): boolean | null { return null; } @@ -58,7 +58,7 @@ export class SSHClient { * const connected = client.ConnectWithKey('acme.com', 22, 'username', privateKey); * ``` */ - public ConnectWithKey(host: string, port: number, username: string): boolean | null { + public ConnectWithKey(ctx: any, host: string, port: number, username: string): boolean | null { return null; } @@ -78,7 +78,7 @@ export class SSHClient { * log(to_json(info)); * ``` */ - public ConnectSSHInfoMode(host: string, port: number): HandshakeLog | null | null { + public ConnectSSHInfoMode(ctx: any, host: string, port: number): HandshakeLog | null | null { return null; } @@ -129,10 +129,10 @@ export class SSHClient { */ export interface Algorithms { - Kex?: string, - HostKey?: string, + Kex?: string, + W?: DirectionAlgorithms, R?: DirectionAlgorithms, @@ -159,13 +159,13 @@ export interface DirectionAlgorithms { */ export interface EndpointId { + ProtoVersion?: string, + SoftwareVersion?: string, Comment?: string, Raw?: string, - - ProtoVersion?: string, } @@ -179,15 +179,15 @@ export interface HandshakeLog { UserAuth?: string[], - ServerID?: EndpointId, - - ClientID?: EndpointId, - ServerKex?: KexInitMsg, ClientKex?: KexInitMsg, AlgorithmSelection?: Algorithms, + + ServerID?: EndpointId, + + ClientID?: EndpointId, } @@ -197,34 +197,34 @@ export interface HandshakeLog { */ export interface KexInitMsg { - KexAlgos?: string[], - - CiphersClientServer?: string[], + /** + * fixed size array of length: [16] + */ - MACsServerClient?: string[], + Cookie?: Uint8Array, - LanguagesClientServer?: string[], + KexAlgos?: string[], - CompressionClientServer?: string[], + ServerHostKeyAlgos?: string[], - CompressionServerClient?: string[], + CiphersClientServer?: string[], - Reserved?: number, + CiphersServerClient?: string[], MACsClientServer?: string[], - /** - * fixed size array of length: [16] - */ + MACsServerClient?: string[], - Cookie?: Uint8Array, + CompressionClientServer?: string[], - ServerHostKeyAlgos?: string[], + CompressionServerClient?: string[], - CiphersServerClient?: string[], + LanguagesClientServer?: string[], LanguagesServerClient?: string[], FirstKexFollows?: boolean, + + Reserved?: number, } diff --git a/pkg/js/generated/ts/telnet.ts b/pkg/js/generated/ts/telnet.ts index 39513bd91b..cc8b13ef2f 100755 --- a/pkg/js/generated/ts/telnet.ts +++ b/pkg/js/generated/ts/telnet.ts @@ -1,5 +1,41 @@ +/** Do */ +export const DO = 253; + +/** Don't */ +export const DONT = 254; + +/** Echo */ +export const ECHO = 1; + +/** Encryption option (0x26) */ +export const ENCRYPT = 38; + +/** Interpret As Command */ +export const IAC = 255; + +/** Negotiate About Window Size */ +export const NAWS = 31; + +/** Subnegotiation Begin */ +export const SB = 250; + +/** Subnegotiation End */ +export const SE = 240; + +/** Suppress Go Ahead */ +export const SUPPRESS_GO_AHEAD = 3; + +/** Terminal Type */ +export const TERMINAL_TYPE = 24; + +/** Will */ +export const WILL = 251; + +/** Won't */ +export const WONT = 252; + /** * IsTelnet checks if a host is running a Telnet server. * @example @@ -9,10 +45,12 @@ * log(toJSON(isTelnet)); * ``` */ -export function IsTelnet(host: string, port: number): IsTelnetResponse | null { +export function IsTelnet(ctx: any, host: string, port: number): IsTelnetResponse | null { return null; } + + /** * TelnetClient is a client for Telnet servers. * @example @@ -23,56 +61,65 @@ export function IsTelnet(host: string, port: number): IsTelnetResponse | null { */ export class TelnetClient { + + // Constructor of TelnetClient + constructor() {} /** - * Connect tries to connect to provided host and port with telnet. - * Optionally provides username and password for authentication. - * Returns state of connection. If the connection is successful, - * the function will return true, otherwise false. - * @example - * ```javascript - * const telnet = require('nuclei/telnet'); - * const client = new telnet.TelnetClient(); - * const connected = client.Connect('acme.com', 23, 'username', 'password'); - * ``` - */ - public Connect(host: string, port: number, username: string, password: string): boolean { - return false; + * Connect tries to connect to provided host and port with telnet. + * Optionally provides username and password for authentication. + * Returns state of connection. If the connection is successful, + * the function will return true, otherwise false. + * @example + * ```javascript + * const telnet = require('nuclei/telnet'); + * const client = new telnet.TelnetClient(); + * const connected = client.Connect('acme.com', 23, 'username', 'password'); + * ``` + */ + public Connect(ctx: any, host: string, port: number, username: string, password: string): boolean | null { + return null; } + /** - * Info gathers information about the telnet server including encryption support. - * Uses the telnetmini library's DetectEncryption helper function. - * WARNING: The connection used for detection becomes unusable after this call. - * @example - * ```javascript - * const telnet = require('nuclei/telnet'); - * const client = new telnet.TelnetClient(); - * const info = client.Info('acme.com', 23); - * log(toJSON(info)); - * ``` - */ - public Info(host: string, port: number): TelnetInfoResponse | null { + * Info gathers information about the telnet server including encryption support. + * Uses the telnetmini library's DetectEncryption helper function. + * WARNING: The connection used for detection becomes unusable after this call. + * @example + * ```javascript + * const telnet = require('nuclei/telnet'); + * const client = new telnet.TelnetClient(); + * const info = client.Info('acme.com', 23); + * log(toJSON(info)); + * ``` + */ + public Info(ctx: any, host: string, port: number): TelnetInfoResponse | null { return null; } + /** - * GetTelnetNTLMInfo implements the Nmap telnet-ntlm-info.nse script functionality. - * This function uses the telnetmini library and SMB packet crafting functions to send - * MS-TNAP NTLM authentication requests with null credentials. It might work only on - * Microsoft Telnet servers. - * @example - * ```javascript - * const telnet = require('nuclei/telnet'); - * const client = new telnet.TelnetClient(); - * const ntlmInfo = client.GetTelnetNTLMInfo('acme.com', 23); - * log(toJSON(ntlmInfo)); - * ``` - */ - public GetTelnetNTLMInfo(host: string, port: number): NTLMInfoResponse | null { + * GetTelnetNTLMInfo implements the Nmap telnet-ntlm-info.nse script functionality. + * This function uses the telnetmini library and SMB packet crafting functions to send + * MS-TNAP NTLM authentication requests with null credentials. It might work only on + * Microsoft Telnet servers. + * @example + * ```javascript + * const telnet = require('nuclei/telnet'); + * const client = new telnet.TelnetClient(); + * const ntlmInfo = client.GetTelnetNTLMInfo('acme.com', 23); + * log(toJSON(ntlmInfo)); + * ``` + */ + public GetTelnetNTLMInfo(ctx: any, host: string, port: number): NTLMInfoResponse | null | null { return null; } + + } + + /** * IsTelnetResponse is the response from the IsTelnet function. * this is returned by IsTelnet function. @@ -90,76 +137,48 @@ export interface IsTelnetResponse { Banner?: string, } + + /** - * TelnetInfoResponse is the response from the Info function. - * @example - * ```javascript - * const telnet = require('nuclei/telnet'); - * const client = new telnet.TelnetClient(); - * const info = client.Info('acme.com', 23); - * log(toJSON(info)); - * ``` + * NTLMInfoResponse Interface */ -export interface TelnetInfoResponse { +export interface NTLMInfoResponse { - SupportsEncryption?: boolean, + DNSComputerName?: string, - Banner?: string, + DNSTreeName?: string, + + ProductVersion?: string, - Options?: { [key: number]: number[] }, + Timestamp?: number, + + TargetName?: string, + + NetBIOSDomainName?: string, + + NetBIOSComputerName?: string, + + DNSDomainName?: string, } + + /** - * NTLMInfoResponse represents the response from NTLM information gathering. - * This matches exactly the output structure from the Nmap telnet-ntlm-info.nse script. + * TelnetInfoResponse is the response from the Info function. * @example * ```javascript * const telnet = require('nuclei/telnet'); * const client = new telnet.TelnetClient(); - * const ntlmInfo = client.GetTelnetNTLMInfo('acme.com', 23); - * log(toJSON(ntlmInfo)); + * const info = client.Info('acme.com', 23); + * log(toJSON(info)); * ``` */ -export interface NTLMInfoResponse { - - /** - * Target_Name from script (target_realm in script) - */ - TargetName?: string, - - /** - * NetBIOS_Domain_Name from script - */ - NetBIOSDomainName?: string, - - /** - * NetBIOS_Computer_Name from script - */ - NetBIOSComputerName?: string, - - /** - * DNS_Domain_Name from script - */ - DNSDomainName?: string, - - /** - * DNS_Computer_Name from script (fqdn in script) - */ - DNSComputerName?: string, +export interface TelnetInfoResponse { - /** - * DNS_Tree_Name from script (dns_forest_name in script) - */ - DNSTreeName?: string, + SupportsEncryption?: boolean, - /** - * Product_Version from script - */ - ProductVersion?: string, + Banner?: string, - /** - * Raw timestamp for skew calculation - */ - Timestamp?: number, + Options?: Record, } diff --git a/pkg/js/generated/ts/utils.ts b/pkg/js/generated/ts/utils.ts new file mode 100755 index 0000000000..bafc338b32 --- /dev/null +++ b/pkg/js/generated/ts/utils.ts @@ -0,0 +1,1426 @@ + + +/** + * Utils is a struct for utils functions + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * ``` + */ +export class Utils { + + + // Constructor of Utils + constructor() {} + /** + * PatternCreate creates a cyclic pattern of specified length for buffer overflow analysis + * The pattern is designed to have unique 4-byte sequences for easy offset identification + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const pattern = utils.PatternCreate(1000); + * ``` + */ + public PatternCreate(length: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PatternOffset finds the offset of a 4-byte pattern within a cyclic pattern + * Returns -1 if pattern is not found + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const pattern = utils.PatternCreate(1000); + * const offset = utils.PatternOffset(pattern, ToBytes('Aa0A')); + * ``` + */ + public PatternOffset(pattern: Uint8Array): number { + return 0; + } + + + /** + * FindBytes finds the first occurrence of needle in haystack + * Returns -1 if not found + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const idx = utils.FindBytes([0x41, 0x42, 0x43, 0x44], [0x42, 0x43]); + * ``` + */ + public FindBytes(haystack: Uint8Array): number { + return 0; + } + + + /** + * FindAllBytes finds all occurrences of needle in haystack + * Returns array of indices + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const indices = utils.FindAllBytes([0x41, 0x42, 0x41, 0x42], [0x41, 0x42]); + * ``` + */ + public FindAllBytes(haystack: Uint8Array): number[] { + return []; + } + + + /** + * ReplaceBytes replaces all occurrences of old with new in data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const result = utils.ReplaceBytes([0x41, 0x42, 0x43], [0x42], [0x44, 0x45]); + * ``` + */ + public ReplaceBytes(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * RepeatBytes repeats data count times + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const repeated = utils.RepeatBytes([0x41, 0x42], 3); + * ``` + */ + public RepeatBytes(data: Uint8Array, count: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * ReverseBytes reverses a byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const reversed = utils.ReverseBytes([0x41, 0x42, 0x43]); + * ``` + */ + public ReverseBytes(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * SwapEndian16 swaps endianness of 16-bit values in data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const swapped = utils.SwapEndian16([0x01, 0x02, 0x03, 0x04]); + * ``` + */ + public SwapEndian16(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * SwapEndian32 swaps endianness of 32-bit values in data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const swapped = utils.SwapEndian32([0x01, 0x02, 0x03, 0x04]); + * ``` + */ + public SwapEndian32(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * GenerateRandomString generates a random string of specified length + * using alphanumeric characters + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const str = utils.GenerateRandomString(16); + * ``` + */ + public GenerateRandomString(length: number): string { + return ""; + } + + + /** + * GenerateRandomAlphanumeric generates a random alphanumeric string + * (alias for GenerateRandomString) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const str = utils.GenerateRandomAlphanumeric(16); + * ``` + */ + public GenerateRandomAlphanumeric(length: number): string { + return ""; + } + + + /** + * GenerateRandomBytes generates random bytes of specified length + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const bytes = utils.GenerateRandomBytes(16); + * ``` + */ + public GenerateRandomBytes(length: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * RepeatString repeats a string count times + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const repeated = utils.RepeatString('A', 100); + * ``` + */ + public RepeatString(s: string, count: number): string { + return ""; + } + + + /** + * PadLeft pads string on the left to specified length + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const padded = utils.PadLeft('123', 8, '0'); + * ``` + */ + public PadLeft(s: string, length: number, pad: string): string { + return ""; + } + + + /** + * PadRight pads string on the right to specified length + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const padded = utils.PadRight('123', 8, '0'); + * ``` + */ + public PadRight(s: string, length: number, pad: string): string { + return ""; + } + + + /** + * ZlibCompress compresses data using zlib + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const compressed = utils.ZlibCompress('hello world'); + * ``` + */ + public ZlibCompress(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * ZlibDecompress decompresses zlib compressed data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decompressed = utils.ZlibDecompress(compressed); + * ``` + */ + public ZlibDecompress(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * GzipCompress compresses data using gzip + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const compressed = utils.GzipCompress('hello world'); + * ``` + */ + public GzipCompress(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * GzipDecompress decompresses gzip compressed data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decompressed = utils.GzipDecompress(compressed); + * ``` + */ + public GzipDecompress(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * DeflateCompress compresses data using raw deflate (no zlib header) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const compressed = utils.DeflateCompress('hello world'); + * ``` + */ + public DeflateCompress(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * DeflateDecompress decompresses raw deflate compressed data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decompressed = utils.DeflateDecompress(compressed); + * ``` + */ + public DeflateDecompress(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * AESEncryptECB encrypts data using AES in ECB mode + * Key must be 16, 24, or 32 bytes for AES-128, AES-192, AES-256 + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const key = Rand(16); + * const encrypted = utils.AESEncryptECB(ToBytes('plaintext'), key); + * ``` + */ + public AESEncryptECB(plaintext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * AESDecryptECB decrypts data using AES in ECB mode + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decrypted = utils.AESDecryptECB(encrypted, key); + * ``` + */ + public AESDecryptECB(ciphertext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * AESEncryptCBC encrypts data using AES in CBC mode + * Key must be 16, 24, or 32 bytes. IV must be 16 bytes. + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const key = Rand(16); + * const iv = Rand(16); + * const encrypted = utils.AESEncryptCBC(ToBytes('plaintext'), key, iv); + * ``` + */ + public AESEncryptCBC(plaintext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * AESDecryptCBC decrypts data using AES in CBC mode + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decrypted = utils.AESDecryptCBC(encrypted, key, iv); + * ``` + */ + public AESDecryptCBC(ciphertext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * AESEncryptGCM encrypts data using AES in GCM mode + * Key must be 16, 24, or 32 bytes. Nonce should be 12 bytes. + * Returns ciphertext with authentication tag appended. + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const key = Rand(16); + * const nonce = Rand(12); + * const encrypted = utils.AESEncryptGCM(ToBytes('plaintext'), key, nonce); + * ``` + */ + public AESEncryptGCM(plaintext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * AESDecryptGCM decrypts data using AES in GCM mode + * Expects ciphertext with authentication tag appended. + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decrypted = utils.AESDecryptGCM(encrypted, key, nonce); + * ``` + */ + public AESDecryptGCM(ciphertext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * DESEncryptECB encrypts data using DES in ECB mode + * Key must be 8 bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const key = Rand(8); + * const encrypted = utils.DESEncryptECB(ToBytes('plaintext'), key); + * ``` + */ + public DESEncryptECB(plaintext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * DESDecryptECB decrypts data using DES in ECB mode + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decrypted = utils.DESDecryptECB(encrypted, key); + * ``` + */ + public DESDecryptECB(ciphertext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * DES3EncryptCBC encrypts data using Triple DES in CBC mode + * Key must be 24 bytes. IV must be 8 bytes. + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const key = Rand(24); + * const iv = Rand(8); + * const encrypted = utils.DES3EncryptCBC(ToBytes('plaintext'), key, iv); + * ``` + */ + public DES3EncryptCBC(plaintext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * DES3DecryptCBC decrypts data using Triple DES in CBC mode + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decrypted = utils.DES3DecryptCBC(encrypted, key, iv); + * ``` + */ + public DES3DecryptCBC(ciphertext: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * RC4Encrypt encrypts/decrypts data using RC4 (symmetric) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const key = Rand(16); + * const encrypted = utils.RC4Encrypt(ToBytes('plaintext'), key); + * const decrypted = utils.RC4Encrypt(encrypted, key); // RC4 is symmetric + * ``` + */ + public RC4Encrypt(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * XORBytes XORs data with a repeating key + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const xored = utils.XORBytes([0x41, 0x42, 0x43], [0x01, 0x02]); + * ``` + */ + public XORBytes(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * XORSingleByte XORs each byte of data with a single byte key + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const xored = utils.XORSingleByte([0x41, 0x42, 0x43], 0x01); + * ``` + */ + public XORSingleByte(data: Uint8Array, key: byte): Uint8Array { + return new Uint8Array(8); + } + + + /** + * URLEncode URL encodes a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.URLEncode('hello world'); + * ``` + */ + public URLEncode(data: string): string { + return ""; + } + + + /** + * URLDecode URL decodes a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decoded = utils.URLDecode('hello%20world'); + * ``` + */ + public URLDecode(data: string): string | null { + return null; + } + + + /** + * HTMLEncode HTML encodes a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.HTMLEncode(''); + * ``` + */ + public HTMLEncode(data: string): string { + return ""; + } + + + /** + * HTMLDecode HTML decodes a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decoded = utils.HTMLDecode('<script>'); + * ``` + */ + public HTMLDecode(data: string): string { + return ""; + } + + + /** + * HexEncode encodes bytes to hex string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hex = utils.HexEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); + * ``` + */ + public HexEncode(data: Uint8Array): string { + return ""; + } + + + /** + * HexDecode decodes hex string to bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const bytes = utils.HexDecode('48656c6c6f'); + * ``` + */ + public HexDecode(data: string): Uint8Array | null { + return null; + } + + + /** + * Base64Encode encodes bytes to base64 string (standard encoding) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.Base64Encode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); + * ``` + */ + public Base64Encode(data: Uint8Array): string { + return ""; + } + + + /** + * Base64Decode decodes base64 string to bytes (standard encoding) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const bytes = utils.Base64Decode('SGVsbG8='); + * ``` + */ + public Base64Decode(data: string): Uint8Array | null { + return null; + } + + + /** + * Base64URLEncode encodes bytes to URL-safe base64 string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.Base64URLEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); + * ``` + */ + public Base64URLEncode(data: Uint8Array): string { + return ""; + } + + + /** + * Base64URLDecode decodes URL-safe base64 string to bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const bytes = utils.Base64URLDecode('SGVsbG8'); + * ``` + */ + public Base64URLDecode(data: string): Uint8Array | null { + return null; + } + + + /** + * Base64RawEncode encodes bytes to base64 string without padding + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.Base64RawEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); + * ``` + */ + public Base64RawEncode(data: Uint8Array): string { + return ""; + } + + + /** + * Base64RawDecode decodes base64 string without padding to bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const bytes = utils.Base64RawDecode('SGVsbG8'); + * ``` + */ + public Base64RawDecode(data: string): Uint8Array | null { + return null; + } + + + /** + * Base64RawURLEncode encodes bytes to URL-safe base64 string without padding + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.Base64RawURLEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); + * ``` + */ + public Base64RawURLEncode(data: Uint8Array): string { + return ""; + } + + + /** + * Base64RawURLDecode decodes URL-safe base64 string without padding to bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const bytes = utils.Base64RawURLDecode('SGVsbG8'); + * ``` + */ + public Base64RawURLDecode(data: string): Uint8Array | null { + return null; + } + + + /** + * UTF16LEEncode encodes a string to UTF-16 Little Endian bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.UTF16LEEncode('hello'); + * ``` + */ + public UTF16LEEncode(data: string): Uint8Array { + return new Uint8Array(8); + } + + + /** + * UTF16LEDecode decodes UTF-16 Little Endian bytes to a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decoded = utils.UTF16LEDecode([0x68, 0x00, 0x65, 0x00]); + * ``` + */ + public UTF16LEDecode(data: Uint8Array): string { + return ""; + } + + + /** + * UTF16BEEncode encodes a string to UTF-16 Big Endian bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const encoded = utils.UTF16BEEncode('hello'); + * ``` + */ + public UTF16BEEncode(data: string): Uint8Array { + return new Uint8Array(8); + } + + + /** + * UTF16BEDecode decodes UTF-16 Big Endian bytes to a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const decoded = utils.UTF16BEDecode([0x00, 0x68, 0x00, 0x65]); + * ``` + */ + public UTF16BEDecode(data: Uint8Array): string { + return ""; + } + + + /** + * MD4 computes MD4 hash of data (needed for NTLM) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.MD4('password'); + * ``` + */ + public MD4(data: Uint8Array): string { + return ""; + } + + + /** + * MD4Raw computes MD4 hash of data and returns raw bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.MD4Raw('password'); + * ``` + */ + public MD4Raw(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * MD5 computes MD5 hash of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.MD5('password'); + * ``` + */ + public MD5(data: Uint8Array): string { + return ""; + } + + + /** + * MD5Raw computes MD5 hash of data and returns raw bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.MD5Raw('password'); + * ``` + */ + public MD5Raw(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * SHA1 computes SHA1 hash of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA1('password'); + * ``` + */ + public SHA1(data: Uint8Array): string { + return ""; + } + + + /** + * SHA1Raw computes SHA1 hash of data and returns raw bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA1Raw('password'); + * ``` + */ + public SHA1Raw(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * SHA256 computes SHA256 hash of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA256('password'); + * ``` + */ + public SHA256(data: Uint8Array): string { + return ""; + } + + + /** + * SHA256Raw computes SHA256 hash of data and returns raw bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA256Raw('password'); + * ``` + */ + public SHA256Raw(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * SHA384 computes SHA384 hash of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA384('password'); + * ``` + */ + public SHA384(data: Uint8Array): string { + return ""; + } + + + /** + * SHA384Raw computes SHA384 hash of data and returns raw bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA384Raw('password'); + * ``` + */ + public SHA384Raw(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * SHA512 computes SHA512 hash of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA512('password'); + * ``` + */ + public SHA512(data: Uint8Array): string { + return ""; + } + + + /** + * SHA512Raw computes SHA512 hash of data and returns raw bytes + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hash = utils.SHA512Raw('password'); + * ``` + */ + public SHA512Raw(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * HMACMD5 computes HMAC-MD5 of data with key + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hmac = utils.HMACMD5('message', 'key'); + * ``` + */ + public HMACMD5(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * HMACSHA1 computes HMAC-SHA1 of data with key + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hmac = utils.HMACSHA1('message', 'key'); + * ``` + */ + public HMACSHA1(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * HMACSHA256 computes HMAC-SHA256 of data with key + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hmac = utils.HMACSHA256('message', 'key'); + * ``` + */ + public HMACSHA256(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * HMACSHA512 computes HMAC-SHA512 of data with key + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const hmac = utils.HMACSHA512('message', 'key'); + * ``` + */ + public HMACSHA512(data: Uint8Array): Uint8Array { + return new Uint8Array(8); + } + + + /** + * CRC32 computes CRC32 checksum of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const checksum = utils.CRC32('data'); + * ``` + */ + public CRC32(data: Uint8Array): number { + return 0; + } + + + /** + * Adler32 computes Adler32 checksum of data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const checksum = utils.Adler32('data'); + * ``` + */ + public Adler32(data: Uint8Array): number { + return 0; + } + + + /** + * PKCS7Pad pads data to the specified block size using PKCS7 padding + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const padded = utils.PKCS7Pad([0x41, 0x42, 0x43], 16); + * ``` + */ + public PKCS7Pad(data: Uint8Array, blockSize: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PKCS7Unpad removes PKCS7 padding from data + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const unpadded = utils.PKCS7Unpad(padded); + * ``` + */ + public PKCS7Unpad(data: Uint8Array): Uint8Array | null { + return null; + } + + + /** + * ZeroPad pads data with zeros to the specified length + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const padded = utils.ZeroPad([0x41, 0x42], 8); + * ``` + */ + public ZeroPad(data: Uint8Array, length: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * NullPad pads data with null bytes to the specified length + * (same as ZeroPad, provided for clarity) + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const padded = utils.NullPad([0x41, 0x42], 8); + * ``` + */ + public NullPad(data: Uint8Array, length: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PadToBlockSize pads data to be a multiple of blockSize using zero padding + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const padded = utils.PadToBlockSize([0x41, 0x42, 0x43], 8); + * ``` + */ + public PadToBlockSize(data: Uint8Array, blockSize: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint8 packs a uint8 value into a byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint8(255); + * ``` + */ + public PackUint8(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint16LE packs a uint16 value into a little-endian byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint16LE(0x1234); // returns [0x34, 0x12] + * ``` + */ + public PackUint16LE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint16BE packs a uint16 value into a big-endian byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint16BE(0x1234); // returns [0x12, 0x34] + * ``` + */ + public PackUint16BE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint32LE packs a uint32 value into a little-endian byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint32LE(0x12345678); // returns [0x78, 0x56, 0x34, 0x12] + * ``` + */ + public PackUint32LE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint32BE packs a uint32 value into a big-endian byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint32BE(0x12345678); // returns [0x12, 0x34, 0x56, 0x78] + * ``` + */ + public PackUint32BE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint64LE packs a uint64 value into a little-endian byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint64LE(0x123456789ABCDEF0); + * ``` + */ + public PackUint64LE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * PackUint64BE packs a uint64 value into a big-endian byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const packed = u.PackUint64BE(0x123456789ABCDEF0); + * ``` + */ + public PackUint64BE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * UnpackUint16LE unpacks a little-endian uint16 from bytes at the given offset + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const value = u.UnpackUint16LE([0x34, 0x12, 0x00, 0x00], 0); // returns 0x1234 + * ``` + */ + public UnpackUint16LE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * UnpackUint16BE unpacks a big-endian uint16 from bytes at the given offset + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const value = u.UnpackUint16BE([0x12, 0x34, 0x00, 0x00], 0); // returns 0x1234 + * ``` + */ + public UnpackUint16BE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * UnpackUint32LE unpacks a little-endian uint32 from bytes at the given offset + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const value = u.UnpackUint32LE([0x78, 0x56, 0x34, 0x12], 0); // returns 0x12345678 + * ``` + */ + public UnpackUint32LE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * UnpackUint32BE unpacks a big-endian uint32 from bytes at the given offset + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const value = u.UnpackUint32BE([0x12, 0x34, 0x56, 0x78], 0); // returns 0x12345678 + * ``` + */ + public UnpackUint32BE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * UnpackUint64LE unpacks a little-endian uint64 from bytes at the given offset + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const value = u.UnpackUint64LE(bytes, 0); + * ``` + */ + public UnpackUint64LE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * UnpackUint64BE unpacks a big-endian uint64 from bytes at the given offset + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const value = u.UnpackUint64BE(bytes, 0); + * ``` + */ + public UnpackUint64BE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * ConcatBytes concatenates multiple byte slices into one + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const result = u.ConcatBytes([0x01, 0x02], [0x03, 0x04], [0x05]); + * ``` + */ + public ConcatBytes(arrays: any): Uint8Array { + return new Uint8Array(8); + } + + + /** + * StringToBytes converts a string to a byte slice + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const bytes = u.StringToBytes('hello'); + * ``` + */ + public StringToBytes(s: string): Uint8Array { + return new Uint8Array(8); + } + + + /** + * BytesToString converts a byte slice to a string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const str = u.BytesToString([0x68, 0x65, 0x6c, 0x6c, 0x6f]); + * ``` + */ + public BytesToString(data: Uint8Array): string { + return ""; + } + + + /** + * ToBytes converts various input types to a byte slice + * Handles: []byte, []interface{} (with numeric values), string + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const bytes = u.ToBytes([0x41, 0x42, 0x43]); + * ``` + */ + public ToBytes(data: any): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P8 packs a uint8 value (pwntools-style alias for PackUint8) + */ + public P8(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P16 packs a uint16 value as little-endian (pwntools-style alias) + */ + public P16(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P16BE packs a uint16 value as big-endian + */ + public P16BE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P32 packs a uint32 value as little-endian (pwntools-style alias) + */ + public P32(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P32BE packs a uint32 value as big-endian + */ + public P32BE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P64 packs a uint64 value as little-endian (pwntools-style alias) + */ + public P64(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * P64BE packs a uint64 value as big-endian + */ + public P64BE(value: number): Uint8Array { + return new Uint8Array(8); + } + + + /** + * U16 unpacks a little-endian uint16 (pwntools-style alias) + */ + public U16(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * U16BE unpacks a big-endian uint16 + */ + public U16BE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * U32 unpacks a little-endian uint32 (pwntools-style alias) + */ + public U32(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * U32BE unpacks a big-endian uint32 + */ + public U32BE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * U64 unpacks a little-endian uint64 (pwntools-style alias) + */ + public U64(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * U64BE unpacks a big-endian uint64 + */ + public U64BE(data: Uint8Array, offset: number): number { + return 0; + } + + + /** + * Flat combines multiple items into a single byte slice + * Accepts: []byte, string, int (single byte), []interface{}, or any Pack result + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const u = new utils.Utils(); + * const payload = u.Flat(u.P32(0x41414141), "AAAA", [0x00, 0x01], 0x42); + * ``` + */ + public Flat(items: any): Uint8Array { + return new Uint8Array(8); + } + + + /** + * Sleep pauses execution for the specified number of milliseconds + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * utils.Sleep(1000); // sleep for 1 second + * ``` + */ + public Sleep(milliseconds: number): void { + return; + } + + + /** + * UnixTimestamp returns the current Unix timestamp in seconds + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const ts = utils.UnixTimestamp(); + * ``` + */ + public UnixTimestamp(): number { + return 0; + } + + + /** + * UnixTimestampMilli returns the current Unix timestamp in milliseconds + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const ts = utils.UnixTimestampMilli(); + * ``` + */ + public UnixTimestampMilli(): number { + return 0; + } + + + /** + * UnixTimestampNano returns the current Unix timestamp in nanoseconds + * @example + * ```javascript + * const utils = require('nuclei/utils'); + * const ts = utils.UnixTimestampNano(); + * ``` + */ + public UnixTimestampNano(): number { + return 0; + } + + +} + diff --git a/pkg/js/generated/ts/vnc.ts b/pkg/js/generated/ts/vnc.ts index f74edb8946..fee7876ab5 100755 --- a/pkg/js/generated/ts/vnc.ts +++ b/pkg/js/generated/ts/vnc.ts @@ -11,34 +11,20 @@ * log(toJSON(isVNC)); * ``` */ -export function IsVNC(host: string, port: number): IsVNCResponse | null { +export function IsVNC(ctx: any, host: string, port: number): IsVNCResponse | null { return null; } -/** - * IsVNCResponse is the response from the IsVNC function. - * @example - * ```javascript - * const vnc = require('nuclei/vnc'); - * const isVNC = vnc.IsVNC('acme.com', 5900); - * log(toJSON(isVNC)); - * ``` - */ -export interface IsVNCResponse { - - IsVNC?: boolean, - - Banner?: string, -} - /** * VNCClient is a client for VNC servers. * @example * ```javascript * const vnc = require('nuclei/vnc'); * const client = new vnc.VNCClient(); + * const connected = client.Connect('acme.com', 5900, 'password'); + * log(toJSON(connected)); * ``` */ export class VNCClient { @@ -46,7 +32,6 @@ export class VNCClient { // Constructor of VNCClient constructor() {} - /** * Connect connects to VNC server using given password. * If connection and authentication is successful, it returns true. @@ -59,8 +44,28 @@ export class VNCClient { * const connected = client.Connect('acme.com', 5900, 'password'); * ``` */ - public Connect(host: string, port: number, password: string): boolean | null { + public Connect(ctx: any, host: string, port: number, password: string): boolean | null { return null; } + + +} + + + +/** + * IsVNCResponse is the response from the IsVNC function. + * @example + * ```javascript + * const vnc = require('nuclei/vnc'); + * const isVNC = vnc.IsVNC('acme.com', 5900); + * log(toJSON(isVNC)); + * ``` + */ +export interface IsVNCResponse { + + IsVNC?: boolean, + + Banner?: string, } diff --git a/pkg/js/libs/net/net.go b/pkg/js/libs/net/net.go index ad1eaadd39..7778dd07ec 100644 --- a/pkg/js/libs/net/net.go +++ b/pkg/js/libs/net/net.go @@ -301,3 +301,115 @@ func (c *NetConn) RecvHex(N int) (string, error) { } return hex.Dump(bin), nil } + +// SendBytes sends raw bytes to the connection (accepts []byte from JS) +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.SendBytes([0x48, 0x45, 0x4c, 0x4c, 0x4f]); +// ``` +func (c *NetConn) SendBytes(data []byte) error { + c.setDeadLine() + defer c.unsetDeadLine() + length, err := c.conn.Write(data) + if err != nil { + return err + } + if length < len(data) { + return fmt.Errorf("failed to write all bytes (%d bytes written, %d bytes expected)", length, len(data)) + } + return nil +} + +// SendLine sends data with a newline appended +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// conn.SendLine('GET / HTTP/1.1'); +// ``` +func (c *NetConn) SendLine(data string) error { + return c.Send(data + "\n") +} + +// RecvUntil receives data until the delimiter is found +// Returns all data including the delimiter +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const data = conn.RecvUntil('\r\n\r\n'); +// ``` +func (c *NetConn) RecvUntil(delim []byte) ([]byte, error) { + c.setDeadLine() + defer c.unsetDeadLine() + var result []byte + buf := make([]byte, 1) + for { + n, err := c.conn.Read(buf) + if err != nil { + if len(result) > 0 { + return result, nil + } + return nil, err + } + if n > 0 { + result = append(result, buf[0]) + if len(result) >= len(delim) { + if bytesEqual(result[len(result)-len(delim):], delim) { + return result, nil + } + } + } + } +} + +// RecvUntilString receives data until the delimiter string is found +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const data = conn.RecvUntilString('\r\n\r\n'); +// ``` +func (c *NetConn) RecvUntilString(delim string) (string, error) { + data, err := c.RecvUntil([]byte(delim)) + if err != nil { + return "", err + } + return string(data), nil +} + +// RecvLine receives data until a newline is found +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const line = conn.RecvLine(); +// ``` +func (c *NetConn) RecvLine() (string, error) { + return c.RecvUntilString("\n") +} + +// RecvN receives exactly N bytes (alias for RecvFull) +// @example +// ```javascript +// const net = require('nuclei/net'); +// const conn = net.Open('tcp', 'acme.com:80'); +// const header = conn.RecvN(16); +// ``` +func (c *NetConn) RecvN(n int) ([]byte, error) { + return c.RecvFull(n) +} + +func bytesEqual(a, b []byte) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} diff --git a/pkg/js/libs/utils/binary.go b/pkg/js/libs/utils/binary.go new file mode 100644 index 0000000000..a8b732f12e --- /dev/null +++ b/pkg/js/libs/utils/binary.go @@ -0,0 +1,245 @@ +package utils + +import ( + "bytes" + "crypto/rand" + "math/big" + "strings" +) + +const alphanumCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + +// PatternCreate creates a cyclic pattern of specified length for buffer overflow analysis +// The pattern is designed to have unique 4-byte sequences for easy offset identification +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const pattern = utils.PatternCreate(1000); +// ``` +func (u *Utils) PatternCreate(length int) []byte { + if length <= 0 { + return []byte{} + } + pattern := make([]byte, length) + idx := 0 + for i := 0; i < 26 && idx < length; i++ { + for j := 0; j < 26 && idx < length; j++ { + for k := 0; k < 10 && idx < length; k++ { + pattern[idx] = byte('A' + i) + idx++ + if idx < length { + pattern[idx] = byte('a' + j) + idx++ + } + if idx < length { + pattern[idx] = byte('0' + k) + idx++ + } + } + } + } + return pattern +} + +// PatternOffset finds the offset of a 4-byte pattern within a cyclic pattern +// Returns -1 if pattern is not found +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const pattern = utils.PatternCreate(1000); +// const offset = utils.PatternOffset(pattern, ToBytes('Aa0A')); +// ``` +func (u *Utils) PatternOffset(pattern, search []byte) int { + return bytes.Index(pattern, search) +} + +// FindBytes finds the first occurrence of needle in haystack +// Returns -1 if not found +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const idx = utils.FindBytes([0x41, 0x42, 0x43, 0x44], [0x42, 0x43]); +// ``` +func (u *Utils) FindBytes(haystack, needle []byte) int { + return bytes.Index(haystack, needle) +} + +// FindAllBytes finds all occurrences of needle in haystack +// Returns array of indices +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const indices = utils.FindAllBytes([0x41, 0x42, 0x41, 0x42], [0x41, 0x42]); +// ``` +func (u *Utils) FindAllBytes(haystack, needle []byte) []int { + if len(needle) == 0 { + return []int{} + } + var indices []int + start := 0 + for { + idx := bytes.Index(haystack[start:], needle) + if idx == -1 { + break + } + indices = append(indices, start+idx) + start += idx + 1 + } + return indices +} + +// ReplaceBytes replaces all occurrences of old with new in data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const result = utils.ReplaceBytes([0x41, 0x42, 0x43], [0x42], [0x44, 0x45]); +// ``` +func (u *Utils) ReplaceBytes(data, old, new []byte) []byte { + return bytes.ReplaceAll(data, old, new) +} + +// RepeatBytes repeats data count times +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const repeated = utils.RepeatBytes([0x41, 0x42], 3); +// ``` +func (u *Utils) RepeatBytes(data []byte, count int) []byte { + return bytes.Repeat(data, count) +} + +// ReverseBytes reverses a byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const reversed = utils.ReverseBytes([0x41, 0x42, 0x43]); +// ``` +func (u *Utils) ReverseBytes(data []byte) []byte { + result := make([]byte, len(data)) + for i, j := 0, len(data)-1; j >= 0; i, j = i+1, j-1 { + result[i] = data[j] + } + return result +} + +// SwapEndian16 swaps endianness of 16-bit values in data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const swapped = utils.SwapEndian16([0x01, 0x02, 0x03, 0x04]); +// ``` +func (u *Utils) SwapEndian16(data []byte) []byte { + result := make([]byte, len(data)) + copy(result, data) + for i := 0; i+1 < len(result); i += 2 { + result[i], result[i+1] = result[i+1], result[i] + } + return result +} + +// SwapEndian32 swaps endianness of 32-bit values in data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const swapped = utils.SwapEndian32([0x01, 0x02, 0x03, 0x04]); +// ``` +func (u *Utils) SwapEndian32(data []byte) []byte { + result := make([]byte, len(data)) + copy(result, data) + for i := 0; i+3 < len(result); i += 4 { + result[i], result[i+1], result[i+2], result[i+3] = result[i+3], result[i+2], result[i+1], result[i] + } + return result +} + +// GenerateRandomString generates a random string of specified length +// using alphanumeric characters +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const str = utils.GenerateRandomString(16); +// ``` +func (u *Utils) GenerateRandomString(length int) string { + b := make([]byte, length) + charsetLen := big.NewInt(int64(len(alphanumCharset))) + for i := range b { + idx, err := rand.Int(rand.Reader, charsetLen) + if err != nil { + b[i] = alphanumCharset[0] + continue + } + b[i] = alphanumCharset[idx.Int64()] + } + return string(b) +} + +// GenerateRandomAlphanumeric generates a random alphanumeric string +// (alias for GenerateRandomString) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const str = utils.GenerateRandomAlphanumeric(16); +// ``` +func (u *Utils) GenerateRandomAlphanumeric(length int) string { + return u.GenerateRandomString(length) +} + +// GenerateRandomBytes generates random bytes of specified length +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const bytes = utils.GenerateRandomBytes(16); +// ``` +func (u *Utils) GenerateRandomBytes(length int) []byte { + b := make([]byte, length) + _, _ = rand.Read(b) + return b +} + +// RepeatString repeats a string count times +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const repeated = utils.RepeatString('A', 100); +// ``` +func (u *Utils) RepeatString(s string, count int) string { + return strings.Repeat(s, count) +} + +// PadLeft pads string on the left to specified length +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const padded = utils.PadLeft('123', 8, '0'); +// ``` +func (u *Utils) PadLeft(s string, length int, pad string) string { + if len(s) >= length { + return s + } + if pad == "" { + pad = " " + } + for len(s) < length { + s = pad + s + } + return s[len(s)-length:] +} + +// PadRight pads string on the right to specified length +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const padded = utils.PadRight('123', 8, '0'); +// ``` +func (u *Utils) PadRight(s string, length int, pad string) string { + if len(s) >= length { + return s + } + if pad == "" { + pad = " " + } + for len(s) < length { + s = s + pad + } + return s[:length] +} diff --git a/pkg/js/libs/utils/compression.go b/pkg/js/libs/utils/compression.go new file mode 100644 index 0000000000..854dcb517e --- /dev/null +++ b/pkg/js/libs/utils/compression.go @@ -0,0 +1,132 @@ +package utils + +import ( + "bytes" + "compress/flate" + "compress/gzip" + "compress/zlib" + "io" +) + +// ZlibCompress compresses data using zlib +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const compressed = utils.ZlibCompress('hello world'); +// ``` +func (u *Utils) ZlibCompress(data []byte) ([]byte, error) { + var buf bytes.Buffer + w := zlib.NewWriter(&buf) + _, err := w.Write(data) + if err != nil { + return nil, err + } + if err := w.Close(); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// ZlibDecompress decompresses zlib compressed data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decompressed = utils.ZlibDecompress(compressed); +// ``` +func (u *Utils) ZlibDecompress(data []byte) ([]byte, error) { + r, err := zlib.NewReader(bytes.NewReader(data)) + if err != nil { + return nil, err + } + result, err := io.ReadAll(r) + cerr := r.Close() + if err != nil { + return nil, err + } + if cerr != nil { + return nil, cerr + } + return result, nil +} + +// GzipCompress compresses data using gzip +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const compressed = utils.GzipCompress('hello world'); +// ``` +func (u *Utils) GzipCompress(data []byte) ([]byte, error) { + var buf bytes.Buffer + w := gzip.NewWriter(&buf) + _, err := w.Write(data) + if err != nil { + return nil, err + } + if err := w.Close(); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// GzipDecompress decompresses gzip compressed data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decompressed = utils.GzipDecompress(compressed); +// ``` +func (u *Utils) GzipDecompress(data []byte) ([]byte, error) { + r, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + return nil, err + } + result, err := io.ReadAll(r) + cerr := r.Close() + if err != nil { + return nil, err + } + if cerr != nil { + return nil, cerr + } + return result, nil +} + +// DeflateCompress compresses data using raw deflate (no zlib header) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const compressed = utils.DeflateCompress('hello world'); +// ``` +func (u *Utils) DeflateCompress(data []byte) ([]byte, error) { + var buf bytes.Buffer + w, err := flate.NewWriter(&buf, flate.DefaultCompression) + if err != nil { + return nil, err + } + _, err = w.Write(data) + if err != nil { + return nil, err + } + if err := w.Close(); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// DeflateDecompress decompresses raw deflate compressed data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decompressed = utils.DeflateDecompress(compressed); +// ``` +func (u *Utils) DeflateDecompress(data []byte) ([]byte, error) { + r := flate.NewReader(bytes.NewReader(data)) + result, err := io.ReadAll(r) + cerr := r.Close() + if err != nil { + return nil, err + } + if cerr != nil { + return nil, cerr + } + return result, nil +} diff --git a/pkg/js/libs/utils/crypto.go b/pkg/js/libs/utils/crypto.go new file mode 100644 index 0000000000..ebaefe7c6b --- /dev/null +++ b/pkg/js/libs/utils/crypto.go @@ -0,0 +1,285 @@ +package utils + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/des" + "crypto/rc4" + "errors" + "fmt" +) + +// AESEncryptECB encrypts data using AES in ECB mode +// Key must be 16, 24, or 32 bytes for AES-128, AES-192, AES-256 +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const key = Rand(16); +// const encrypted = utils.AESEncryptECB(ToBytes('plaintext'), key); +// ``` +func (u *Utils) AESEncryptECB(plaintext, key []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + plaintext = pkcs7Pad(plaintext, aes.BlockSize) + ciphertext := make([]byte, len(plaintext)) + for i := 0; i < len(plaintext); i += aes.BlockSize { + block.Encrypt(ciphertext[i:], plaintext[i:]) + } + return ciphertext, nil +} + +// AESDecryptECB decrypts data using AES in ECB mode +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decrypted = utils.AESDecryptECB(encrypted, key); +// ``` +func (u *Utils) AESDecryptECB(ciphertext, key []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(ciphertext)%aes.BlockSize != 0 { + return nil, errors.New("ciphertext is not a multiple of the block size") + } + plaintext := make([]byte, len(ciphertext)) + for i := 0; i < len(ciphertext); i += aes.BlockSize { + block.Decrypt(plaintext[i:], ciphertext[i:]) + } + return pkcs7Unpad(plaintext) +} + +// AESEncryptCBC encrypts data using AES in CBC mode +// Key must be 16, 24, or 32 bytes. IV must be 16 bytes. +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const key = Rand(16); +// const iv = Rand(16); +// const encrypted = utils.AESEncryptCBC(ToBytes('plaintext'), key, iv); +// ``` +func (u *Utils) AESEncryptCBC(plaintext, key, iv []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(iv) != aes.BlockSize { + return nil, errors.New("IV must be 16 bytes") + } + plaintext = pkcs7Pad(plaintext, aes.BlockSize) + ciphertext := make([]byte, len(plaintext)) + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext, plaintext) + return ciphertext, nil +} + +// AESDecryptCBC decrypts data using AES in CBC mode +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decrypted = utils.AESDecryptCBC(encrypted, key, iv); +// ``` +func (u *Utils) AESDecryptCBC(ciphertext, key, iv []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(iv) != aes.BlockSize { + return nil, errors.New("IV must be 16 bytes") + } + if len(ciphertext)%aes.BlockSize != 0 { + return nil, errors.New("ciphertext is not a multiple of the block size") + } + plaintext := make([]byte, len(ciphertext)) + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(plaintext, ciphertext) + return pkcs7Unpad(plaintext) +} + +// AESEncryptGCM encrypts data using AES in GCM mode +// Key must be 16, 24, or 32 bytes. Nonce should be 12 bytes. +// Returns ciphertext with authentication tag appended. +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const key = Rand(16); +// const nonce = Rand(12); +// const encrypted = utils.AESEncryptGCM(ToBytes('plaintext'), key, nonce); +// ``` +func (u *Utils) AESEncryptGCM(plaintext, key, nonce []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + if len(nonce) != gcm.NonceSize() { + return nil, fmt.Errorf("invalid nonce length: got %d, want %d", len(nonce), gcm.NonceSize()) + } + ciphertext := gcm.Seal(nil, nonce, plaintext, nil) + return ciphertext, nil +} + +// AESDecryptGCM decrypts data using AES in GCM mode +// Expects ciphertext with authentication tag appended. +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decrypted = utils.AESDecryptGCM(encrypted, key, nonce); +// ``` +func (u *Utils) AESDecryptGCM(ciphertext, key, nonce []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + if len(nonce) != gcm.NonceSize() { + return nil, fmt.Errorf("invalid nonce length: got %d, want %d", len(nonce), gcm.NonceSize()) + } + return gcm.Open(nil, nonce, ciphertext, nil) +} + +// DESEncryptECB encrypts data using DES in ECB mode +// Key must be 8 bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const key = Rand(8); +// const encrypted = utils.DESEncryptECB(ToBytes('plaintext'), key); +// ``` +func (u *Utils) DESEncryptECB(plaintext, key []byte) ([]byte, error) { + block, err := des.NewCipher(key) + if err != nil { + return nil, err + } + plaintext = pkcs7Pad(plaintext, des.BlockSize) + ciphertext := make([]byte, len(plaintext)) + for i := 0; i < len(plaintext); i += des.BlockSize { + block.Encrypt(ciphertext[i:], plaintext[i:]) + } + return ciphertext, nil +} + +// DESDecryptECB decrypts data using DES in ECB mode +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decrypted = utils.DESDecryptECB(encrypted, key); +// ``` +func (u *Utils) DESDecryptECB(ciphertext, key []byte) ([]byte, error) { + block, err := des.NewCipher(key) + if err != nil { + return nil, err + } + if len(ciphertext)%des.BlockSize != 0 { + return nil, errors.New("ciphertext is not a multiple of the block size") + } + plaintext := make([]byte, len(ciphertext)) + for i := 0; i < len(ciphertext); i += des.BlockSize { + block.Decrypt(plaintext[i:], ciphertext[i:]) + } + return pkcs7Unpad(plaintext) +} + +// DES3EncryptCBC encrypts data using Triple DES in CBC mode +// Key must be 24 bytes. IV must be 8 bytes. +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const key = Rand(24); +// const iv = Rand(8); +// const encrypted = utils.DES3EncryptCBC(ToBytes('plaintext'), key, iv); +// ``` +func (u *Utils) DES3EncryptCBC(plaintext, key, iv []byte) ([]byte, error) { + block, err := des.NewTripleDESCipher(key) + if err != nil { + return nil, err + } + if len(iv) != des.BlockSize { + return nil, errors.New("IV must be 8 bytes") + } + plaintext = pkcs7Pad(plaintext, des.BlockSize) + ciphertext := make([]byte, len(plaintext)) + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext, plaintext) + return ciphertext, nil +} + +// DES3DecryptCBC decrypts data using Triple DES in CBC mode +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decrypted = utils.DES3DecryptCBC(encrypted, key, iv); +// ``` +func (u *Utils) DES3DecryptCBC(ciphertext, key, iv []byte) ([]byte, error) { + block, err := des.NewTripleDESCipher(key) + if err != nil { + return nil, err + } + if len(iv) != des.BlockSize { + return nil, errors.New("IV must be 8 bytes") + } + if len(ciphertext)%des.BlockSize != 0 { + return nil, errors.New("ciphertext is not a multiple of the block size") + } + plaintext := make([]byte, len(ciphertext)) + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(plaintext, ciphertext) + return pkcs7Unpad(plaintext) +} + +// RC4Encrypt encrypts/decrypts data using RC4 (symmetric) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const key = Rand(16); +// const encrypted = utils.RC4Encrypt(ToBytes('plaintext'), key); +// const decrypted = utils.RC4Encrypt(encrypted, key); // RC4 is symmetric +// ``` +func (u *Utils) RC4Encrypt(data, key []byte) ([]byte, error) { + c, err := rc4.NewCipher(key) + if err != nil { + return nil, err + } + result := make([]byte, len(data)) + c.XORKeyStream(result, data) + return result, nil +} + +// XORBytes XORs data with a repeating key +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const xored = utils.XORBytes([0x41, 0x42, 0x43], [0x01, 0x02]); +// ``` +func (u *Utils) XORBytes(data, key []byte) []byte { + if len(key) == 0 { + return data + } + result := make([]byte, len(data)) + for i := range data { + result[i] = data[i] ^ key[i%len(key)] + } + return result +} + +// XORSingleByte XORs each byte of data with a single byte key +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const xored = utils.XORSingleByte([0x41, 0x42, 0x43], 0x01); +// ``` +func (u *Utils) XORSingleByte(data []byte, key byte) []byte { + result := make([]byte, len(data)) + for i := range data { + result[i] = data[i] ^ key + } + return result +} diff --git a/pkg/js/libs/utils/encoding.go b/pkg/js/libs/utils/encoding.go new file mode 100644 index 0000000000..f4acf588f6 --- /dev/null +++ b/pkg/js/libs/utils/encoding.go @@ -0,0 +1,217 @@ +package utils + +import ( + "encoding/base64" + "encoding/hex" + "html" + "net/url" + "unicode/utf16" +) + +// URLEncode URL encodes a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.URLEncode('hello world'); +// ``` +func (u *Utils) URLEncode(data string) string { + return url.QueryEscape(data) +} + +// URLDecode URL decodes a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decoded = utils.URLDecode('hello%20world'); +// ``` +func (u *Utils) URLDecode(data string) (string, error) { + return url.QueryUnescape(data) +} + +// HTMLEncode HTML encodes a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.HTMLEncode(''); +// ``` +func (u *Utils) HTMLEncode(data string) string { + return html.EscapeString(data) +} + +// HTMLDecode HTML decodes a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decoded = utils.HTMLDecode('<script>'); +// ``` +func (u *Utils) HTMLDecode(data string) string { + return html.UnescapeString(data) +} + +// HexEncode encodes bytes to hex string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hex = utils.HexEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); +// ``` +func (u *Utils) HexEncode(data []byte) string { + return hex.EncodeToString(data) +} + +// HexDecode decodes hex string to bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const bytes = utils.HexDecode('48656c6c6f'); +// ``` +func (u *Utils) HexDecode(data string) ([]byte, error) { + return hex.DecodeString(data) +} + +// Base64Encode encodes bytes to base64 string (standard encoding) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.Base64Encode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); +// ``` +func (u *Utils) Base64Encode(data []byte) string { + return base64.StdEncoding.EncodeToString(data) +} + +// Base64Decode decodes base64 string to bytes (standard encoding) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const bytes = utils.Base64Decode('SGVsbG8='); +// ``` +func (u *Utils) Base64Decode(data string) ([]byte, error) { + return base64.StdEncoding.DecodeString(data) +} + +// Base64URLEncode encodes bytes to URL-safe base64 string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.Base64URLEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); +// ``` +func (u *Utils) Base64URLEncode(data []byte) string { + return base64.URLEncoding.EncodeToString(data) +} + +// Base64URLDecode decodes URL-safe base64 string to bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const bytes = utils.Base64URLDecode('SGVsbG8'); +// ``` +func (u *Utils) Base64URLDecode(data string) ([]byte, error) { + return base64.URLEncoding.DecodeString(data) +} + +// Base64RawEncode encodes bytes to base64 string without padding +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.Base64RawEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); +// ``` +func (u *Utils) Base64RawEncode(data []byte) string { + return base64.RawStdEncoding.EncodeToString(data) +} + +// Base64RawDecode decodes base64 string without padding to bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const bytes = utils.Base64RawDecode('SGVsbG8'); +// ``` +func (u *Utils) Base64RawDecode(data string) ([]byte, error) { + return base64.RawStdEncoding.DecodeString(data) +} + +// Base64RawURLEncode encodes bytes to URL-safe base64 string without padding +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.Base64RawURLEncode([0x48, 0x65, 0x6c, 0x6c, 0x6f]); +// ``` +func (u *Utils) Base64RawURLEncode(data []byte) string { + return base64.RawURLEncoding.EncodeToString(data) +} + +// Base64RawURLDecode decodes URL-safe base64 string without padding to bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const bytes = utils.Base64RawURLDecode('SGVsbG8'); +// ``` +func (u *Utils) Base64RawURLDecode(data string) ([]byte, error) { + return base64.RawURLEncoding.DecodeString(data) +} + +// UTF16LEEncode encodes a string to UTF-16 Little Endian bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.UTF16LEEncode('hello'); +// ``` +func (u *Utils) UTF16LEEncode(data string) []byte { + runes := []rune(data) + u16 := utf16.Encode(runes) + result := make([]byte, len(u16)*2) + for i, r := range u16 { + result[i*2] = byte(r) + result[i*2+1] = byte(r >> 8) + } + return result +} + +// UTF16LEDecode decodes UTF-16 Little Endian bytes to a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decoded = utils.UTF16LEDecode([0x68, 0x00, 0x65, 0x00]); +// ``` +func (u *Utils) UTF16LEDecode(data []byte) string { + if len(data)%2 != 0 { + data = append(data, 0) + } + u16 := make([]uint16, len(data)/2) + for i := 0; i < len(u16); i++ { + u16[i] = uint16(data[i*2]) | uint16(data[i*2+1])<<8 + } + return string(utf16.Decode(u16)) +} + +// UTF16BEEncode encodes a string to UTF-16 Big Endian bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const encoded = utils.UTF16BEEncode('hello'); +// ``` +func (u *Utils) UTF16BEEncode(data string) []byte { + runes := []rune(data) + u16 := utf16.Encode(runes) + result := make([]byte, len(u16)*2) + for i, r := range u16 { + result[i*2] = byte(r >> 8) + result[i*2+1] = byte(r) + } + return result +} + +// UTF16BEDecode decodes UTF-16 Big Endian bytes to a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const decoded = utils.UTF16BEDecode([0x00, 0x68, 0x00, 0x65]); +// ``` +func (u *Utils) UTF16BEDecode(data []byte) string { + if len(data)%2 != 0 { + data = append(data, 0) + } + u16 := make([]uint16, len(data)/2) + for i := 0; i < len(u16); i++ { + u16[i] = uint16(data[i*2])<<8 | uint16(data[i*2+1]) + } + return string(utf16.Decode(u16)) +} diff --git a/pkg/js/libs/utils/hash.go b/pkg/js/libs/utils/hash.go new file mode 100644 index 0000000000..52ec06ee46 --- /dev/null +++ b/pkg/js/libs/utils/hash.go @@ -0,0 +1,217 @@ +package utils + +import ( + "crypto/hmac" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "hash/adler32" + "hash/crc32" + + //nolint:staticcheck // SA1019: MD4 is deprecated but required for NTLM compatibility + "golang.org/x/crypto/md4" +) + +// MD4 computes MD4 hash of data (needed for NTLM) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.MD4('password'); +// ``` +func (u *Utils) MD4(data []byte) string { + h := md4.New() + h.Write(data) + return hex.EncodeToString(h.Sum(nil)) +} + +// MD4Raw computes MD4 hash of data and returns raw bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.MD4Raw('password'); +// ``` +func (u *Utils) MD4Raw(data []byte) []byte { + h := md4.New() + h.Write(data) + return h.Sum(nil) +} + +// MD5 computes MD5 hash of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.MD5('password'); +// ``` +func (u *Utils) MD5(data []byte) string { + h := md5.Sum(data) + return hex.EncodeToString(h[:]) +} + +// MD5Raw computes MD5 hash of data and returns raw bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.MD5Raw('password'); +// ``` +func (u *Utils) MD5Raw(data []byte) []byte { + h := md5.Sum(data) + return h[:] +} + +// SHA1 computes SHA1 hash of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA1('password'); +// ``` +func (u *Utils) SHA1(data []byte) string { + h := sha1.Sum(data) + return hex.EncodeToString(h[:]) +} + +// SHA1Raw computes SHA1 hash of data and returns raw bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA1Raw('password'); +// ``` +func (u *Utils) SHA1Raw(data []byte) []byte { + h := sha1.Sum(data) + return h[:] +} + +// SHA256 computes SHA256 hash of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA256('password'); +// ``` +func (u *Utils) SHA256(data []byte) string { + h := sha256.Sum256(data) + return hex.EncodeToString(h[:]) +} + +// SHA256Raw computes SHA256 hash of data and returns raw bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA256Raw('password'); +// ``` +func (u *Utils) SHA256Raw(data []byte) []byte { + h := sha256.Sum256(data) + return h[:] +} + +// SHA384 computes SHA384 hash of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA384('password'); +// ``` +func (u *Utils) SHA384(data []byte) string { + h := sha512.Sum384(data) + return hex.EncodeToString(h[:]) +} + +// SHA384Raw computes SHA384 hash of data and returns raw bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA384Raw('password'); +// ``` +func (u *Utils) SHA384Raw(data []byte) []byte { + h := sha512.Sum384(data) + return h[:] +} + +// SHA512 computes SHA512 hash of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA512('password'); +// ``` +func (u *Utils) SHA512(data []byte) string { + h := sha512.Sum512(data) + return hex.EncodeToString(h[:]) +} + +// SHA512Raw computes SHA512 hash of data and returns raw bytes +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hash = utils.SHA512Raw('password'); +// ``` +func (u *Utils) SHA512Raw(data []byte) []byte { + h := sha512.Sum512(data) + return h[:] +} + +// HMACMD5 computes HMAC-MD5 of data with key +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hmac = utils.HMACMD5('message', 'key'); +// ``` +func (u *Utils) HMACMD5(data, key []byte) []byte { + h := hmac.New(md5.New, key) + h.Write(data) + return h.Sum(nil) +} + +// HMACSHA1 computes HMAC-SHA1 of data with key +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hmac = utils.HMACSHA1('message', 'key'); +// ``` +func (u *Utils) HMACSHA1(data, key []byte) []byte { + h := hmac.New(sha1.New, key) + h.Write(data) + return h.Sum(nil) +} + +// HMACSHA256 computes HMAC-SHA256 of data with key +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hmac = utils.HMACSHA256('message', 'key'); +// ``` +func (u *Utils) HMACSHA256(data, key []byte) []byte { + h := hmac.New(sha256.New, key) + h.Write(data) + return h.Sum(nil) +} + +// HMACSHA512 computes HMAC-SHA512 of data with key +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const hmac = utils.HMACSHA512('message', 'key'); +// ``` +func (u *Utils) HMACSHA512(data, key []byte) []byte { + h := hmac.New(sha512.New, key) + h.Write(data) + return h.Sum(nil) +} + +// CRC32 computes CRC32 checksum of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const checksum = utils.CRC32('data'); +// ``` +func (u *Utils) CRC32(data []byte) uint32 { + return crc32.ChecksumIEEE(data) +} + +// Adler32 computes Adler32 checksum of data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const checksum = utils.Adler32('data'); +// ``` +func (u *Utils) Adler32(data []byte) uint32 { + return adler32.Checksum(data) +} diff --git a/pkg/js/libs/utils/padding.go b/pkg/js/libs/utils/padding.go new file mode 100644 index 0000000000..eda381148e --- /dev/null +++ b/pkg/js/libs/utils/padding.go @@ -0,0 +1,98 @@ +package utils + +import ( + "bytes" + "errors" +) + +// PKCS7Pad pads data to the specified block size using PKCS7 padding +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const padded = utils.PKCS7Pad([0x41, 0x42, 0x43], 16); +// ``` +func (u *Utils) PKCS7Pad(data []byte, blockSize int) []byte { + if blockSize <= 0 || blockSize > 255 { + return data + } + return pkcs7Pad(data, blockSize) +} + +// PKCS7Unpad removes PKCS7 padding from data +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const unpadded = utils.PKCS7Unpad(padded); +// ``` +func (u *Utils) PKCS7Unpad(data []byte) ([]byte, error) { + return pkcs7Unpad(data) +} + +// ZeroPad pads data with zeros to the specified length +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const padded = utils.ZeroPad([0x41, 0x42], 8); +// ``` +func (u *Utils) ZeroPad(data []byte, length int) []byte { + if len(data) >= length { + return data + } + result := make([]byte, length) + copy(result, data) + return result +} + +// NullPad pads data with null bytes to the specified length +// (same as ZeroPad, provided for clarity) +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const padded = utils.NullPad([0x41, 0x42], 8); +// ``` +func (u *Utils) NullPad(data []byte, length int) []byte { + return u.ZeroPad(data, length) +} + +// PadToBlockSize pads data to be a multiple of blockSize using zero padding +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const padded = utils.PadToBlockSize([0x41, 0x42, 0x43], 8); +// ``` +func (u *Utils) PadToBlockSize(data []byte, blockSize int) []byte { + if blockSize <= 0 { + return data + } + remainder := len(data) % blockSize + if remainder == 0 { + return data + } + padding := blockSize - remainder + return append(data, bytes.Repeat([]byte{0}, padding)...) +} + +func pkcs7Pad(data []byte, blockSize int) []byte { + if blockSize <= 0 || blockSize > 255 { + return data + } + padding := blockSize - len(data)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(data, padtext...) +} + +func pkcs7Unpad(data []byte) ([]byte, error) { + if len(data) == 0 { + return nil, errors.New("data is empty") + } + padding := int(data[len(data)-1]) + if padding == 0 || padding > len(data) { + return nil, errors.New("invalid padding") + } + for i := len(data) - padding; i < len(data); i++ { + if data[i] != byte(padding) { + return nil, errors.New("invalid padding") + } + } + return data[:len(data)-padding], nil +} diff --git a/pkg/js/libs/utils/struct.go b/pkg/js/libs/utils/struct.go new file mode 100644 index 0000000000..7511ddd4ce --- /dev/null +++ b/pkg/js/libs/utils/struct.go @@ -0,0 +1,330 @@ +package utils + +import ( + "encoding/binary" +) + +// PackUint8 packs a uint8 value into a byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint8(255); +// ``` +func (u *Utils) PackUint8(value int) []byte { + return []byte{byte(value & 0xFF)} +} + +// PackUint16LE packs a uint16 value into a little-endian byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint16LE(0x1234); // returns [0x34, 0x12] +// ``` +func (u *Utils) PackUint16LE(value int) []byte { + buf := make([]byte, 2) + binary.LittleEndian.PutUint16(buf, uint16(value)) + return buf +} + +// PackUint16BE packs a uint16 value into a big-endian byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint16BE(0x1234); // returns [0x12, 0x34] +// ``` +func (u *Utils) PackUint16BE(value int) []byte { + buf := make([]byte, 2) + binary.BigEndian.PutUint16(buf, uint16(value)) + return buf +} + +// PackUint32LE packs a uint32 value into a little-endian byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint32LE(0x12345678); // returns [0x78, 0x56, 0x34, 0x12] +// ``` +func (u *Utils) PackUint32LE(value int) []byte { + buf := make([]byte, 4) + binary.LittleEndian.PutUint32(buf, uint32(value)) + return buf +} + +// PackUint32BE packs a uint32 value into a big-endian byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint32BE(0x12345678); // returns [0x12, 0x34, 0x56, 0x78] +// ``` +func (u *Utils) PackUint32BE(value int) []byte { + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, uint32(value)) + return buf +} + +// PackUint64LE packs a uint64 value into a little-endian byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint64LE(0x123456789ABCDEF0); +// ``` +func (u *Utils) PackUint64LE(value int64) []byte { + buf := make([]byte, 8) + binary.LittleEndian.PutUint64(buf, uint64(value)) + return buf +} + +// PackUint64BE packs a uint64 value into a big-endian byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const packed = u.PackUint64BE(0x123456789ABCDEF0); +// ``` +func (u *Utils) PackUint64BE(value int64) []byte { + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, uint64(value)) + return buf +} + +// UnpackUint16LE unpacks a little-endian uint16 from bytes at the given offset +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const value = u.UnpackUint16LE([0x34, 0x12, 0x00, 0x00], 0); // returns 0x1234 +// ``` +func (u *Utils) UnpackUint16LE(data []byte, offset int) int { + if offset+2 > len(data) { + return 0 + } + return int(binary.LittleEndian.Uint16(data[offset:])) +} + +// UnpackUint16BE unpacks a big-endian uint16 from bytes at the given offset +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const value = u.UnpackUint16BE([0x12, 0x34, 0x00, 0x00], 0); // returns 0x1234 +// ``` +func (u *Utils) UnpackUint16BE(data []byte, offset int) int { + if offset+2 > len(data) { + return 0 + } + return int(binary.BigEndian.Uint16(data[offset:])) +} + +// UnpackUint32LE unpacks a little-endian uint32 from bytes at the given offset +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const value = u.UnpackUint32LE([0x78, 0x56, 0x34, 0x12], 0); // returns 0x12345678 +// ``` +func (u *Utils) UnpackUint32LE(data []byte, offset int) int { + if offset+4 > len(data) { + return 0 + } + return int(binary.LittleEndian.Uint32(data[offset:])) +} + +// UnpackUint32BE unpacks a big-endian uint32 from bytes at the given offset +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const value = u.UnpackUint32BE([0x12, 0x34, 0x56, 0x78], 0); // returns 0x12345678 +// ``` +func (u *Utils) UnpackUint32BE(data []byte, offset int) int { + if offset+4 > len(data) { + return 0 + } + return int(binary.BigEndian.Uint32(data[offset:])) +} + +// UnpackUint64LE unpacks a little-endian uint64 from bytes at the given offset +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const value = u.UnpackUint64LE(bytes, 0); +// ``` +func (u *Utils) UnpackUint64LE(data []byte, offset int) int64 { + if offset+8 > len(data) { + return 0 + } + return int64(binary.LittleEndian.Uint64(data[offset:])) +} + +// UnpackUint64BE unpacks a big-endian uint64 from bytes at the given offset +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const value = u.UnpackUint64BE(bytes, 0); +// ``` +func (u *Utils) UnpackUint64BE(data []byte, offset int) int64 { + if offset+8 > len(data) { + return 0 + } + return int64(binary.BigEndian.Uint64(data[offset:])) +} + +// ConcatBytes concatenates multiple byte slices into one +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const result = u.ConcatBytes([0x01, 0x02], [0x03, 0x04], [0x05]); +// ``` +func (u *Utils) ConcatBytes(arrays ...[]byte) []byte { + totalLen := 0 + for _, arr := range arrays { + totalLen += len(arr) + } + result := make([]byte, 0, totalLen) + for _, arr := range arrays { + result = append(result, arr...) + } + return result +} + +// StringToBytes converts a string to a byte slice +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const bytes = u.StringToBytes('hello'); +// ``` +func (u *Utils) StringToBytes(s string) []byte { + return []byte(s) +} + +// BytesToString converts a byte slice to a string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const str = u.BytesToString([0x68, 0x65, 0x6c, 0x6c, 0x6f]); +// ``` +func (u *Utils) BytesToString(data []byte) string { + return string(data) +} + +// ToBytes converts various input types to a byte slice +// Handles: []byte, []interface{} (with numeric values), string +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const bytes = u.ToBytes([0x41, 0x42, 0x43]); +// ``` +func (u *Utils) ToBytes(data interface{}) []byte { + switch v := data.(type) { + case []byte: + return v + case string: + return []byte(v) + case []interface{}: + result := make([]byte, len(v)) + for i, val := range v { + switch n := val.(type) { + case int: + result[i] = byte(n) + case int64: + result[i] = byte(n) + case float64: + result[i] = byte(int(n)) + default: + result[i] = 0 + } + } + return result + default: + return nil + } +} + +// P8 packs a uint8 value (pwntools-style alias for PackUint8) +func (u *Utils) P8(value int) []byte { return u.PackUint8(value) } + +// P16 packs a uint16 value as little-endian (pwntools-style alias) +func (u *Utils) P16(value int) []byte { return u.PackUint16LE(value) } + +// P16BE packs a uint16 value as big-endian +func (u *Utils) P16BE(value int) []byte { return u.PackUint16BE(value) } + +// P32 packs a uint32 value as little-endian (pwntools-style alias) +func (u *Utils) P32(value int) []byte { return u.PackUint32LE(value) } + +// P32BE packs a uint32 value as big-endian +func (u *Utils) P32BE(value int) []byte { return u.PackUint32BE(value) } + +// P64 packs a uint64 value as little-endian (pwntools-style alias) +func (u *Utils) P64(value int64) []byte { return u.PackUint64LE(value) } + +// P64BE packs a uint64 value as big-endian +func (u *Utils) P64BE(value int64) []byte { return u.PackUint64BE(value) } + +// U16 unpacks a little-endian uint16 (pwntools-style alias) +func (u *Utils) U16(data []byte, offset int) int { return u.UnpackUint16LE(data, offset) } + +// U16BE unpacks a big-endian uint16 +func (u *Utils) U16BE(data []byte, offset int) int { return u.UnpackUint16BE(data, offset) } + +// U32 unpacks a little-endian uint32 (pwntools-style alias) +func (u *Utils) U32(data []byte, offset int) int { return u.UnpackUint32LE(data, offset) } + +// U32BE unpacks a big-endian uint32 +func (u *Utils) U32BE(data []byte, offset int) int { return u.UnpackUint32BE(data, offset) } + +// U64 unpacks a little-endian uint64 (pwntools-style alias) +func (u *Utils) U64(data []byte, offset int) int64 { return u.UnpackUint64LE(data, offset) } + +// U64BE unpacks a big-endian uint64 +func (u *Utils) U64BE(data []byte, offset int) int64 { return u.UnpackUint64BE(data, offset) } + +// Flat combines multiple items into a single byte slice +// Accepts: []byte, string, int (single byte), []interface{}, or any Pack result +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const u = new utils.Utils(); +// const payload = u.Flat(u.P32(0x41414141), "AAAA", [0x00, 0x01], 0x42); +// ``` +func (u *Utils) Flat(items ...interface{}) []byte { + var result []byte + for _, item := range items { + switch v := item.(type) { + case []byte: + result = append(result, v...) + case string: + result = append(result, []byte(v)...) + case int: + result = append(result, byte(v)) + case int64: + result = append(result, byte(v)) + case float64: + result = append(result, byte(int(v))) + case []interface{}: + for _, elem := range v { + switch n := elem.(type) { + case int: + result = append(result, byte(n)) + case int64: + result = append(result, byte(n)) + case float64: + result = append(result, byte(int(n))) + } + } + } + } + return result +} diff --git a/pkg/js/libs/utils/time.go b/pkg/js/libs/utils/time.go new file mode 100644 index 0000000000..434fdbca22 --- /dev/null +++ b/pkg/js/libs/utils/time.go @@ -0,0 +1,45 @@ +package utils + +import ( + "time" +) + +// Sleep pauses execution for the specified number of milliseconds +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// utils.Sleep(1000); // sleep for 1 second +// ``` +func (u *Utils) Sleep(milliseconds int) { + time.Sleep(time.Duration(milliseconds) * time.Millisecond) +} + +// UnixTimestamp returns the current Unix timestamp in seconds +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const ts = utils.UnixTimestamp(); +// ``` +func (u *Utils) UnixTimestamp() int64 { + return time.Now().Unix() +} + +// UnixTimestampMilli returns the current Unix timestamp in milliseconds +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const ts = utils.UnixTimestampMilli(); +// ``` +func (u *Utils) UnixTimestampMilli() int64 { + return time.Now().UnixMilli() +} + +// UnixTimestampNano returns the current Unix timestamp in nanoseconds +// @example +// ```javascript +// const utils = require('nuclei/utils'); +// const ts = utils.UnixTimestampNano(); +// ``` +func (u *Utils) UnixTimestampNano() int64 { + return time.Now().UnixNano() +} diff --git a/pkg/js/libs/utils/utils.go b/pkg/js/libs/utils/utils.go new file mode 100644 index 0000000000..84b18bfcef --- /dev/null +++ b/pkg/js/libs/utils/utils.go @@ -0,0 +1,10 @@ +package utils + +type ( + // Utils is a struct for utils functions + // @example + // ```javascript + // const utils = require('nuclei/utils'); + // ``` + Utils struct{} +) diff --git a/pkg/js/libs/utils/utils_test.go b/pkg/js/libs/utils/utils_test.go new file mode 100644 index 0000000000..26909dced1 --- /dev/null +++ b/pkg/js/libs/utils/utils_test.go @@ -0,0 +1,1288 @@ +package utils + +import ( + "bytes" + "testing" +) + +func TestURLEncode(t *testing.T) { + u := &Utils{} + tests := []struct { + input string + expected string + }{ + {"hello world", "hello+world"}, + {"test@example.com", "test%40example.com"}, + {"a=b&c=d", "a%3Db%26c%3Dd"}, + } + for _, tt := range tests { + result := u.URLEncode(tt.input) + if result != tt.expected { + t.Errorf("URLEncode(%q) = %q, want %q", tt.input, result, tt.expected) + } + } +} + +func TestURLDecode(t *testing.T) { + u := &Utils{} + tests := []struct { + input string + expected string + }{ + {"hello+world", "hello world"}, + {"test%40example.com", "test@example.com"}, + {"a%3Db%26c%3Dd", "a=b&c=d"}, + } + for _, tt := range tests { + result, err := u.URLDecode(tt.input) + if err != nil { + t.Errorf("URLDecode(%q) error: %v", tt.input, err) + continue + } + if result != tt.expected { + t.Errorf("URLDecode(%q) = %q, want %q", tt.input, result, tt.expected) + } + } +} + +func TestHTMLEncode(t *testing.T) { + u := &Utils{} + input := "" + expected := "<script>alert('xss')</script>" + result := u.HTMLEncode(input) + if result != expected { + t.Errorf("HTMLEncode(%q) = %q, want %q", input, result, expected) + } +} + +func TestHTMLDecode(t *testing.T) { + u := &Utils{} + input := "<script>alert('xss')</script>" + expected := "" + result := u.HTMLDecode(input) + if result != expected { + t.Errorf("HTMLDecode(%q) = %q, want %q", input, result, expected) + } +} + +func TestHexEncodeDecode(t *testing.T) { + u := &Utils{} + data := []byte("hello") + encoded := u.HexEncode(data) + if encoded != "68656c6c6f" { + t.Errorf("HexEncode = %q, want %q", encoded, "68656c6c6f") + } + decoded, err := u.HexDecode(encoded) + if err != nil { + t.Errorf("HexDecode error: %v", err) + } + if !bytes.Equal(decoded, data) { + t.Errorf("HexDecode = %v, want %v", decoded, data) + } +} + +func TestBase64EncodeDecode(t *testing.T) { + u := &Utils{} + data := []byte("hello world") + encoded := u.Base64Encode(data) + if encoded != "aGVsbG8gd29ybGQ=" { + t.Errorf("Base64Encode = %q, want %q", encoded, "aGVsbG8gd29ybGQ=") + } + decoded, err := u.Base64Decode(encoded) + if err != nil { + t.Errorf("Base64Decode error: %v", err) + } + if !bytes.Equal(decoded, data) { + t.Errorf("Base64Decode = %v, want %v", decoded, data) + } +} + +func TestBase64URLEncodeDecode(t *testing.T) { + u := &Utils{} + data := []byte{0xfb, 0xff, 0xfe} + encoded := u.Base64URLEncode(data) + decoded, err := u.Base64URLDecode(encoded) + if err != nil { + t.Errorf("Base64URLDecode error: %v", err) + } + if !bytes.Equal(decoded, data) { + t.Errorf("Base64URL roundtrip failed") + } +} + +func TestBase64RawEncodeDecode(t *testing.T) { + u := &Utils{} + data := []byte("test") + encoded := u.Base64RawEncode(data) + if encoded != "dGVzdA" { + t.Errorf("Base64RawEncode = %q, want %q", encoded, "dGVzdA") + } + decoded, err := u.Base64RawDecode(encoded) + if err != nil { + t.Errorf("Base64RawDecode error: %v", err) + } + if !bytes.Equal(decoded, data) { + t.Errorf("Base64RawDecode = %v, want %v", decoded, data) + } +} + +func TestUTF16LEEncodeDecode(t *testing.T) { + u := &Utils{} + data := "hello" + encoded := u.UTF16LEEncode(data) + expected := []byte{0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00} + if !bytes.Equal(encoded, expected) { + t.Errorf("UTF16LEEncode = %v, want %v", encoded, expected) + } + decoded := u.UTF16LEDecode(encoded) + if decoded != data { + t.Errorf("UTF16LEDecode = %q, want %q", decoded, data) + } +} + +func TestUTF16BEEncodeDecode(t *testing.T) { + u := &Utils{} + data := "hello" + encoded := u.UTF16BEEncode(data) + expected := []byte{0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f} + if !bytes.Equal(encoded, expected) { + t.Errorf("UTF16BEEncode = %v, want %v", encoded, expected) + } + decoded := u.UTF16BEDecode(encoded) + if decoded != data { + t.Errorf("UTF16BEDecode = %q, want %q", decoded, data) + } +} + +func TestMD5(t *testing.T) { + u := &Utils{} + result := u.MD5([]byte("hello")) + expected := "5d41402abc4b2a76b9719d911017c592" + if result != expected { + t.Errorf("MD5 = %q, want %q", result, expected) + } +} + +func TestSHA1(t *testing.T) { + u := &Utils{} + result := u.SHA1([]byte("hello")) + expected := "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d" + if result != expected { + t.Errorf("SHA1 = %q, want %q", result, expected) + } +} + +func TestSHA256(t *testing.T) { + u := &Utils{} + result := u.SHA256([]byte("hello")) + expected := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" + if result != expected { + t.Errorf("SHA256 = %q, want %q", result, expected) + } +} + +func TestSHA512(t *testing.T) { + u := &Utils{} + result := u.SHA512([]byte("hello")) + expected := "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043" + if result != expected { + t.Errorf("SHA512 = %q, want %q", result, expected) + } +} + +func TestHMACSHA256(t *testing.T) { + u := &Utils{} + result := u.HMACSHA256([]byte("message"), []byte("key")) + if len(result) != 32 { + t.Errorf("HMACSHA256 length = %d, want 32", len(result)) + } + result2 := u.HMACSHA256([]byte("message"), []byte("key")) + if !bytes.Equal(result, result2) { + t.Errorf("HMACSHA256 is not deterministic") + } + result3 := u.HMACSHA256([]byte("different"), []byte("key")) + if bytes.Equal(result, result3) { + t.Errorf("HMACSHA256 should produce different output for different input") + } +} + +func TestCRC32(t *testing.T) { + u := &Utils{} + result := u.CRC32([]byte("hello")) + expected := uint32(0x3610a686) + if result != expected { + t.Errorf("CRC32 = %x, want %x", result, expected) + } +} + +func TestZlibCompressDecompress(t *testing.T) { + u := &Utils{} + data := []byte("hello world hello world hello world") + compressed, err := u.ZlibCompress(data) + if err != nil { + t.Errorf("ZlibCompress error: %v", err) + } + if len(compressed) >= len(data) { + t.Logf("Warning: compressed size (%d) >= original size (%d)", len(compressed), len(data)) + } + decompressed, err := u.ZlibDecompress(compressed) + if err != nil { + t.Errorf("ZlibDecompress error: %v", err) + } + if !bytes.Equal(decompressed, data) { + t.Errorf("Zlib roundtrip failed") + } +} + +func TestGzipCompressDecompress(t *testing.T) { + u := &Utils{} + data := []byte("hello world hello world hello world") + compressed, err := u.GzipCompress(data) + if err != nil { + t.Errorf("GzipCompress error: %v", err) + } + decompressed, err := u.GzipDecompress(compressed) + if err != nil { + t.Errorf("GzipDecompress error: %v", err) + } + if !bytes.Equal(decompressed, data) { + t.Errorf("Gzip roundtrip failed") + } +} + +func TestDeflateCompressDecompress(t *testing.T) { + u := &Utils{} + data := []byte("hello world hello world hello world") + compressed, err := u.DeflateCompress(data) + if err != nil { + t.Errorf("DeflateCompress error: %v", err) + } + decompressed, err := u.DeflateDecompress(compressed) + if err != nil { + t.Errorf("DeflateDecompress error: %v", err) + } + if !bytes.Equal(decompressed, data) { + t.Errorf("Deflate roundtrip failed") + } +} + +func TestAESEncryptDecryptECB(t *testing.T) { + u := &Utils{} + key := []byte("0123456789abcdef") + plaintext := []byte("hello world test") + encrypted, err := u.AESEncryptECB(plaintext, key) + if err != nil { + t.Errorf("AESEncryptECB error: %v", err) + } + decrypted, err := u.AESDecryptECB(encrypted, key) + if err != nil { + t.Errorf("AESDecryptECB error: %v", err) + } + if !bytes.Equal(decrypted, plaintext) { + t.Errorf("AES ECB roundtrip failed: got %q, want %q", decrypted, plaintext) + } +} + +func TestAESEncryptDecryptCBC(t *testing.T) { + u := &Utils{} + key := []byte("0123456789abcdef") + iv := []byte("abcdefghijklmnop") + plaintext := []byte("hello world test") + encrypted, err := u.AESEncryptCBC(plaintext, key, iv) + if err != nil { + t.Errorf("AESEncryptCBC error: %v", err) + } + decrypted, err := u.AESDecryptCBC(encrypted, key, iv) + if err != nil { + t.Errorf("AESDecryptCBC error: %v", err) + } + if !bytes.Equal(decrypted, plaintext) { + t.Errorf("AES CBC roundtrip failed: got %q, want %q", decrypted, plaintext) + } +} + +func TestAESEncryptDecryptGCM(t *testing.T) { + u := &Utils{} + key := []byte("0123456789abcdef") + nonce := []byte("123456789012") + plaintext := []byte("hello world test") + encrypted, err := u.AESEncryptGCM(plaintext, key, nonce) + if err != nil { + t.Errorf("AESEncryptGCM error: %v", err) + } + decrypted, err := u.AESDecryptGCM(encrypted, key, nonce) + if err != nil { + t.Errorf("AESDecryptGCM error: %v", err) + } + if !bytes.Equal(decrypted, plaintext) { + t.Errorf("AES GCM roundtrip failed: got %q, want %q", decrypted, plaintext) + } +} + +func TestDESEncryptDecryptECB(t *testing.T) { + u := &Utils{} + key := []byte("12345678") + plaintext := []byte("hello wo") + encrypted, err := u.DESEncryptECB(plaintext, key) + if err != nil { + t.Errorf("DESEncryptECB error: %v", err) + } + decrypted, err := u.DESDecryptECB(encrypted, key) + if err != nil { + t.Errorf("DESDecryptECB error: %v", err) + } + if !bytes.Equal(decrypted, plaintext) { + t.Errorf("DES ECB roundtrip failed: got %q, want %q", decrypted, plaintext) + } +} + +func TestDES3EncryptDecryptCBC(t *testing.T) { + u := &Utils{} + key := []byte("123456789012345678901234") + iv := []byte("12345678") + plaintext := []byte("hello world test") + encrypted, err := u.DES3EncryptCBC(plaintext, key, iv) + if err != nil { + t.Errorf("DES3EncryptCBC error: %v", err) + } + decrypted, err := u.DES3DecryptCBC(encrypted, key, iv) + if err != nil { + t.Errorf("DES3DecryptCBC error: %v", err) + } + if !bytes.Equal(decrypted, plaintext) { + t.Errorf("3DES CBC roundtrip failed: got %q, want %q", decrypted, plaintext) + } +} + +func TestRC4Encrypt(t *testing.T) { + u := &Utils{} + key := []byte("secretkey") + plaintext := []byte("hello world") + encrypted, err := u.RC4Encrypt(plaintext, key) + if err != nil { + t.Errorf("RC4Encrypt error: %v", err) + } + decrypted, err := u.RC4Encrypt(encrypted, key) + if err != nil { + t.Errorf("RC4 decrypt error: %v", err) + } + if !bytes.Equal(decrypted, plaintext) { + t.Errorf("RC4 roundtrip failed: got %q, want %q", decrypted, plaintext) + } +} + +func TestXORBytes(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43, 0x44} + key := []byte{0x01, 0x02} + result := u.XORBytes(data, key) + expected := []byte{0x40, 0x40, 0x42, 0x46} + if !bytes.Equal(result, expected) { + t.Errorf("XORBytes = %v, want %v", result, expected) + } + original := u.XORBytes(result, key) + if !bytes.Equal(original, data) { + t.Errorf("XORBytes roundtrip failed") + } +} + +func TestXORSingleByte(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43} + key := byte(0x01) + result := u.XORSingleByte(data, key) + expected := []byte{0x40, 0x43, 0x42} + if !bytes.Equal(result, expected) { + t.Errorf("XORSingleByte = %v, want %v", result, expected) + } +} + +func TestPKCS7PadUnpad(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43} + padded := u.PKCS7Pad(data, 8) + if len(padded) != 8 { + t.Errorf("PKCS7Pad length = %d, want 8", len(padded)) + } + unpadded, err := u.PKCS7Unpad(padded) + if err != nil { + t.Errorf("PKCS7Unpad error: %v", err) + } + if !bytes.Equal(unpadded, data) { + t.Errorf("PKCS7 roundtrip failed") + } +} + +func TestZeroPad(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42} + result := u.ZeroPad(data, 8) + expected := []byte{0x41, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + if !bytes.Equal(result, expected) { + t.Errorf("ZeroPad = %v, want %v", result, expected) + } +} + +func TestPadToBlockSize(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43} + result := u.PadToBlockSize(data, 8) + if len(result) != 8 { + t.Errorf("PadToBlockSize length = %d, want 8", len(result)) + } + if !bytes.Equal(result[:3], data) { + t.Errorf("PadToBlockSize data mismatch") + } +} + +func TestPatternCreate(t *testing.T) { + u := &Utils{} + pattern := u.PatternCreate(100) + if len(pattern) != 100 { + t.Errorf("PatternCreate length = %d, want 100", len(pattern)) + } + if pattern[0] != 'A' || pattern[1] != 'a' || pattern[2] != '0' { + t.Errorf("PatternCreate start = %q, want 'Aa0'", pattern[:3]) + } +} + +func TestPatternOffset(t *testing.T) { + u := &Utils{} + pattern := u.PatternCreate(1000) + offset := u.PatternOffset(pattern, []byte("Ab0")) + if offset != 30 { + t.Errorf("PatternOffset = %d, want 30", offset) + } +} + +func TestFindBytes(t *testing.T) { + u := &Utils{} + haystack := []byte{0x41, 0x42, 0x43, 0x44, 0x42, 0x43} + needle := []byte{0x42, 0x43} + idx := u.FindBytes(haystack, needle) + if idx != 1 { + t.Errorf("FindBytes = %d, want 1", idx) + } +} + +func TestFindAllBytes(t *testing.T) { + u := &Utils{} + haystack := []byte{0x41, 0x42, 0x43, 0x44, 0x42, 0x43} + needle := []byte{0x42, 0x43} + indices := u.FindAllBytes(haystack, needle) + if len(indices) != 2 || indices[0] != 1 || indices[1] != 4 { + t.Errorf("FindAllBytes = %v, want [1, 4]", indices) + } +} + +func TestReplaceBytes(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43, 0x42} + result := u.ReplaceBytes(data, []byte{0x42}, []byte{0x44, 0x45}) + expected := []byte{0x41, 0x44, 0x45, 0x43, 0x44, 0x45} + if !bytes.Equal(result, expected) { + t.Errorf("ReplaceBytes = %v, want %v", result, expected) + } +} + +func TestRepeatBytes(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42} + result := u.RepeatBytes(data, 3) + expected := []byte{0x41, 0x42, 0x41, 0x42, 0x41, 0x42} + if !bytes.Equal(result, expected) { + t.Errorf("RepeatBytes = %v, want %v", result, expected) + } +} + +func TestReverseBytes(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43} + result := u.ReverseBytes(data) + expected := []byte{0x43, 0x42, 0x41} + if !bytes.Equal(result, expected) { + t.Errorf("ReverseBytes = %v, want %v", result, expected) + } +} + +func TestSwapEndian16(t *testing.T) { + u := &Utils{} + data := []byte{0x01, 0x02, 0x03, 0x04} + result := u.SwapEndian16(data) + expected := []byte{0x02, 0x01, 0x04, 0x03} + if !bytes.Equal(result, expected) { + t.Errorf("SwapEndian16 = %v, want %v", result, expected) + } +} + +func TestSwapEndian32(t *testing.T) { + u := &Utils{} + data := []byte{0x01, 0x02, 0x03, 0x04} + result := u.SwapEndian32(data) + expected := []byte{0x04, 0x03, 0x02, 0x01} + if !bytes.Equal(result, expected) { + t.Errorf("SwapEndian32 = %v, want %v", result, expected) + } +} + +func TestGenerateRandomString(t *testing.T) { + u := &Utils{} + s := u.GenerateRandomString(16) + if len(s) != 16 { + t.Errorf("GenerateRandomString length = %d, want 16", len(s)) + } +} + +func TestGenerateRandomBytes(t *testing.T) { + u := &Utils{} + b := u.GenerateRandomBytes(16) + if len(b) != 16 { + t.Errorf("GenerateRandomBytes length = %d, want 16", len(b)) + } +} + +func TestRepeatString(t *testing.T) { + u := &Utils{} + result := u.RepeatString("AB", 3) + if result != "ABABAB" { + t.Errorf("RepeatString = %q, want %q", result, "ABABAB") + } +} + +func TestPadLeft(t *testing.T) { + u := &Utils{} + result := u.PadLeft("123", 8, "0") + if result != "00000123" { + t.Errorf("PadLeft = %q, want %q", result, "00000123") + } +} + +func TestPadRight(t *testing.T) { + u := &Utils{} + result := u.PadRight("123", 8, "0") + if result != "12300000" { + t.Errorf("PadRight = %q, want %q", result, "12300000") + } +} + +func TestUnixTimestamp(t *testing.T) { + u := &Utils{} + ts := u.UnixTimestamp() + if ts <= 0 { + t.Errorf("UnixTimestamp = %d, want > 0", ts) + } +} + +func TestUnixTimestampMilli(t *testing.T) { + u := &Utils{} + ts := u.UnixTimestampMilli() + if ts <= 0 { + t.Errorf("UnixTimestampMilli = %d, want > 0", ts) + } +} + +func TestUnixTimestampNano(t *testing.T) { + u := &Utils{} + ts := u.UnixTimestampNano() + if ts <= 0 { + t.Errorf("UnixTimestampNano = %d, want > 0", ts) + } +} + +func TestMD4(t *testing.T) { + u := &Utils{} + result := u.MD4([]byte("hello")) + if len(result) != 32 { + t.Errorf("MD4 length = %d, want 32", len(result)) + } + result2 := u.MD4([]byte("hello")) + if result != result2 { + t.Errorf("MD4 is not deterministic") + } +} + +func TestMD4Raw(t *testing.T) { + u := &Utils{} + result := u.MD4Raw([]byte("hello")) + if len(result) != 16 { + t.Errorf("MD4Raw length = %d, want 16", len(result)) + } +} + +func TestMD5Raw(t *testing.T) { + u := &Utils{} + result := u.MD5Raw([]byte("hello")) + if len(result) != 16 { + t.Errorf("MD5Raw length = %d, want 16", len(result)) + } + expected := u.HexEncode(result) + if expected != "5d41402abc4b2a76b9719d911017c592" { + t.Errorf("MD5Raw hex = %q, want %q", expected, "5d41402abc4b2a76b9719d911017c592") + } +} + +func TestSHA1Raw(t *testing.T) { + u := &Utils{} + result := u.SHA1Raw([]byte("hello")) + if len(result) != 20 { + t.Errorf("SHA1Raw length = %d, want 20", len(result)) + } +} + +func TestSHA256Raw(t *testing.T) { + u := &Utils{} + result := u.SHA256Raw([]byte("hello")) + if len(result) != 32 { + t.Errorf("SHA256Raw length = %d, want 32", len(result)) + } +} + +func TestSHA384(t *testing.T) { + u := &Utils{} + result := u.SHA384([]byte("hello")) + if len(result) != 96 { + t.Errorf("SHA384 length = %d, want 96", len(result)) + } +} + +func TestSHA384Raw(t *testing.T) { + u := &Utils{} + result := u.SHA384Raw([]byte("hello")) + if len(result) != 48 { + t.Errorf("SHA384Raw length = %d, want 48", len(result)) + } +} + +func TestSHA512Raw(t *testing.T) { + u := &Utils{} + result := u.SHA512Raw([]byte("hello")) + if len(result) != 64 { + t.Errorf("SHA512Raw length = %d, want 64", len(result)) + } +} + +func TestHMACMD5(t *testing.T) { + u := &Utils{} + result := u.HMACMD5([]byte("message"), []byte("key")) + if len(result) != 16 { + t.Errorf("HMACMD5 length = %d, want 16", len(result)) + } + result2 := u.HMACMD5([]byte("message"), []byte("key")) + if !bytes.Equal(result, result2) { + t.Errorf("HMACMD5 is not deterministic") + } +} + +func TestHMACSHA1(t *testing.T) { + u := &Utils{} + result := u.HMACSHA1([]byte("message"), []byte("key")) + if len(result) != 20 { + t.Errorf("HMACSHA1 length = %d, want 20", len(result)) + } +} + +func TestHMACSHA512(t *testing.T) { + u := &Utils{} + result := u.HMACSHA512([]byte("message"), []byte("key")) + if len(result) != 64 { + t.Errorf("HMACSHA512 length = %d, want 64", len(result)) + } +} + +func TestAdler32(t *testing.T) { + u := &Utils{} + result := u.Adler32([]byte("hello")) + if result == 0 { + t.Errorf("Adler32 = 0, want non-zero") + } + result2 := u.Adler32([]byte("hello")) + if result != result2 { + t.Errorf("Adler32 is not deterministic") + } +} + +func TestNullPad(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42} + result := u.NullPad(data, 8) + expected := []byte{0x41, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + if !bytes.Equal(result, expected) { + t.Errorf("NullPad = %v, want %v", result, expected) + } +} + +func TestGenerateRandomAlphanumeric(t *testing.T) { + u := &Utils{} + s := u.GenerateRandomAlphanumeric(16) + if len(s) != 16 { + t.Errorf("GenerateRandomAlphanumeric length = %d, want 16", len(s)) + } + for _, c := range s { + isAlphanumeric := (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') + if !isAlphanumeric { + t.Errorf("GenerateRandomAlphanumeric contains invalid char: %c", c) + } + } +} + +func TestBase64RawURLEncodeDecode(t *testing.T) { + u := &Utils{} + data := []byte{0xfb, 0xff, 0xfe} + encoded := u.Base64RawURLEncode(data) + decoded, err := u.Base64RawURLDecode(encoded) + if err != nil { + t.Errorf("Base64RawURLDecode error: %v", err) + } + if !bytes.Equal(decoded, data) { + t.Errorf("Base64RawURL roundtrip failed") + } +} + +func TestPatternCreateCyclicUniqueness(t *testing.T) { + u := &Utils{} + pattern := u.PatternCreate(20280) + seen := make(map[string]int) + for i := 0; i <= len(pattern)-4; i++ { + chunk := string(pattern[i : i+4]) + if prev, exists := seen[chunk]; exists { + t.Errorf("PatternCreate: duplicate 4-byte sequence %q at offsets %d and %d", chunk, prev, i) + return + } + seen[chunk] = i + } +} + +func TestPatternOffsetMultiple(t *testing.T) { + u := &Utils{} + pattern := u.PatternCreate(1000) + + tests := []struct { + search string + expected int + }{ + {"Aa0A", 0}, + {"Aa1A", 3}, + {"Aa2A", 6}, + {"Ab0A", 30}, + {"Ba0B", 780}, + } + + for _, tt := range tests { + offset := u.PatternOffset(pattern, []byte(tt.search)) + if offset != tt.expected { + t.Errorf("PatternOffset(%q) = %d, want %d", tt.search, offset, tt.expected) + } + } +} + +func TestPatternOffsetNotFound(t *testing.T) { + u := &Utils{} + pattern := u.PatternCreate(100) + offset := u.PatternOffset(pattern, []byte("ZZZZ")) + if offset != -1 { + t.Errorf("PatternOffset(not found) = %d, want -1", offset) + } +} + +func TestFindBytesNotFound(t *testing.T) { + u := &Utils{} + haystack := []byte{0x41, 0x42, 0x43} + needle := []byte{0x44, 0x45} + idx := u.FindBytes(haystack, needle) + if idx != -1 { + t.Errorf("FindBytes(not found) = %d, want -1", idx) + } +} + +func TestFindAllBytesEmpty(t *testing.T) { + u := &Utils{} + haystack := []byte{0x41, 0x42, 0x43} + needle := []byte{0x44, 0x45} + indices := u.FindAllBytes(haystack, needle) + if len(indices) != 0 { + t.Errorf("FindAllBytes(not found) = %v, want []", indices) + } +} + +func TestSwapEndian16OddLength(t *testing.T) { + u := &Utils{} + data := []byte{0x01, 0x02, 0x03} + result := u.SwapEndian16(data) + expected := []byte{0x02, 0x01, 0x03} + if !bytes.Equal(result, expected) { + t.Errorf("SwapEndian16 odd length = %v, want %v", result, expected) + } +} + +func TestSwapEndian32ShortData(t *testing.T) { + u := &Utils{} + data := []byte{0x01, 0x02, 0x03} + result := u.SwapEndian32(data) + if !bytes.Equal(result, data) { + t.Errorf("SwapEndian32 short data = %v, want %v (unchanged)", result, data) + } +} + +func TestXORBytesEmptyKey(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43} + result := u.XORBytes(data, []byte{}) + if !bytes.Equal(result, data) { + t.Errorf("XORBytes empty key = %v, want %v (unchanged)", result, data) + } +} + +func TestPKCS7UnpadInvalid(t *testing.T) { + u := &Utils{} + _, err := u.PKCS7Unpad([]byte{}) + if err == nil { + t.Errorf("PKCS7Unpad empty should return error") + } + _, err = u.PKCS7Unpad([]byte{0x00}) + if err == nil { + t.Errorf("PKCS7Unpad zero padding should return error") + } +} + +func TestZeroPadAlreadyLong(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43, 0x44, 0x45} + result := u.ZeroPad(data, 3) + if !bytes.Equal(result, data) { + t.Errorf("ZeroPad already long = %v, want %v (unchanged)", result, data) + } +} + +func TestPadToBlockSizeAlreadyAligned(t *testing.T) { + u := &Utils{} + data := []byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48} + result := u.PadToBlockSize(data, 8) + if !bytes.Equal(result, data) { + t.Errorf("PadToBlockSize already aligned = %v, want %v (unchanged)", result, data) + } +} + +func TestPackUint8(t *testing.T) { + u := &Utils{} + tests := []struct { + input int + expected []byte + }{ + {0, []byte{0x00}}, + {255, []byte{0xFF}}, + {0x41, []byte{0x41}}, + {256, []byte{0x00}}, + } + for _, tt := range tests { + result := u.PackUint8(tt.input) + if !bytes.Equal(result, tt.expected) { + t.Errorf("PackUint8(%d) = %v, want %v", tt.input, result, tt.expected) + } + } +} + +func TestPackUint16LE(t *testing.T) { + u := &Utils{} + tests := []struct { + input int + expected []byte + }{ + {0x1234, []byte{0x34, 0x12}}, + {0, []byte{0x00, 0x00}}, + {0xFFFF, []byte{0xFF, 0xFF}}, + {0x0100, []byte{0x00, 0x01}}, + } + for _, tt := range tests { + result := u.PackUint16LE(tt.input) + if !bytes.Equal(result, tt.expected) { + t.Errorf("PackUint16LE(0x%X) = %v, want %v", tt.input, result, tt.expected) + } + } +} + +func TestPackUint16BE(t *testing.T) { + u := &Utils{} + tests := []struct { + input int + expected []byte + }{ + {0x1234, []byte{0x12, 0x34}}, + {0, []byte{0x00, 0x00}}, + {0xFFFF, []byte{0xFF, 0xFF}}, + {0x0100, []byte{0x01, 0x00}}, + } + for _, tt := range tests { + result := u.PackUint16BE(tt.input) + if !bytes.Equal(result, tt.expected) { + t.Errorf("PackUint16BE(0x%X) = %v, want %v", tt.input, result, tt.expected) + } + } +} + +func TestPackUint32LE(t *testing.T) { + u := &Utils{} + tests := []struct { + input int + expected []byte + }{ + {0x12345678, []byte{0x78, 0x56, 0x34, 0x12}}, + {0, []byte{0x00, 0x00, 0x00, 0x00}}, + {0xFFFFFFFF, []byte{0xFF, 0xFF, 0xFF, 0xFF}}, + {1, []byte{0x01, 0x00, 0x00, 0x00}}, + } + for _, tt := range tests { + result := u.PackUint32LE(tt.input) + if !bytes.Equal(result, tt.expected) { + t.Errorf("PackUint32LE(0x%X) = %v, want %v", tt.input, result, tt.expected) + } + } +} + +func TestPackUint32BE(t *testing.T) { + u := &Utils{} + tests := []struct { + input int + expected []byte + }{ + {0x12345678, []byte{0x12, 0x34, 0x56, 0x78}}, + {0, []byte{0x00, 0x00, 0x00, 0x00}}, + {0xFFFFFFFF, []byte{0xFF, 0xFF, 0xFF, 0xFF}}, + {1, []byte{0x00, 0x00, 0x00, 0x01}}, + } + for _, tt := range tests { + result := u.PackUint32BE(tt.input) + if !bytes.Equal(result, tt.expected) { + t.Errorf("PackUint32BE(0x%X) = %v, want %v", tt.input, result, tt.expected) + } + } +} + +func TestPackUint64LE(t *testing.T) { + u := &Utils{} + result := u.PackUint64LE(0x123456789ABCDEF0) + expected := []byte{0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12} + if !bytes.Equal(result, expected) { + t.Errorf("PackUint64LE = %v, want %v", result, expected) + } +} + +func TestPackUint64BE(t *testing.T) { + u := &Utils{} + result := u.PackUint64BE(0x123456789ABCDEF0) + expected := []byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0} + if !bytes.Equal(result, expected) { + t.Errorf("PackUint64BE = %v, want %v", result, expected) + } +} + +func TestUnpackUint16LE(t *testing.T) { + u := &Utils{} + tests := []struct { + data []byte + offset int + expected int + }{ + {[]byte{0x34, 0x12}, 0, 0x1234}, + {[]byte{0x00, 0x00, 0x34, 0x12}, 2, 0x1234}, + {[]byte{0xFF, 0xFF}, 0, 0xFFFF}, + {[]byte{0x00}, 0, 0}, + } + for _, tt := range tests { + result := u.UnpackUint16LE(tt.data, tt.offset) + if result != tt.expected { + t.Errorf("UnpackUint16LE(%v, %d) = 0x%X, want 0x%X", tt.data, tt.offset, result, tt.expected) + } + } +} + +func TestUnpackUint16BE(t *testing.T) { + u := &Utils{} + result := u.UnpackUint16BE([]byte{0x12, 0x34}, 0) + if result != 0x1234 { + t.Errorf("UnpackUint16BE = 0x%X, want 0x1234", result) + } +} + +func TestUnpackUint32LE(t *testing.T) { + u := &Utils{} + tests := []struct { + data []byte + offset int + expected int + }{ + {[]byte{0x78, 0x56, 0x34, 0x12}, 0, 0x12345678}, + {[]byte{0x00, 0x00, 0x78, 0x56, 0x34, 0x12}, 2, 0x12345678}, + {[]byte{0x01, 0x00, 0x00, 0x00}, 0, 1}, + {[]byte{0x00, 0x00, 0x00}, 0, 0}, + } + for _, tt := range tests { + result := u.UnpackUint32LE(tt.data, tt.offset) + if result != tt.expected { + t.Errorf("UnpackUint32LE(%v, %d) = 0x%X, want 0x%X", tt.data, tt.offset, result, tt.expected) + } + } +} + +func TestUnpackUint32BE(t *testing.T) { + u := &Utils{} + result := u.UnpackUint32BE([]byte{0x12, 0x34, 0x56, 0x78}, 0) + if result != 0x12345678 { + t.Errorf("UnpackUint32BE = 0x%X, want 0x12345678", result) + } +} + +func TestUnpackUint64LE(t *testing.T) { + u := &Utils{} + data := []byte{0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12} + result := u.UnpackUint64LE(data, 0) + expected := int64(0x123456789ABCDEF0) + if result != expected { + t.Errorf("UnpackUint64LE = 0x%X, want 0x%X", result, expected) + } +} + +func TestUnpackUint64BE(t *testing.T) { + u := &Utils{} + data := []byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0} + result := u.UnpackUint64BE(data, 0) + expected := int64(0x123456789ABCDEF0) + if result != expected { + t.Errorf("UnpackUint64BE = 0x%X, want 0x%X", result, expected) + } +} + +func TestUnpackBoundaryCheck(t *testing.T) { + u := &Utils{} + if u.UnpackUint16LE([]byte{0x00}, 0) != 0 { + t.Errorf("UnpackUint16LE should return 0 for short data") + } + if u.UnpackUint32LE([]byte{0x00, 0x00}, 0) != 0 { + t.Errorf("UnpackUint32LE should return 0 for short data") + } + if u.UnpackUint64LE([]byte{0x00, 0x00, 0x00, 0x00}, 0) != 0 { + t.Errorf("UnpackUint64LE should return 0 for short data") + } +} + +func TestConcatBytes(t *testing.T) { + u := &Utils{} + result := u.ConcatBytes([]byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05}) + expected := []byte{0x01, 0x02, 0x03, 0x04, 0x05} + if !bytes.Equal(result, expected) { + t.Errorf("ConcatBytes = %v, want %v", result, expected) + } +} + +func TestConcatBytesEmpty(t *testing.T) { + u := &Utils{} + result := u.ConcatBytes() + if len(result) != 0 { + t.Errorf("ConcatBytes() = %v, want empty", result) + } + result2 := u.ConcatBytes([]byte{0x01}, []byte{}, []byte{0x02}) + expected := []byte{0x01, 0x02} + if !bytes.Equal(result2, expected) { + t.Errorf("ConcatBytes with empty = %v, want %v", result2, expected) + } +} + +func TestStringToBytes(t *testing.T) { + u := &Utils{} + result := u.StringToBytes("hello") + expected := []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f} + if !bytes.Equal(result, expected) { + t.Errorf("StringToBytes = %v, want %v", result, expected) + } +} + +func TestBytesToString(t *testing.T) { + u := &Utils{} + result := u.BytesToString([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f}) + if result != "hello" { + t.Errorf("BytesToString = %q, want %q", result, "hello") + } +} + +func TestToBytes(t *testing.T) { + u := &Utils{} + result := u.ToBytes([]byte{0x41, 0x42}) + expected := []byte{0x41, 0x42} + if !bytes.Equal(result, expected) { + t.Errorf("ToBytes([]byte) = %v, want %v", result, expected) + } + + result = u.ToBytes("AB") + if !bytes.Equal(result, expected) { + t.Errorf("ToBytes(string) = %v, want %v", result, expected) + } + + result = u.ToBytes([]interface{}{int64(0x41), int64(0x42)}) + if !bytes.Equal(result, expected) { + t.Errorf("ToBytes([]interface{}) = %v, want %v", result, expected) + } + + result = u.ToBytes([]interface{}{float64(0x41), float64(0x42)}) + if !bytes.Equal(result, expected) { + t.Errorf("ToBytes([]interface{} float64) = %v, want %v", result, expected) + } +} + +func TestToBytesNil(t *testing.T) { + u := &Utils{} + result := u.ToBytes(123) + if result != nil { + t.Errorf("ToBytes(unsupported) = %v, want nil", result) + } +} + +func TestP8Alias(t *testing.T) { + u := &Utils{} + if !bytes.Equal(u.P8(0x41), u.PackUint8(0x41)) { + t.Errorf("P8 should equal PackUint8") + } +} + +func TestP16Aliases(t *testing.T) { + u := &Utils{} + if !bytes.Equal(u.P16(0x1234), u.PackUint16LE(0x1234)) { + t.Errorf("P16 should equal PackUint16LE") + } + if !bytes.Equal(u.P16BE(0x1234), u.PackUint16BE(0x1234)) { + t.Errorf("P16BE should equal PackUint16BE") + } +} + +func TestP32Aliases(t *testing.T) { + u := &Utils{} + if !bytes.Equal(u.P32(0x12345678), u.PackUint32LE(0x12345678)) { + t.Errorf("P32 should equal PackUint32LE") + } + if !bytes.Equal(u.P32BE(0x12345678), u.PackUint32BE(0x12345678)) { + t.Errorf("P32BE should equal PackUint32BE") + } +} + +func TestP64Aliases(t *testing.T) { + u := &Utils{} + if !bytes.Equal(u.P64(0x123456789ABCDEF0), u.PackUint64LE(0x123456789ABCDEF0)) { + t.Errorf("P64 should equal PackUint64LE") + } + if !bytes.Equal(u.P64BE(0x123456789ABCDEF0), u.PackUint64BE(0x123456789ABCDEF0)) { + t.Errorf("P64BE should equal PackUint64BE") + } +} + +func TestU16Aliases(t *testing.T) { + u := &Utils{} + data := []byte{0x34, 0x12} + if u.U16(data, 0) != u.UnpackUint16LE(data, 0) { + t.Errorf("U16 should equal UnpackUint16LE") + } + dataBE := []byte{0x12, 0x34} + if u.U16BE(dataBE, 0) != u.UnpackUint16BE(dataBE, 0) { + t.Errorf("U16BE should equal UnpackUint16BE") + } +} + +func TestU32Aliases(t *testing.T) { + u := &Utils{} + data := []byte{0x78, 0x56, 0x34, 0x12} + if u.U32(data, 0) != u.UnpackUint32LE(data, 0) { + t.Errorf("U32 should equal UnpackUint32LE") + } + dataBE := []byte{0x12, 0x34, 0x56, 0x78} + if u.U32BE(dataBE, 0) != u.UnpackUint32BE(dataBE, 0) { + t.Errorf("U32BE should equal UnpackUint32BE") + } +} + +func TestU64Aliases(t *testing.T) { + u := &Utils{} + data := []byte{0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12} + if u.U64(data, 0) != u.UnpackUint64LE(data, 0) { + t.Errorf("U64 should equal UnpackUint64LE") + } + dataBE := []byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0} + if u.U64BE(dataBE, 0) != u.UnpackUint64BE(dataBE, 0) { + t.Errorf("U64BE should equal UnpackUint64BE") + } +} + +func TestFlat(t *testing.T) { + u := &Utils{} + result := u.Flat( + []byte{0x01, 0x02}, + "AB", + 0x03, + []interface{}{float64(0x04), float64(0x05)}, + ) + expected := []byte{0x01, 0x02, 0x41, 0x42, 0x03, 0x04, 0x05} + if !bytes.Equal(result, expected) { + t.Errorf("Flat = %v, want %v", result, expected) + } +} + +func TestFlatEmpty(t *testing.T) { + u := &Utils{} + result := u.Flat() + if len(result) != 0 { + t.Errorf("Flat() = %v, want empty", result) + } +} + +func TestFlatWithPackedValues(t *testing.T) { + u := &Utils{} + result := u.Flat( + u.P32(0x12345678), + u.P16(0xABCD), + u.P8(0xFF), + ) + expected := []byte{0x78, 0x56, 0x34, 0x12, 0xCD, 0xAB, 0xFF} + if !bytes.Equal(result, expected) { + t.Errorf("Flat with packed = %v, want %v", result, expected) + } +} + +func TestFlatInt64(t *testing.T) { + u := &Utils{} + result := u.Flat(int64(0x41)) + expected := []byte{0x41} + if !bytes.Equal(result, expected) { + t.Errorf("Flat(int64) = %v, want %v", result, expected) + } +} + +func TestFlatMixedJSArray(t *testing.T) { + u := &Utils{} + result := u.Flat( + []interface{}{int(0x41), int64(0x42), float64(0x43)}, + ) + expected := []byte{0x41, 0x42, 0x43} + if !bytes.Equal(result, expected) { + t.Errorf("Flat mixed JS array = %v, want %v", result, expected) + } +} + +func TestPackUnpackRoundtrip(t *testing.T) { + u := &Utils{} + original16 := 0x1234 + packed16 := u.P16(original16) + unpacked16 := u.U16(packed16, 0) + if unpacked16 != original16 { + t.Errorf("P16/U16 roundtrip: got 0x%X, want 0x%X", unpacked16, original16) + } + + original32 := 0x12345678 + packed32 := u.P32(original32) + unpacked32 := u.U32(packed32, 0) + if unpacked32 != original32 { + t.Errorf("P32/U32 roundtrip: got 0x%X, want 0x%X", unpacked32, original32) + } + + original64 := int64(0x123456789ABCDEF0) + packed64 := u.P64(original64) + unpacked64 := u.U64(packed64, 0) + if unpacked64 != original64 { + t.Errorf("P64/U64 roundtrip: got 0x%X, want 0x%X", unpacked64, original64) + } +}