From 915b429eefba51f35532d22c4e2177ced6207d8f Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Fri, 9 May 2025 11:05:28 -0600 Subject: [PATCH 01/13] Added a LastSeen value to session and added automatic updating of it. Also added an Active param to the Session struct and changed the logic to RemoveSession(s) functions to set this value to false instead of deleting it --- c2/channel/channel.go | 64 +++++++++++++++++++++++++++++++++++++------ c2/cli/basic.go | 7 +++++ 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/c2/channel/channel.go b/c2/channel/channel.go index 3e51a33..e22b324 100644 --- a/c2/channel/channel.go +++ b/c2/channel/channel.go @@ -31,6 +31,8 @@ type Session struct { RemoteAddr string ConnectionTime time.Time conn *net.Conn + Active bool + LastSeen time.Time } // HasSessions checks if a channel has any tracked sessions. This can be used to lookup if a C2 @@ -39,7 +41,13 @@ type Session struct { // c, ok := c2.GetInstance(conf.C2Type) // c.Channel().HasSessions() func (c *Channel) HasSessions() bool { - return len(c.Sessions) > 0 + for _, sess := range c.Sessions { + if sess.Active { + return true + } + } + + return false } // AddSession adds a remote connection for session tracking. If a network connection is being @@ -65,11 +73,53 @@ func (c *Channel) AddSession(conn *net.Conn, addr string) bool { ConnectionTime: time.Now(), conn: conn, RemoteAddr: addr, + LastSeen: time.Now(), + Active: true, + } + + return true +} + +// Updates the LastSeen value for provided connection to the provided time +func (c *Channel) UpdateLastSeenByConn(conn net.Conn, timeStamp time.Time) bool { + id, ok := c.GetSessionIDByConn(conn) + if !ok { + return false + } + + session, ok := c.Sessions[id] + if !ok { + output.PrintFrameworkError("Session ID does not exist") + + return false } + session.LastSeen = timeStamp + c.Sessions[id] = session + return true } +// Returns the session ID that contains a given connection +func (c *Channel) GetSessionIDByConn(conn net.Conn) (string, bool) { + if len(c.Sessions) == 0 { + output.PrintFrameworkDebug("No sessions exist") + + return "", false + } + + for id, session := range c.Sessions { + if *session.conn == conn { + return id, true + } + } + + output.PrintFrameworkError("Conn does not exist in sessions") + + return "", false +} + + // RemoveSession removes a specific session ID and if a connection exists, closes it. func (c *Channel) RemoveSession(id string) bool { if len(c.Sessions) == 0 { @@ -77,7 +127,7 @@ func (c *Channel) RemoveSession(id string) bool { return false } - _, ok := c.Sessions[id] + session, ok := c.Sessions[id] if !ok { output.PrintFrameworkError("Session ID does not exist") @@ -86,7 +136,8 @@ func (c *Channel) RemoveSession(id string) bool { if c.Sessions[id].conn != nil { (*c.Sessions[id].conn).Close() } - delete(c.Sessions, id) + session.Active = false + c.Sessions[id] = session return true } @@ -98,11 +149,8 @@ func (c *Channel) RemoveSessions() bool { return false } - for k := range c.Sessions { - if c.Sessions[k].conn != nil { - (*c.Sessions[k].conn).Close() - } - delete(c.Sessions, k) + for id := range c.Sessions { + c.RemoveSession(id) } return true diff --git a/c2/cli/basic.go b/c2/cli/basic.go index 11d6c23..554bf8b 100644 --- a/c2/cli/basic.go +++ b/c2/cli/basic.go @@ -48,6 +48,13 @@ func backgroundResponse(ch *channel.Channel, wg *sync.WaitGroup, conn net.Conn, // could have move data to write, but the user has already called exit // below. I that that's tolerable for now. responseCh <- string(responseBuffer[:bytesRead]) + // Update "Last Seen" + ok := ch.UpdateLastSeenByConn(conn, time.Now()) + if !ok { + output.PrintFrameworkError("Failed to update LastSeen value for connection") + + return + } } time.Sleep(10 * time.Millisecond) } From 35ee776ad56bf3a6bab2d09dab79b854982e1679 Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Wed, 29 Oct 2025 00:38:49 -0600 Subject: [PATCH 02/13] init --- protocol/ikev2/ikev2.go | 379 +++++++++++++++++++++++++++++++++++ protocol/ikev2/ikev2_test.go | 28 +++ 2 files changed, 407 insertions(+) create mode 100644 protocol/ikev2/ikev2.go create mode 100644 protocol/ikev2/ikev2_test.go diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go new file mode 100644 index 0000000..fb3cf32 --- /dev/null +++ b/protocol/ikev2/ikev2.go @@ -0,0 +1,379 @@ +// I hate go idioms for enums, so we're doing string maps. +// The primary reason is that I want the context to be evident, much like a namespace when using the structures here. +// The intent with adding this package is not to add an entire, fully functional protocol but rather providing a convenient interface for generating the data structures for ike-related exploits. +// We will presumably add to this as we go, as needed. +package ikve2 + +import ( + "crypto/rand" + "encoding/binary" + "fmt" + "math/big" + mrand "math/rand" + "net" + + "github.com/vulncheck-oss/go-exploit/config" + "github.com/vulncheck-oss/go-exploit/output" + "github.com/vulncheck-oss/go-exploit/transform" +) + +var PayloadType = map[string]int{ + "NONE": 0, + "TRANSFORM": 3, + "SECURITY_ASSOCIATION": 33, + "KEY_EXCHANGE": 34, + "IDENTIFIER_INITIATOR": 35, + "IDENTIFIER_RESPONDER": 36, + "CERTIFICATE": 37, + "CERTIFICATE_REQUEST": 38, + "AUTHENTICATION": 39, + "NONCE": 40, + "NOTIFY": 41, + "DELETE": 42, + "VENDOR_ID": 43, + "TRAFFIC_SELECTOR_INITIATOR": 44, + "TRAFFIC_SELECTOR_RESPONDER": 45, + "ENCRYPTED": 46, + "CONFIGURATION": 47, + "EXTENSIBLE_AUTHENTICATION": 48, +} + +var ExchangeType = map[string]int{ + "IKE_SA_INIT": 34, + "IKE_AUTH": 35, + "CREATE_CHILD_SA": 36, + "INFORMATIONAL": 37, +} + +var TransformType = map[string]int{ + "ENCRYPTION_ALGORITHM": 1, + "PSEUDO_RANDOM_FUNCTION": 2, + "INTEGRITY_ALGORITHM": 3, + "DIFFIE_HELLMAN_GROUP": 4, +} + +var NotifyType = map[string]int{ + "UNSUPPORTED_CRITICAL_PAYLOAD": 1, + "INVALID_IKE_SPI": 4, + "INVALID_MAJOR_VERSION": 5, + "INVALID_SYNTAX": 7, + "INVALID_MESSAGE_ID": 9, + "INVALID_SPI": 11, + "NO_PROPOSAL_CHOSEN": 14, + "INVALID_KE_PAYLOAD": 17, + "AUTHENTICATION_FAILED": 24, + "SINGLE_PAIR_REQUIRED": 34, + "NO_ADDITIONAL_SAS": 35, + "INTERNAL_ADDRESS_FAILURE": 36, + "FAILED_CP_REQUIRED": 37, + "TS_UNACCEPTABLE": 38, + "INVALID_SELECTORS": 39, + "INITIAL_CONTACT": 16384, + "SET_WINDOW_SIZE": 16385, + "ADDITIONAL_TS_POSSIBLE": 16386, + "IPCOMP_SUPPORTED": 16387, + "NAT_DETECTION_SOURCE_IP": 16388, + "NAT_DETECTION_DESTINATION_IP": 16389, + "COOKIE": 16390, + "USE_TRANSPORT_MODE": 16391, + "HTTP_CERT_LOOKUP_SUPPORTED": 16392, + "REKEY_SA": 16393, + "ESP_TFC_PADDING_NOT_SUPPORTED": 16394, + "NON_FIRST_FRAGMENTS_ALSO": 16395, + "MOBIKE_SUPPORTED": 16396, + "MULTIPLE_AUTH_SUPPORTED": 16404, + "REDIRECT_SUPPORTED": 16406, + "IKEV2_FRAGMENTATION_SUPPORTED": 16430, + "SIGNATURE_HASH_ALGORITHMS": 16431, +} + +var ConfigurationAttribute = map[string]int{ + "INTERNAL_IP4_ADDRESS": 1, + "INTERNAL_IP4_NETMASK": 2, + "INTERNAL_IP4_DNS": 3, + "INTERNAL_IP4_MBNS": 4, + "APPLICATION_VERSION": 7, + "INTERNAL_IP6_ADDRESS": 8, + "INTERNAL_IP6_DNS": 10, +} + +var EncryptionAlgorithm = map[string]int{ + "ENCR_DES_IV64": 1, + "ENCR_DES": 2, + "ENCR_3DES": 3, + "ENCR_RC5": 4, + "ENCR_IDEA": 5, + "ENCR_CAST": 6, + "ENCR_BLOWFISH": 7, + "ENCR_3IDEA": 8, + "ENCR_DES_IV32": 9, + "RESERVED": 10, + "ENCR_NULL": 11, + "ENCR_AES_CBC": 12, + "ENCR_AES_CTR": 13, + "ENCR_AES_CCM_8": 14, + "ENCR_AES_CCM_12": 15, + "ENCR_AES_CCM_16": 16, + "ENCR_AES_GCM_8": 18, + "ENCR_AES_GCM_12": 19, + "ENCR_AES_GCM_16": 20, + "ENCR_NULL_AUTH_AES_GMAC": 21, + "P1619_XTS_AES": 22, + "ENCR_CAMELLIA_CBC": 23, + "ENCR_CAMELLIA_CTR": 24, + "ENCR_CAMELLIA_CCM_8": 25, + "ENCR_CAMELLIA_CCM_12": 26, + "ENCR_CAMELLIA_CCM_16": 27, + "ENCR_CHACHA20_POLY1305": 28, + "ENCR_AES_CCM_8_IIV": 29, + "ENCR_AES_GCM_16_IIV": 30, + "ENCR_CHACHA20_POLY1305_IIV": 31, + "ENCR_KUZNYECHIK_MGM_KTREE": 32, + "ENCR_MAGMA_MGM_KTREE": 33, + "ENCR_KUZNYECHIK_MGM_MAC_KTREE": 34, + "ENCR_MAGMA_MGM_MAC_KTREE": 35, +} + +var PseudoRandomFunction = map[string]int{ + "PRF_HMAC_MD5": 1, + "PRF_HMAC_SHA1": 2, + "PRF_HMAC_TIGER": 3, + "PRF_AES128_XCBC": 4, + "PRF_HMAC_SHA2_256": 5, + "PRF_HMAC_SHA2_384": 6, + "PRF_HMAC_SHA2_512": 7, + "PRF_AES128_CMAC": 8, + "PRF_HMAC_STREEBOG_512": 9, +} + +var IntegrityAlgorithm = map[string]int{ + "AUTH_HMAC_MD5_96": 1, + "AUTH_HMAC_SHA1_96": 2, + "AUTH_DES_MAC": 3, + "AUTH_KPDK_MD5": 4, + "AUTH_AES_XCBC_96": 5, + "AUTH_HMAC_MD5_128": 6, + "AUTH_HMAC_SHA1_160": 7, + "AUTH_AES_CMAC_96": 8, + "AUTH_AES_128_GMAC": 9, + "AUTH_AES_192_GMAC": 10, + "AUTH_AES_256_GMAC": 11, + "AUTH_HMAC_SHA2_256_128": 12, + "AUTH_HMAC_SHA2_384_192": 13, + "AUTH_HMAC_SHA2_512_256": 14, +} + +var DiffieHellmanGroup = map[string]int{ + "DH_GROUP_2048_BIT_MODP": 14, + "DH_GROUP_768_BIT_MODP": 1, + "DH_GROUP_1024_BIT_MODP": 2, + "DH_GROUP_1536_BIT_MODP": 5, + "DH_GROUP_3072_BIT_MODP": 15, + "DH_GROUP_4096_BIT_MODP": 16, + "DH_GROUP_6144_BIT_MODP": 17, + "DH_GROUP_8192_BIT_MODP": 18, + "RANDOM_ECP_GROUP_256_BIT": 19, + "RANDOM_ECP_GROUP_384_BIT": 20, + "RANDOM_ECP_GROUP_521_BIT": 21, + "DH_GROUP_1024_BIT_MODP_WITH_160_BIT_PRIME_ORDER_SUBGROUP": 22, + "DH_GROUP_2048_BIT_MODP_WITH_224_BIT_PRIME_ORDER_SUBGROUP": 23, + "DH_GROUP_2048_BIT_MODP_WITH_256_BIT_PRIME_ORDER_SUBGROUP": 24, + "RANDOM_ECP_GROUP_192_BIT": 25, + "RANDOM_ECP_GROUP_224_BIT": 26, + "BRAINPOOLP224R1": 27, + "BRAINPOOLP256R1": 28, + "BRAINPOOLP384R1": 29, + "BRAINPOOLP512R1": 30, + "CURVE25519": 31, + "CURVE448": 32, + "GOST3410_2012_256": 33, + "GOST3410_2012_512": 34, + "ML_KEM_512": 35, + "ML_KEM_768": 36, + "ML_KEM_1024": 37, +} + +type IkeClient struct { + Conf *config.Config + Conn net.Conn + IkeCrypto IkeCrypto +} + +type IkeCrypto struct { + Prime *big.Int + + InitNonce string + RespNonce string + InitSPI uint64 + RespSPI uint64 + + ClientPrivKey *big.Int + ClientPubKey *big.Int + ServerPubKey string + + SharedSecret *big.Int + SKeySeed string + SK_d string + SK_ai string + SK_ar string + SK_ei string + SK_er string +} + +func Uint64ToString(num uint64) string { + bytes := make([]byte, 8) + binary.BigEndian.PutUint64(bytes, num) + byteString := string(bytes) + return byteString +} + +func (ikeCrypto *IkeCrypto) Init() { + ikeCrypto.InitNonce = generateNonce(32) + ikeCrypto.RespNonce = "" + ikeCrypto.InitSPI = mrand.Uint64() + ikeCrypto.RespSPI = 0x0000000000000000 +} + +func generateNonce(length int) string { + nonce := make([]byte, length) + _, _ = rand.Read(nonce) + return string(nonce) +} + +type IkeProposal struct { + ProposalNumber int + ProtocolID int + SPI int + Transforms []IkeTransform +} + +func IkePackSecurityAssociation(payloadType int, proposal string) string { + // IkePacker.security_association(PayloadType["KEY_EXCHANGE"], IkePacker.proposal(PayloadType.NONE, 1, 1, transforms)) + return IkePackPayloadHeader(payloadType, proposal) +} + +type IkeTransform struct { + NextPayload int + TransformType int + TransformID int + TransformAttributes int // a bit lazy perhaps, but it gets used infrequently enough that providing an int instead of a list of maps + enums should suffice + // Reserved int = 0 +} + +func (ikeTransform *IkeTransform) Pack() string { + // def pack(self): // TODO DELETE + // transform = struct.pack('>BBH', self.transform_type, self.reserved, self.transform_id) // TODO DELETE + // if self.transform_attributes: // TODO DELETE + // transform += struct.pack('>I', self.transform_attributes) // TODO DELETE + // return IkePacker.payload_header(self.next_payload, transform) // TODO DELETE + + transformData := string(byte(ikeTransform.TransformType)) + + string(byte(0)) + // reserved byte + transform.PackBigInt16(ikeTransform.TransformID) + + if ikeTransform.TransformAttributes != 0 { + transformData += transform.PackBigInt32(ikeTransform.TransformAttributes) + } + + return IkePackPayloadHeader(ikeTransform.NextPayload, transformData) +} + +func IkePackPayloadHeader(payloadType int, payload string) string { + //def payload_header(next_payload, payload, critical = 0): // TODO DELETE + // return struct.pack('>BBH', next_payload, critical, 4 + len(payload)) + payload // TODO DELETE + return string(byte(payloadType)) + + string(byte(0)) + // critical bit + reserved (7 bits) combine to make this single 0x00 byte + transform.PackBigInt16(len(payload)+4) + payload +} + +func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) string { + var transformData string + for _, transform := range transforms { + transformData += transform.Pack() + } + payload := string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData + return IkePackPayloadHeader(nextPayload, payload) + + // return string(byte(payloadType)) + string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData + /* // TODO DELETE + def proposal(next_payload, number, id, transforms = [], spi = b''): // TODO DELETE + b_transforms = b'' // TODO DELETE + for transform in transforms: // TODO DELETE + if isinstance(transform, IkeTransform): // TODO DELETE + b_transforms += transform.pack() // TODO DELETE + continue // TODO DELETE + b_transforms += transform // TODO DELETE + return IkePacker.payload_header(next_payload, struct.pack('>BBBB', number, id, len(spi), len(transforms)) + spi + b_transforms) // TODO DELETE + */ // TODO DELETE +} + +func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) string { + return Uint64ToString(ikeClient.IkeCrypto.InitSPI) + + Uint64ToString(ikeClient.IkeCrypto.RespSPI) + + string(byte(payloadType)) + + string(byte(version)) + // default 0x20 + string(byte(exchangeType)) + + string(byte(flags)) + // default 0x08 + transform.PackBigInt32(messageID) +} + +func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { + switch diffieHellmanGroup { + case DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]: + ikeCrypto.Prime = new(big.Int) + ikeCrypto.Prime.SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) // https://www.ietf.org/rfc/rfc3526.txt + //ikeCrypto.Prime, _ = rand.Prime(rand.Reader, 2048) // TODO DELETE + g := big.NewInt(2) + ikeCrypto.ClientPrivKey, _ = rand.Int(rand.Reader, ikeCrypto.Prime) + ikeCrypto.ClientPubKey = new(big.Int).Exp(g, ikeCrypto.ClientPrivKey, ikeCrypto.Prime) + ikeCrypto.SharedSecret = new(big.Int).Exp(ikeCrypto.ClientPubKey, ikeCrypto.ClientPrivKey, ikeCrypto.Prime) + return true + + default: + output.PrintFrameworkError("Provided DH group is currently unsupported.") + return false + + } +} + +func (ikeClient *IkeClient) SAInit(diffieHellmanGroup int) (string, bool) { + ikeClient.IkeCrypto = IkeCrypto{} + ikeClient.IkeCrypto.Init() + ok := ikeClient.IkeCrypto.GenerateDHKey(diffieHellmanGroup) + if !ok { + return "", false + } + + defaultTransforms := []IkeTransform{ + IkeTransform{PayloadType["TRANSFORM"], TransformType["ENCRYPTION_ALGORITHM"], EncryptionAlgorithm["ENCR_AES_CBC"], 0x800e0100}, + IkeTransform{PayloadType["TRANSFORM"], TransformType["PSEUDO_RANDOM_FUNCTION"], PseudoRandomFunction["PRF_HMAC_SHA2_256"], 0}, + IkeTransform{PayloadType["TRANSFORM"], TransformType["INTEGRITY_ALGORITHM"], IntegrityAlgorithm["AUTH_HMAC_SHA2_256_128"], 0}, + IkeTransform{PayloadType["NONE"], TransformType["DIFFIE_HELLMAN_GROUP"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], 0}, + } + + var message string + header := IkePackHeader(ikeClient, PayloadType["SECURITY_ASSOCIATION"], 0x20, ExchangeType["IKE_SA_INIT"], 0x08, 0x0) + message += IkePackSecurityAssociation(PayloadType["KEY_EXCHANGE"], IkePackProposal(PayloadType["NONE"], 1, 1, defaultTransforms, "")) + + return header + transform.PackBigInt32(len(message)) + message, true // revisit this and make sure the ordering is correct and that the length encompasses exactly what it is intended +} + +// The initial reset/connect function. +// Should be the first step of a new connection but will likely not be run from within an exploit, but rather the +// SAInit function +func (ikeClient *IkeClient) Connect() bool { + var err error + // the connection may not be active, just want to close it if so, if it's not active, great. + _ = ikeClient.Conn.Close() + + connectionString := fmt.Sprintf("%s:%d", ikeClient.Conf.Rhost, ikeClient.Conf.Rport) + ikeClient.Conn, err = net.Dial("udp", connectionString) + if err != nil { + output.PrintfFrameworkError("Dial failed: %s", err.Error()) + + return false + } + + output.PrintfFrameworkDebug("Successfully established UDP connection to %s", connectionString) + return true +} diff --git a/protocol/ikev2/ikev2_test.go b/protocol/ikev2/ikev2_test.go new file mode 100644 index 0000000..b171694 --- /dev/null +++ b/protocol/ikev2/ikev2_test.go @@ -0,0 +1,28 @@ +package ikve2 + +import ( + "fmt" + "testing" +) + +func TestSAIinit(t *testing.T) { + ikeClient := IkeClient{} + want := "x" // TODO correct this + got, ok := ikeClient.SAInit(DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) + if !ok { + t.Fatalf("SAInit failed to run") + } + + if len(got) < 8 { + t.Fatalf("SAInit output is too short!") + } + + got = got[8:] // removing the random parts so the test can be predictable + + if fmt.Sprintf("%02x", got) != want { + t.Logf("INITSPI-> %02x", ikeClient.IkeCrypto.InitSPI) + t.Fatalf("%q : %02x != %s", got, got, want) + } + + t.Logf("%q", got) +} From 034f2f3a5fbd2569b5c7cb16f521cb0271ab40ab Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Wed, 29 Oct 2025 01:56:35 -0600 Subject: [PATCH 03/13] added more --- protocol/ikev2/ikev2.go | 85 +++++++++++++++++++-------- protocol/ikev2/ikev2_test.go | 109 +++++++++++++++++++++++++++++++---- 2 files changed, 157 insertions(+), 37 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index fb3cf32..0a30143 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -7,6 +7,7 @@ package ikve2 import ( "crypto/rand" "encoding/binary" + "encoding/hex" "fmt" "math/big" mrand "math/rand" @@ -247,8 +248,35 @@ type IkeProposal struct { Transforms []IkeTransform } +func IkePackNonce(nextPayload int, nonce string) string { + return IkePackPayloadHeader(nextPayload, nonce) +} + +func IkePackVendorID(nextPayload int, vendorID string) string { + return IkePackPayloadHeader(nextPayload, vendorID) +} + +/* +def notify(next_payload, notify_type, data = b”, protocol_id = 1, spi_size = 0): +return IkePacker.payload_header(next_payload, struct.pack('>BBH', protocol_id, spi_size, notify_type) + data) +*/ +func IkePackNotify(nextPayload int, notifyType int, data string, protocolID int, SPISize int) string { + payload := string(byte(protocolID)) + payload += string(byte(SPISize)) + payload += transform.PackBigInt16(notifyType) + payload += data + + return IkePackPayloadHeader(nextPayload, payload) +} + +func IkePackKeyExchange(nextPayload int, dhGroup int, data string) string { + // reserved = 0 + payload := transform.PackBigInt16(dhGroup) + payload += transform.PackBigInt16(0) + return IkePackPayloadHeader(nextPayload, payload+data) +} + func IkePackSecurityAssociation(payloadType int, proposal string) string { - // IkePacker.security_association(PayloadType["KEY_EXCHANGE"], IkePacker.proposal(PayloadType.NONE, 1, 1, transforms)) return IkePackPayloadHeader(payloadType, proposal) } @@ -261,12 +289,6 @@ type IkeTransform struct { } func (ikeTransform *IkeTransform) Pack() string { - // def pack(self): // TODO DELETE - // transform = struct.pack('>BBH', self.transform_type, self.reserved, self.transform_id) // TODO DELETE - // if self.transform_attributes: // TODO DELETE - // transform += struct.pack('>I', self.transform_attributes) // TODO DELETE - // return IkePacker.payload_header(self.next_payload, transform) // TODO DELETE - transformData := string(byte(ikeTransform.TransformType)) + string(byte(0)) + // reserved byte transform.PackBigInt16(ikeTransform.TransformID) @@ -279,8 +301,6 @@ func (ikeTransform *IkeTransform) Pack() string { } func IkePackPayloadHeader(payloadType int, payload string) string { - //def payload_header(next_payload, payload, critical = 0): // TODO DELETE - // return struct.pack('>BBH', next_payload, critical, 4 + len(payload)) + payload // TODO DELETE return string(byte(payloadType)) + string(byte(0)) + // critical bit + reserved (7 bits) combine to make this single 0x00 byte transform.PackBigInt16(len(payload)+4) + payload @@ -294,17 +314,6 @@ func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransf payload := string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData return IkePackPayloadHeader(nextPayload, payload) - // return string(byte(payloadType)) + string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData - /* // TODO DELETE - def proposal(next_payload, number, id, transforms = [], spi = b''): // TODO DELETE - b_transforms = b'' // TODO DELETE - for transform in transforms: // TODO DELETE - if isinstance(transform, IkeTransform): // TODO DELETE - b_transforms += transform.pack() // TODO DELETE - continue // TODO DELETE - b_transforms += transform // TODO DELETE - return IkePacker.payload_header(next_payload, struct.pack('>BBBB', number, id, len(spi), len(transforms)) + spi + b_transforms) // TODO DELETE - */ // TODO DELETE } func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) string { @@ -345,17 +354,43 @@ func (ikeClient *IkeClient) SAInit(diffieHellmanGroup int) (string, bool) { } defaultTransforms := []IkeTransform{ - IkeTransform{PayloadType["TRANSFORM"], TransformType["ENCRYPTION_ALGORITHM"], EncryptionAlgorithm["ENCR_AES_CBC"], 0x800e0100}, - IkeTransform{PayloadType["TRANSFORM"], TransformType["PSEUDO_RANDOM_FUNCTION"], PseudoRandomFunction["PRF_HMAC_SHA2_256"], 0}, - IkeTransform{PayloadType["TRANSFORM"], TransformType["INTEGRITY_ALGORITHM"], IntegrityAlgorithm["AUTH_HMAC_SHA2_256_128"], 0}, - IkeTransform{PayloadType["NONE"], TransformType["DIFFIE_HELLMAN_GROUP"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], 0}, + {PayloadType["TRANSFORM"], TransformType["ENCRYPTION_ALGORITHM"], EncryptionAlgorithm["ENCR_AES_CBC"], 0x800e0100}, + {PayloadType["TRANSFORM"], TransformType["PSEUDO_RANDOM_FUNCTION"], PseudoRandomFunction["PRF_HMAC_SHA2_256"], 0}, + {PayloadType["TRANSFORM"], TransformType["INTEGRITY_ALGORITHM"], IntegrityAlgorithm["AUTH_HMAC_SHA2_256_128"], 0}, + {PayloadType["NONE"], TransformType["DIFFIE_HELLMAN_GROUP"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], 0}, } var message string header := IkePackHeader(ikeClient, PayloadType["SECURITY_ASSOCIATION"], 0x20, ExchangeType["IKE_SA_INIT"], 0x08, 0x0) message += IkePackSecurityAssociation(PayloadType["KEY_EXCHANGE"], IkePackProposal(PayloadType["NONE"], 1, 1, defaultTransforms, "")) + message += IkePackKeyExchange(PayloadType["NONCE"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], string(ikeClient.IkeCrypto.ClientPubKey.Bytes())) + message += IkePackNonce(PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) + + tempBytes, _ := hex.DecodeString("a6358d813592fdd80a9aaa3390f39c8a5a76b6e4") + message += IkePackNotify(PayloadType["NOTIFY"], NotifyType["NAT_DETECTION_DESTINATION_IP"], string(tempBytes), 1, 0) + + tempBytes, _ = hex.DecodeString("4cc324152ba3f68ef649ac1e6f96f33791611db2") + message += IkePackNotify(PayloadType["VENDOR_ID"], NotifyType["NAT_DETECTION_SOURCE_IP"], string(tempBytes), 1, 0) + + tempBytes, _ = hex.DecodeString("c590254e5403cbb71f3d493111d7fcad") + message += IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + + tempBytes, _ = hex.DecodeString("c61baca1f1a60cc10800000000000000") + message += IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + + tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3c0000000") + message += IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + + tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") + message += IkePackVendorID(PayloadType["NOTIFY"], string(tempBytes)) + + message += IkePackNotify(PayloadType["NOTIFY"], NotifyType["IKEV2_FRAGMENTATION_SUPPORTED"], "", 0, 0) + message += IkePackNotify(PayloadType["NOTIFY"], NotifyType["REDIRECT_SUPPORTED"], "", 0, 0) + + tempBytes, _ = hex.DecodeString("0001000200030004") + message += IkePackNotify(PayloadType["NONE"], NotifyType["SIGNATURE_HASH_ALGORITHMS"], string(tempBytes), 0, 0) - return header + transform.PackBigInt32(len(message)) + message, true // revisit this and make sure the ordering is correct and that the length encompasses exactly what it is intended + return header + transform.PackBigInt32(len(message)+len(header)+4) + message, true // revisit this and make sure the ordering is correct and that the length encompasses exactly what it is intended } // The initial reset/connect function. diff --git a/protocol/ikev2/ikev2_test.go b/protocol/ikev2/ikev2_test.go index b171694..cbe95b6 100644 --- a/protocol/ikev2/ikev2_test.go +++ b/protocol/ikev2/ikev2_test.go @@ -1,28 +1,113 @@ package ikve2 import ( + "encoding/hex" "fmt" "testing" ) -func TestSAIinit(t *testing.T) { - ikeClient := IkeClient{} - want := "x" // TODO correct this - got, ok := ikeClient.SAInit(DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) - if !ok { - t.Fatalf("SAInit failed to run") +func TestVendorIDPack(t *testing.T) { + want := "2b000014c590254e5403cbb71f3d493111d7fcad" + tempBytes, _ := hex.DecodeString("c590254e5403cbb71f3d493111d7fcad") + got := IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[1] %q : %02x != %s", got, got, want) + } + + want = "2b000014c61baca1f1a60cc10800000000000000" + tempBytes, _ = hex.DecodeString("c61baca1f1a60cc10800000000000000") + got = IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[2] %q : %02x != %s", got, got, want) + } + + want = "2b0000184048b7d56ebce88525e7de7f00d6c2d3c0000000" + tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3c0000000") + got = IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[3] %q : %02x != %s", got, got, want) + } + + want = "290000144048b7d56ebce88525e7de7f00d6c2d3" + tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") + got = IkePackVendorID(PayloadType["NOTIFY"], string(tempBytes)) + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[4] %q : %02x != %s", got, got, want) + } + +} + +func TestSecurityAssociationPack(t *testing.T) { + want := "220000300000002c010100040300000c0100000c800e01000300000802000005030000080300000c000000080400000e" + defaultTransforms := []IkeTransform{ + {PayloadType["TRANSFORM"], TransformType["ENCRYPTION_ALGORITHM"], EncryptionAlgorithm["ENCR_AES_CBC"], 0x800e0100}, + {PayloadType["TRANSFORM"], TransformType["PSEUDO_RANDOM_FUNCTION"], PseudoRandomFunction["PRF_HMAC_SHA2_256"], 0}, + {PayloadType["TRANSFORM"], TransformType["INTEGRITY_ALGORITHM"], IntegrityAlgorithm["AUTH_HMAC_SHA2_256_128"], 0}, + {PayloadType["NONE"], TransformType["DIFFIE_HELLMAN_GROUP"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], 0}, } + got := IkePackSecurityAssociation(PayloadType["KEY_EXCHANGE"], IkePackProposal(PayloadType["NONE"], 1, 1, defaultTransforms, "")) - if len(got) < 8 { - t.Fatalf("SAInit output is too short!") + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[1] %q : %02x != %s", got, got, want) } +} - got = got[8:] // removing the random parts so the test can be predictable +func TestNotifyPack(t *testing.T) { + want := "2900001c01004005a6358d813592fdd80a9aaa3390f39c8a5a76b6e4" + tempBytes, _ := hex.DecodeString("a6358d813592fdd80a9aaa3390f39c8a5a76b6e4") + got := IkePackNotify(PayloadType["NOTIFY"], NotifyType["NAT_DETECTION_DESTINATION_IP"], string(tempBytes), 1, 0) + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[1] %q : %02x != %s", got, got, want) + } + want = "2b00001c010040044cc324152ba3f68ef649ac1e6f96f33791611db2" + tempBytes, _ = hex.DecodeString("4cc324152ba3f68ef649ac1e6f96f33791611db2") + got = IkePackNotify(PayloadType["VENDOR_ID"], NotifyType["NAT_DETECTION_SOURCE_IP"], string(tempBytes), 1, 0) if fmt.Sprintf("%02x", got) != want { - t.Logf("INITSPI-> %02x", ikeClient.IkeCrypto.InitSPI) - t.Fatalf("%q : %02x != %s", got, got, want) + t.Fatalf("[2] %q : %02x != %s", got, got, want) } - t.Logf("%q", got) + want = "290000080000402e" + got = IkePackNotify(PayloadType["NOTIFY"], NotifyType["IKEV2_FRAGMENTATION_SUPPORTED"], "", 0, 0) + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[3] %q : %02x != %s", got, got, want) + } + + want = "2900000800004016" + got = IkePackNotify(PayloadType["NOTIFY"], NotifyType["REDIRECT_SUPPORTED"], "", 0, 0) + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[4] %q : %02x != %s", got, got, want) + } + + want = "000000100000402f0001000200030004" + tempBytes, _ = hex.DecodeString("0001000200030004") + got = IkePackNotify(PayloadType["NONE"], NotifyType["SIGNATURE_HASH_ALGORITHMS"], string(tempBytes), 0, 0) + if fmt.Sprintf("%02x", got) != want { + t.Fatalf("[5] %q : %02x != %s", got, got, want) + } } + +//func TestSAIinit(t *testing.T) { +//ikeClient := IkeClient{} +//want := "x" // TODO correct this +//got, ok := ikeClient.SAInit(DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) +//if !ok { +//t.Fatalf("SAInit failed to run") +//} + +//if len(got) < 8 { +//t.Fatalf("SAInit output is too short!") +//} + +//got = got[8:] // removing the random parts so the test can be predictable + +//if fmt.Sprintf("%02x", got) != want { +//t.Logf("INITSPI-> %02x", ikeClient.IkeCrypto.InitSPI) +//t.Fatalf("%q : %02x != %s", got, got, want) +//} + +//t.Logf("%q", got) +//} From 20c756325ccab58c23466b5575cc82189762996b Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Wed, 29 Oct 2025 03:08:23 -0600 Subject: [PATCH 04/13] more updates --- protocol/ikev2/ikev2.go | 15 ++++++++++----- protocol/ikev2/ikev2_test.go | 24 +----------------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 0a30143..97033ac 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -2,7 +2,7 @@ // The primary reason is that I want the context to be evident, much like a namespace when using the structures here. // The intent with adding this package is not to add an entire, fully functional protocol but rather providing a convenient interface for generating the data structures for ike-related exploits. // We will presumably add to this as we go, as needed. -package ikve2 +package ikev2 import ( "crypto/rand" @@ -195,7 +195,6 @@ var DiffieHellmanGroup = map[string]int{ } type IkeClient struct { - Conf *config.Config Conn net.Conn IkeCrypto IkeCrypto } @@ -396,12 +395,18 @@ func (ikeClient *IkeClient) SAInit(diffieHellmanGroup int) (string, bool) { // The initial reset/connect function. // Should be the first step of a new connection but will likely not be run from within an exploit, but rather the // SAInit function -func (ikeClient *IkeClient) Connect() bool { +func (ikeClient *IkeClient) Connect(conf *config.Config) bool { var err error // the connection may not be active, just want to close it if so, if it's not active, great. - _ = ikeClient.Conn.Close() + if ikeClient.Conn != nil { + err = ikeClient.Conn.Close() + if err != nil { + output.PrintfFrameworkWarn("Failed to close socket: %s", err.Error()) + // we probably do not want to exit on this, we're establishing a new connection anyways + } + } - connectionString := fmt.Sprintf("%s:%d", ikeClient.Conf.Rhost, ikeClient.Conf.Rport) + connectionString := fmt.Sprintf("%s:%d", conf.Rhost, conf.Rport) ikeClient.Conn, err = net.Dial("udp", connectionString) if err != nil { output.PrintfFrameworkError("Dial failed: %s", err.Error()) diff --git a/protocol/ikev2/ikev2_test.go b/protocol/ikev2/ikev2_test.go index cbe95b6..12c2927 100644 --- a/protocol/ikev2/ikev2_test.go +++ b/protocol/ikev2/ikev2_test.go @@ -1,4 +1,4 @@ -package ikve2 +package ikev2 import ( "encoding/hex" @@ -89,25 +89,3 @@ func TestNotifyPack(t *testing.T) { t.Fatalf("[5] %q : %02x != %s", got, got, want) } } - -//func TestSAIinit(t *testing.T) { -//ikeClient := IkeClient{} -//want := "x" // TODO correct this -//got, ok := ikeClient.SAInit(DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) -//if !ok { -//t.Fatalf("SAInit failed to run") -//} - -//if len(got) < 8 { -//t.Fatalf("SAInit output is too short!") -//} - -//got = got[8:] // removing the random parts so the test can be predictable - -//if fmt.Sprintf("%02x", got) != want { -//t.Logf("INITSPI-> %02x", ikeClient.IkeCrypto.InitSPI) -//t.Fatalf("%q : %02x != %s", got, got, want) -//} - -//t.Logf("%q", got) -//} From 4a9bb46602bd35d79c52318ec03e403ec351e62f Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Wed, 29 Oct 2025 23:25:36 -0600 Subject: [PATCH 05/13] cleanup --- protocol/ikev2/ikev2.go | 311 ++--------------------------------- protocol/ikev2/ikev2_test.go | 1 - protocol/ikev2/packs.go | 74 +++++++++ protocol/ikev2/types.go | 223 +++++++++++++++++++++++++ 4 files changed, 311 insertions(+), 298 deletions(-) create mode 100644 protocol/ikev2/packs.go create mode 100644 protocol/ikev2/types.go diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 97033ac..7f1fb69 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -18,311 +18,19 @@ import ( "github.com/vulncheck-oss/go-exploit/transform" ) -var PayloadType = map[string]int{ - "NONE": 0, - "TRANSFORM": 3, - "SECURITY_ASSOCIATION": 33, - "KEY_EXCHANGE": 34, - "IDENTIFIER_INITIATOR": 35, - "IDENTIFIER_RESPONDER": 36, - "CERTIFICATE": 37, - "CERTIFICATE_REQUEST": 38, - "AUTHENTICATION": 39, - "NONCE": 40, - "NOTIFY": 41, - "DELETE": 42, - "VENDOR_ID": 43, - "TRAFFIC_SELECTOR_INITIATOR": 44, - "TRAFFIC_SELECTOR_RESPONDER": 45, - "ENCRYPTED": 46, - "CONFIGURATION": 47, - "EXTENSIBLE_AUTHENTICATION": 48, -} - -var ExchangeType = map[string]int{ - "IKE_SA_INIT": 34, - "IKE_AUTH": 35, - "CREATE_CHILD_SA": 36, - "INFORMATIONAL": 37, -} - -var TransformType = map[string]int{ - "ENCRYPTION_ALGORITHM": 1, - "PSEUDO_RANDOM_FUNCTION": 2, - "INTEGRITY_ALGORITHM": 3, - "DIFFIE_HELLMAN_GROUP": 4, -} - -var NotifyType = map[string]int{ - "UNSUPPORTED_CRITICAL_PAYLOAD": 1, - "INVALID_IKE_SPI": 4, - "INVALID_MAJOR_VERSION": 5, - "INVALID_SYNTAX": 7, - "INVALID_MESSAGE_ID": 9, - "INVALID_SPI": 11, - "NO_PROPOSAL_CHOSEN": 14, - "INVALID_KE_PAYLOAD": 17, - "AUTHENTICATION_FAILED": 24, - "SINGLE_PAIR_REQUIRED": 34, - "NO_ADDITIONAL_SAS": 35, - "INTERNAL_ADDRESS_FAILURE": 36, - "FAILED_CP_REQUIRED": 37, - "TS_UNACCEPTABLE": 38, - "INVALID_SELECTORS": 39, - "INITIAL_CONTACT": 16384, - "SET_WINDOW_SIZE": 16385, - "ADDITIONAL_TS_POSSIBLE": 16386, - "IPCOMP_SUPPORTED": 16387, - "NAT_DETECTION_SOURCE_IP": 16388, - "NAT_DETECTION_DESTINATION_IP": 16389, - "COOKIE": 16390, - "USE_TRANSPORT_MODE": 16391, - "HTTP_CERT_LOOKUP_SUPPORTED": 16392, - "REKEY_SA": 16393, - "ESP_TFC_PADDING_NOT_SUPPORTED": 16394, - "NON_FIRST_FRAGMENTS_ALSO": 16395, - "MOBIKE_SUPPORTED": 16396, - "MULTIPLE_AUTH_SUPPORTED": 16404, - "REDIRECT_SUPPORTED": 16406, - "IKEV2_FRAGMENTATION_SUPPORTED": 16430, - "SIGNATURE_HASH_ALGORITHMS": 16431, -} - -var ConfigurationAttribute = map[string]int{ - "INTERNAL_IP4_ADDRESS": 1, - "INTERNAL_IP4_NETMASK": 2, - "INTERNAL_IP4_DNS": 3, - "INTERNAL_IP4_MBNS": 4, - "APPLICATION_VERSION": 7, - "INTERNAL_IP6_ADDRESS": 8, - "INTERNAL_IP6_DNS": 10, -} - -var EncryptionAlgorithm = map[string]int{ - "ENCR_DES_IV64": 1, - "ENCR_DES": 2, - "ENCR_3DES": 3, - "ENCR_RC5": 4, - "ENCR_IDEA": 5, - "ENCR_CAST": 6, - "ENCR_BLOWFISH": 7, - "ENCR_3IDEA": 8, - "ENCR_DES_IV32": 9, - "RESERVED": 10, - "ENCR_NULL": 11, - "ENCR_AES_CBC": 12, - "ENCR_AES_CTR": 13, - "ENCR_AES_CCM_8": 14, - "ENCR_AES_CCM_12": 15, - "ENCR_AES_CCM_16": 16, - "ENCR_AES_GCM_8": 18, - "ENCR_AES_GCM_12": 19, - "ENCR_AES_GCM_16": 20, - "ENCR_NULL_AUTH_AES_GMAC": 21, - "P1619_XTS_AES": 22, - "ENCR_CAMELLIA_CBC": 23, - "ENCR_CAMELLIA_CTR": 24, - "ENCR_CAMELLIA_CCM_8": 25, - "ENCR_CAMELLIA_CCM_12": 26, - "ENCR_CAMELLIA_CCM_16": 27, - "ENCR_CHACHA20_POLY1305": 28, - "ENCR_AES_CCM_8_IIV": 29, - "ENCR_AES_GCM_16_IIV": 30, - "ENCR_CHACHA20_POLY1305_IIV": 31, - "ENCR_KUZNYECHIK_MGM_KTREE": 32, - "ENCR_MAGMA_MGM_KTREE": 33, - "ENCR_KUZNYECHIK_MGM_MAC_KTREE": 34, - "ENCR_MAGMA_MGM_MAC_KTREE": 35, -} - -var PseudoRandomFunction = map[string]int{ - "PRF_HMAC_MD5": 1, - "PRF_HMAC_SHA1": 2, - "PRF_HMAC_TIGER": 3, - "PRF_AES128_XCBC": 4, - "PRF_HMAC_SHA2_256": 5, - "PRF_HMAC_SHA2_384": 6, - "PRF_HMAC_SHA2_512": 7, - "PRF_AES128_CMAC": 8, - "PRF_HMAC_STREEBOG_512": 9, -} - -var IntegrityAlgorithm = map[string]int{ - "AUTH_HMAC_MD5_96": 1, - "AUTH_HMAC_SHA1_96": 2, - "AUTH_DES_MAC": 3, - "AUTH_KPDK_MD5": 4, - "AUTH_AES_XCBC_96": 5, - "AUTH_HMAC_MD5_128": 6, - "AUTH_HMAC_SHA1_160": 7, - "AUTH_AES_CMAC_96": 8, - "AUTH_AES_128_GMAC": 9, - "AUTH_AES_192_GMAC": 10, - "AUTH_AES_256_GMAC": 11, - "AUTH_HMAC_SHA2_256_128": 12, - "AUTH_HMAC_SHA2_384_192": 13, - "AUTH_HMAC_SHA2_512_256": 14, -} - -var DiffieHellmanGroup = map[string]int{ - "DH_GROUP_2048_BIT_MODP": 14, - "DH_GROUP_768_BIT_MODP": 1, - "DH_GROUP_1024_BIT_MODP": 2, - "DH_GROUP_1536_BIT_MODP": 5, - "DH_GROUP_3072_BIT_MODP": 15, - "DH_GROUP_4096_BIT_MODP": 16, - "DH_GROUP_6144_BIT_MODP": 17, - "DH_GROUP_8192_BIT_MODP": 18, - "RANDOM_ECP_GROUP_256_BIT": 19, - "RANDOM_ECP_GROUP_384_BIT": 20, - "RANDOM_ECP_GROUP_521_BIT": 21, - "DH_GROUP_1024_BIT_MODP_WITH_160_BIT_PRIME_ORDER_SUBGROUP": 22, - "DH_GROUP_2048_BIT_MODP_WITH_224_BIT_PRIME_ORDER_SUBGROUP": 23, - "DH_GROUP_2048_BIT_MODP_WITH_256_BIT_PRIME_ORDER_SUBGROUP": 24, - "RANDOM_ECP_GROUP_192_BIT": 25, - "RANDOM_ECP_GROUP_224_BIT": 26, - "BRAINPOOLP224R1": 27, - "BRAINPOOLP256R1": 28, - "BRAINPOOLP384R1": 29, - "BRAINPOOLP512R1": 30, - "CURVE25519": 31, - "CURVE448": 32, - "GOST3410_2012_256": 33, - "GOST3410_2012_512": 34, - "ML_KEM_512": 35, - "ML_KEM_768": 36, - "ML_KEM_1024": 37, -} - -type IkeClient struct { - Conn net.Conn - IkeCrypto IkeCrypto -} - -type IkeCrypto struct { - Prime *big.Int - - InitNonce string - RespNonce string - InitSPI uint64 - RespSPI uint64 - - ClientPrivKey *big.Int - ClientPubKey *big.Int - ServerPubKey string - - SharedSecret *big.Int - SKeySeed string - SK_d string - SK_ai string - SK_ar string - SK_ei string - SK_er string -} - func Uint64ToString(num uint64) string { bytes := make([]byte, 8) binary.BigEndian.PutUint64(bytes, num) byteString := string(bytes) - return byteString -} -func (ikeCrypto *IkeCrypto) Init() { - ikeCrypto.InitNonce = generateNonce(32) - ikeCrypto.RespNonce = "" - ikeCrypto.InitSPI = mrand.Uint64() - ikeCrypto.RespSPI = 0x0000000000000000 + return byteString } func generateNonce(length int) string { nonce := make([]byte, length) _, _ = rand.Read(nonce) - return string(nonce) -} - -type IkeProposal struct { - ProposalNumber int - ProtocolID int - SPI int - Transforms []IkeTransform -} -func IkePackNonce(nextPayload int, nonce string) string { - return IkePackPayloadHeader(nextPayload, nonce) -} - -func IkePackVendorID(nextPayload int, vendorID string) string { - return IkePackPayloadHeader(nextPayload, vendorID) -} - -/* -def notify(next_payload, notify_type, data = b”, protocol_id = 1, spi_size = 0): -return IkePacker.payload_header(next_payload, struct.pack('>BBH', protocol_id, spi_size, notify_type) + data) -*/ -func IkePackNotify(nextPayload int, notifyType int, data string, protocolID int, SPISize int) string { - payload := string(byte(protocolID)) - payload += string(byte(SPISize)) - payload += transform.PackBigInt16(notifyType) - payload += data - - return IkePackPayloadHeader(nextPayload, payload) -} - -func IkePackKeyExchange(nextPayload int, dhGroup int, data string) string { - // reserved = 0 - payload := transform.PackBigInt16(dhGroup) - payload += transform.PackBigInt16(0) - return IkePackPayloadHeader(nextPayload, payload+data) -} - -func IkePackSecurityAssociation(payloadType int, proposal string) string { - return IkePackPayloadHeader(payloadType, proposal) -} - -type IkeTransform struct { - NextPayload int - TransformType int - TransformID int - TransformAttributes int // a bit lazy perhaps, but it gets used infrequently enough that providing an int instead of a list of maps + enums should suffice - // Reserved int = 0 -} - -func (ikeTransform *IkeTransform) Pack() string { - transformData := string(byte(ikeTransform.TransformType)) + - string(byte(0)) + // reserved byte - transform.PackBigInt16(ikeTransform.TransformID) - - if ikeTransform.TransformAttributes != 0 { - transformData += transform.PackBigInt32(ikeTransform.TransformAttributes) - } - - return IkePackPayloadHeader(ikeTransform.NextPayload, transformData) -} - -func IkePackPayloadHeader(payloadType int, payload string) string { - return string(byte(payloadType)) + - string(byte(0)) + // critical bit + reserved (7 bits) combine to make this single 0x00 byte - transform.PackBigInt16(len(payload)+4) + payload -} - -func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) string { - var transformData string - for _, transform := range transforms { - transformData += transform.Pack() - } - payload := string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData - return IkePackPayloadHeader(nextPayload, payload) - -} - -func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) string { - return Uint64ToString(ikeClient.IkeCrypto.InitSPI) + - Uint64ToString(ikeClient.IkeCrypto.RespSPI) + - string(byte(payloadType)) + - string(byte(version)) + // default 0x20 - string(byte(exchangeType)) + - string(byte(flags)) + // default 0x08 - transform.PackBigInt32(messageID) + return string(nonce) } func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { @@ -330,20 +38,28 @@ func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { case DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]: ikeCrypto.Prime = new(big.Int) ikeCrypto.Prime.SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) // https://www.ietf.org/rfc/rfc3526.txt - //ikeCrypto.Prime, _ = rand.Prime(rand.Reader, 2048) // TODO DELETE + // ikeCrypto.Prime, _ = rand.Prime(rand.Reader, 2048) // TODO DELETE g := big.NewInt(2) ikeCrypto.ClientPrivKey, _ = rand.Int(rand.Reader, ikeCrypto.Prime) ikeCrypto.ClientPubKey = new(big.Int).Exp(g, ikeCrypto.ClientPrivKey, ikeCrypto.Prime) ikeCrypto.SharedSecret = new(big.Int).Exp(ikeCrypto.ClientPubKey, ikeCrypto.ClientPrivKey, ikeCrypto.Prime) + return true default: output.PrintFrameworkError("Provided DH group is currently unsupported.") - return false + return false } } +func (ikeCrypto *IkeCrypto) Init() { + ikeCrypto.InitNonce = generateNonce(32) + ikeCrypto.RespNonce = "" + ikeCrypto.InitSPI = mrand.Uint64() + ikeCrypto.RespSPI = 0x0000000000000000 +} + func (ikeClient *IkeClient) SAInit(diffieHellmanGroup int) (string, bool) { ikeClient.IkeCrypto = IkeCrypto{} ikeClient.IkeCrypto.Init() @@ -394,7 +110,7 @@ func (ikeClient *IkeClient) SAInit(diffieHellmanGroup int) (string, bool) { // The initial reset/connect function. // Should be the first step of a new connection but will likely not be run from within an exploit, but rather the -// SAInit function +// SAInit function. func (ikeClient *IkeClient) Connect(conf *config.Config) bool { var err error // the connection may not be active, just want to close it if so, if it's not active, great. @@ -415,5 +131,6 @@ func (ikeClient *IkeClient) Connect(conf *config.Config) bool { } output.PrintfFrameworkDebug("Successfully established UDP connection to %s", connectionString) + return true } diff --git a/protocol/ikev2/ikev2_test.go b/protocol/ikev2/ikev2_test.go index 12c2927..0b10369 100644 --- a/protocol/ikev2/ikev2_test.go +++ b/protocol/ikev2/ikev2_test.go @@ -37,7 +37,6 @@ func TestVendorIDPack(t *testing.T) { if fmt.Sprintf("%02x", got) != want { t.Fatalf("[4] %q : %02x != %s", got, got, want) } - } func TestSecurityAssociationPack(t *testing.T) { diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go new file mode 100644 index 0000000..af0f470 --- /dev/null +++ b/protocol/ikev2/packs.go @@ -0,0 +1,74 @@ +package ikev2 + +import "github.com/vulncheck-oss/go-exploit/transform" + +func IkePackNonce(nextPayload int, nonce string) string { + return IkePackPayloadHeader(nextPayload, nonce) +} + +func IkePackVendorID(nextPayload int, vendorID string) string { + return IkePackPayloadHeader(nextPayload, vendorID) +} + +/* +def notify(next_payload, notify_type, data = b”, protocol_id = 1, spi_size = 0): +return IkePacker.payload_header(next_payload, struct.pack('>BBH', protocol_id, spi_size, notify_type) + data). +*/ +func IkePackNotify(nextPayload int, notifyType int, data string, protocolID int, spiSize int) string { + payload := string(byte(protocolID)) + payload += string(byte(spiSize)) + payload += transform.PackBigInt16(notifyType) + payload += data + + return IkePackPayloadHeader(nextPayload, payload) +} + +func IkePackKeyExchange(nextPayload int, dhGroup int, data string) string { + // reserved = 0 + payload := transform.PackBigInt16(dhGroup) + payload += transform.PackBigInt16(0) + + return IkePackPayloadHeader(nextPayload, payload+data) +} + +func IkePackSecurityAssociation(payloadType int, proposal string) string { + return IkePackPayloadHeader(payloadType, proposal) +} + +func (ikeTransform *IkeTransform) Pack() string { + transformData := string(byte(ikeTransform.TransformType)) + + string(byte(0)) + // reserved byte + transform.PackBigInt16(ikeTransform.TransformID) + + if ikeTransform.TransformAttributes != 0 { + transformData += transform.PackBigInt32(ikeTransform.TransformAttributes) + } + + return IkePackPayloadHeader(ikeTransform.NextPayload, transformData) +} + +func IkePackPayloadHeader(payloadType int, payload string) string { + return string(byte(payloadType)) + + string(byte(0)) + // critical bit + reserved (7 bits) combine to make this single 0x00 byte + transform.PackBigInt16(len(payload)+4) + payload +} + +func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) string { + var transformData string + for _, transform := range transforms { + transformData += transform.Pack() + } + payload := string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData + + return IkePackPayloadHeader(nextPayload, payload) +} + +func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) string { + return Uint64ToString(ikeClient.IkeCrypto.InitSPI) + + Uint64ToString(ikeClient.IkeCrypto.RespSPI) + + string(byte(payloadType)) + + string(byte(version)) + // default 0x20 + string(byte(exchangeType)) + + string(byte(flags)) + // default 0x08 + transform.PackBigInt32(messageID) +} diff --git a/protocol/ikev2/types.go b/protocol/ikev2/types.go new file mode 100644 index 0000000..774b8fe --- /dev/null +++ b/protocol/ikev2/types.go @@ -0,0 +1,223 @@ +package ikev2 + +import ( + "math/big" + "net" +) + +var PayloadType = map[string]int{ + "NONE": 0, + "TRANSFORM": 3, + "SECURITY_ASSOCIATION": 33, + "KEY_EXCHANGE": 34, + "IDENTIFIER_INITIATOR": 35, + "IDENTIFIER_RESPONDER": 36, + "CERTIFICATE": 37, + "CERTIFICATE_REQUEST": 38, + "AUTHENTICATION": 39, + "NONCE": 40, + "NOTIFY": 41, + "DELETE": 42, + "VENDOR_ID": 43, + "TRAFFIC_SELECTOR_INITIATOR": 44, + "TRAFFIC_SELECTOR_RESPONDER": 45, + "ENCRYPTED": 46, + "CONFIGURATION": 47, + "EXTENSIBLE_AUTHENTICATION": 48, +} + +var ExchangeType = map[string]int{ + "IKE_SA_INIT": 34, + "IKE_AUTH": 35, + "CREATE_CHILD_SA": 36, + "INFORMATIONAL": 37, +} + +var TransformType = map[string]int{ + "ENCRYPTION_ALGORITHM": 1, + "PSEUDO_RANDOM_FUNCTION": 2, + "INTEGRITY_ALGORITHM": 3, + "DIFFIE_HELLMAN_GROUP": 4, +} + +var NotifyType = map[string]int{ + "UNSUPPORTED_CRITICAL_PAYLOAD": 1, + "INVALID_IKE_SPI": 4, + "INVALID_MAJOR_VERSION": 5, + "INVALID_SYNTAX": 7, + "INVALID_MESSAGE_ID": 9, + "INVALID_SPI": 11, + "NO_PROPOSAL_CHOSEN": 14, + "INVALID_KE_PAYLOAD": 17, + "AUTHENTICATION_FAILED": 24, + "SINGLE_PAIR_REQUIRED": 34, + "NO_ADDITIONAL_SAS": 35, + "INTERNAL_ADDRESS_FAILURE": 36, + "FAILED_CP_REQUIRED": 37, + "TS_UNACCEPTABLE": 38, + "INVALID_SELECTORS": 39, + "INITIAL_CONTACT": 16384, + "SET_WINDOW_SIZE": 16385, + "ADDITIONAL_TS_POSSIBLE": 16386, + "IPCOMP_SUPPORTED": 16387, + "NAT_DETECTION_SOURCE_IP": 16388, + "NAT_DETECTION_DESTINATION_IP": 16389, + "COOKIE": 16390, + "USE_TRANSPORT_MODE": 16391, + "HTTP_CERT_LOOKUP_SUPPORTED": 16392, + "REKEY_SA": 16393, + "ESP_TFC_PADDING_NOT_SUPPORTED": 16394, + "NON_FIRST_FRAGMENTS_ALSO": 16395, + "MOBIKE_SUPPORTED": 16396, + "MULTIPLE_AUTH_SUPPORTED": 16404, + "REDIRECT_SUPPORTED": 16406, + "IKEV2_FRAGMENTATION_SUPPORTED": 16430, + "SIGNATURE_HASH_ALGORITHMS": 16431, +} + +var ConfigurationAttribute = map[string]int{ + "INTERNAL_IP4_ADDRESS": 1, + "INTERNAL_IP4_NETMASK": 2, + "INTERNAL_IP4_DNS": 3, + "INTERNAL_IP4_MBNS": 4, + "APPLICATION_VERSION": 7, + "INTERNAL_IP6_ADDRESS": 8, + "INTERNAL_IP6_DNS": 10, +} + +var EncryptionAlgorithm = map[string]int{ + "ENCR_DES_IV64": 1, + "ENCR_DES": 2, + "ENCR_3DES": 3, + "ENCR_RC5": 4, + "ENCR_IDEA": 5, + "ENCR_CAST": 6, + "ENCR_BLOWFISH": 7, + "ENCR_3IDEA": 8, + "ENCR_DES_IV32": 9, + "RESERVED": 10, + "ENCR_NULL": 11, + "ENCR_AES_CBC": 12, + "ENCR_AES_CTR": 13, + "ENCR_AES_CCM_8": 14, + "ENCR_AES_CCM_12": 15, + "ENCR_AES_CCM_16": 16, + "ENCR_AES_GCM_8": 18, + "ENCR_AES_GCM_12": 19, + "ENCR_AES_GCM_16": 20, + "ENCR_NULL_AUTH_AES_GMAC": 21, + "P1619_XTS_AES": 22, + "ENCR_CAMELLIA_CBC": 23, + "ENCR_CAMELLIA_CTR": 24, + "ENCR_CAMELLIA_CCM_8": 25, + "ENCR_CAMELLIA_CCM_12": 26, + "ENCR_CAMELLIA_CCM_16": 27, + "ENCR_CHACHA20_POLY1305": 28, + "ENCR_AES_CCM_8_IIV": 29, + "ENCR_AES_GCM_16_IIV": 30, + "ENCR_CHACHA20_POLY1305_IIV": 31, + "ENCR_KUZNYECHIK_MGM_KTREE": 32, + "ENCR_MAGMA_MGM_KTREE": 33, + "ENCR_KUZNYECHIK_MGM_MAC_KTREE": 34, + "ENCR_MAGMA_MGM_MAC_KTREE": 35, +} + +var PseudoRandomFunction = map[string]int{ + "PRF_HMAC_MD5": 1, + "PRF_HMAC_SHA1": 2, + "PRF_HMAC_TIGER": 3, + "PRF_AES128_XCBC": 4, + "PRF_HMAC_SHA2_256": 5, + "PRF_HMAC_SHA2_384": 6, + "PRF_HMAC_SHA2_512": 7, + "PRF_AES128_CMAC": 8, + "PRF_HMAC_STREEBOG_512": 9, +} + +var IntegrityAlgorithm = map[string]int{ + "AUTH_HMAC_MD5_96": 1, + "AUTH_HMAC_SHA1_96": 2, + "AUTH_DES_MAC": 3, + "AUTH_KPDK_MD5": 4, + "AUTH_AES_XCBC_96": 5, + "AUTH_HMAC_MD5_128": 6, + "AUTH_HMAC_SHA1_160": 7, + "AUTH_AES_CMAC_96": 8, + "AUTH_AES_128_GMAC": 9, + "AUTH_AES_192_GMAC": 10, + "AUTH_AES_256_GMAC": 11, + "AUTH_HMAC_SHA2_256_128": 12, + "AUTH_HMAC_SHA2_384_192": 13, + "AUTH_HMAC_SHA2_512_256": 14, +} + +var DiffieHellmanGroup = map[string]int{ + "DH_GROUP_2048_BIT_MODP": 14, + "DH_GROUP_768_BIT_MODP": 1, + "DH_GROUP_1024_BIT_MODP": 2, + "DH_GROUP_1536_BIT_MODP": 5, + "DH_GROUP_3072_BIT_MODP": 15, + "DH_GROUP_4096_BIT_MODP": 16, + "DH_GROUP_6144_BIT_MODP": 17, + "DH_GROUP_8192_BIT_MODP": 18, + "RANDOM_ECP_GROUP_256_BIT": 19, + "RANDOM_ECP_GROUP_384_BIT": 20, + "RANDOM_ECP_GROUP_521_BIT": 21, + "DH_GROUP_1024_BIT_MODP_WITH_160_BIT_PRIME_ORDER_SUBGROUP": 22, + "DH_GROUP_2048_BIT_MODP_WITH_224_BIT_PRIME_ORDER_SUBGROUP": 23, + "DH_GROUP_2048_BIT_MODP_WITH_256_BIT_PRIME_ORDER_SUBGROUP": 24, + "RANDOM_ECP_GROUP_192_BIT": 25, + "RANDOM_ECP_GROUP_224_BIT": 26, + "BRAINPOOLP224R1": 27, + "BRAINPOOLP256R1": 28, + "BRAINPOOLP384R1": 29, + "BRAINPOOLP512R1": 30, + "CURVE25519": 31, + "CURVE448": 32, + "GOST3410_2012_256": 33, + "GOST3410_2012_512": 34, + "ML_KEM_512": 35, + "ML_KEM_768": 36, + "ML_KEM_1024": 37, +} + +type IkeClient struct { + Conn net.Conn + IkeCrypto IkeCrypto +} + +type IkeCrypto struct { + Prime *big.Int + + InitNonce string + RespNonce string + InitSPI uint64 + RespSPI uint64 + + ClientPrivKey *big.Int + ClientPubKey *big.Int + ServerPubKey string + + SharedSecret *big.Int + SKeySeed string + SKd string + SKai string + SKar string + SKei string + SKer string +} + +type IkeProposal struct { + ProposalNumber int + ProtocolID int + SPI int + Transforms []IkeTransform +} + +type IkeTransform struct { + NextPayload int + TransformType int + TransformID int + TransformAttributes int // a bit lazy perhaps, but it gets used infrequently enough that providing an int instead of a list of maps + enums should suffice + // Reserved int = 0 +} From 487e01cd27b0b1170a6c086779fe36edcd8a49f1 Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 10:22:33 -0600 Subject: [PATCH 06/13] moved sainit out --- protocol/ikev2/ikev2.go | 51 +---------------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 7f1fb69..ada40fd 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -7,7 +7,6 @@ package ikev2 import ( "crypto/rand" "encoding/binary" - "encoding/hex" "fmt" "math/big" mrand "math/rand" @@ -15,7 +14,6 @@ import ( "github.com/vulncheck-oss/go-exploit/config" "github.com/vulncheck-oss/go-exploit/output" - "github.com/vulncheck-oss/go-exploit/transform" ) func Uint64ToString(num uint64) string { @@ -33,6 +31,7 @@ func generateNonce(length int) string { return string(nonce) } +// Switch case is here in case anyone wants to add additional DH support. func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { switch diffieHellmanGroup { case DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]: @@ -60,54 +59,6 @@ func (ikeCrypto *IkeCrypto) Init() { ikeCrypto.RespSPI = 0x0000000000000000 } -func (ikeClient *IkeClient) SAInit(diffieHellmanGroup int) (string, bool) { - ikeClient.IkeCrypto = IkeCrypto{} - ikeClient.IkeCrypto.Init() - ok := ikeClient.IkeCrypto.GenerateDHKey(diffieHellmanGroup) - if !ok { - return "", false - } - - defaultTransforms := []IkeTransform{ - {PayloadType["TRANSFORM"], TransformType["ENCRYPTION_ALGORITHM"], EncryptionAlgorithm["ENCR_AES_CBC"], 0x800e0100}, - {PayloadType["TRANSFORM"], TransformType["PSEUDO_RANDOM_FUNCTION"], PseudoRandomFunction["PRF_HMAC_SHA2_256"], 0}, - {PayloadType["TRANSFORM"], TransformType["INTEGRITY_ALGORITHM"], IntegrityAlgorithm["AUTH_HMAC_SHA2_256_128"], 0}, - {PayloadType["NONE"], TransformType["DIFFIE_HELLMAN_GROUP"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], 0}, - } - - var message string - header := IkePackHeader(ikeClient, PayloadType["SECURITY_ASSOCIATION"], 0x20, ExchangeType["IKE_SA_INIT"], 0x08, 0x0) - message += IkePackSecurityAssociation(PayloadType["KEY_EXCHANGE"], IkePackProposal(PayloadType["NONE"], 1, 1, defaultTransforms, "")) - message += IkePackKeyExchange(PayloadType["NONCE"], DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], string(ikeClient.IkeCrypto.ClientPubKey.Bytes())) - message += IkePackNonce(PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) - - tempBytes, _ := hex.DecodeString("a6358d813592fdd80a9aaa3390f39c8a5a76b6e4") - message += IkePackNotify(PayloadType["NOTIFY"], NotifyType["NAT_DETECTION_DESTINATION_IP"], string(tempBytes), 1, 0) - - tempBytes, _ = hex.DecodeString("4cc324152ba3f68ef649ac1e6f96f33791611db2") - message += IkePackNotify(PayloadType["VENDOR_ID"], NotifyType["NAT_DETECTION_SOURCE_IP"], string(tempBytes), 1, 0) - - tempBytes, _ = hex.DecodeString("c590254e5403cbb71f3d493111d7fcad") - message += IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) - - tempBytes, _ = hex.DecodeString("c61baca1f1a60cc10800000000000000") - message += IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) - - tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3c0000000") - message += IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) - - tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") - message += IkePackVendorID(PayloadType["NOTIFY"], string(tempBytes)) - - message += IkePackNotify(PayloadType["NOTIFY"], NotifyType["IKEV2_FRAGMENTATION_SUPPORTED"], "", 0, 0) - message += IkePackNotify(PayloadType["NOTIFY"], NotifyType["REDIRECT_SUPPORTED"], "", 0, 0) - - tempBytes, _ = hex.DecodeString("0001000200030004") - message += IkePackNotify(PayloadType["NONE"], NotifyType["SIGNATURE_HASH_ALGORITHMS"], string(tempBytes), 0, 0) - - return header + transform.PackBigInt32(len(message)+len(header)+4) + message, true // revisit this and make sure the ordering is correct and that the length encompasses exactly what it is intended -} - // The initial reset/connect function. // Should be the first step of a new connection but will likely not be run from within an exploit, but rather the // SAInit function. From d61a5914c0bd753f6cb4e1ecc848b706e59c06cc Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 10:36:14 -0600 Subject: [PATCH 07/13] bot comments --- protocol/ikev2/ikev2.go | 2 -- protocol/ikev2/packs.go | 4 ---- protocol/ikev2/types.go | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index ada40fd..e5d834e 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -37,11 +37,9 @@ func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { case DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]: ikeCrypto.Prime = new(big.Int) ikeCrypto.Prime.SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) // https://www.ietf.org/rfc/rfc3526.txt - // ikeCrypto.Prime, _ = rand.Prime(rand.Reader, 2048) // TODO DELETE g := big.NewInt(2) ikeCrypto.ClientPrivKey, _ = rand.Int(rand.Reader, ikeCrypto.Prime) ikeCrypto.ClientPubKey = new(big.Int).Exp(g, ikeCrypto.ClientPrivKey, ikeCrypto.Prime) - ikeCrypto.SharedSecret = new(big.Int).Exp(ikeCrypto.ClientPubKey, ikeCrypto.ClientPrivKey, ikeCrypto.Prime) return true diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go index af0f470..7faf800 100644 --- a/protocol/ikev2/packs.go +++ b/protocol/ikev2/packs.go @@ -10,10 +10,6 @@ func IkePackVendorID(nextPayload int, vendorID string) string { return IkePackPayloadHeader(nextPayload, vendorID) } -/* -def notify(next_payload, notify_type, data = b”, protocol_id = 1, spi_size = 0): -return IkePacker.payload_header(next_payload, struct.pack('>BBH', protocol_id, spi_size, notify_type) + data). -*/ func IkePackNotify(nextPayload int, notifyType int, data string, protocolID int, spiSize int) string { payload := string(byte(protocolID)) payload += string(byte(spiSize)) diff --git a/protocol/ikev2/types.go b/protocol/ikev2/types.go index 774b8fe..1a39579 100644 --- a/protocol/ikev2/types.go +++ b/protocol/ikev2/types.go @@ -196,7 +196,7 @@ type IkeCrypto struct { ClientPrivKey *big.Int ClientPubKey *big.Int - ServerPubKey string + ServerPubKey *big.Int SharedSecret *big.Int SKeySeed string From b27db71892ff3ad2b6acc3bd3ad198f40c7ce00e Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 10:58:05 -0600 Subject: [PATCH 08/13] added more docs --- protocol/ikev2/ikev2.go | 57 +++++++++++++++++++++++++++++++++++------ protocol/ikev2/packs.go | 3 +-- protocol/ikev2/types.go | 2 ++ 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index e5d834e..515490c 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -1,7 +1,51 @@ -// I hate go idioms for enums, so we're doing string maps. -// The primary reason is that I want the context to be evident, much like a namespace when using the structures here. +// A (very) basic framework for an ikev2 protocol. // The intent with adding this package is not to add an entire, fully functional protocol but rather providing a convenient interface for generating the data structures for ike-related exploits. -// We will presumably add to this as we go, as needed. +// The goal is to add to this as we go, as new exploits demand it. +// +// Using this will probably require you to make your own SAInit function to generate the message data and then sending it over the ikeClient connection. +// A basic example of something like this follows: +// +// func saInit(ikeClient *ikev2.IkeClient, diffieHellmanGroup int) (string, bool) { +// ikeClient.IkeCrypto = ikev2.IkeCrypto{} +// ikeClient.IkeCrypto.Init() +// ok := ikeClient.IkeCrypto.GenerateDHKey(diffieHellmanGroup) +// if !ok { +// return "", false +// } +// +// transforms := []ikev2.IkeTransform{ +// {NextPayload: ikev2.PayloadType["NONE"], TransformType: ikev2.TransformType["DIFFIE_HELLMAN_GROUP"], TransformID: ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], TransformAttributes: 0}, +// } +// +// header := ikev2.IkePackHeader(ikeClient, ikev2.PayloadType["SECURITY_ASSOCIATION"], 0x20, ikev2.ExchangeType["IKE_SA_INIT"], 0x08, 0x0) +// message := ikev2.IkePackSecurityAssociation(ikev2.PayloadType["KEY_EXCHANGE"], ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, transforms, "")) +// message += ikev2.IkePackKeyExchange(ikev2.PayloadType["NONCE"], ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], string(ikeClient.IkeCrypto.ClientPubKey.Bytes())) +// message += ikev2.IkePackNonce(ikev2.PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) +// +// tempBytes, _ := hex.DecodeString("a6358d813592fdd80a9aaa3390f39c8a5a76b6e4") +// message += ikev2.IkePackNotify(ikev2.PayloadType["NOTIFY"], ikev2.NotifyType["NAT_DETECTION_DESTINATION_IP"], string(tempBytes), 1, 0) +// // whatever else... +// +// return header + transform.PackBigInt32(len(message)+len(header)+4) + message, true +// } +// +// ikeClient := ikev2.IkeClient{} +// saInitPayload, _ := saInit(&ikeClient, ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) +// if !ok { +// output.PrintError("error encountered while generating SAInit payload") +// return false +// } +// +// if !ikeClient.Connect(conf){ +// return false +// } +// +// _, err := ikeClient.Conn.Write([]byte(saInitPayload)) +// if err != nil { +// output.PrintfDebug("SAInit Send failed: %s", err.Error()) +// return false +// } +// output.PrintDebug("Sent SAInit message") package ikev2 import ( @@ -57,17 +101,14 @@ func (ikeCrypto *IkeCrypto) Init() { ikeCrypto.RespSPI = 0x0000000000000000 } -// The initial reset/connect function. -// Should be the first step of a new connection but will likely not be run from within an exploit, but rather the -// SAInit function. +// An initial reset/connect helper function. func (ikeClient *IkeClient) Connect(conf *config.Config) bool { var err error - // the connection may not be active, just want to close it if so, if it's not active, great. if ikeClient.Conn != nil { err = ikeClient.Conn.Close() if err != nil { - output.PrintfFrameworkWarn("Failed to close socket: %s", err.Error()) // we probably do not want to exit on this, we're establishing a new connection anyways + output.PrintfFrameworkWarn("Failed to close socket: %s", err.Error()) } } diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go index 7faf800..4beb957 100644 --- a/protocol/ikev2/packs.go +++ b/protocol/ikev2/packs.go @@ -20,9 +20,8 @@ func IkePackNotify(nextPayload int, notifyType int, data string, protocolID int, } func IkePackKeyExchange(nextPayload int, dhGroup int, data string) string { - // reserved = 0 payload := transform.PackBigInt16(dhGroup) - payload += transform.PackBigInt16(0) + payload += transform.PackBigInt16(0) // reserved bytes (2) return IkePackPayloadHeader(nextPayload, payload+data) } diff --git a/protocol/ikev2/types.go b/protocol/ikev2/types.go index 1a39579..f7e5e7e 100644 --- a/protocol/ikev2/types.go +++ b/protocol/ikev2/types.go @@ -5,6 +5,8 @@ import ( "net" ) +// I hate go idioms for enums, so we're doing string maps. +// The primary reason is that I want the context to be evident, much like a namespace when using the structures here. var PayloadType = map[string]int{ "NONE": 0, "TRANSFORM": 3, From 46c3f627de04b55cc2938072bd1e1670f67a911e Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 12:11:00 -0600 Subject: [PATCH 09/13] strings to bytes, woohooo --- protocol/ikev2/ikev2.go | 17 ++++--- protocol/ikev2/ikev2_test.go | 18 ++++---- protocol/ikev2/packs.go | 86 +++++++++++++++++++++--------------- protocol/ikev2/types.go | 4 +- 4 files changed, 70 insertions(+), 55 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 515490c..5e92b5e 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -1,3 +1,4 @@ +// Package ikev2 // A (very) basic framework for an ikev2 protocol. // The intent with adding this package is not to add an entire, fully functional protocol but rather providing a convenient interface for generating the data structures for ike-related exploits. // The goal is to add to this as we go, as new exploits demand it. @@ -51,28 +52,26 @@ package ikev2 import ( "crypto/rand" "encoding/binary" - "fmt" "math/big" mrand "math/rand" "net" + "strconv" "github.com/vulncheck-oss/go-exploit/config" "github.com/vulncheck-oss/go-exploit/output" ) -func Uint64ToString(num uint64) string { +func Uint64ToString(num uint64) []byte { bytes := make([]byte, 8) binary.BigEndian.PutUint64(bytes, num) - byteString := string(bytes) - - return byteString + return bytes } -func generateNonce(length int) string { +func generateNonce(length int) []byte { nonce := make([]byte, length) _, _ = rand.Read(nonce) - return string(nonce) + return nonce } // Switch case is here in case anyone wants to add additional DH support. @@ -96,7 +95,7 @@ func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { func (ikeCrypto *IkeCrypto) Init() { ikeCrypto.InitNonce = generateNonce(32) - ikeCrypto.RespNonce = "" + ikeCrypto.RespNonce = []byte{} ikeCrypto.InitSPI = mrand.Uint64() ikeCrypto.RespSPI = 0x0000000000000000 } @@ -112,7 +111,7 @@ func (ikeClient *IkeClient) Connect(conf *config.Config) bool { } } - connectionString := fmt.Sprintf("%s:%d", conf.Rhost, conf.Rport) + connectionString := net.JoinHostPort(conf.Rhost, strconv.Itoa(conf.Rport)) ikeClient.Conn, err = net.Dial("udp", connectionString) if err != nil { output.PrintfFrameworkError("Dial failed: %s", err.Error()) diff --git a/protocol/ikev2/ikev2_test.go b/protocol/ikev2/ikev2_test.go index 0b10369..da20eb8 100644 --- a/protocol/ikev2/ikev2_test.go +++ b/protocol/ikev2/ikev2_test.go @@ -9,7 +9,7 @@ import ( func TestVendorIDPack(t *testing.T) { want := "2b000014c590254e5403cbb71f3d493111d7fcad" tempBytes, _ := hex.DecodeString("c590254e5403cbb71f3d493111d7fcad") - got := IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + got := IkePackVendorID(PayloadType["VENDOR_ID"], tempBytes) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[1] %q : %02x != %s", got, got, want) @@ -17,7 +17,7 @@ func TestVendorIDPack(t *testing.T) { want = "2b000014c61baca1f1a60cc10800000000000000" tempBytes, _ = hex.DecodeString("c61baca1f1a60cc10800000000000000") - got = IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + got = IkePackVendorID(PayloadType["VENDOR_ID"], tempBytes) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[2] %q : %02x != %s", got, got, want) @@ -25,7 +25,7 @@ func TestVendorIDPack(t *testing.T) { want = "2b0000184048b7d56ebce88525e7de7f00d6c2d3c0000000" tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3c0000000") - got = IkePackVendorID(PayloadType["VENDOR_ID"], string(tempBytes)) + got = IkePackVendorID(PayloadType["VENDOR_ID"], tempBytes) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[3] %q : %02x != %s", got, got, want) @@ -33,7 +33,7 @@ func TestVendorIDPack(t *testing.T) { want = "290000144048b7d56ebce88525e7de7f00d6c2d3" tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") - got = IkePackVendorID(PayloadType["NOTIFY"], string(tempBytes)) + got = IkePackVendorID(PayloadType["NOTIFY"], tempBytes) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[4] %q : %02x != %s", got, got, want) } @@ -57,33 +57,33 @@ func TestSecurityAssociationPack(t *testing.T) { func TestNotifyPack(t *testing.T) { want := "2900001c01004005a6358d813592fdd80a9aaa3390f39c8a5a76b6e4" tempBytes, _ := hex.DecodeString("a6358d813592fdd80a9aaa3390f39c8a5a76b6e4") - got := IkePackNotify(PayloadType["NOTIFY"], NotifyType["NAT_DETECTION_DESTINATION_IP"], string(tempBytes), 1, 0) + got := IkePackNotify(PayloadType["NOTIFY"], NotifyType["NAT_DETECTION_DESTINATION_IP"], tempBytes, 1, 0) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[1] %q : %02x != %s", got, got, want) } want = "2b00001c010040044cc324152ba3f68ef649ac1e6f96f33791611db2" tempBytes, _ = hex.DecodeString("4cc324152ba3f68ef649ac1e6f96f33791611db2") - got = IkePackNotify(PayloadType["VENDOR_ID"], NotifyType["NAT_DETECTION_SOURCE_IP"], string(tempBytes), 1, 0) + got = IkePackNotify(PayloadType["VENDOR_ID"], NotifyType["NAT_DETECTION_SOURCE_IP"], tempBytes, 1, 0) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[2] %q : %02x != %s", got, got, want) } want = "290000080000402e" - got = IkePackNotify(PayloadType["NOTIFY"], NotifyType["IKEV2_FRAGMENTATION_SUPPORTED"], "", 0, 0) + got = IkePackNotify(PayloadType["NOTIFY"], NotifyType["IKEV2_FRAGMENTATION_SUPPORTED"], []byte{}, 0, 0) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[3] %q : %02x != %s", got, got, want) } want = "2900000800004016" - got = IkePackNotify(PayloadType["NOTIFY"], NotifyType["REDIRECT_SUPPORTED"], "", 0, 0) + got = IkePackNotify(PayloadType["NOTIFY"], NotifyType["REDIRECT_SUPPORTED"], []byte{}, 0, 0) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[4] %q : %02x != %s", got, got, want) } want = "000000100000402f0001000200030004" tempBytes, _ = hex.DecodeString("0001000200030004") - got = IkePackNotify(PayloadType["NONE"], NotifyType["SIGNATURE_HASH_ALGORITHMS"], string(tempBytes), 0, 0) + got = IkePackNotify(PayloadType["NONE"], NotifyType["SIGNATURE_HASH_ALGORITHMS"], tempBytes, 0, 0) if fmt.Sprintf("%02x", got) != want { t.Fatalf("[5] %q : %02x != %s", got, got, want) } diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go index 4beb957..40d06fa 100644 --- a/protocol/ikev2/packs.go +++ b/protocol/ikev2/packs.go @@ -1,69 +1,85 @@ package ikev2 -import "github.com/vulncheck-oss/go-exploit/transform" +import ( + "github.com/vulncheck-oss/go-exploit/transform" +) -func IkePackNonce(nextPayload int, nonce string) string { +func IkePackNonce(nextPayload int, nonce []byte) []byte { return IkePackPayloadHeader(nextPayload, nonce) } -func IkePackVendorID(nextPayload int, vendorID string) string { +func IkePackVendorID(nextPayload int, vendorID []byte) []byte { return IkePackPayloadHeader(nextPayload, vendorID) } -func IkePackNotify(nextPayload int, notifyType int, data string, protocolID int, spiSize int) string { - payload := string(byte(protocolID)) - payload += string(byte(spiSize)) - payload += transform.PackBigInt16(notifyType) - payload += data +func IkePackNotify(nextPayload int, notifyType int, data []byte, protocolID int, spiSize int) []byte { + payload := make([]byte, 0) + payload = append(payload, byte(protocolID)) + payload = append(payload, byte(spiSize)) + payload = append(payload, []byte(transform.PackBigInt16(notifyType))...) + payload = append(payload, []byte(data)...) return IkePackPayloadHeader(nextPayload, payload) } -func IkePackKeyExchange(nextPayload int, dhGroup int, data string) string { - payload := transform.PackBigInt16(dhGroup) - payload += transform.PackBigInt16(0) // reserved bytes (2) +func IkePackKeyExchange(nextPayload int, dhGroup int, data []byte) []byte { + payload := []byte(transform.PackBigInt16(dhGroup)) + payload = append(payload, []byte(transform.PackBigInt16(0))...) // reserved bytes (2) + payload = append(payload, data...) - return IkePackPayloadHeader(nextPayload, payload+data) + return IkePackPayloadHeader(nextPayload, payload) } -func IkePackSecurityAssociation(payloadType int, proposal string) string { +func IkePackSecurityAssociation(payloadType int, proposal []byte) []byte { return IkePackPayloadHeader(payloadType, proposal) } -func (ikeTransform *IkeTransform) Pack() string { - transformData := string(byte(ikeTransform.TransformType)) + - string(byte(0)) + // reserved byte - transform.PackBigInt16(ikeTransform.TransformID) +func (ikeTransform *IkeTransform) Pack() []byte { + payload := make([]byte, 0) + // transformData := + payload = append(payload, byte(ikeTransform.TransformType)) + payload = append(payload, byte(0)) + payload = append(payload, []byte(transform.PackBigInt16(ikeTransform.TransformID))...) + transform.PackBigInt16(ikeTransform.TransformID) if ikeTransform.TransformAttributes != 0 { - transformData += transform.PackBigInt32(ikeTransform.TransformAttributes) + payload = append(payload, []byte(transform.PackBigInt32(ikeTransform.TransformAttributes))...) } - return IkePackPayloadHeader(ikeTransform.NextPayload, transformData) + return IkePackPayloadHeader(ikeTransform.NextPayload, payload) } -func IkePackPayloadHeader(payloadType int, payload string) string { - return string(byte(payloadType)) + - string(byte(0)) + // critical bit + reserved (7 bits) combine to make this single 0x00 byte - transform.PackBigInt16(len(payload)+4) + payload +func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { + payload := make([]byte, 0) + payload = append(payload, byte(payloadType)) + payload = append(payload, byte(0)) + payload = append(payload, []byte(transform.PackBigInt16(len(payloadIn)+4))...) + payload = append(payload, payloadIn...) + return payload } -func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) string { - var transformData string +func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) []byte { + payload := make([]byte, 0) + payload = append(payload, byte(number)) + payload = append(payload, byte(id)) + payload = append(payload, byte(len(spi))) + payload = append(payload, byte(len(transforms))) + payload = append(payload, []byte(spi)...) for _, transform := range transforms { - transformData += transform.Pack() + payload = append(payload, transform.Pack()...) } - payload := string(byte(number)) + string(byte(id)) + string(byte(len(spi))) + string(byte(len(transforms))) + spi + transformData return IkePackPayloadHeader(nextPayload, payload) } -func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) string { - return Uint64ToString(ikeClient.IkeCrypto.InitSPI) + - Uint64ToString(ikeClient.IkeCrypto.RespSPI) + - string(byte(payloadType)) + - string(byte(version)) + // default 0x20 - string(byte(exchangeType)) + - string(byte(flags)) + // default 0x08 - transform.PackBigInt32(messageID) +func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) []byte { + payload := make([]byte, 0) + payload = append(payload, []byte(Uint64ToString(ikeClient.IkeCrypto.InitSPI))...) + payload = append(payload, []byte(Uint64ToString(ikeClient.IkeCrypto.RespSPI))...) + payload = append(payload, byte(payloadType)) + payload = append(payload, byte(version)) + payload = append(payload, byte(exchangeType)) + payload = append(payload, byte(flags)) + payload = append(payload, []byte(transform.PackBigInt32(messageID))...) + return payload } diff --git a/protocol/ikev2/types.go b/protocol/ikev2/types.go index f7e5e7e..8f29796 100644 --- a/protocol/ikev2/types.go +++ b/protocol/ikev2/types.go @@ -191,8 +191,8 @@ type IkeClient struct { type IkeCrypto struct { Prime *big.Int - InitNonce string - RespNonce string + InitNonce []byte + RespNonce []byte InitSPI uint64 RespSPI uint64 From 084ac53c4d480a973e94cd0a6e678a7c5a905a33 Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 12:17:49 -0600 Subject: [PATCH 10/13] updated example --- protocol/ikev2/ikev2.go | 74 +++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 5e92b5e..427f603 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -6,47 +6,57 @@ // Using this will probably require you to make your own SAInit function to generate the message data and then sending it over the ikeClient connection. // A basic example of something like this follows: // -// func saInit(ikeClient *ikev2.IkeClient, diffieHellmanGroup int) (string, bool) { -// ikeClient.IkeCrypto = ikev2.IkeCrypto{} -// ikeClient.IkeCrypto.Init() -// ok := ikeClient.IkeCrypto.GenerateDHKey(diffieHellmanGroup) -// if !ok { -// return "", false -// } +// func saInit(ikeClient *ikev2.IkeClient, diffieHellmanGroup int) ([]byte, bool) { // -// transforms := []ikev2.IkeTransform{ -// {NextPayload: ikev2.PayloadType["NONE"], TransformType: ikev2.TransformType["DIFFIE_HELLMAN_GROUP"], TransformID: ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], TransformAttributes: 0}, -// } +// ikeClient.IkeCrypto = ikev2.IkeCrypto{} +// ikeClient.IkeCrypto.Init() +// ok := ikeClient.IkeCrypto.GenerateDHKey(diffieHellmanGroup) +// if !ok { +// return []byte{}, false +// } // -// header := ikev2.IkePackHeader(ikeClient, ikev2.PayloadType["SECURITY_ASSOCIATION"], 0x20, ikev2.ExchangeType["IKE_SA_INIT"], 0x08, 0x0) -// message := ikev2.IkePackSecurityAssociation(ikev2.PayloadType["KEY_EXCHANGE"], ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, transforms, "")) -// message += ikev2.IkePackKeyExchange(ikev2.PayloadType["NONCE"], ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], string(ikeClient.IkeCrypto.ClientPubKey.Bytes())) -// message += ikev2.IkePackNonce(ikev2.PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) +// defaultTransforms := []ikev2.IkeTransform{ +// {NextPayload: ikev2.PayloadType["TRANSFORM"], TransformType: ikev2.TransformType["ENCRYPTION_ALGORITHM"], TransformID: ikev2.EncryptionAlgorithm["ENCR_AES_CBC"], TransformAttributes: 0x800e0100}, +// } // -// tempBytes, _ := hex.DecodeString("a6358d813592fdd80a9aaa3390f39c8a5a76b6e4") -// message += ikev2.IkePackNotify(ikev2.PayloadType["NOTIFY"], ikev2.NotifyType["NAT_DETECTION_DESTINATION_IP"], string(tempBytes), 1, 0) -// // whatever else... +// message := make([]byte, 0) +// header := ikev2.IkePackHeader(ikeClient, ikev2.PayloadType["SECURITY_ASSOCIATION"], 0x20, ikev2.ExchangeType["IKE_SA_INIT"], 0x08, 0x0) +// message = append(message, ikev2.IkePackSecurityAssociation(ikev2.PayloadType["KEY_EXCHANGE"], ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, ""))...) +// message = append(message, ikev2.IkePackKeyExchange(ikev2.PayloadType["NONCE"], ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], ikeClient.IkeCrypto.ClientPubKey.Bytes())...) +// message = append(message, ikev2.IkePackNonce(ikev2.PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce)...) // -// return header + transform.PackBigInt32(len(message)+len(header)+4) + message, true -// } +// tempBytes, _ := hex.DecodeString("deadbeef") +// message = append(message, ikev2.IkePackNotify(ikev2.PayloadType["NOTIFY"], ikev2.NotifyType["NAT_DETECTION_DESTINATION_IP"], tempBytes, 1, 0)...) // -// ikeClient := ikev2.IkeClient{} -// saInitPayload, _ := saInit(&ikeClient, ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) -// if !ok { -// output.PrintError("error encountered while generating SAInit payload") -// return false -// } +// tempBytes, _ = hex.DecodeString("0021030203030006") +// message = append(message, ikev2.IkePackNotify(ikev2.PayloadType["NONE"], ikev2.NotifyType["SIGNATURE_HASH_ALGORITHMS"], tempBytes, 0, 0)...) // -// if !ikeClient.Connect(conf){ -// return false +// // combining the message +// payload := make([]byte, 0) +// payload = append(header, []byte(transform.PackBigInt32(len(message)+len(header)+4))...) +// payload = append(payload, message...) +// return payload, true // } // -// _, err := ikeClient.Conn.Write([]byte(saInitPayload)) -// if err != nil { -// output.PrintfDebug("SAInit Send failed: %s", err.Error()) -// return false +// func main() { +// ikeClient := ikev2.IkeClient{} +// saInitPayload, _ := saInit(&ikeClient, ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"]) +// if !ok { +// output.PrintError("error encountered while generating SAInit payload") +// return false +// } +// +// if !ikeClient.Connect(conf){ +// return false +// } +// +// _, err := ikeClient.Conn.Write([]byte(saInitPayload)) +// if err != nil { +// output.PrintfDebug("SAInit Send failed: %s", err.Error()) +// return false +// } +// output.PrintDebug("Sent SAInit message") // } -// output.PrintDebug("Sent SAInit message") package ikev2 import ( From dc4a022bd45a737b0c3e5a9cb2167c977a6ebc0b Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 12:44:12 -0600 Subject: [PATCH 11/13] added more docs for pack stuff --- protocol/ikev2/ikev2.go | 19 ++++++++++++++----- protocol/ikev2/packs.go | 29 ++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 427f603..2df2592 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -77,11 +77,15 @@ func Uint64ToString(num uint64) []byte { return bytes } -func generateNonce(length int) []byte { +func generateNonce(length int) ([]byte, bool) { nonce := make([]byte, length) - _, _ = rand.Read(nonce) + _, err := rand.Read(nonce) + if err != nil { + output.PrintfFrameworkError("Error while generating nonce: %s", err.Error()) + return []byte{}, false + } - return nonce + return nonce, true } // Switch case is here in case anyone wants to add additional DH support. @@ -103,11 +107,16 @@ func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { } } -func (ikeCrypto *IkeCrypto) Init() { - ikeCrypto.InitNonce = generateNonce(32) +func (ikeCrypto *IkeCrypto) Init() bool { + var ok bool + ikeCrypto.InitNonce, ok = generateNonce(32) + if !ok { + return false + } ikeCrypto.RespNonce = []byte{} ikeCrypto.InitSPI = mrand.Uint64() ikeCrypto.RespSPI = 0x0000000000000000 + return true } // An initial reset/connect helper function. diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go index 40d06fa..e1a1dc5 100644 --- a/protocol/ikev2/packs.go +++ b/protocol/ikev2/packs.go @@ -4,14 +4,25 @@ import ( "github.com/vulncheck-oss/go-exploit/transform" ) +// Creates a Nonce component. +// +// ikev2.IkePackNonce(ikev2.PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) func IkePackNonce(nextPayload int, nonce []byte) []byte { return IkePackPayloadHeader(nextPayload, nonce) } +// Creates a VendorID component. +// +// tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") +// ikev2.IkePackVendorID(ikev2.PayloadType["NOTIFY"], tempBytes) func IkePackVendorID(nextPayload int, vendorID []byte) []byte { return IkePackPayloadHeader(nextPayload, vendorID) } +// Creates a Notify component. +// +// tempBytes, _ = hex.DecodeString("0021030203030006") +// ikev2.IkePackNotify(ikev2.PayloadType["NONE"], ikev2.NotifyType["SIGNATURE_HASH_ALGORITHMS"], tempBytes, 0, 0) func IkePackNotify(nextPayload int, notifyType int, data []byte, protocolID int, spiSize int) []byte { payload := make([]byte, 0) payload = append(payload, byte(protocolID)) @@ -22,6 +33,9 @@ func IkePackNotify(nextPayload int, notifyType int, data []byte, protocolID int, return IkePackPayloadHeader(nextPayload, payload) } +// Creates a KeyExchange component. +// +// ikev2.IkePackKeyExchange(ikev2.PayloadType["NONCE"], ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], ikeClient.IkeCrypto.ClientPubKey.Bytes()) func IkePackKeyExchange(nextPayload int, dhGroup int, data []byte) []byte { payload := []byte(transform.PackBigInt16(dhGroup)) payload = append(payload, []byte(transform.PackBigInt16(0))...) // reserved bytes (2) @@ -30,13 +44,19 @@ func IkePackKeyExchange(nextPayload int, dhGroup int, data []byte) []byte { return IkePackPayloadHeader(nextPayload, payload) } +// Creates a Security Association component. +// +// ikev2.IkePackSecurityAssociation(ikev2.PayloadType["KEY_EXCHANGE"], ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, "")) func IkePackSecurityAssociation(payloadType int, proposal []byte) []byte { return IkePackPayloadHeader(payloadType, proposal) } +// Creates a trasnform byte array from a transform. +// +// // creating a transform +// ikev2.IkeTransform{NextPayload: ikev2.PayloadType["TRANSFORM"], TransformType: ikev2.TransformType["ENCRYPTION_ALGORITHM"], TransformID: ikev2.EncryptionAlgorithm["ENCR_AES_CBC"], TransformAttributes: 0x800e0100} func (ikeTransform *IkeTransform) Pack() []byte { payload := make([]byte, 0) - // transformData := payload = append(payload, byte(ikeTransform.TransformType)) payload = append(payload, byte(0)) payload = append(payload, []byte(transform.PackBigInt16(ikeTransform.TransformID))...) @@ -49,6 +69,7 @@ func (ikeTransform *IkeTransform) Pack() []byte { return IkePackPayloadHeader(ikeTransform.NextPayload, payload) } +// Encapsulates a Packed component (or any binary array) with the nextHeader. Used by most of these packs. func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { payload := make([]byte, 0) payload = append(payload, byte(payloadType)) @@ -58,6 +79,9 @@ func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { return payload } +// Creates a Proposal component. +// +// ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, "") func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) []byte { payload := make([]byte, 0) payload = append(payload, byte(number)) @@ -72,6 +96,9 @@ func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransf return IkePackPayloadHeader(nextPayload, payload) } +// Creates a Header component. +// +// ikev2.IkePackHeader(ikeClient, ikev2.PayloadType["SECURITY_ASSOCIATION"], 0x20, ikev2.ExchangeType["IKE_SA_INIT"], 0x08, 0x0) func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) []byte { payload := make([]byte, 0) payload = append(payload, []byte(Uint64ToString(ikeClient.IkeCrypto.InitSPI))...) From 7e0c2fed0bf416c92c0b37773b32013773a93bc8 Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 12:50:02 -0600 Subject: [PATCH 12/13] added more docs --- protocol/ikev2/ikev2.go | 5 +++++ protocol/ikev2/packs.go | 21 ++++++++++++++++----- protocol/ikev2/types.go | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 2df2592..98f2f0d 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -74,6 +74,7 @@ import ( func Uint64ToString(num uint64) []byte { bytes := make([]byte, 8) binary.BigEndian.PutUint64(bytes, num) + return bytes } @@ -82,12 +83,14 @@ func generateNonce(length int) ([]byte, bool) { _, err := rand.Read(nonce) if err != nil { output.PrintfFrameworkError("Error while generating nonce: %s", err.Error()) + return []byte{}, false } return nonce, true } +// GenerateDHKey // Switch case is here in case anyone wants to add additional DH support. func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { switch diffieHellmanGroup { @@ -116,9 +119,11 @@ func (ikeCrypto *IkeCrypto) Init() bool { ikeCrypto.RespNonce = []byte{} ikeCrypto.InitSPI = mrand.Uint64() ikeCrypto.RespSPI = 0x0000000000000000 + return true } +// Connect // An initial reset/connect helper function. func (ikeClient *IkeClient) Connect(conf *config.Config) bool { var err error diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go index e1a1dc5..1193e0e 100644 --- a/protocol/ikev2/packs.go +++ b/protocol/ikev2/packs.go @@ -4,6 +4,7 @@ import ( "github.com/vulncheck-oss/go-exploit/transform" ) +// IkePackNonce // Creates a Nonce component. // // ikev2.IkePackNonce(ikev2.PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) @@ -11,6 +12,7 @@ func IkePackNonce(nextPayload int, nonce []byte) []byte { return IkePackPayloadHeader(nextPayload, nonce) } +// IkePackVendorID // Creates a VendorID component. // // tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") @@ -19,6 +21,7 @@ func IkePackVendorID(nextPayload int, vendorID []byte) []byte { return IkePackPayloadHeader(nextPayload, vendorID) } +// IkePackNotify // Creates a Notify component. // // tempBytes, _ = hex.DecodeString("0021030203030006") @@ -28,11 +31,12 @@ func IkePackNotify(nextPayload int, notifyType int, data []byte, protocolID int, payload = append(payload, byte(protocolID)) payload = append(payload, byte(spiSize)) payload = append(payload, []byte(transform.PackBigInt16(notifyType))...) - payload = append(payload, []byte(data)...) + payload = append(payload, data...) return IkePackPayloadHeader(nextPayload, payload) } +// IkePackKeyExchange // Creates a KeyExchange component. // // ikev2.IkePackKeyExchange(ikev2.PayloadType["NONCE"], ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], ikeClient.IkeCrypto.ClientPubKey.Bytes()) @@ -44,6 +48,7 @@ func IkePackKeyExchange(nextPayload int, dhGroup int, data []byte) []byte { return IkePackPayloadHeader(nextPayload, payload) } +// IkePackSecurityAssociation // Creates a Security Association component. // // ikev2.IkePackSecurityAssociation(ikev2.PayloadType["KEY_EXCHANGE"], ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, "")) @@ -51,7 +56,8 @@ func IkePackSecurityAssociation(payloadType int, proposal []byte) []byte { return IkePackPayloadHeader(payloadType, proposal) } -// Creates a trasnform byte array from a transform. +// Pack +// Creates a transform byte array from a transform. // // // creating a transform // ikev2.IkeTransform{NextPayload: ikev2.PayloadType["TRANSFORM"], TransformType: ikev2.TransformType["ENCRYPTION_ALGORITHM"], TransformID: ikev2.EncryptionAlgorithm["ENCR_AES_CBC"], TransformAttributes: 0x800e0100} @@ -69,6 +75,7 @@ func (ikeTransform *IkeTransform) Pack() []byte { return IkePackPayloadHeader(ikeTransform.NextPayload, payload) } +// IkePackPayloadHeader // Encapsulates a Packed component (or any binary array) with the nextHeader. Used by most of these packs. func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { payload := make([]byte, 0) @@ -76,12 +83,14 @@ func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { payload = append(payload, byte(0)) payload = append(payload, []byte(transform.PackBigInt16(len(payloadIn)+4))...) payload = append(payload, payloadIn...) + return payload } +// IkePackProposal // Creates a Proposal component. // -// ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, "") +// ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, ""). func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransform, spi string) []byte { payload := make([]byte, 0) payload = append(payload, byte(number)) @@ -96,17 +105,19 @@ func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransf return IkePackPayloadHeader(nextPayload, payload) } +// IkePackHeader // Creates a Header component. // // ikev2.IkePackHeader(ikeClient, ikev2.PayloadType["SECURITY_ASSOCIATION"], 0x20, ikev2.ExchangeType["IKE_SA_INIT"], 0x08, 0x0) func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, exchangeType int, flags int, messageID int) []byte { payload := make([]byte, 0) - payload = append(payload, []byte(Uint64ToString(ikeClient.IkeCrypto.InitSPI))...) - payload = append(payload, []byte(Uint64ToString(ikeClient.IkeCrypto.RespSPI))...) + payload = append(payload, Uint64ToString(ikeClient.IkeCrypto.InitSPI)...) + payload = append(payload, Uint64ToString(ikeClient.IkeCrypto.RespSPI)...) payload = append(payload, byte(payloadType)) payload = append(payload, byte(version)) payload = append(payload, byte(exchangeType)) payload = append(payload, byte(flags)) payload = append(payload, []byte(transform.PackBigInt32(messageID))...) + return payload } diff --git a/protocol/ikev2/types.go b/protocol/ikev2/types.go index 8f29796..8058a19 100644 --- a/protocol/ikev2/types.go +++ b/protocol/ikev2/types.go @@ -7,6 +7,7 @@ import ( // I hate go idioms for enums, so we're doing string maps. // The primary reason is that I want the context to be evident, much like a namespace when using the structures here. + var PayloadType = map[string]int{ "NONE": 0, "TRANSFORM": 3, From 1c5c19b2f3b9e27eace49ddc891d8a2f88a747bd Mon Sep 17 00:00:00 2001 From: lobsterjerusalem Date: Thu, 30 Oct 2025 13:13:04 -0600 Subject: [PATCH 13/13] fixed docs, ignored linter --- protocol/ikev2/ikev2.go | 2 -- protocol/ikev2/packs.go | 12 +----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/protocol/ikev2/ikev2.go b/protocol/ikev2/ikev2.go index 98f2f0d..d9e1d7a 100644 --- a/protocol/ikev2/ikev2.go +++ b/protocol/ikev2/ikev2.go @@ -90,7 +90,6 @@ func generateNonce(length int) ([]byte, bool) { return nonce, true } -// GenerateDHKey // Switch case is here in case anyone wants to add additional DH support. func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool { switch diffieHellmanGroup { @@ -123,7 +122,6 @@ func (ikeCrypto *IkeCrypto) Init() bool { return true } -// Connect // An initial reset/connect helper function. func (ikeClient *IkeClient) Connect(conf *config.Config) bool { var err error diff --git a/protocol/ikev2/packs.go b/protocol/ikev2/packs.go index 1193e0e..b28baaa 100644 --- a/protocol/ikev2/packs.go +++ b/protocol/ikev2/packs.go @@ -4,7 +4,6 @@ import ( "github.com/vulncheck-oss/go-exploit/transform" ) -// IkePackNonce // Creates a Nonce component. // // ikev2.IkePackNonce(ikev2.PayloadType["NOTIFY"], ikeClient.IkeCrypto.InitNonce) @@ -12,7 +11,6 @@ func IkePackNonce(nextPayload int, nonce []byte) []byte { return IkePackPayloadHeader(nextPayload, nonce) } -// IkePackVendorID // Creates a VendorID component. // // tempBytes, _ = hex.DecodeString("4048b7d56ebce88525e7de7f00d6c2d3") @@ -21,7 +19,6 @@ func IkePackVendorID(nextPayload int, vendorID []byte) []byte { return IkePackPayloadHeader(nextPayload, vendorID) } -// IkePackNotify // Creates a Notify component. // // tempBytes, _ = hex.DecodeString("0021030203030006") @@ -36,7 +33,6 @@ func IkePackNotify(nextPayload int, notifyType int, data []byte, protocolID int, return IkePackPayloadHeader(nextPayload, payload) } -// IkePackKeyExchange // Creates a KeyExchange component. // // ikev2.IkePackKeyExchange(ikev2.PayloadType["NONCE"], ikev2.DiffieHellmanGroup["DH_GROUP_2048_BIT_MODP"], ikeClient.IkeCrypto.ClientPubKey.Bytes()) @@ -48,7 +44,6 @@ func IkePackKeyExchange(nextPayload int, dhGroup int, data []byte) []byte { return IkePackPayloadHeader(nextPayload, payload) } -// IkePackSecurityAssociation // Creates a Security Association component. // // ikev2.IkePackSecurityAssociation(ikev2.PayloadType["KEY_EXCHANGE"], ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, "")) @@ -56,11 +51,9 @@ func IkePackSecurityAssociation(payloadType int, proposal []byte) []byte { return IkePackPayloadHeader(payloadType, proposal) } -// Pack // Creates a transform byte array from a transform. // -// // creating a transform -// ikev2.IkeTransform{NextPayload: ikev2.PayloadType["TRANSFORM"], TransformType: ikev2.TransformType["ENCRYPTION_ALGORITHM"], TransformID: ikev2.EncryptionAlgorithm["ENCR_AES_CBC"], TransformAttributes: 0x800e0100} +// ikev2.IkeTransform{NextPayload: ikev2.PayloadType["TRANSFORM"], TransformType: ikev2.TransformType["ENCRYPTION_ALGORITHM"], TransformID: ikev2.EncryptionAlgorithm["ENCR_AES_CBC"], TransformAttributes: 0x800e0100} func (ikeTransform *IkeTransform) Pack() []byte { payload := make([]byte, 0) payload = append(payload, byte(ikeTransform.TransformType)) @@ -75,7 +68,6 @@ func (ikeTransform *IkeTransform) Pack() []byte { return IkePackPayloadHeader(ikeTransform.NextPayload, payload) } -// IkePackPayloadHeader // Encapsulates a Packed component (or any binary array) with the nextHeader. Used by most of these packs. func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { payload := make([]byte, 0) @@ -87,7 +79,6 @@ func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte { return payload } -// IkePackProposal // Creates a Proposal component. // // ikev2.IkePackProposal(ikev2.PayloadType["NONE"], 1, 1, defaultTransforms, ""). @@ -105,7 +96,6 @@ func IkePackProposal(nextPayload int, number int, id int, transforms []IkeTransf return IkePackPayloadHeader(nextPayload, payload) } -// IkePackHeader // Creates a Header component. // // ikev2.IkePackHeader(ikeClient, ikev2.PayloadType["SECURITY_ASSOCIATION"], 0x20, ikev2.ExchangeType["IKE_SA_INIT"], 0x08, 0x0)