@etcsec-com/etc-collector 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (617) hide show
  1. package/.env.example +60 -0
  2. package/.env.test.example +33 -0
  3. package/.github/workflows/ci.yml +83 -0
  4. package/.github/workflows/release.yml +246 -0
  5. package/.prettierrc.json +10 -0
  6. package/CHANGELOG.md +15 -0
  7. package/Dockerfile +57 -0
  8. package/LICENSE +190 -0
  9. package/README.md +194 -0
  10. package/dist/api/controllers/audit.controller.d.ts +21 -0
  11. package/dist/api/controllers/audit.controller.d.ts.map +1 -0
  12. package/dist/api/controllers/audit.controller.js +179 -0
  13. package/dist/api/controllers/audit.controller.js.map +1 -0
  14. package/dist/api/controllers/auth.controller.d.ts +16 -0
  15. package/dist/api/controllers/auth.controller.d.ts.map +1 -0
  16. package/dist/api/controllers/auth.controller.js +146 -0
  17. package/dist/api/controllers/auth.controller.js.map +1 -0
  18. package/dist/api/controllers/export.controller.d.ts +27 -0
  19. package/dist/api/controllers/export.controller.d.ts.map +1 -0
  20. package/dist/api/controllers/export.controller.js +80 -0
  21. package/dist/api/controllers/export.controller.js.map +1 -0
  22. package/dist/api/controllers/health.controller.d.ts +5 -0
  23. package/dist/api/controllers/health.controller.d.ts.map +1 -0
  24. package/dist/api/controllers/health.controller.js +16 -0
  25. package/dist/api/controllers/health.controller.js.map +1 -0
  26. package/dist/api/controllers/jobs.controller.d.ts +13 -0
  27. package/dist/api/controllers/jobs.controller.d.ts.map +1 -0
  28. package/dist/api/controllers/jobs.controller.js +125 -0
  29. package/dist/api/controllers/jobs.controller.js.map +1 -0
  30. package/dist/api/controllers/providers.controller.d.ts +15 -0
  31. package/dist/api/controllers/providers.controller.d.ts.map +1 -0
  32. package/dist/api/controllers/providers.controller.js +112 -0
  33. package/dist/api/controllers/providers.controller.js.map +1 -0
  34. package/dist/api/dto/AuditRequest.dto.d.ts +6 -0
  35. package/dist/api/dto/AuditRequest.dto.d.ts.map +1 -0
  36. package/dist/api/dto/AuditRequest.dto.js +3 -0
  37. package/dist/api/dto/AuditRequest.dto.js.map +1 -0
  38. package/dist/api/dto/AuditResponse.dto.d.ts +17 -0
  39. package/dist/api/dto/AuditResponse.dto.d.ts.map +1 -0
  40. package/dist/api/dto/AuditResponse.dto.js +3 -0
  41. package/dist/api/dto/AuditResponse.dto.js.map +1 -0
  42. package/dist/api/dto/TokenRequest.dto.d.ts +6 -0
  43. package/dist/api/dto/TokenRequest.dto.d.ts.map +1 -0
  44. package/dist/api/dto/TokenRequest.dto.js +3 -0
  45. package/dist/api/dto/TokenRequest.dto.js.map +1 -0
  46. package/dist/api/dto/TokenResponse.dto.d.ts +12 -0
  47. package/dist/api/dto/TokenResponse.dto.d.ts.map +1 -0
  48. package/dist/api/dto/TokenResponse.dto.js +3 -0
  49. package/dist/api/dto/TokenResponse.dto.js.map +1 -0
  50. package/dist/api/middlewares/authenticate.d.ts +12 -0
  51. package/dist/api/middlewares/authenticate.d.ts.map +1 -0
  52. package/dist/api/middlewares/authenticate.js +141 -0
  53. package/dist/api/middlewares/authenticate.js.map +1 -0
  54. package/dist/api/middlewares/errorHandler.d.ts +3 -0
  55. package/dist/api/middlewares/errorHandler.d.ts.map +1 -0
  56. package/dist/api/middlewares/errorHandler.js +30 -0
  57. package/dist/api/middlewares/errorHandler.js.map +1 -0
  58. package/dist/api/middlewares/rateLimit.d.ts +3 -0
  59. package/dist/api/middlewares/rateLimit.d.ts.map +1 -0
  60. package/dist/api/middlewares/rateLimit.js +34 -0
  61. package/dist/api/middlewares/rateLimit.js.map +1 -0
  62. package/dist/api/middlewares/validate.d.ts +4 -0
  63. package/dist/api/middlewares/validate.d.ts.map +1 -0
  64. package/dist/api/middlewares/validate.js +31 -0
  65. package/dist/api/middlewares/validate.js.map +1 -0
  66. package/dist/api/routes/audit.routes.d.ts +5 -0
  67. package/dist/api/routes/audit.routes.d.ts.map +1 -0
  68. package/dist/api/routes/audit.routes.js +24 -0
  69. package/dist/api/routes/audit.routes.js.map +1 -0
  70. package/dist/api/routes/auth.routes.d.ts +6 -0
  71. package/dist/api/routes/auth.routes.d.ts.map +1 -0
  72. package/dist/api/routes/auth.routes.js +22 -0
  73. package/dist/api/routes/auth.routes.js.map +1 -0
  74. package/dist/api/routes/export.routes.d.ts +5 -0
  75. package/dist/api/routes/export.routes.d.ts.map +1 -0
  76. package/dist/api/routes/export.routes.js +16 -0
  77. package/dist/api/routes/export.routes.js.map +1 -0
  78. package/dist/api/routes/health.routes.d.ts +4 -0
  79. package/dist/api/routes/health.routes.d.ts.map +1 -0
  80. package/dist/api/routes/health.routes.js +11 -0
  81. package/dist/api/routes/health.routes.js.map +1 -0
  82. package/dist/api/routes/index.d.ts +10 -0
  83. package/dist/api/routes/index.d.ts.map +1 -0
  84. package/dist/api/routes/index.js +20 -0
  85. package/dist/api/routes/index.js.map +1 -0
  86. package/dist/api/routes/providers.routes.d.ts +5 -0
  87. package/dist/api/routes/providers.routes.d.ts.map +1 -0
  88. package/dist/api/routes/providers.routes.js +13 -0
  89. package/dist/api/routes/providers.routes.js.map +1 -0
  90. package/dist/api/validators/audit.schemas.d.ts +60 -0
  91. package/dist/api/validators/audit.schemas.d.ts.map +1 -0
  92. package/dist/api/validators/audit.schemas.js +55 -0
  93. package/dist/api/validators/audit.schemas.js.map +1 -0
  94. package/dist/api/validators/auth.schemas.d.ts +17 -0
  95. package/dist/api/validators/auth.schemas.d.ts.map +1 -0
  96. package/dist/api/validators/auth.schemas.js +21 -0
  97. package/dist/api/validators/auth.schemas.js.map +1 -0
  98. package/dist/app.d.ts +3 -0
  99. package/dist/app.d.ts.map +1 -0
  100. package/dist/app.js +62 -0
  101. package/dist/app.js.map +1 -0
  102. package/dist/config/config.schema.d.ts +65 -0
  103. package/dist/config/config.schema.d.ts.map +1 -0
  104. package/dist/config/config.schema.js +95 -0
  105. package/dist/config/config.schema.js.map +1 -0
  106. package/dist/config/index.d.ts +4 -0
  107. package/dist/config/index.d.ts.map +1 -0
  108. package/dist/config/index.js +75 -0
  109. package/dist/config/index.js.map +1 -0
  110. package/dist/container.d.ts +47 -0
  111. package/dist/container.d.ts.map +1 -0
  112. package/dist/container.js +137 -0
  113. package/dist/container.js.map +1 -0
  114. package/dist/data/database.d.ts +13 -0
  115. package/dist/data/database.d.ts.map +1 -0
  116. package/dist/data/database.js +68 -0
  117. package/dist/data/database.js.map +1 -0
  118. package/dist/data/jobs/token-cleanup.job.d.ts +23 -0
  119. package/dist/data/jobs/token-cleanup.job.d.ts.map +1 -0
  120. package/dist/data/jobs/token-cleanup.job.js +96 -0
  121. package/dist/data/jobs/token-cleanup.job.js.map +1 -0
  122. package/dist/data/migrations/migration.runner.d.ts +13 -0
  123. package/dist/data/migrations/migration.runner.d.ts.map +1 -0
  124. package/dist/data/migrations/migration.runner.js +136 -0
  125. package/dist/data/migrations/migration.runner.js.map +1 -0
  126. package/dist/data/models/Token.model.d.ts +30 -0
  127. package/dist/data/models/Token.model.d.ts.map +1 -0
  128. package/dist/data/models/Token.model.js +3 -0
  129. package/dist/data/models/Token.model.js.map +1 -0
  130. package/dist/data/repositories/token.repository.d.ts +16 -0
  131. package/dist/data/repositories/token.repository.d.ts.map +1 -0
  132. package/dist/data/repositories/token.repository.js +97 -0
  133. package/dist/data/repositories/token.repository.js.map +1 -0
  134. package/dist/providers/azure/auth.provider.d.ts +5 -0
  135. package/dist/providers/azure/auth.provider.d.ts.map +1 -0
  136. package/dist/providers/azure/auth.provider.js +13 -0
  137. package/dist/providers/azure/auth.provider.js.map +1 -0
  138. package/dist/providers/azure/azure-errors.d.ts +40 -0
  139. package/dist/providers/azure/azure-errors.d.ts.map +1 -0
  140. package/dist/providers/azure/azure-errors.js +121 -0
  141. package/dist/providers/azure/azure-errors.js.map +1 -0
  142. package/dist/providers/azure/azure-retry.d.ts +41 -0
  143. package/dist/providers/azure/azure-retry.d.ts.map +1 -0
  144. package/dist/providers/azure/azure-retry.js +85 -0
  145. package/dist/providers/azure/azure-retry.js.map +1 -0
  146. package/dist/providers/azure/graph-client.d.ts +26 -0
  147. package/dist/providers/azure/graph-client.d.ts.map +1 -0
  148. package/dist/providers/azure/graph-client.js +146 -0
  149. package/dist/providers/azure/graph-client.js.map +1 -0
  150. package/dist/providers/azure/graph.provider.d.ts +23 -0
  151. package/dist/providers/azure/graph.provider.d.ts.map +1 -0
  152. package/dist/providers/azure/graph.provider.js +161 -0
  153. package/dist/providers/azure/graph.provider.js.map +1 -0
  154. package/dist/providers/azure/queries/app.queries.d.ts +6 -0
  155. package/dist/providers/azure/queries/app.queries.d.ts.map +1 -0
  156. package/dist/providers/azure/queries/app.queries.js +9 -0
  157. package/dist/providers/azure/queries/app.queries.js.map +1 -0
  158. package/dist/providers/azure/queries/policy.queries.d.ts +6 -0
  159. package/dist/providers/azure/queries/policy.queries.d.ts.map +1 -0
  160. package/dist/providers/azure/queries/policy.queries.js +9 -0
  161. package/dist/providers/azure/queries/policy.queries.js.map +1 -0
  162. package/dist/providers/azure/queries/user.queries.d.ts +7 -0
  163. package/dist/providers/azure/queries/user.queries.d.ts.map +1 -0
  164. package/dist/providers/azure/queries/user.queries.js +10 -0
  165. package/dist/providers/azure/queries/user.queries.js.map +1 -0
  166. package/dist/providers/interfaces/IGraphProvider.d.ts +31 -0
  167. package/dist/providers/interfaces/IGraphProvider.d.ts.map +1 -0
  168. package/dist/providers/interfaces/IGraphProvider.js +3 -0
  169. package/dist/providers/interfaces/IGraphProvider.js.map +1 -0
  170. package/dist/providers/interfaces/ILDAPProvider.d.ts +37 -0
  171. package/dist/providers/interfaces/ILDAPProvider.d.ts.map +1 -0
  172. package/dist/providers/interfaces/ILDAPProvider.js +3 -0
  173. package/dist/providers/interfaces/ILDAPProvider.js.map +1 -0
  174. package/dist/providers/ldap/acl-parser.d.ts +8 -0
  175. package/dist/providers/ldap/acl-parser.d.ts.map +1 -0
  176. package/dist/providers/ldap/acl-parser.js +157 -0
  177. package/dist/providers/ldap/acl-parser.js.map +1 -0
  178. package/dist/providers/ldap/ad-mappers.d.ts +8 -0
  179. package/dist/providers/ldap/ad-mappers.d.ts.map +1 -0
  180. package/dist/providers/ldap/ad-mappers.js +162 -0
  181. package/dist/providers/ldap/ad-mappers.js.map +1 -0
  182. package/dist/providers/ldap/ldap-client.d.ts +33 -0
  183. package/dist/providers/ldap/ldap-client.d.ts.map +1 -0
  184. package/dist/providers/ldap/ldap-client.js +195 -0
  185. package/dist/providers/ldap/ldap-client.js.map +1 -0
  186. package/dist/providers/ldap/ldap-errors.d.ts +48 -0
  187. package/dist/providers/ldap/ldap-errors.d.ts.map +1 -0
  188. package/dist/providers/ldap/ldap-errors.js +120 -0
  189. package/dist/providers/ldap/ldap-errors.js.map +1 -0
  190. package/dist/providers/ldap/ldap-retry.d.ts +14 -0
  191. package/dist/providers/ldap/ldap-retry.d.ts.map +1 -0
  192. package/dist/providers/ldap/ldap-retry.js +102 -0
  193. package/dist/providers/ldap/ldap-retry.js.map +1 -0
  194. package/dist/providers/ldap/ldap-sanitizer.d.ts +12 -0
  195. package/dist/providers/ldap/ldap-sanitizer.d.ts.map +1 -0
  196. package/dist/providers/ldap/ldap-sanitizer.js +104 -0
  197. package/dist/providers/ldap/ldap-sanitizer.js.map +1 -0
  198. package/dist/providers/ldap/ldap.provider.d.ts +21 -0
  199. package/dist/providers/ldap/ldap.provider.d.ts.map +1 -0
  200. package/dist/providers/ldap/ldap.provider.js +165 -0
  201. package/dist/providers/ldap/ldap.provider.js.map +1 -0
  202. package/dist/providers/ldap/queries/computer.queries.d.ts +6 -0
  203. package/dist/providers/ldap/queries/computer.queries.d.ts.map +1 -0
  204. package/dist/providers/ldap/queries/computer.queries.js +9 -0
  205. package/dist/providers/ldap/queries/computer.queries.js.map +1 -0
  206. package/dist/providers/ldap/queries/group.queries.d.ts +6 -0
  207. package/dist/providers/ldap/queries/group.queries.d.ts.map +1 -0
  208. package/dist/providers/ldap/queries/group.queries.js +9 -0
  209. package/dist/providers/ldap/queries/group.queries.js.map +1 -0
  210. package/dist/providers/ldap/queries/user.queries.d.ts +7 -0
  211. package/dist/providers/ldap/queries/user.queries.d.ts.map +1 -0
  212. package/dist/providers/ldap/queries/user.queries.js +10 -0
  213. package/dist/providers/ldap/queries/user.queries.js.map +1 -0
  214. package/dist/providers/smb/smb.provider.d.ts +68 -0
  215. package/dist/providers/smb/smb.provider.d.ts.map +1 -0
  216. package/dist/providers/smb/smb.provider.js +382 -0
  217. package/dist/providers/smb/smb.provider.js.map +1 -0
  218. package/dist/server.d.ts +2 -0
  219. package/dist/server.d.ts.map +1 -0
  220. package/dist/server.js +44 -0
  221. package/dist/server.js.map +1 -0
  222. package/dist/services/audit/ad-audit.service.d.ts +70 -0
  223. package/dist/services/audit/ad-audit.service.d.ts.map +1 -0
  224. package/dist/services/audit/ad-audit.service.js +1019 -0
  225. package/dist/services/audit/ad-audit.service.js.map +1 -0
  226. package/dist/services/audit/attack-graph.service.d.ts +62 -0
  227. package/dist/services/audit/attack-graph.service.d.ts.map +1 -0
  228. package/dist/services/audit/attack-graph.service.js +702 -0
  229. package/dist/services/audit/attack-graph.service.js.map +1 -0
  230. package/dist/services/audit/audit.service.d.ts +4 -0
  231. package/dist/services/audit/audit.service.d.ts.map +1 -0
  232. package/dist/services/audit/audit.service.js +10 -0
  233. package/dist/services/audit/audit.service.js.map +1 -0
  234. package/dist/services/audit/azure-audit.service.d.ts +37 -0
  235. package/dist/services/audit/azure-audit.service.d.ts.map +1 -0
  236. package/dist/services/audit/azure-audit.service.js +153 -0
  237. package/dist/services/audit/azure-audit.service.js.map +1 -0
  238. package/dist/services/audit/detectors/ad/accounts.detector.d.ts +37 -0
  239. package/dist/services/audit/detectors/ad/accounts.detector.d.ts.map +1 -0
  240. package/dist/services/audit/detectors/ad/accounts.detector.js +881 -0
  241. package/dist/services/audit/detectors/ad/accounts.detector.js.map +1 -0
  242. package/dist/services/audit/detectors/ad/adcs.detector.d.ts +21 -0
  243. package/dist/services/audit/detectors/ad/adcs.detector.d.ts.map +1 -0
  244. package/dist/services/audit/detectors/ad/adcs.detector.js +227 -0
  245. package/dist/services/audit/detectors/ad/adcs.detector.js.map +1 -0
  246. package/dist/services/audit/detectors/ad/advanced.detector.d.ts +63 -0
  247. package/dist/services/audit/detectors/ad/advanced.detector.d.ts.map +1 -0
  248. package/dist/services/audit/detectors/ad/advanced.detector.js +867 -0
  249. package/dist/services/audit/detectors/ad/advanced.detector.js.map +1 -0
  250. package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts +16 -0
  251. package/dist/services/audit/detectors/ad/attack-paths.detector.d.ts.map +1 -0
  252. package/dist/services/audit/detectors/ad/attack-paths.detector.js +369 -0
  253. package/dist/services/audit/detectors/ad/attack-paths.detector.js.map +1 -0
  254. package/dist/services/audit/detectors/ad/compliance.detector.d.ts +28 -0
  255. package/dist/services/audit/detectors/ad/compliance.detector.d.ts.map +1 -0
  256. package/dist/services/audit/detectors/ad/compliance.detector.js +896 -0
  257. package/dist/services/audit/detectors/ad/compliance.detector.js.map +1 -0
  258. package/dist/services/audit/detectors/ad/computers.detector.d.ts +30 -0
  259. package/dist/services/audit/detectors/ad/computers.detector.d.ts.map +1 -0
  260. package/dist/services/audit/detectors/ad/computers.detector.js +799 -0
  261. package/dist/services/audit/detectors/ad/computers.detector.js.map +1 -0
  262. package/dist/services/audit/detectors/ad/gpo.detector.d.ts +17 -0
  263. package/dist/services/audit/detectors/ad/gpo.detector.d.ts.map +1 -0
  264. package/dist/services/audit/detectors/ad/gpo.detector.js +257 -0
  265. package/dist/services/audit/detectors/ad/gpo.detector.js.map +1 -0
  266. package/dist/services/audit/detectors/ad/groups.detector.d.ts +19 -0
  267. package/dist/services/audit/detectors/ad/groups.detector.d.ts.map +1 -0
  268. package/dist/services/audit/detectors/ad/groups.detector.js +488 -0
  269. package/dist/services/audit/detectors/ad/groups.detector.js.map +1 -0
  270. package/dist/services/audit/detectors/ad/index.d.ts +15 -0
  271. package/dist/services/audit/detectors/ad/index.d.ts.map +1 -0
  272. package/dist/services/audit/detectors/ad/index.js +51 -0
  273. package/dist/services/audit/detectors/ad/index.js.map +1 -0
  274. package/dist/services/audit/detectors/ad/kerberos.detector.d.ts +17 -0
  275. package/dist/services/audit/detectors/ad/kerberos.detector.d.ts.map +1 -0
  276. package/dist/services/audit/detectors/ad/kerberos.detector.js +293 -0
  277. package/dist/services/audit/detectors/ad/kerberos.detector.js.map +1 -0
  278. package/dist/services/audit/detectors/ad/monitoring.detector.d.ts +23 -0
  279. package/dist/services/audit/detectors/ad/monitoring.detector.d.ts.map +1 -0
  280. package/dist/services/audit/detectors/ad/monitoring.detector.js +328 -0
  281. package/dist/services/audit/detectors/ad/monitoring.detector.js.map +1 -0
  282. package/dist/services/audit/detectors/ad/network.detector.d.ts +39 -0
  283. package/dist/services/audit/detectors/ad/network.detector.d.ts.map +1 -0
  284. package/dist/services/audit/detectors/ad/network.detector.js +257 -0
  285. package/dist/services/audit/detectors/ad/network.detector.js.map +1 -0
  286. package/dist/services/audit/detectors/ad/password.detector.d.ts +14 -0
  287. package/dist/services/audit/detectors/ad/password.detector.d.ts.map +1 -0
  288. package/dist/services/audit/detectors/ad/password.detector.js +235 -0
  289. package/dist/services/audit/detectors/ad/password.detector.js.map +1 -0
  290. package/dist/services/audit/detectors/ad/permissions.detector.d.ts +20 -0
  291. package/dist/services/audit/detectors/ad/permissions.detector.d.ts.map +1 -0
  292. package/dist/services/audit/detectors/ad/permissions.detector.js +392 -0
  293. package/dist/services/audit/detectors/ad/permissions.detector.js.map +1 -0
  294. package/dist/services/audit/detectors/ad/trusts.detector.d.ts +11 -0
  295. package/dist/services/audit/detectors/ad/trusts.detector.d.ts.map +1 -0
  296. package/dist/services/audit/detectors/ad/trusts.detector.js +186 -0
  297. package/dist/services/audit/detectors/ad/trusts.detector.js.map +1 -0
  298. package/dist/services/audit/detectors/azure/app-security.detector.d.ts +11 -0
  299. package/dist/services/audit/detectors/azure/app-security.detector.d.ts.map +1 -0
  300. package/dist/services/audit/detectors/azure/app-security.detector.js +184 -0
  301. package/dist/services/audit/detectors/azure/app-security.detector.js.map +1 -0
  302. package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts +10 -0
  303. package/dist/services/audit/detectors/azure/conditional-access.detector.d.ts.map +1 -0
  304. package/dist/services/audit/detectors/azure/conditional-access.detector.js +130 -0
  305. package/dist/services/audit/detectors/azure/conditional-access.detector.js.map +1 -0
  306. package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts +8 -0
  307. package/dist/services/audit/detectors/azure/privilege-security.detector.d.ts.map +1 -0
  308. package/dist/services/audit/detectors/azure/privilege-security.detector.js +113 -0
  309. package/dist/services/audit/detectors/azure/privilege-security.detector.js.map +1 -0
  310. package/dist/services/audit/detectors/azure/user-security.detector.d.ts +14 -0
  311. package/dist/services/audit/detectors/azure/user-security.detector.d.ts.map +1 -0
  312. package/dist/services/audit/detectors/azure/user-security.detector.js +198 -0
  313. package/dist/services/audit/detectors/azure/user-security.detector.js.map +1 -0
  314. package/dist/services/audit/detectors/index.d.ts +2 -0
  315. package/dist/services/audit/detectors/index.d.ts.map +1 -0
  316. package/dist/services/audit/detectors/index.js +38 -0
  317. package/dist/services/audit/detectors/index.js.map +1 -0
  318. package/dist/services/audit/response-formatter.d.ts +176 -0
  319. package/dist/services/audit/response-formatter.d.ts.map +1 -0
  320. package/dist/services/audit/response-formatter.js +240 -0
  321. package/dist/services/audit/response-formatter.js.map +1 -0
  322. package/dist/services/audit/scoring.service.d.ts +15 -0
  323. package/dist/services/audit/scoring.service.d.ts.map +1 -0
  324. package/dist/services/audit/scoring.service.js +139 -0
  325. package/dist/services/audit/scoring.service.js.map +1 -0
  326. package/dist/services/auth/crypto.service.d.ts +19 -0
  327. package/dist/services/auth/crypto.service.d.ts.map +1 -0
  328. package/dist/services/auth/crypto.service.js +135 -0
  329. package/dist/services/auth/crypto.service.js.map +1 -0
  330. package/dist/services/auth/errors.d.ts +19 -0
  331. package/dist/services/auth/errors.d.ts.map +1 -0
  332. package/dist/services/auth/errors.js +46 -0
  333. package/dist/services/auth/errors.js.map +1 -0
  334. package/dist/services/auth/token.service.d.ts +41 -0
  335. package/dist/services/auth/token.service.d.ts.map +1 -0
  336. package/dist/services/auth/token.service.js +208 -0
  337. package/dist/services/auth/token.service.js.map +1 -0
  338. package/dist/services/config/config.service.d.ts +6 -0
  339. package/dist/services/config/config.service.d.ts.map +1 -0
  340. package/dist/services/config/config.service.js +64 -0
  341. package/dist/services/config/config.service.js.map +1 -0
  342. package/dist/services/export/export.service.d.ts +28 -0
  343. package/dist/services/export/export.service.d.ts.map +1 -0
  344. package/dist/services/export/export.service.js +28 -0
  345. package/dist/services/export/export.service.js.map +1 -0
  346. package/dist/services/export/formatters/csv.formatter.d.ts +8 -0
  347. package/dist/services/export/formatters/csv.formatter.d.ts.map +1 -0
  348. package/dist/services/export/formatters/csv.formatter.js +46 -0
  349. package/dist/services/export/formatters/csv.formatter.js.map +1 -0
  350. package/dist/services/export/formatters/json.formatter.d.ts +40 -0
  351. package/dist/services/export/formatters/json.formatter.d.ts.map +1 -0
  352. package/dist/services/export/formatters/json.formatter.js +58 -0
  353. package/dist/services/export/formatters/json.formatter.js.map +1 -0
  354. package/dist/services/jobs/azure-job-runner.d.ts +38 -0
  355. package/dist/services/jobs/azure-job-runner.d.ts.map +1 -0
  356. package/dist/services/jobs/azure-job-runner.js +199 -0
  357. package/dist/services/jobs/azure-job-runner.js.map +1 -0
  358. package/dist/services/jobs/index.d.ts +4 -0
  359. package/dist/services/jobs/index.d.ts.map +1 -0
  360. package/dist/services/jobs/index.js +20 -0
  361. package/dist/services/jobs/index.js.map +1 -0
  362. package/dist/services/jobs/job-runner.d.ts +64 -0
  363. package/dist/services/jobs/job-runner.d.ts.map +1 -0
  364. package/dist/services/jobs/job-runner.js +952 -0
  365. package/dist/services/jobs/job-runner.js.map +1 -0
  366. package/dist/services/jobs/job-store.d.ts +27 -0
  367. package/dist/services/jobs/job-store.d.ts.map +1 -0
  368. package/dist/services/jobs/job-store.js +261 -0
  369. package/dist/services/jobs/job-store.js.map +1 -0
  370. package/dist/services/jobs/job.types.d.ts +67 -0
  371. package/dist/services/jobs/job.types.d.ts.map +1 -0
  372. package/dist/services/jobs/job.types.js +36 -0
  373. package/dist/services/jobs/job.types.js.map +1 -0
  374. package/dist/types/ad.types.d.ts +74 -0
  375. package/dist/types/ad.types.d.ts.map +1 -0
  376. package/dist/types/ad.types.js +3 -0
  377. package/dist/types/ad.types.js.map +1 -0
  378. package/dist/types/adcs.types.d.ts +58 -0
  379. package/dist/types/adcs.types.d.ts.map +1 -0
  380. package/dist/types/adcs.types.js +38 -0
  381. package/dist/types/adcs.types.js.map +1 -0
  382. package/dist/types/attack-graph.types.d.ts +135 -0
  383. package/dist/types/attack-graph.types.d.ts.map +1 -0
  384. package/dist/types/attack-graph.types.js +58 -0
  385. package/dist/types/attack-graph.types.js.map +1 -0
  386. package/dist/types/audit.types.d.ts +34 -0
  387. package/dist/types/audit.types.d.ts.map +1 -0
  388. package/dist/types/audit.types.js +3 -0
  389. package/dist/types/audit.types.js.map +1 -0
  390. package/dist/types/azure.types.d.ts +61 -0
  391. package/dist/types/azure.types.d.ts.map +1 -0
  392. package/dist/types/azure.types.js +3 -0
  393. package/dist/types/azure.types.js.map +1 -0
  394. package/dist/types/config.types.d.ts +63 -0
  395. package/dist/types/config.types.d.ts.map +1 -0
  396. package/dist/types/config.types.js +3 -0
  397. package/dist/types/config.types.js.map +1 -0
  398. package/dist/types/error.types.d.ts +33 -0
  399. package/dist/types/error.types.d.ts.map +1 -0
  400. package/dist/types/error.types.js +70 -0
  401. package/dist/types/error.types.js.map +1 -0
  402. package/dist/types/finding.types.d.ts +133 -0
  403. package/dist/types/finding.types.d.ts.map +1 -0
  404. package/dist/types/finding.types.js +3 -0
  405. package/dist/types/finding.types.js.map +1 -0
  406. package/dist/types/gpo.types.d.ts +39 -0
  407. package/dist/types/gpo.types.d.ts.map +1 -0
  408. package/dist/types/gpo.types.js +15 -0
  409. package/dist/types/gpo.types.js.map +1 -0
  410. package/dist/types/token.types.d.ts +26 -0
  411. package/dist/types/token.types.d.ts.map +1 -0
  412. package/dist/types/token.types.js +3 -0
  413. package/dist/types/token.types.js.map +1 -0
  414. package/dist/types/trust.types.d.ts +45 -0
  415. package/dist/types/trust.types.d.ts.map +1 -0
  416. package/dist/types/trust.types.js +71 -0
  417. package/dist/types/trust.types.js.map +1 -0
  418. package/dist/utils/entity-converter.d.ts +17 -0
  419. package/dist/utils/entity-converter.d.ts.map +1 -0
  420. package/dist/utils/entity-converter.js +285 -0
  421. package/dist/utils/entity-converter.js.map +1 -0
  422. package/dist/utils/graph.util.d.ts +66 -0
  423. package/dist/utils/graph.util.d.ts.map +1 -0
  424. package/dist/utils/graph.util.js +382 -0
  425. package/dist/utils/graph.util.js.map +1 -0
  426. package/dist/utils/logger.d.ts +7 -0
  427. package/dist/utils/logger.d.ts.map +1 -0
  428. package/dist/utils/logger.js +86 -0
  429. package/dist/utils/logger.js.map +1 -0
  430. package/dist/utils/type-name-normalizer.d.ts +5 -0
  431. package/dist/utils/type-name-normalizer.d.ts.map +1 -0
  432. package/dist/utils/type-name-normalizer.js +218 -0
  433. package/dist/utils/type-name-normalizer.js.map +1 -0
  434. package/docker-compose.yml +26 -0
  435. package/docs/api/README.md +178 -0
  436. package/docs/api/openapi.yaml +1524 -0
  437. package/eslint.config.js +54 -0
  438. package/jest.config.js +38 -0
  439. package/package.json +97 -0
  440. package/scripts/fetch-ad-cert.sh +142 -0
  441. package/src/.gitkeep +0 -0
  442. package/src/api/.gitkeep +0 -0
  443. package/src/api/controllers/.gitkeep +0 -0
  444. package/src/api/controllers/audit.controller.ts +313 -0
  445. package/src/api/controllers/auth.controller.ts +258 -0
  446. package/src/api/controllers/export.controller.ts +153 -0
  447. package/src/api/controllers/health.controller.ts +16 -0
  448. package/src/api/controllers/jobs.controller.ts +187 -0
  449. package/src/api/controllers/providers.controller.ts +165 -0
  450. package/src/api/dto/.gitkeep +0 -0
  451. package/src/api/dto/AuditRequest.dto.ts +8 -0
  452. package/src/api/dto/AuditResponse.dto.ts +19 -0
  453. package/src/api/dto/TokenRequest.dto.ts +8 -0
  454. package/src/api/dto/TokenResponse.dto.ts +14 -0
  455. package/src/api/middlewares/.gitkeep +0 -0
  456. package/src/api/middlewares/authenticate.ts +203 -0
  457. package/src/api/middlewares/errorHandler.ts +54 -0
  458. package/src/api/middlewares/rateLimit.ts +35 -0
  459. package/src/api/middlewares/validate.ts +32 -0
  460. package/src/api/routes/.gitkeep +0 -0
  461. package/src/api/routes/audit.routes.ts +77 -0
  462. package/src/api/routes/auth.routes.ts +71 -0
  463. package/src/api/routes/export.routes.ts +34 -0
  464. package/src/api/routes/health.routes.ts +14 -0
  465. package/src/api/routes/index.ts +40 -0
  466. package/src/api/routes/providers.routes.ts +24 -0
  467. package/src/api/validators/.gitkeep +0 -0
  468. package/src/api/validators/audit.schemas.ts +59 -0
  469. package/src/api/validators/auth.schemas.ts +59 -0
  470. package/src/app.ts +87 -0
  471. package/src/config/.gitkeep +0 -0
  472. package/src/config/config.schema.ts +108 -0
  473. package/src/config/index.ts +82 -0
  474. package/src/container.ts +221 -0
  475. package/src/data/.gitkeep +0 -0
  476. package/src/data/database.ts +78 -0
  477. package/src/data/jobs/token-cleanup.job.ts +166 -0
  478. package/src/data/migrations/.gitkeep +0 -0
  479. package/src/data/migrations/001_initial_schema.sql +47 -0
  480. package/src/data/migrations/migration.runner.ts +125 -0
  481. package/src/data/models/.gitkeep +0 -0
  482. package/src/data/models/Token.model.ts +35 -0
  483. package/src/data/repositories/.gitkeep +0 -0
  484. package/src/data/repositories/token.repository.ts +160 -0
  485. package/src/providers/.gitkeep +0 -0
  486. package/src/providers/azure/.gitkeep +0 -0
  487. package/src/providers/azure/auth.provider.ts +14 -0
  488. package/src/providers/azure/azure-errors.ts +189 -0
  489. package/src/providers/azure/azure-retry.ts +168 -0
  490. package/src/providers/azure/graph-client.ts +315 -0
  491. package/src/providers/azure/graph.provider.ts +294 -0
  492. package/src/providers/azure/queries/app.queries.ts +9 -0
  493. package/src/providers/azure/queries/policy.queries.ts +9 -0
  494. package/src/providers/azure/queries/user.queries.ts +10 -0
  495. package/src/providers/interfaces/.gitkeep +0 -0
  496. package/src/providers/interfaces/IGraphProvider.ts +117 -0
  497. package/src/providers/interfaces/ILDAPProvider.ts +142 -0
  498. package/src/providers/ldap/.gitkeep +0 -0
  499. package/src/providers/ldap/acl-parser.ts +231 -0
  500. package/src/providers/ldap/ad-mappers.ts +280 -0
  501. package/src/providers/ldap/ldap-client.ts +259 -0
  502. package/src/providers/ldap/ldap-errors.ts +188 -0
  503. package/src/providers/ldap/ldap-retry.ts +267 -0
  504. package/src/providers/ldap/ldap-sanitizer.ts +273 -0
  505. package/src/providers/ldap/ldap.provider.ts +293 -0
  506. package/src/providers/ldap/queries/computer.queries.ts +9 -0
  507. package/src/providers/ldap/queries/group.queries.ts +9 -0
  508. package/src/providers/ldap/queries/user.queries.ts +10 -0
  509. package/src/providers/smb/smb.provider.ts +653 -0
  510. package/src/server.ts +60 -0
  511. package/src/services/.gitkeep +0 -0
  512. package/src/services/audit/.gitkeep +0 -0
  513. package/src/services/audit/ad-audit.service.ts +1481 -0
  514. package/src/services/audit/attack-graph.service.ts +1104 -0
  515. package/src/services/audit/audit.service.ts +12 -0
  516. package/src/services/audit/azure-audit.service.ts +286 -0
  517. package/src/services/audit/detectors/ad/accounts.detector.ts +1232 -0
  518. package/src/services/audit/detectors/ad/adcs.detector.ts +449 -0
  519. package/src/services/audit/detectors/ad/advanced.detector.ts +1270 -0
  520. package/src/services/audit/detectors/ad/attack-paths.detector.ts +600 -0
  521. package/src/services/audit/detectors/ad/compliance.detector.ts +1421 -0
  522. package/src/services/audit/detectors/ad/computers.detector.ts +1188 -0
  523. package/src/services/audit/detectors/ad/gpo.detector.ts +485 -0
  524. package/src/services/audit/detectors/ad/groups.detector.ts +685 -0
  525. package/src/services/audit/detectors/ad/index.ts +84 -0
  526. package/src/services/audit/detectors/ad/kerberos.detector.ts +424 -0
  527. package/src/services/audit/detectors/ad/monitoring.detector.ts +501 -0
  528. package/src/services/audit/detectors/ad/network.detector.ts +538 -0
  529. package/src/services/audit/detectors/ad/password.detector.ts +324 -0
  530. package/src/services/audit/detectors/ad/permissions.detector.ts +637 -0
  531. package/src/services/audit/detectors/ad/trusts.detector.ts +315 -0
  532. package/src/services/audit/detectors/azure/app-security.detector.ts +246 -0
  533. package/src/services/audit/detectors/azure/conditional-access.detector.ts +186 -0
  534. package/src/services/audit/detectors/azure/privilege-security.detector.ts +176 -0
  535. package/src/services/audit/detectors/azure/user-security.detector.ts +280 -0
  536. package/src/services/audit/detectors/index.ts +18 -0
  537. package/src/services/audit/response-formatter.ts +604 -0
  538. package/src/services/audit/scoring.service.ts +234 -0
  539. package/src/services/auth/.gitkeep +0 -0
  540. package/src/services/auth/crypto.service.ts +230 -0
  541. package/src/services/auth/errors.ts +47 -0
  542. package/src/services/auth/token.service.ts +420 -0
  543. package/src/services/config/.gitkeep +0 -0
  544. package/src/services/config/config.service.ts +75 -0
  545. package/src/services/export/.gitkeep +0 -0
  546. package/src/services/export/export.service.ts +99 -0
  547. package/src/services/export/formatters/csv.formatter.ts +124 -0
  548. package/src/services/export/formatters/json.formatter.ts +160 -0
  549. package/src/services/jobs/azure-job-runner.ts +312 -0
  550. package/src/services/jobs/index.ts +9 -0
  551. package/src/services/jobs/job-runner.ts +1280 -0
  552. package/src/services/jobs/job-store.ts +384 -0
  553. package/src/services/jobs/job.types.ts +182 -0
  554. package/src/types/.gitkeep +0 -0
  555. package/src/types/ad.types.ts +91 -0
  556. package/src/types/adcs.types.ts +107 -0
  557. package/src/types/attack-graph.types.ts +260 -0
  558. package/src/types/audit.types.ts +42 -0
  559. package/src/types/azure.types.ts +68 -0
  560. package/src/types/config.types.ts +79 -0
  561. package/src/types/error.types.ts +69 -0
  562. package/src/types/finding.types.ts +284 -0
  563. package/src/types/gpo.types.ts +72 -0
  564. package/src/types/smb2.d.ts +73 -0
  565. package/src/types/token.types.ts +32 -0
  566. package/src/types/trust.types.ts +140 -0
  567. package/src/utils/.gitkeep +0 -0
  568. package/src/utils/entity-converter.ts +453 -0
  569. package/src/utils/graph.util.ts +609 -0
  570. package/src/utils/logger.ts +111 -0
  571. package/src/utils/type-name-normalizer.ts +302 -0
  572. package/tests/.gitkeep +0 -0
  573. package/tests/e2e/.gitkeep +0 -0
  574. package/tests/fixtures/.gitkeep +0 -0
  575. package/tests/integration/.gitkeep +0 -0
  576. package/tests/integration/README.md +156 -0
  577. package/tests/integration/ad-audit.integration.test.ts +216 -0
  578. package/tests/integration/api/.gitkeep +0 -0
  579. package/tests/integration/api/endpoints.integration.test.ts +431 -0
  580. package/tests/integration/auth/jwt-authentication.integration.test.ts +358 -0
  581. package/tests/integration/providers/.gitkeep +0 -0
  582. package/tests/integration/providers/azure-basic.integration.test.ts +167 -0
  583. package/tests/integration/providers/ldap-basic.integration.test.ts +152 -0
  584. package/tests/integration/providers/ldap-connectivity.test.ts +44 -0
  585. package/tests/integration/providers/ldap-provider.integration.test.ts +347 -0
  586. package/tests/mocks/.gitkeep +0 -0
  587. package/tests/setup.ts +16 -0
  588. package/tests/unit/.gitkeep +0 -0
  589. package/tests/unit/api/middlewares/authenticate.test.ts +446 -0
  590. package/tests/unit/providers/.gitkeep +0 -0
  591. package/tests/unit/providers/azure/azure-errors.test.ts +193 -0
  592. package/tests/unit/providers/azure/azure-retry.test.ts +254 -0
  593. package/tests/unit/providers/azure/graph-provider.test.ts +313 -0
  594. package/tests/unit/providers/ldap/ad-mappers.test.ts +392 -0
  595. package/tests/unit/providers/ldap/ldap-provider.test.ts +376 -0
  596. package/tests/unit/providers/ldap/ldap-retry.test.ts +377 -0
  597. package/tests/unit/providers/ldap/ldap-sanitizer.test.ts +301 -0
  598. package/tests/unit/sample.test.ts +19 -0
  599. package/tests/unit/services/.gitkeep +0 -0
  600. package/tests/unit/services/audit/detectors/ad/accounts.detector.test.ts +393 -0
  601. package/tests/unit/services/audit/detectors/ad/advanced.detector.test.ts +380 -0
  602. package/tests/unit/services/audit/detectors/ad/computers.detector.test.ts +440 -0
  603. package/tests/unit/services/audit/detectors/ad/groups.detector.test.ts +276 -0
  604. package/tests/unit/services/audit/detectors/ad/kerberos.detector.test.ts +215 -0
  605. package/tests/unit/services/audit/detectors/ad/password.detector.test.ts +226 -0
  606. package/tests/unit/services/audit/detectors/ad/permissions.detector.test.ts +244 -0
  607. package/tests/unit/services/audit/detectors/azure/app-security.detector.test.ts +349 -0
  608. package/tests/unit/services/audit/detectors/azure/conditional-access.detector.test.ts +374 -0
  609. package/tests/unit/services/audit/detectors/azure/privilege-security.detector.test.ts +374 -0
  610. package/tests/unit/services/audit/detectors/azure/user-security.detector.test.ts +297 -0
  611. package/tests/unit/services/auth/crypto.service.test.ts +296 -0
  612. package/tests/unit/services/auth/token.service.test.ts +579 -0
  613. package/tests/unit/services/export/export.service.test.ts +241 -0
  614. package/tests/unit/services/export/formatters/csv.formatter.test.ts +270 -0
  615. package/tests/unit/services/export/formatters/json.formatter.test.ts +258 -0
  616. package/tests/unit/utils/.gitkeep +0 -0
  617. package/tsconfig.json +50 -0
