Merge pull request #4647 from 5amu/remove-kerberos-dependency

switch dependency for kerberos js module (ropnop/gorkb5 -> jcmturner/gokrb5)
This commit is contained in:
Tarun Koyalwar 2024-02-06 02:37:57 +05:30 committed by GitHub
commit 3b75db46c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 733 additions and 212 deletions

8
go.mod
View File

@ -93,7 +93,6 @@ require (
github.com/projectdiscovery/utils v0.0.77 github.com/projectdiscovery/utils v0.0.77
github.com/projectdiscovery/wappalyzergo v0.0.109 github.com/projectdiscovery/wappalyzergo v0.0.109
github.com/redis/go-redis/v9 v9.1.0 github.com/redis/go-redis/v9 v9.1.0
github.com/ropnop/gokrb5/v8 v8.0.0-20201111231119-729746023c02
github.com/sashabaranov/go-openai v1.15.3 github.com/sashabaranov/go-openai v1.15.3
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/zmap/zgrab2 v0.1.8-0.20230806160807-97ba87c0e706 github.com/zmap/zgrab2 v0.1.8-0.20230806160807-97ba87c0e706
@ -153,14 +152,14 @@ require (
github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/go-github/v30 v30.1.0 // indirect
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.6 // indirect github.com/hashicorp/golang-lru/v2 v2.0.6 // indirect
github.com/hbakhtiyor/strsim v0.0.0-20190107154042-4d2bbb273edf // indirect github.com/hbakhtiyor/strsim v0.0.0-20190107154042-4d2bbb273edf // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.0.0 // indirect github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/rpc/v2 v2.0.2 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kataras/jwt v0.1.10 // indirect github.com/kataras/jwt v0.1.10 // indirect
@ -316,6 +315,7 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/imdario/mergo v0.3.16 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect

19
go.sum
View File

@ -504,7 +504,7 @@ github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@ -529,8 +529,9 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
@ -569,12 +570,14 @@ github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFK
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/rpc/v2 v2.0.2 h1:gMB4IwRXYsWw4Bc6o/az2HJgFUA1ffSh90i26ZJ6Xl0= github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
github.com/jcmturner/rpc/v2 v2.0.2/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
@ -908,8 +911,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/ropnop/gokrb5/v8 v8.0.0-20201111231119-729746023c02 h1:Nk74A6E84pynxLN74hIrQ7Q3cS0/0L5I7coOLNSFAMs=
github.com/ropnop/gokrb5/v8 v8.0.0-20201111231119-729746023c02/go.mod h1:OGEfzIZJs5m/VgAb1BvWR8fH17RTQWx84HTB1koGf9s=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -1139,7 +1140,6 @@ golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -1150,6 +1150,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=

View File

@ -16,12 +16,14 @@ var (
dir string dir string
generatedDir string generatedDir string
targetModules string targetModules string
goOnly bool
) )
func main() { func main() {
flag.StringVar(&dir, "dir", "libs", "directory to process") flag.StringVar(&dir, "dir", "libs", "directory to process")
flag.StringVar(&generatedDir, "out", "generated", "directory to output generated files") flag.StringVar(&generatedDir, "out", "generated", "directory to output generated files")
flag.StringVar(&targetModules, "target", "", "target modules to generate") flag.StringVar(&targetModules, "target", "", "target modules to generate")
flag.BoolVar(&goOnly, "go", false, "generate only go files")
flag.Parse() flag.Parse()
log.SetFlags(0) log.SetFlags(0)
if !fileutil.FolderExists(dir) { if !fileutil.FolderExists(dir) {
@ -52,10 +54,12 @@ func process() error {
} }
prefixed := "lib" + module prefixed := "lib" + module
if !goOnly {
err = data.WriteJSTemplate(filepath.Join(generatedDir, "js/"+prefixed), module) err = data.WriteJSTemplate(filepath.Join(generatedDir, "js/"+prefixed), module)
if err != nil { if err != nil {
return fmt.Errorf("could not write js template: %v", err) return fmt.Errorf("could not write js template: %v", err)
} }
}
err = data.WriteGoTemplate(path.Join(generatedDir, "go/"+prefixed), module) err = data.WriteGoTemplate(path.Join(generatedDir, "go/"+prefixed), module)
if err != nil { if err != nil {
return fmt.Errorf("could not write go template: %v", err) return fmt.Errorf("could not write go template: %v", err)

View File

@ -345,6 +345,10 @@ func (d *TemplateData) handleStarExpr(v *ast.StarExpr) string {
} }
func (d *TemplateData) collectTypeFromExternal(pkg *types.Package, pkgName, name string) { func (d *TemplateData) collectTypeFromExternal(pkg *types.Package, pkgName, name string) {
if pkgName == "goja" {
// no need to attempt to collect types from goja ( this is metadata )
return
}
extra := PackageTypeExtra{ extra := PackageTypeExtra{
Fields: make(map[string]string), Fields: make(map[string]string),
} }

View File

@ -15,16 +15,25 @@ func init() {
module.Set( module.Set(
gojs.Objects{ gojs.Objects{
// Functions // Functions
"ASRepToHashcat": lib_kerberos.ASRepToHashcat,
"CheckKrbError": lib_kerberos.CheckKrbError,
"NewKerberosClient": lib_kerberos.NewKerberosClient,
"NewKerberosClientFromString": lib_kerberos.NewKerberosClientFromString,
"SendToKDC": lib_kerberos.SendToKDC,
"TGStoHashcat": lib_kerberos.TGStoHashcat,
// Var and consts // Var and consts
// Types (value type) // Types (value type)
"Client": lib_kerberos.NewKerberosClient,
"EnumerateUserResponse": func() lib_kerberos.EnumerateUserResponse { return lib_kerberos.EnumerateUserResponse{} }, "EnumerateUserResponse": func() lib_kerberos.EnumerateUserResponse { return lib_kerberos.EnumerateUserResponse{} },
"KerberosClient": func() lib_kerberos.KerberosClient { return lib_kerberos.KerberosClient{} }, "TGS": func() lib_kerberos.TGS { return lib_kerberos.TGS{} },
"Config": func() lib_kerberos.Config { return lib_kerberos.Config{} },
// Types (pointer type) // Types (pointer type)
"NewEnumerateUserResponse": func() *lib_kerberos.EnumerateUserResponse { return &lib_kerberos.EnumerateUserResponse{} }, // "NewClient": func() *lib_kerberos.Client { return &lib_kerberos.Client{} },
"NewKerberosClient": func() *lib_kerberos.KerberosClient { return &lib_kerberos.KerberosClient{} }, // "NewEnumerateUserResponse": func() *lib_kerberos.EnumerateUserResponse { return &lib_kerberos.EnumerateUserResponse{} },
// "NewTGS": func() *lib_kerberos.TGS { return &lib_kerberos.TGS{} },
}, },
).Register() ).Register()
} }

View File

@ -1,193 +0,0 @@
package kerberos
import (
"encoding/hex"
"fmt"
"html/template"
"strings"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
kclient "github.com/ropnop/gokrb5/v8/client"
kconfig "github.com/ropnop/gokrb5/v8/config"
"github.com/ropnop/gokrb5/v8/iana/errorcode"
"github.com/ropnop/gokrb5/v8/messages"
)
// Client is a kerberos client
type KerberosClient struct{}
type kerberosEnumUserOpts struct {
realm string
config *kconfig.Config
kdcs map[int]string
}
// Taken from kerbrute: https://github.com/ropnop/kerbrute/blob/master/session/session.go
const krb5ConfigTemplateDNS = `[libdefaults]
dns_lookup_kdc = true
default_realm = {{.Realm}}
`
const krb5ConfigTemplateKDC = `[libdefaults]
default_realm = {{.Realm}}
[realms]
{{.Realm}} = {
kdc = {{.DomainController}}
admin_server = {{.DomainController}}
}
`
func buildKrb5Template(realm, domainController string) string {
data := map[string]interface{}{
"Realm": realm,
"DomainController": domainController,
}
var kTemplate string
if domainController == "" {
kTemplate = krb5ConfigTemplateDNS
} else {
kTemplate = krb5ConfigTemplateKDC
}
t := template.Must(template.New("krb5ConfigString").Parse(kTemplate))
builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
panic(err)
}
return builder.String()
}
func newKerbrosEnumUserOpts(domain, domainController string) (*kerberosEnumUserOpts, error) {
realm := strings.ToUpper(domain)
configstring := buildKrb5Template(realm, domainController)
Config, err := kconfig.NewFromString(configstring)
if err != nil {
return nil, err
}
_, kdcs, err := Config.GetKDCs(realm, false)
if err != nil {
err = fmt.Errorf("couldn't find any KDCs for realm %s. Please specify a Domain Controller", realm)
return nil, err
}
return &kerberosEnumUserOpts{realm: realm, config: Config, kdcs: kdcs}, nil
}
// EnumerateUserResponse is the response from EnumerateUser
type EnumerateUserResponse struct {
Valid bool
ASREPHash string
}
// EnumerateUser returns true if the user exists in the domain
//
// If the user is not found, false is returned.
// If the user is found, true is returned. Optionally, the AS-REP
// hash is also returned if discovered.
func (c *KerberosClient) EnumerateUser(domain, controller string, username string) (EnumerateUserResponse, error) {
resp := EnumerateUserResponse{}
if !protocolstate.IsHostAllowed(domain) {
// host is not valid according to network policy
return resp, protocolstate.ErrHostDenied.Msgf(domain)
}
opts, err := newKerbrosEnumUserOpts(domain, controller)
if err != nil {
return resp, err
}
cl := kclient.NewWithPassword(username, opts.realm, "foobar", opts.config, kclient.DisablePAFXFAST(true))
defer cl.Destroy()
req, err := messages.NewASReqForTGT(cl.Credentials.Domain(), cl.Config, cl.Credentials.CName())
if err != nil {
return resp, err
}
b, err := req.Marshal()
if err != nil {
return resp, err
}
rb, err := cl.SendToKDC(b, opts.realm)
if err == nil {
var ASRep messages.ASRep
err = ASRep.Unmarshal(rb)
if err != nil {
// something went wrong, it's not a valid response
return resp, err
}
hashcatString, _ := asRepToHashcat(ASRep)
resp.Valid = true
resp.ASREPHash = hashcatString
return resp, nil
}
e, ok := err.(messages.KRBError)
if !ok {
return resp, nil
}
switch e.ErrorCode {
case errorcode.KDC_ERR_C_PRINCIPAL_UNKNOWN:
return resp, nil
case errorcode.KDC_ERR_PREAUTH_REQUIRED:
resp.Valid = true
return resp, nil
default:
return resp, err
}
}
func asRepToHashcat(asrep messages.ASRep) (string, error) {
return fmt.Sprintf("$krb5asrep$%d$%s@%s:%s$%s",
asrep.EncPart.EType,
asrep.CName.PrincipalNameString(),
asrep.CRealm,
hex.EncodeToString(asrep.EncPart.Cipher[:16]),
hex.EncodeToString(asrep.EncPart.Cipher[16:])), nil
}
type TGS struct {
Ticket messages.Ticket
Hash string
}
func (c *KerberosClient) GetServiceTicket(domain, controller string, username, password string, target, spn string) (TGS, error) {
var tgs TGS
if !protocolstate.IsHostAllowed(domain) {
// host is not valid according to network policy
return tgs, protocolstate.ErrHostDenied.Msgf(domain)
}
opts, err := newKerbrosEnumUserOpts(domain, controller)
if err != nil {
return tgs, err
}
cl := kclient.NewWithPassword(username, opts.realm, password, opts.config, kclient.DisablePAFXFAST(true))
defer cl.Destroy()
ticket, _, err := cl.GetServiceTicket(spn)
if err != nil {
return tgs, err
}
hashcat, err := tgsToHashcat(ticket, target)
if err != nil {
return tgs, err
}
return TGS{
Ticket: ticket,
Hash: hashcat,
}, nil
}
func tgsToHashcat(tgs messages.Ticket, username string) (string, error) {
return fmt.Sprintf("$krb5tgs$%d$*%s$%s$%s*$%s$%s",
tgs.EncPart.EType,
username,
tgs.Realm,
strings.Join(tgs.SName.NameString[:], "/"),
hex.EncodeToString(tgs.EncPart.Cipher[:16]),
hex.EncodeToString(tgs.EncPart.Cipher[16:]),
), nil
}

View File

@ -0,0 +1,313 @@
package kerberos
import (
"strings"
"github.com/dop251/goja"
kclient "github.com/jcmturner/gokrb5/v8/client"
kconfig "github.com/jcmturner/gokrb5/v8/config"
"github.com/jcmturner/gokrb5/v8/iana/errorcode"
"github.com/jcmturner/gokrb5/v8/messages"
"github.com/projectdiscovery/nuclei/v3/pkg/js/utils"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
ConversionUtil "github.com/projectdiscovery/utils/conversion"
)
// Known Issues:
// Hardcoded timeout in gokrb5 library
// TGT / Session Handling not exposed
// EnumerateUserResponse is the response from EnumerateUser
type EnumerateUserResponse struct {
Valid bool `json:"valid"`
ASREPHash string `json:"asrep_hash"`
Error string `json:"error"`
}
// TGS is the response from GetServiceTicket
type TGS struct {
Ticket messages.Ticket `json:"ticket"`
Hash string `json:"hash"`
ErrMsg string `json:"error"`
}
// Config is extra configuration for the kerberos client
type Config struct {
ip string
timeout int // in seconds
}
func (c *Config) SetIPAddress(ip string) *Config {
c.ip = ip
return c
}
func (c *Config) SetTimeout(timeout int) *Config {
c.timeout = timeout
return c
}
// Example Values for jargons
// Realm: ACME.COM (Authentical zone / security area)
// Domain: acme.com (Public website / domain)
// DomainController: dc.acme.com (Domain Controller / Active Directory Server)
// KDC: kdc.acme.com (Key Distribution Center / Authentication Server)
// Updated Package definations and structure
type Client struct {
nj *utils.NucleiJS // helper functions/bindings
Krb5Config *kconfig.Config
Realm string
config Config
}
// Constructor for KerberosClient
// if controller is empty a dns lookup for default kdc server will be performed
// Signature: Client(domain, {controller})
// @param domain: string
// @param controller: string (optional)
// When controller is empty or not given krb5 will perform a DNS lookup for the default KDC server
// and retrieve its address from the DNS server
func NewKerberosClient(call goja.ConstructorCall, runtime *goja.Runtime) *goja.Object {
// setup nucleijs utils
c := &Client{nj: utils.NewNucleiJS(runtime)}
c.nj.ObjectSig = "Client(domain, controller)" // will be included in error messages
// get arguments (type assertion is efficient than reflection)
// when accepting type as input like net.Conn we can use utils.GetArg
domain, _ := c.nj.GetArg(call.Arguments, 0).(string)
controller, _ := c.nj.GetArg(call.Arguments, 1).(string)
// validate arguments
c.nj.Require(domain != "", "domain cannot be empty")
cfg := kconfig.New()
if controller != "" {
// validate controller hostport
if !protocolstate.IsHostAllowed(controller) {
c.nj.Throw("domain controller address blacklisted by network policy")
}
tmp := strings.Split(controller, ":")
if len(tmp) == 1 {
tmp = append(tmp, "88")
}
realm := strings.ToUpper(domain)
cfg.LibDefaults.DefaultRealm = realm // set default realm
cfg.Realms = []kconfig.Realm{
{
Realm: realm,
KDC: []string{tmp[0] + ":" + tmp[1]},
AdminServer: []string{tmp[0] + ":" + tmp[1]},
KPasswdServer: []string{tmp[0] + ":464"}, // default password server port
},
}
cfg.DomainRealm = make(kconfig.DomainRealm)
} else {
// if controller is empty use DNS lookup
cfg.LibDefaults.DNSLookupKDC = true
cfg.LibDefaults.DefaultRealm = strings.ToUpper(domain)
cfg.DomainRealm = make(kconfig.DomainRealm)
}
c.Krb5Config = cfg
c.Realm = strings.ToUpper(domain)
// Link Constructor to Client and return
return utils.LinkConstructor(call, runtime, c)
}
// NewKerberosClientFromString creates a new kerberos client from a string
// by parsing krb5.conf
// @param cfg: string
// Example krb5.conf:
// [libdefaults]
// default_realm = ACME.COM
// dns_lookup_kdc = true
func NewKerberosClientFromString(cfg string) (*Client, error) {
config, err := kconfig.NewFromString(cfg)
if err != nil {
return nil, err
}
return &Client{Krb5Config: config}, nil
}
// SetConfig sets additional config for the kerberos client
// Signature: SetConfig(cfg)
// @param cfg: @Config
// Note: as of now ip and timeout overrides are only supported
// in EnumerateUser due to fastdialer but can be extended to other methods currently
func (c *Client) SetConfig(cfg *Config) {
if cfg == nil {
c.nj.Throw("config cannot be nil")
}
c.config = *cfg
}
// EnumerateUser and attempt to get AS-REP hash by disabling PA-FX-FAST
// Signature: EnumerateUser(username, {password})
// @param username: string
func (c *Client) EnumerateUser(username string) (EnumerateUserResponse, error) {
c.nj.Require(c.Krb5Config != nil, "Kerberos client not initialized")
password := "password"
// client does not actually attempt connection it manages state here
client := kclient.NewWithPassword(username, c.Realm, password, c.Krb5Config, kclient.DisablePAFXFAST(true))
defer client.Destroy()
// generate ASReq hash
req, err := messages.NewASReqForTGT(client.Credentials.Domain(), client.Config, client.Credentials.CName())
c.nj.HandleError(err, "failed to generate TGT request")
// marshal request
b, err := req.Marshal()
c.nj.HandleError(err, "failed to marshal TGT request")
data, err := SendToKDC(c, string(b))
rb := ConversionUtil.Bytes(data)
if err == nil {
var ASRep messages.ASRep
resp := EnumerateUserResponse{Valid: true}
err = ASRep.Unmarshal(rb)
if err != nil {
resp.Error = err.Error()
return resp, nil
}
hashcatString, _ := ASRepToHashcat(ASRep)
resp.ASREPHash = hashcatString
return resp, nil
}
resp := EnumerateUserResponse{}
e, ok := err.(messages.KRBError)
if !ok {
return resp, err
}
if e.ErrorCode == errorcode.KDC_ERR_PREAUTH_REQUIRED {
resp.Valid = true
resp.Error = errorcode.Lookup(e.ErrorCode)
return resp, nil
}
resp.Error = errorcode.Lookup(e.ErrorCode)
return resp, nil
}
// GetServiceTicket returns a TGS for a given user, password, target and SPN
// Signature: GetServiceTicket(User, Pass, Target, SPN)
// @param User: string
// @param Pass: string
// @param SPN: string Service Principal Name
func (c *Client) GetServiceTicket(User, Pass, SPN string) (TGS, error) {
c.nj.Require(c.Krb5Config != nil, "Kerberos client not initialized")
c.nj.Require(User != "", "User cannot be empty")
c.nj.Require(Pass != "", "Pass cannot be empty")
c.nj.Require(SPN != "", "SPN cannot be empty")
if len(c.Krb5Config.Realms) > 0 {
// this means dc address was given
for _, r := range c.Krb5Config.Realms {
for _, kdc := range r.KDC {
if !protocolstate.IsHostAllowed(kdc) {
c.nj.Throw("KDC address %v blacklisted by network policy", kdc)
}
}
for _, kpasswd := range r.KPasswdServer {
if !protocolstate.IsHostAllowed(kpasswd) {
c.nj.Throw("Kpasswd address %v blacklisted by network policy", kpasswd)
}
}
}
} else {
// here net.Dialer is used instead of fastdialer hence get possible addresses
// and check if they are allowed by network policy
_, kdcs, _ := c.Krb5Config.GetKDCs(c.Realm, true)
for _, v := range kdcs {
if !protocolstate.IsHostAllowed(v) {
c.nj.Throw("KDC address %v blacklisted by network policy", v)
}
}
}
// client does not actually attempt connection it manages state here
client := kclient.NewWithPassword(User, c.Realm, Pass, c.Krb5Config, kclient.DisablePAFXFAST(true))
defer client.Destroy()
resp := TGS{}
ticket, _, err := client.GetServiceTicket(SPN)
resp.Ticket = ticket
if err != nil {
if code, ok := err.(messages.KRBError); ok {
resp.ErrMsg = errorcode.Lookup(code.ErrorCode)
return resp, err
}
return resp, err
}
// convert AS-REP to hashcat format
hashcat, err := TGStoHashcat(ticket, c.Realm)
if err != nil {
if code, ok := err.(messages.KRBError); ok {
resp.ErrMsg = errorcode.Lookup(code.ErrorCode)
return resp, err
}
return resp, err
}
resp.Ticket = ticket
resp.Hash = hashcat
return resp, nil
}
// // GetASREP returns AS-REP for a given user and password
// // it contains Client's TGT , Principal and Session Key
// // Signature: GetASREP(User, Pass)
// // @param User: string
// // @param Pass: string
// func (c *Client) GetASREP(User, Pass string) messages.ASRep {
// c.nj.Require(c.Krb5Config != nil, "Kerberos client not initialized")
// c.nj.Require(User != "", "User cannot be empty")
// c.nj.Require(Pass != "", "Pass cannot be empty")
// if len(c.Krb5Config.Realms) > 0 {
// // this means dc address was given
// for _, r := range c.Krb5Config.Realms {
// for _, kdc := range r.KDC {
// if !protocolstate.IsHostAllowed(kdc) {
// c.nj.Throw("KDC address blacklisted by network policy")
// }
// }
// for _, kpasswd := range r.KPasswdServer {
// if !protocolstate.IsHostAllowed(kpasswd) {
// c.nj.Throw("Kpasswd address blacklisted by network policy")
// }
// }
// }
// } else {
// // here net.Dialer is used instead of fastdialer hence get possible addresses
// // and check if they are allowed by network policy
// _, kdcs, _ := c.Krb5Config.GetKDCs(c.Realm, true)
// for _, v := range kdcs {
// if !protocolstate.IsHostAllowed(v) {
// c.nj.Throw("KDC address blacklisted by network policy")
// }
// }
// }
// // login to get TGT
// cl := kclient.NewWithPassword(User, c.Realm, Pass, c.Krb5Config, kclient.DisablePAFXFAST(true))
// defer cl.Destroy()
// // generate ASReq
// ASReq, err := messages.NewASReqForTGT(cl.Credentials.Domain(), cl.Config, cl.Credentials.CName())
// c.nj.HandleError(err, "failed to generate TGT request")
// // exchange AS-REQ for AS-REP
// resp, err := cl.ASExchange(c.Realm, ASReq, 0)
// c.nj.HandleError(err, "failed to exchange AS-REQ")
// // try to decrypt encrypted parts of the response and TGT
// key, err := resp.DecryptEncPart(cl.Credentials)
// if err == nil {
// _ = resp.Ticket.Decrypt(key)
// }
// return resp
// }

View File

@ -0,0 +1,206 @@
package kerberos
// the following code is adapted from the original library
// https://github.com/jcmturner/gokrb5/blob/855dbc707a37a21467aef6c0245fcf3328dc39ed/v8/client/network.go
// it is copied here because the library does not export "SendToKDC()"
import (
"context"
"encoding/binary"
"encoding/hex"
"fmt"
"io"
"net"
"strings"
"time"
"github.com/jcmturner/gokrb5/v8/messages"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)
// sendtokdc.go deals with actual sending and receiving responses from KDC
// SendToKDC sends a message to the KDC and returns the response.
func SendToKDC(kclient *Client, msg string) (string, error) {
if kclient == nil || kclient.nj == nil || kclient.Krb5Config == nil || kclient.Realm == "" {
return "", fmt.Errorf("kerberos client is not initialized")
}
if kclient.config.timeout == 0 {
kclient.config.timeout = 5 // default timeout 5 seconds
}
var response []byte
var err error
response, err = sendToKDCTcp(kclient, msg)
if err == nil {
// if it related to tcp
bin, err := CheckKrbError(response)
if err == nil {
return string(bin), nil
}
// if it is krb error no need to do udp
if e, ok := err.(messages.KRBError); ok {
return string(response), e
}
}
// fallback to udp
response, err = sendToKDCUdp(kclient, msg)
if err == nil {
// if it related to udp
bin, err := CheckKrbError(response)
if err == nil {
return string(bin), nil
}
}
return string(response), err
}
// sendToKDCTcp sends a message to the KDC via TCP.
func sendToKDCTcp(kclient *Client, msg string) ([]byte, error) {
_, kdcs, err := kclient.Krb5Config.GetKDCs(kclient.Realm, true)
kclient.nj.HandleError(err, "error getting KDCs")
kclient.nj.Require(len(kdcs) > 0, "no KDCs found")
var errs []string
for i := 1; i <= len(kdcs); i++ {
host, port, err := net.SplitHostPort(kdcs[i])
if err == nil && kclient.config.ip != "" {
// use that ip address instead of realm/domain for resolving
host = kclient.config.ip
}
tcpConn, err := protocolstate.Dialer.Dial(context.TODO(), "tcp", net.JoinHostPort(host, port))
if err != nil {
errs = append(errs, fmt.Sprintf("error establishing connection to %s: %v", kdcs[i], err))
continue
}
defer tcpConn.Close()
_ = tcpConn.SetDeadline(time.Now().Add(time.Duration(kclient.config.timeout) * time.Second)) //read and write deadline
rb, err := sendTCP(tcpConn.(*net.TCPConn), []byte(msg))
if err != nil {
errs = append(errs, fmt.Sprintf("error sending to %s: %v", kdcs[i], err))
continue
}
return rb, nil
}
if len(errs) > 0 {
return nil, fmt.Errorf("error sending to a KDC: %s", strings.Join(errs, "; "))
}
return nil, nil
}
// sendToKDCUdp sends a message to the KDC via UDP.
func sendToKDCUdp(kclient *Client, msg string) ([]byte, error) {
_, kdcs, err := kclient.Krb5Config.GetKDCs(kclient.Realm, true)
kclient.nj.HandleError(err, "error getting KDCs")
kclient.nj.Require(len(kdcs) > 0, "no KDCs found")
var errs []string
for i := 1; i <= len(kdcs); i++ {
host, port, err := net.SplitHostPort(kdcs[i])
if err == nil && kclient.config.ip != "" {
// use that ip address instead of realm/domain for resolving
host = kclient.config.ip
}
udpConn, err := protocolstate.Dialer.Dial(context.TODO(), "udp", net.JoinHostPort(host, port))
if err != nil {
errs = append(errs, fmt.Sprintf("error establishing connection to %s: %v", kdcs[i], err))
continue
}
defer udpConn.Close()
_ = udpConn.SetDeadline(time.Now().Add(time.Duration(kclient.config.timeout) * time.Second)) //read and write deadline
rb, err := sendUDP(udpConn.(*net.UDPConn), []byte(msg))
if err != nil {
errs = append(errs, fmt.Sprintf("error sending to %s: %v", kdcs[i], err))
continue
}
return rb, nil
}
if len(errs) > 0 {
// fallback to tcp
return nil, fmt.Errorf("error sending to a KDC: %s", strings.Join(errs, "; "))
}
return nil, nil
}
// sendUDP sends bytes to connection over UDP.
func sendUDP(conn *net.UDPConn, b []byte) ([]byte, error) {
var r []byte
defer conn.Close()
_, err := conn.Write(b)
if err != nil {
return r, fmt.Errorf("error sending to (%s): %v", conn.RemoteAddr().String(), err)
}
udpbuf := make([]byte, 4096)
n, _, err := conn.ReadFrom(udpbuf)
r = udpbuf[:n]
if err != nil {
return r, fmt.Errorf("sending over UDP failed to %s: %v", conn.RemoteAddr().String(), err)
}
if len(r) < 1 {
return r, fmt.Errorf("no response data from %s", conn.RemoteAddr().String())
}
return r, nil
}
// sendTCP sends bytes to connection over TCP.
func sendTCP(conn *net.TCPConn, b []byte) ([]byte, error) {
defer conn.Close()
var r []byte
// RFC 4120 7.2.2 specifies the first 4 bytes indicate the length of the message in big endian order.
hb := make([]byte, 4)
binary.BigEndian.PutUint32(hb, uint32(len(b)))
b = append(hb, b...)
_, err := conn.Write(b)
if err != nil {
return r, fmt.Errorf("error sending to KDC (%s): %v", conn.RemoteAddr().String(), err)
}
sh := make([]byte, 4)
_, err = conn.Read(sh)
if err != nil {
return r, fmt.Errorf("error reading response size header: %v", err)
}
s := binary.BigEndian.Uint32(sh)
rb := make([]byte, s)
_, err = io.ReadFull(conn, rb)
if err != nil {
return r, fmt.Errorf("error reading response: %v", err)
}
if len(rb) < 1 {
return r, fmt.Errorf("no response data from KDC %s", conn.RemoteAddr().String())
}
return rb, nil
}
// CheckKrbError checks if the response bytes from the KDC are a KRBError.
func CheckKrbError(b []byte) ([]byte, error) {
var KRBErr messages.KRBError
if err := KRBErr.Unmarshal(b); err == nil {
return b, KRBErr
}
return b, nil
}
// TGStoHashcat converts a TGS to a hashcat format.
func TGStoHashcat(tgs messages.Ticket, username string) (string, error) {
return fmt.Sprintf("$krb5tgs$%d$*%s$%s$%s*$%s$%s",
tgs.EncPart.EType,
username,
tgs.Realm,
strings.Join(tgs.SName.NameString[:], "/"),
hex.EncodeToString(tgs.EncPart.Cipher[:16]),
hex.EncodeToString(tgs.EncPart.Cipher[16:]),
), nil
}
// ASRepToHashcat converts an AS-REP message to a hashcat format
func ASRepToHashcat(asrep messages.ASRep) (string, error) {
return fmt.Sprintf("$krb5asrep$%d$%s@%s:%s$%s",
asrep.EncPart.EType,
asrep.CName.PrincipalNameString(),
asrep.CRealm,
hex.EncodeToString(asrep.EncPart.Cipher[:16]),
hex.EncodeToString(asrep.EncPart.Cipher[16:])), nil
}

158
pkg/js/utils/nucleijs.go Normal file
View File

@ -0,0 +1,158 @@
package utils
import (
"fmt"
"reflect"
"strings"
"sync"
"github.com/dop251/goja"
)
// temporary on demand runtime to throw errors when vm is not available
var (
tmpRuntime *goja.Runtime
runtimeInit func() = sync.OnceFunc(func() {
tmpRuntime = goja.New()
})
)
func getRuntime() *goja.Runtime {
runtimeInit()
return tmpRuntime
}
// NucleiJS is js bindings that handles goja runtime related issue
// and allows setting a defer statements to close resources
type NucleiJS struct {
vm *goja.Runtime
ObjectSig string
}
// NewNucleiJS creates a new nucleijs instance
func NewNucleiJS(vm *goja.Runtime) *NucleiJS {
return &NucleiJS{vm: vm}
}
// internal runtime getter
func (j *NucleiJS) runtime() *goja.Runtime {
if j == nil {
return getRuntime()
}
return j.vm
}
// see: https://arc.net/l/quote/wpenftpc for throwing docs
// ThrowError throws an error in goja runtime if is not nil
func (j *NucleiJS) ThrowError(err error) {
if err == nil {
return
}
panic(j.runtime().ToValue(err.Error()))
}
// HandleError handles error and throws a
func (j *NucleiJS) HandleError(err error, msg ...string) {
if err == nil {
return
}
if len(msg) == 0 {
j.ThrowError(err)
}
j.Throw(fmt.Sprintf("%s: %s", strings.Join(msg, ":"), err.Error()))
}
// Throw throws an error in goja runtime
func (j *NucleiJS) Throw(format string, args ...interface{}) {
panic(j.runtime().ToValue(fmt.Sprintf(format, args...)))
}
// GetArg returns argument at index from goja runtime if not found throws error
func (j *NucleiJS) GetArg(args []goja.Value, index int) any {
if index >= len(args) {
j.Throw("Missing argument at index %v: %v", index, j.ObjectSig)
}
val := args[index]
if goja.IsUndefined(val) {
j.Throw("Missing argument at index %v: %v", index, j.ObjectSig)
}
return val.Export()
}
// GetArgSafe returns argument at index from goja runtime if not found returns default value
func (j *NucleiJS) GetArgSafe(args []goja.Value, index int, defaultValue any) any {
if index >= len(args) {
return defaultValue
}
val := args[index]
if goja.IsUndefined(val) {
return defaultValue
}
return val.Export()
}
// Require throws an error if expression is false
func (j *NucleiJS) Require(expr bool, msg string) {
if !expr {
j.Throw(msg)
}
}
// LinkConstructor links a type with invocation doing this allows
// usage of instance of type in js
func LinkConstructor[T any](call goja.ConstructorCall, vm *goja.Runtime, obj T) *goja.Object {
instance := vm.ToValue(obj).(*goja.Object)
_ = instance.SetPrototype(call.This.Prototype())
return instance
}
// GetStructType gets a type defined in go and passed as argument from goja runtime if not found throws error
// Donot use this unless you are accepting a struct type from constructor
func GetStructType[T any](nj *NucleiJS, args []goja.Value, index int, FuncSig string) T {
if nj == nil {
nj = &NucleiJS{}
}
if index >= len(args) {
if FuncSig == "" {
nj.Throw("Missing argument at index %v", index)
}
nj.Throw("Missing arguments expected : %v", FuncSig)
}
value := args[index]
// validate type
var ptr T
expected := reflect.ValueOf(ptr).Type()
argType := expected.Name()
valueType := value.ExportType().Name()
if argType != valueType {
nj.Throw("Type Mismatch expected %v got %v", argType, valueType)
}
ptrValue := reflect.New(expected).Elem()
ptrValue.Set(reflect.ValueOf(value.Export()))
return ptrValue.Interface().(T)
}
// GetStructTypeSafe gets an type defined in go and passed as argument from goja runtime if not found returns default value
// Donot use this unless you are accepting a struct type from constructor
func GetStructTypeSafe[T any](nj *NucleiJS, args []goja.Value, index int, defaultValue T) T {
if nj == nil {
nj = &NucleiJS{}
}
if index >= len(args) {
return defaultValue
}
value := args[index]
// validate type
var ptr T
argType := reflect.ValueOf(ptr).Type().Name()
valueType := value.ExportType().Name()
if argType != valueType {
return defaultValue
}
return value.ToObject(nj.runtime()).Export().(T)
}

View File

@ -1,6 +1,7 @@
package protocolstate package protocolstate
import ( import (
"net"
"strings" "strings"
"github.com/go-rod/rod" "github.com/go-rod/rod"
@ -81,6 +82,24 @@ func IsHostAllowed(targetUrl string) bool {
if NetworkPolicy == nil { if NetworkPolicy == nil {
return true return true
} }
sepCount := strings.Count(targetUrl, ":")
if sepCount > 1 {
// most likely a ipv6 address (parse url and validate host)
return NetworkPolicy.Validate(targetUrl)
}
if sepCount == 1 {
host, _, _ := net.SplitHostPort(targetUrl)
if _, ok := NetworkPolicy.ValidateHost(host); !ok {
return false
}
return true
// portInt, _ := strconv.Atoi(port)
// fixme: broken port validation logic in networkpolicy
// if !NetworkPolicy.ValidatePort(portInt) {
// return false
// }
}
// just a hostname or ip without port
_, ok := NetworkPolicy.ValidateHost(targetUrl) _, ok := NetworkPolicy.ValidateHost(targetUrl)
return ok return ok
} }