@@ -0,0 +1,600 @@
1
+ /**
2
+ * Attack Paths Vulnerability Detector
3
+ *
4
+ * Analyzes privilege escalation paths in Active Directory by combining:
5
+ * - Group membership chains
6
+ * - ACL-based attack vectors
7
+ * - Delegation relationships
8
+ * - Service account risks
9
+ *
10
+ * Phase 2: Attack Paths Detection
11
+ *
12
+ * Vulnerabilities detected (10):
13
+ * CRITICAL (4):
14
+ * - PATH_KERBEROASTING_TO_DA: Kerberoastable user in DA path
15
+ * - PATH_ACL_TO_DA: ACL chain to Domain Admin
16
+ * - PATH_SERVICE_TO_DA: Service account with path to DA
17
+ * - PATH_CERTIFICATE_ESC: ADCS template vulnerability to DA
18
+ *
19
+ * HIGH (5):
20
+ * - PATH_ASREP_TO_ADMIN: AS-REP roastable user in admin group
21
+ * - PATH_DELEGATION_CHAIN: Delegation chain to privileged target
22
+ * - PATH_NESTED_ADMIN: Excessive group nesting to admin
23
+ * - PATH_COMPUTER_TAKEOVER: RBCD attack path
24
+ * - PATH_GPO_TO_DA: GPO modification leads to DA
25
+ *
26
+ * MEDIUM (1):
27
+ * - PATH_TRUST_LATERAL: Trust enables lateral movement
28
+ */
29
+
30
+ import { ADUser, ADGroup, ADComputer, AclEntry } from '../../../../types/ad.types';
31
+ import { Finding } from '../../../../types/finding.types';
32
+ import { toAffectedUserEntities } from '../../../../utils/entity-converter';
33
+ import {
34
+ buildGroupMembershipGraph,
35
+ buildAclGraph,
36
+ addDelegationEdges,
37
+ detectNestingDepth,
38
+ isPrivilegedMember,
39
+ PRIVILEGED_GROUPS,
40
+ } from '../../../../utils/graph.util';
41
+ import { ADGPO } from '../../../../types/gpo.types';
42
+ import { ADTrustExtended } from '../../../../types/trust.types';
43
+
44
+ /**
45
+ * Detect kerberoastable users with path to Domain Admin
46
+ * Users with SPNs that are members (direct or nested) of privileged groups
47
+ */
48
+ export function detectPathKerberoastingToDA(
49
+ users: ADUser[],
50
+ groups: ADGroup[],
51
+ computers: ADComputer[],
52
+ includeDetails: boolean
53
+ ): Finding {
54
+ const graph = buildGroupMembershipGraph(users, groups, computers);
55
+
56
+ // Find kerberoastable users (have SPN and are enabled)
57
+ const kerberoastableUsers = users.filter((u) => {
58
+ const spn = u['servicePrincipalName'];
59
+ const hasSPN = spn && Array.isArray(spn) && spn.length > 0;
60
+ return hasSPN && u.enabled;
61
+ });
62
+
63
+ // Check which ones have path to privileged groups
64
+ const affected = kerberoastableUsers.filter((u) => isPrivilegedMember(u.dn, graph));
65
+
66
+ return {
67
+ type: 'PATH_KERBEROASTING_TO_DA',
68
+ severity: 'critical',
69
+ category: 'attack-paths',
70
+ title: 'Kerberoasting Path to Domain Admin',
71
+ description:
72
+ 'User with SPN is member of privileged group. Kerberoasting this account and cracking the password leads to Domain Admin compromise.',
73
+ count: affected.length,
74
+ affectedEntities: includeDetails ? toAffectedUserEntities(affected) : undefined,
75
+ details:
76
+ affected.length > 0
77
+ ? {
78
+ attackVector: 'Request TGS ticket → Offline crack → Domain Admin access',
79
+ mitigation: 'Use gMSA for service accounts, remove from privileged groups, use long complex passwords',
80
+ }
81
+ : undefined,
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Detect AS-REP roastable users with path to admin groups
87
+ * Users without Kerberos pre-auth that are in admin groups
88
+ */
89
+ export function detectPathAsrepToAdmin(
90
+ users: ADUser[],
91
+ groups: ADGroup[],
92
+ computers: ADComputer[],
93
+ includeDetails: boolean
94
+ ): Finding {
95
+ const graph = buildGroupMembershipGraph(users, groups, computers);
96
+
97
+ // Find AS-REP roastable users (DONT_REQUIRE_PREAUTH flag)
98
+ const asrepUsers = users.filter((u) => {
99
+ const hasNoPreauth = u.userAccountControl ? (u.userAccountControl & 0x400000) !== 0 : false;
100
+ return hasNoPreauth && u.enabled;
101
+ });
102
+
103
+ // Check which ones have path to privileged groups
104
+ const affected = asrepUsers.filter((u) => isPrivilegedMember(u.dn, graph));
105
+
106
+ return {
107
+ type: 'PATH_ASREP_TO_ADMIN',
108
+ severity: 'high',
109
+ category: 'attack-paths',
110
+ title: 'AS-REP Roasting Path to Admin',
111
+ description:
112
+ 'User without Kerberos pre-authentication is member of admin group. AS-REP roasting can lead to admin compromise.',
113
+ count: affected.length,
114
+ affectedEntities: includeDetails ? toAffectedUserEntities(affected) : undefined,
115
+ details:
116
+ affected.length > 0
117
+ ? {
118
+ attackVector: 'Request AS-REP → Offline crack → Admin access',
119
+ mitigation: 'Enable Kerberos pre-authentication, remove from admin groups',
120
+ }
121
+ : undefined,
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Detect ACL-based privilege escalation paths to Domain Admin
127
+ * Non-privileged users with write access chain to admin objects
128
+ */
129
+ export function detectPathAclToDA(
130
+ users: ADUser[],
131
+ groups: ADGroup[],
132
+ computers: ADComputer[],
133
+ aclEntries: AclEntry[],
134
+ includeDetails: boolean
135
+ ): Finding {
136
+ // Build combined graph
137
+ const graph = buildGroupMembershipGraph(users, groups, computers);
138
+ buildAclGraph(aclEntries, graph);
139
+
140
+ // Find non-privileged users with paths to privileged targets
141
+ const nonPrivilegedUsers = users.filter((u) => u.enabled && u.adminCount !== 1);
142
+
143
+ const pathsFound: { user: ADUser; pathLength: number }[] = [];
144
+
145
+ for (const user of nonPrivilegedUsers) {
146
+ const path = graph.findShortestPathToPrivileged(user.dn, 4);
147
+ if (path && path.edges.some((e) => e.type === 'canModify')) {
148
+ pathsFound.push({ user, pathLength: path.length });
149
+ }
150
+ }
151
+
152
+ // Sort by path length (shorter = more dangerous)
153
+ pathsFound.sort((a, b) => a.pathLength - b.pathLength);
154
+ const affected = pathsFound.map((p) => p.user);
155
+
156
+ return {
157
+ type: 'PATH_ACL_TO_DA',
158
+ severity: 'critical',
159
+ category: 'attack-paths',
160
+ title: 'ACL-Based Privilege Escalation to Domain Admin',
161
+ description:
162
+ 'Non-privileged users can escalate to Domain Admin through ACL chain (WriteDACL, GenericAll, WriteOwner).',
163
+ count: affected.length,
164
+ affectedEntities: includeDetails ? toAffectedUserEntities(affected.slice(0, 50)) : undefined,
165
+ details:
166
+ affected.length > 0
167
+ ? {
168
+ attackVector: 'Modify ACL → Take ownership → Add to DA group',
169
+ shortestPath: pathsFound[0]?.pathLength,
170
+ totalPaths: pathsFound.length,
171
+ mitigation: 'Review and restrict dangerous ACL permissions',
172
+ }
173
+ : undefined,
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Detect delegation chains to privileged targets
179
+ * Users/computers with constrained delegation to privileged services
180
+ */
181
+ export function detectPathDelegationChain(
182
+ users: ADUser[],
183
+ computers: ADComputer[],
184
+ groups: ADGroup[],
185
+ includeDetails: boolean
186
+ ): Finding {
187
+ const graph = buildGroupMembershipGraph(users, groups, computers);
188
+ addDelegationEdges(users, computers, graph);
189
+
190
+ // Find users with delegation rights
191
+ const usersWithDelegation = users.filter((u) => {
192
+ const allowedTo = (u as any)['msDS-AllowedToDelegateTo'];
193
+ return allowedTo && Array.isArray(allowedTo) && allowedTo.length > 0;
194
+ });
195
+
196
+ // Find computers with delegation rights
197
+ const computersWithDelegation = computers.filter((c) => {
198
+ const allowedTo = (c as any)['msDS-AllowedToDelegateTo'];
199
+ return allowedTo && Array.isArray(allowedTo) && allowedTo.length > 0;
200
+ });
201
+
202
+ // Check if delegation targets include privileged services (DC services, admin workstations)
203
+ const dcServicePatterns = ['ldap/', 'cifs/', 'host/', 'krbtgt/'];
204
+ const affectedUsers: ADUser[] = [];
205
+
206
+ for (const user of usersWithDelegation) {
207
+ const targets = (user as any)['msDS-AllowedToDelegateTo'] as string[];
208
+ const hasDCTarget = targets.some((t) =>
209
+ dcServicePatterns.some((p) => t.toLowerCase().startsWith(p.toLowerCase()))
210
+ );
211
+ if (hasDCTarget) {
212
+ affectedUsers.push(user);
213
+ }
214
+ }
215
+
216
+ return {
217
+ type: 'PATH_DELEGATION_CHAIN',
218
+ severity: 'high',
219
+ category: 'attack-paths',
220
+ title: 'Delegation Chain to Privileged Target',
221
+ description:
222
+ 'Accounts with constrained delegation to domain controller services. Can be exploited to impersonate privileged users.',
223
+ count: affectedUsers.length + computersWithDelegation.length,
224
+ affectedEntities: includeDetails ? toAffectedUserEntities(affectedUsers) : undefined,
225
+ details: {
226
+ usersWithDelegation: usersWithDelegation.length,
227
+ computersWithDelegation: computersWithDelegation.length,
228
+ attackVector: 'Request S4U2Self → S4U2Proxy to DC service → Impersonate DA',
229
+ mitigation: 'Remove unnecessary delegation, use Protected Users group',
230
+ },
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Detect excessive group nesting leading to admin access
236
+ * Groups nested more than 3 levels deep reaching admin groups
237
+ */
238
+ export function detectPathNestedAdmin(
239
+ users: ADUser[],
240
+ groups: ADGroup[],
241
+ includeDetails: boolean
242
+ ): Finding {
243
+ const EXCESSIVE_DEPTH = 3;
244
+
245
+ // Find privileged groups
246
+ const privilegedGroupDns = groups
247
+ .filter((g) =>
248
+ PRIVILEGED_GROUPS.some(
249
+ (pg) =>
250
+ g.sAMAccountName?.toLowerCase().includes(pg.toLowerCase()) ||
251
+ g.dn.toLowerCase().includes(`cn=${pg.toLowerCase()}`)
252
+ )
253
+ )
254
+ .map((g) => g.dn);
255
+
256
+ // Find users in deeply nested paths to admin
257
+ const affected: ADUser[] = [];
258
+ const deepNestingDetails: { user: string; depth: number; group: string }[] = [];
259
+
260
+ for (const user of users) {
261
+ if (!user.memberOf || user.memberOf.length === 0) continue;
262
+
263
+ for (const groupDn of user.memberOf) {
264
+ const depth = detectNestingDepth(groupDn, groups);
265
+
266
+ // Check if this chain reaches a privileged group
267
+ if (depth > EXCESSIVE_DEPTH) {
268
+ // Check if any parent in chain is privileged
269
+ const group = groups.find((g) => g.dn.toLowerCase() === groupDn.toLowerCase());
270
+ if (group?.memberOf?.some((parent) => privilegedGroupDns.includes(parent))) {
271
+ affected.push(user);
272
+ deepNestingDetails.push({
273
+ user: user.sAMAccountName,
274
+ depth,
275
+ group: groupDn,
276
+ });
277
+ break;
278
+ }
279
+ }
280
+ }
281
+ }
282
+
283
+ return {
284
+ type: 'PATH_NESTED_ADMIN',
285
+ severity: 'high',
286
+ category: 'attack-paths',
287
+ title: 'Excessive Group Nesting to Admin',
288
+ description: `Users reach admin groups through excessive nesting (>${EXCESSIVE_DEPTH} levels). Makes privilege review difficult and may hide admin access.`,
289
+ count: affected.length,
290
+ affectedEntities: includeDetails ? toAffectedUserEntities(affected) : undefined,
291
+ details:
292
+ affected.length > 0
293
+ ? {
294
+ threshold: EXCESSIVE_DEPTH,
295
+ deepestNesting: Math.max(...deepNestingDetails.map((d) => d.depth), 0),
296
+ mitigation: 'Flatten group structure, limit nesting to 2-3 levels',
297
+ }
298
+ : undefined,
299
+ };
300
+ }
301
+
302
+ /**
303
+ * Detect service accounts with path to Domain Admin
304
+ * Service accounts (SPN) that can reach DA through various vectors
305
+ */
306
+ export function detectPathServiceToDA(
307
+ users: ADUser[],
308
+ groups: ADGroup[],
309
+ computers: ADComputer[],
310
+ aclEntries: AclEntry[],
311
+ includeDetails: boolean
312
+ ): Finding {
313
+ const graph = buildGroupMembershipGraph(users, groups, computers);
314
+ buildAclGraph(aclEntries, graph);
315
+ addDelegationEdges(users, computers, graph);
316
+
317
+ // Service accounts = users with SPNs
318
+ const serviceAccounts = users.filter((u) => {
319
+ const spn = u['servicePrincipalName'];
320
+ const hasSPN = spn && Array.isArray(spn) && spn.length > 0;
321
+ return hasSPN && u.enabled;
322
+ });
323
+
324
+ // Check which have any path to DA (membership, ACL, delegation)
325
+ const affected = serviceAccounts.filter((sa) => {
326
+ const path = graph.findShortestPathToPrivileged(sa.dn, 5);
327
+ return path !== null;
328
+ });
329
+
330
+ return {
331
+ type: 'PATH_SERVICE_TO_DA',
332
+ severity: 'critical',
333
+ category: 'attack-paths',
334
+ title: 'Service Account Path to Domain Admin',
335
+ description:
336
+ 'Service accounts with paths to Domain Admin through membership, ACLs, or delegation. Compromising these accounts leads to DA.',
337
+ count: affected.length,
338
+ affectedEntities: includeDetails ? toAffectedUserEntities(affected) : undefined,
339
+ details:
340
+ affected.length > 0
341
+ ? {
342
+ totalServiceAccounts: serviceAccounts.length,
343
+ withPathToDA: affected.length,
344
+ attackVector: 'Kerberoast/Credential theft → Exploit path → Domain Admin',
345
+ mitigation: 'Use gMSA, minimize service account privileges, regular password rotation',
346
+ }
347
+ : undefined,
348
+ };
349
+ }
350
+
351
+ /**
352
+ * Detect RBCD attack paths
353
+ * Computers with Resource-Based Constrained Delegation configured
354
+ */
355
+ export function detectPathComputerTakeover(
356
+ computers: ADComputer[],
357
+ users: ADUser[],
358
+ groups: ADGroup[],
359
+ includeDetails: boolean
360
+ ): Finding {
361
+ const graph = buildGroupMembershipGraph(users, groups, computers);
362
+
363
+ // Find computers with RBCD configured
364
+ const rbcdComputers = computers.filter((c) => {
365
+ const rbcd = (c as any)['msDS-AllowedToActOnBehalfOfOtherIdentity'];
366
+ return rbcd && rbcd !== '';
367
+ });
368
+
369
+ // Check which are privileged (DCs, admin workstations)
370
+ const dcPattern = /^(dc|domain controller)/i;
371
+ const affected = rbcdComputers.filter((c) => {
372
+ const computerMemberOf = c['memberOf'] as string[] | undefined;
373
+ const isDC = dcPattern.test(c.sAMAccountName || '') || computerMemberOf?.some((g: string) => g.includes('Domain Controllers'));
374
+ const isPrivileged = graph.isPrivileged(c.dn);
375
+ return isDC || isPrivileged;
376
+ });
377
+
378
+ return {
379
+ type: 'PATH_COMPUTER_TAKEOVER',
380
+ severity: 'high',
381
+ category: 'attack-paths',
382
+ title: 'RBCD Computer Takeover Path',
383
+ description:
384
+ 'Privileged computers have Resource-Based Constrained Delegation configured. Attackers controlling the delegating principal can compromise these computers.',
385
+ count: affected.length,
386
+ affectedEntities: includeDetails
387
+ ? affected.map((c) => ({
388
+ type: 'computer' as const,
389
+ id: c.dn,
390
+ displayName: c.sAMAccountName || c.dn,
391
+ sAMAccountName: c.sAMAccountName,
392
+ dNSHostName: c.dNSHostName || null,
393
+ operatingSystem: c.operatingSystem || null,
394
+ operatingSystemVersion: c.operatingSystemVersion || null,
395
+ whenCreated: null,
396
+ whenChanged: null,
397
+ lastLogon: null,
398
+ pwdLastSet: null,
399
+ enabled: c.enabled ?? true,
400
+ userAccountControl: 0,
401
+ }))
402
+ : undefined,
403
+ details: {
404
+ totalRbcdComputers: rbcdComputers.length,
405
+ privilegedRbcdComputers: affected.length,
406
+ attackVector: 'Control delegating account → RBCD → Impersonate on target',
407
+ mitigation: 'Remove RBCD from privileged computers, monitor msDS-AllowedToActOnBehalfOfOtherIdentity',
408
+ },
409
+ };
410
+ }
411
+
412
+ /**
413
+ * Detect GPO modification paths to Domain Admin
414
+ * Non-admins who can modify GPOs applied to privileged users/computers
415
+ */
416
+ export function detectPathGpoToDA(
417
+ gpos: ADGPO[],
418
+ aclEntries: AclEntry[],
419
+ includeDetails: boolean
420
+ ): Finding {
421
+ // Find GPOs with weak ACLs (non-admin can modify)
422
+ const adminSids = [
423
+ 'S-1-5-32-544', // Administrators
424
+ 'S-1-5-21-*-512', // Domain Admins pattern
425
+ 'S-1-5-21-*-519', // Enterprise Admins pattern
426
+ ];
427
+
428
+ const vulnerableGpos: ADGPO[] = [];
429
+
430
+ for (const gpo of gpos) {
431
+ // Find ACLs for this GPO
432
+ const gpoAcls = aclEntries.filter((acl) => acl.objectDn.toLowerCase() === gpo.dn.toLowerCase());
433
+
434
+ // Check for dangerous write permissions from non-admin principals
435
+ const hasWeakAcl = gpoAcls.some((acl) => {
436
+ const isAdmin = adminSids.some((pattern) => {
437
+ if (pattern.includes('*')) {
438
+ const regex = new RegExp(pattern.replace('*', '.*'));
439
+ return regex.test(acl.trustee);
440
+ }
441
+ return acl.trustee === pattern;
442
+ });
443
+
444
+ // Has write permission but not an admin
445
+ const hasWrite = (acl.accessMask & 0x40000000) !== 0 || (acl.accessMask & 0x10000000) !== 0;
446
+ // aceType is string '0' for ACCESS_ALLOWED_ACE_TYPE
447
+ return hasWrite && !isAdmin && String(acl.aceType) === '0';
448
+ });
449
+
450
+ if (hasWeakAcl) {
451
+ vulnerableGpos.push(gpo);
452
+ }
453
+ }
454
+
455
+ return {
456
+ type: 'PATH_GPO_TO_DA',
457
+ severity: 'critical',
458
+ category: 'attack-paths',
459
+ title: 'GPO Modification Path to Domain Admin',
460
+ description:
461
+ 'GPOs can be modified by non-admin users. If these GPOs apply to privileged users or DCs, attackers can achieve Domain Admin.',
462
+ count: vulnerableGpos.length,
463
+ affectedEntities: includeDetails ? vulnerableGpos.map((g) => g.dn) : undefined,
464
+ details:
465
+ vulnerableGpos.length > 0
466
+ ? {
467
+ vulnerableGpos: vulnerableGpos.map((g) => g.displayName || g.cn),
468
+ attackVector: 'Modify GPO → Add malicious script/scheduled task → Execute on DA logon',
469
+ mitigation: 'Restrict GPO modification rights, implement GPO change monitoring',
470
+ }
471
+ : undefined,
472
+ };
473
+ }
474
+
475
+ /**
476
+ * Detect ADCS certificate template paths to Domain Admin
477
+ * Vulnerable ESC templates that enable DA compromise
478
+ */
479
+ export function detectPathCertificateEsc(
480
+ templates: any[],
481
+ users: ADUser[],
482
+ _groups: ADGroup[],
483
+ _computers: ADComputer[],
484
+ includeDetails: boolean
485
+ ): Finding {
486
+ // Note: groups and computers could be used for more complex enrollment permission checks
487
+
488
+ // Find ESC1-like templates (client auth + enrollee supplies subject)
489
+ const vulnerableTemplates = templates.filter((t) => {
490
+ const hasClientAuth = t.pKIExtendedKeyUsage?.includes('1.3.6.1.5.5.7.3.2');
491
+ const enrolleeSupplies = t['msPKI-Certificate-Name-Flag'] && (t['msPKI-Certificate-Name-Flag'] & 0x1) !== 0;
492
+ return hasClientAuth && enrolleeSupplies;
493
+ });
494
+
495
+ if (vulnerableTemplates.length === 0) {
496
+ return {
497
+ type: 'PATH_CERTIFICATE_ESC',
498
+ severity: 'critical',
499
+ category: 'attack-paths',
500
+ title: 'Certificate Template Escalation to Domain Admin',
501
+ description: 'No vulnerable certificate templates that enable privilege escalation to Domain Admin.',
502
+ count: 0,
503
+ };
504
+ }
505
+
506
+ // Find non-admin users who can enroll
507
+ // This is simplified - full check would require CA enrollment permissions
508
+ const usersWhoCanEnroll = users.filter((u) => u.enabled && u.adminCount !== 1);
509
+
510
+ return {
511
+ type: 'PATH_CERTIFICATE_ESC',
512
+ severity: 'critical',
513
+ category: 'attack-paths',
514
+ title: 'Certificate Template Escalation to Domain Admin',
515
+ description:
516
+ 'Vulnerable certificate templates (ESC1-like) allow users to request certificates for any user including Domain Admins.',
517
+ count: vulnerableTemplates.length,
518
+ affectedEntities: includeDetails ? vulnerableTemplates.map((t) => t.dn || t.cn) : undefined,
519
+ details: {
520
+ vulnerableTemplates: vulnerableTemplates.map((t) => t.cn || t.name),
521
+ attackVector: 'Enroll in vulnerable template → Request cert as DA → Authenticate as DA',
522
+ potentialAttackers: usersWhoCanEnroll.length,
523
+ mitigation:
524
+ 'Disable ENROLLEE_SUPPLIES_SUBJECT flag, restrict enrollment permissions, use Certificate Manager Approval',
525
+ },
526
+ };
527
+ }
528
+
529
+ /**
530
+ * Detect trust relationships enabling lateral movement
531
+ * Trusts without SID filtering or with bidirectional access
532
+ */
533
+ export function detectPathTrustLateral(trusts: ADTrustExtended[], includeDetails: boolean): Finding {
534
+ const riskyTrusts = trusts.filter((t) => {
535
+ // SID filtering disabled = can inject SIDs from trusted domain
536
+ const noSidFiltering = !t.sidFilteringEnabled;
537
+ // Bidirectional = both domains can authenticate to each other
538
+ const bidirectional = t.trustDirection === 3 || t.direction === 'bidirectional';
539
+ // Forest trust without selective auth
540
+ const forestNoSelectiveAuth = t.type === 'forest' && !t.selectiveAuthEnabled;
541
+
542
+ return noSidFiltering || (bidirectional && forestNoSelectiveAuth);
543
+ });
544
+
545
+ return {
546
+ type: 'PATH_TRUST_LATERAL',
547
+ severity: 'high',
548
+ category: 'attack-paths',
549
+ title: 'Trust Relationship Enables Lateral Movement',
550
+ description:
551
+ 'Domain trusts configured without proper security controls (SID filtering, selective authentication). Compromising trusted domain can lead to this domain.',
552
+ count: riskyTrusts.length,
553
+ affectedEntities: includeDetails ? riskyTrusts.map((t) => t.name) : undefined,
554
+ details:
555
+ riskyTrusts.length > 0
556
+ ? {
557
+ totalTrusts: trusts.length,
558
+ riskyTrusts: riskyTrusts.map((t) => ({
559
+ name: t.name,
560
+ direction: t.direction,
561
+ type: t.type,
562
+ sidFiltering: t.sidFilteringEnabled,
563
+ selectiveAuth: t.selectiveAuthEnabled,
564
+ })),
565
+ attackVector: 'Compromise trusted domain → Exploit trust → Access this domain',
566
+ mitigation: 'Enable SID filtering, use selective authentication for forest trusts',
567
+ }
568
+ : undefined,
569
+ };
570
+ }
571
+
572
+ /**
573
+ * Detect all attack path vulnerabilities
574
+ */
575
+ export function detectAttackPathVulnerabilities(
576
+ users: ADUser[],
577
+ groups: ADGroup[],
578
+ computers: ADComputer[],
579
+ aclEntries: AclEntry[],
580
+ gpos: ADGPO[],
581
+ trusts: ADTrustExtended[],
582
+ templates: any[],
583
+ includeDetails: boolean
584
+ ): Finding[] {
585
+ return [
586
+ // Critical
587
+ detectPathKerberoastingToDA(users, groups, computers, includeDetails),
588
+ detectPathAclToDA(users, groups, computers, aclEntries, includeDetails),
589
+ detectPathServiceToDA(users, groups, computers, aclEntries, includeDetails),
590
+ detectPathCertificateEsc(templates, users, groups, computers, includeDetails),
591
+ // High
592
+ detectPathAsrepToAdmin(users, groups, computers, includeDetails),
593
+ detectPathDelegationChain(users, computers, groups, includeDetails),
594
+ detectPathNestedAdmin(users, groups, includeDetails),
595
+ detectPathComputerTakeover(computers, users, groups, includeDetails),
596
+ detectPathGpoToDA(gpos, aclEntries, includeDetails),
597
+ // Medium
598
+ detectPathTrustLateral(trusts, includeDetails),
599
+ ].filter((finding) => finding.count > 0);
600
+ }