@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,952 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobRunner = void 0;
4
+ const acl_parser_1 = require("../../providers/ldap/acl-parser");
5
+ const scoring_service_1 = require("../audit/scoring.service");
6
+ const logger_1 = require("../../utils/logger");
7
+ const job_store_1 = require("./job-store");
8
+ const smb_provider_1 = require("../../providers/smb/smb.provider");
9
+ const ad_1 = require("../audit/detectors/ad");
10
+ const trust_types_1 = require("../../types/trust.types");
11
+ const attack_graph_service_1 = require("../audit/attack-graph.service");
12
+ function createSDFlagsControl() {
13
+ const LDAP_SERVER_SD_FLAGS_OID = '1.2.840.113556.1.4.801';
14
+ const SD_FLAGS = 0x00000007;
15
+ const buffer = Buffer.from([0x02, 0x01, SD_FLAGS]);
16
+ return {
17
+ oid: LDAP_SERVER_SD_FLAGS_OID,
18
+ critical: false,
19
+ value: buffer,
20
+ };
21
+ }
22
+ function convertFiletimeToDate(filetime) {
23
+ if (!filetime)
24
+ return undefined;
25
+ let filetimeNum;
26
+ if (typeof filetime === 'string') {
27
+ filetimeNum = parseInt(filetime, 10);
28
+ }
29
+ else if (typeof filetime === 'number') {
30
+ filetimeNum = filetime;
31
+ }
32
+ else {
33
+ return undefined;
34
+ }
35
+ if (filetimeNum === 0 || filetimeNum >= 9223372036854775807) {
36
+ return undefined;
37
+ }
38
+ const milliseconds = filetimeNum / 10000;
39
+ const epochOffset = 11644473600000;
40
+ const unixTimestamp = milliseconds - epochOffset;
41
+ if (unixTimestamp < 0 || unixTimestamp > Date.now() + 100 * 365 * 24 * 60 * 60 * 1000) {
42
+ return undefined;
43
+ }
44
+ return new Date(unixTimestamp);
45
+ }
46
+ class JobRunner {
47
+ jobStore;
48
+ ldapProvider;
49
+ smbConfig;
50
+ constructor(ldapProvider, smbConfig) {
51
+ this.jobStore = job_store_1.JobStore.getInstance();
52
+ this.ldapProvider = ldapProvider;
53
+ this.smbConfig = smbConfig;
54
+ }
55
+ startAudit(options = {}) {
56
+ const job = this.jobStore.createJob({
57
+ type: 'ad-audit',
58
+ options: options,
59
+ });
60
+ this.runAuditAsync(job.job_id, options).catch((error) => {
61
+ logger_1.logger.error('Async audit failed', { job_id: job.job_id, error });
62
+ });
63
+ return job;
64
+ }
65
+ async runAuditAsync(jobId, options) {
66
+ const startTime = Date.now();
67
+ const { includeDetails = false, maxUsers, maxGroups, maxComputers } = options;
68
+ try {
69
+ this.jobStore.startJob(jobId);
70
+ this.jobStore.startStep(jobId, 'CONNECTING', 'Connecting to LDAP server');
71
+ const connectionTest = await this.ldapProvider.testConnection();
72
+ if (!connectionTest.success) {
73
+ throw new Error(`LDAP connection failed: ${connectionTest.message}`);
74
+ }
75
+ this.jobStore.completeStep(jobId, 'CONNECTING');
76
+ this.jobStore.startStep(jobId, 'FETCHING_USERS', 'Fetching users from Active Directory');
77
+ const users = await this.fetchUsers(maxUsers);
78
+ this.jobStore.completeStep(jobId, 'FETCHING_USERS', { count: users.length });
79
+ this.jobStore.startStep(jobId, 'FETCHING_GROUPS', 'Fetching groups from Active Directory');
80
+ const groups = await this.fetchGroups(maxGroups);
81
+ this.jobStore.completeStep(jobId, 'FETCHING_GROUPS', { count: groups.length });
82
+ this.jobStore.startStep(jobId, 'FETCHING_COMPUTERS', 'Fetching computers from Active Directory');
83
+ const computers = await this.fetchComputers(maxComputers);
84
+ this.jobStore.completeStep(jobId, 'FETCHING_COMPUTERS', { count: computers.length });
85
+ this.jobStore.startStep(jobId, 'FETCHING_DOMAIN', 'Fetching domain information and OUs');
86
+ const [domain, ouCount] = await Promise.all([
87
+ this.fetchDomain(),
88
+ this.fetchOUCount(),
89
+ ]);
90
+ this.jobStore.completeStep(jobId, 'FETCHING_DOMAIN', { count: ouCount });
91
+ this.jobStore.startStep(jobId, 'FETCHING_ACLS', 'Fetching security descriptors (ACLs)');
92
+ const aclEntries = await this.fetchAcls(users, groups, computers, jobId);
93
+ this.jobStore.completeStep(jobId, 'FETCHING_ACLS', { count: aclEntries.length });
94
+ const [certTemplates, certAuthorities, gpoData, trustsExtended] = await Promise.all([
95
+ this.fetchCertificateTemplates(),
96
+ this.fetchCertificateAuthorities(),
97
+ this.fetchGPOsWithAcls(),
98
+ this.fetchTrustsExtended(),
99
+ ]);
100
+ const templates = certTemplates;
101
+ const cas = certAuthorities;
102
+ const fsps = [];
103
+ const findings = [];
104
+ this.jobStore.startStep(jobId, 'DETECTING_PASSWORDS', 'Analyzing password vulnerabilities (7 checks)');
105
+ const passwordFindings = (0, ad_1.detectPasswordVulnerabilities)(users, includeDetails);
106
+ findings.push(...passwordFindings);
107
+ this.jobStore.completeStep(jobId, 'DETECTING_PASSWORDS', { findings: passwordFindings.length });
108
+ this.jobStore.startStep(jobId, 'DETECTING_KERBEROS', 'Analyzing Kerberos vulnerabilities (8 checks)');
109
+ const kerberosFindings = (0, ad_1.detectKerberosVulnerabilities)(users, includeDetails);
110
+ findings.push(...kerberosFindings);
111
+ this.jobStore.completeStep(jobId, 'DETECTING_KERBEROS', { findings: kerberosFindings.length });
112
+ this.jobStore.startStep(jobId, 'DETECTING_ACCOUNTS', 'Analyzing account vulnerabilities (15 checks)');
113
+ const accountsFindings = (0, ad_1.detectAccountsVulnerabilities)(users, includeDetails);
114
+ findings.push(...accountsFindings);
115
+ this.jobStore.completeStep(jobId, 'DETECTING_ACCOUNTS', { findings: accountsFindings.length });
116
+ this.jobStore.startStep(jobId, 'DETECTING_GROUPS', 'Analyzing group vulnerabilities (7 checks)');
117
+ const groupsFindings = (0, ad_1.detectGroupsVulnerabilities)(users, groups, includeDetails);
118
+ findings.push(...groupsFindings);
119
+ this.jobStore.completeStep(jobId, 'DETECTING_GROUPS', { findings: groupsFindings.length });
120
+ this.jobStore.startStep(jobId, 'DETECTING_COMPUTERS', 'Analyzing computer vulnerabilities (17 checks)');
121
+ const computersFindings = (0, ad_1.detectComputersVulnerabilities)(computers, includeDetails);
122
+ findings.push(...computersFindings);
123
+ this.jobStore.completeStep(jobId, 'DETECTING_COMPUTERS', { findings: computersFindings.length });
124
+ this.jobStore.startStep(jobId, 'DETECTING_ADVANCED', 'Analyzing advanced vulnerabilities (22 checks)');
125
+ const advancedFindings = (0, ad_1.detectAdvancedVulnerabilities)(users, computers, domain, templates, cas, fsps, includeDetails);
126
+ findings.push(...advancedFindings);
127
+ this.jobStore.completeStep(jobId, 'DETECTING_ADVANCED', { findings: advancedFindings.length });
128
+ this.jobStore.startStep(jobId, 'DETECTING_PERMISSIONS', 'Analyzing permission vulnerabilities (9 checks)');
129
+ const permissionsFindings = (0, ad_1.detectPermissionsVulnerabilities)(aclEntries, includeDetails);
130
+ findings.push(...permissionsFindings);
131
+ this.jobStore.completeStep(jobId, 'DETECTING_PERMISSIONS', { findings: permissionsFindings.length });
132
+ this.jobStore.startStep(jobId, 'DETECTING_ADCS', 'Analyzing ADCS vulnerabilities (ESC1-ESC8)');
133
+ const adcsFindings = (0, ad_1.detectAdcsVulnerabilities)(certTemplates, certAuthorities, includeDetails);
134
+ findings.push(...adcsFindings);
135
+ this.jobStore.completeStep(jobId, 'DETECTING_ADCS', { findings: adcsFindings.length });
136
+ this.jobStore.startStep(jobId, 'DETECTING_GPO', 'Analyzing GPO security (5 checks)');
137
+ const gpoFindings = (0, ad_1.detectGpoVulnerabilities)(gpoData.gpos, gpoData.links, domain ? { minPasswordLength: domain['minPwdLength'] } : null, includeDetails);
138
+ findings.push(...gpoFindings);
139
+ this.jobStore.completeStep(jobId, 'DETECTING_GPO', { findings: gpoFindings.length });
140
+ this.jobStore.startStep(jobId, 'DETECTING_TRUSTS', 'Analyzing trust relationships (4 checks)');
141
+ const trustsFindings = (0, ad_1.detectTrustVulnerabilities)(trustsExtended, includeDetails);
142
+ findings.push(...trustsFindings);
143
+ this.jobStore.completeStep(jobId, 'DETECTING_TRUSTS', { findings: trustsFindings.length });
144
+ this.jobStore.startStep(jobId, 'DETECTING_ATTACK_PATHS', 'Analyzing attack paths (11 checks)');
145
+ const attackPathFindings = (0, ad_1.detectAttackPathVulnerabilities)(users, groups, computers, aclEntries, gpoData.gpos, trustsExtended, certTemplates, includeDetails);
146
+ findings.push(...attackPathFindings);
147
+ this.jobStore.completeStep(jobId, 'DETECTING_ATTACK_PATHS', { findings: attackPathFindings.length });
148
+ this.jobStore.startStep(jobId, 'DETECTING_MONITORING', 'Analyzing monitoring configuration (6 checks)');
149
+ const monitoringFindings = (0, ad_1.detectMonitoringVulnerabilities)(users, groups, domain, includeDetails);
150
+ findings.push(...monitoringFindings);
151
+ this.jobStore.completeStep(jobId, 'DETECTING_MONITORING', { findings: monitoringFindings.length });
152
+ this.jobStore.startStep(jobId, 'CALCULATING_SCORE', 'Calculating security score');
153
+ const score = (0, scoring_service_1.calculateSecurityScore)(findings, users.length);
154
+ this.jobStore.completeStep(jobId, 'CALCULATING_SCORE');
155
+ this.jobStore.startStep(jobId, 'FETCHING_CONFIG', 'Fetching domain configuration');
156
+ const domainConfig = await this.fetchDomainConfig(domain);
157
+ this.jobStore.completeStep(jobId, 'FETCHING_CONFIG');
158
+ this.jobStore.startStep(jobId, 'COMPUTING_ATTACK_GRAPH', 'Computing attack paths graph');
159
+ const baseDN = this.ldapProvider.getBaseDN();
160
+ const attackGraph = (0, attack_graph_service_1.computeAttackGraph)(users, groups, computers, aclEntries, certTemplates, gpoData.gpos, {
161
+ name: domainConfig?.domainInfo?.domainName || this.extractDomainNameFromDN(baseDN),
162
+ sid: undefined,
163
+ }, 500);
164
+ this.jobStore.completeStep(jobId, 'COMPUTING_ATTACK_GRAPH', {
165
+ count: attackGraph.paths.length,
166
+ });
167
+ this.jobStore.startStep(jobId, 'FORMATTING', 'Formatting audit response');
168
+ const executionTimeMs = Date.now() - startTime;
169
+ const disabledUsers = users.filter((u) => ((u.userAccountControl ?? 0) & 0x2) !== 0).length;
170
+ const enabledUsers = users.length - disabledUsers;
171
+ const result = {
172
+ score,
173
+ findings,
174
+ stats: {
175
+ totalUsers: users.length,
176
+ enabledUsers,
177
+ disabledUsers,
178
+ totalGroups: groups.length,
179
+ totalComputers: computers.length,
180
+ totalOUs: ouCount,
181
+ totalFindings: findings.length,
182
+ executionTimeMs,
183
+ },
184
+ timestamp: new Date(),
185
+ domainConfig,
186
+ attackGraph,
187
+ };
188
+ this.jobStore.completeStep(jobId, 'FORMATTING');
189
+ this.jobStore.completeJob(jobId, result);
190
+ }
191
+ catch (error) {
192
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
193
+ const currentStep = this.jobStore.getJob(jobId)?.current_step || 'CONNECTING';
194
+ this.jobStore.failStep(jobId, currentStep, errorMessage);
195
+ this.jobStore.failJob(jobId, {
196
+ code: 'AUDIT_FAILED',
197
+ message: errorMessage,
198
+ step: currentStep,
199
+ });
200
+ }
201
+ }
202
+ async fetchUsers(maxUsers) {
203
+ const baseDN = this.ldapProvider.getBaseDN();
204
+ const filter = '(&(objectClass=user)(objectCategory=person))';
205
+ const attributes = [
206
+ 'dn',
207
+ 'sAMAccountName',
208
+ 'userPrincipalName',
209
+ 'displayName',
210
+ 'mail',
211
+ 'title',
212
+ 'department',
213
+ 'company',
214
+ 'manager',
215
+ 'physicalDeliveryOfficeName',
216
+ 'description',
217
+ 'employeeID',
218
+ 'telephoneNumber',
219
+ 'whenCreated',
220
+ 'whenChanged',
221
+ 'lastLogon',
222
+ 'pwdLastSet',
223
+ 'passwordLastSet',
224
+ 'accountExpires',
225
+ 'badPwdCount',
226
+ 'lockoutTime',
227
+ 'adminCount',
228
+ 'memberOf',
229
+ 'userAccountControl',
230
+ 'servicePrincipalName',
231
+ 'msDS-SupportedEncryptionTypes',
232
+ 'sIDHistory',
233
+ 'msDS-KeyCredentialLink',
234
+ 'msDS-AllowedToActOnBehalfOfOtherIdentity',
235
+ 'msDS-AllowedToDelegateTo',
236
+ ];
237
+ const results = await this.ldapProvider.search(baseDN, {
238
+ filter,
239
+ attributes,
240
+ scope: 'sub',
241
+ sizeLimit: maxUsers,
242
+ paged: true,
243
+ });
244
+ return results.map((entry) => ({
245
+ ...entry,
246
+ dn: entry.dn,
247
+ sAMAccountName: entry.sAMAccountName,
248
+ userPrincipalName: entry.userPrincipalName,
249
+ displayName: entry.displayName,
250
+ enabled: !(entry.userAccountControl & 0x2),
251
+ passwordLastSet: convertFiletimeToDate(entry.passwordLastSet),
252
+ lastLogon: convertFiletimeToDate(entry.lastLogon),
253
+ accountExpires: convertFiletimeToDate(entry.accountExpires),
254
+ adminCount: entry.adminCount,
255
+ memberOf: !entry.memberOf ? [] : Array.isArray(entry.memberOf) ? entry.memberOf : [entry.memberOf],
256
+ servicePrincipalName: !entry.servicePrincipalName
257
+ ? []
258
+ : Array.isArray(entry.servicePrincipalName)
259
+ ? entry.servicePrincipalName
260
+ : [entry.servicePrincipalName],
261
+ userAccountControl: entry.userAccountControl,
262
+ }));
263
+ }
264
+ async fetchGroups(maxGroups) {
265
+ const baseDN = this.ldapProvider.getBaseDN();
266
+ const filter = '(objectClass=group)';
267
+ const attributes = ['dn', 'sAMAccountName', 'displayName', 'groupType', 'memberOf', 'member'];
268
+ const results = await this.ldapProvider.search(baseDN, {
269
+ filter,
270
+ attributes,
271
+ scope: 'sub',
272
+ sizeLimit: maxGroups,
273
+ paged: true,
274
+ });
275
+ return results.map((entry) => ({
276
+ ...entry,
277
+ dn: entry.dn,
278
+ sAMAccountName: entry.sAMAccountName,
279
+ displayName: entry.displayName,
280
+ groupType: entry.groupType,
281
+ memberOf: !entry.memberOf ? [] : Array.isArray(entry.memberOf) ? entry.memberOf : [entry.memberOf],
282
+ member: !entry.member ? [] : Array.isArray(entry.member) ? entry.member : [entry.member],
283
+ }));
284
+ }
285
+ async fetchComputers(maxComputers) {
286
+ const baseDN = this.ldapProvider.getBaseDN();
287
+ const filter = '(objectClass=computer)';
288
+ const attributes = [
289
+ 'dn',
290
+ 'sAMAccountName',
291
+ 'dNSHostName',
292
+ 'operatingSystem',
293
+ 'operatingSystemVersion',
294
+ 'lastLogon',
295
+ 'userAccountControl',
296
+ 'pwdLastSet',
297
+ 'servicePrincipalName',
298
+ 'ms-Mcs-AdmPwd',
299
+ 'msLAPS-Password',
300
+ 'msDS-AllowedToDelegateTo',
301
+ 'msDS-AllowedToActOnBehalfOfOtherIdentity',
302
+ 'msDS-SupportedEncryptionTypes',
303
+ 'memberOf',
304
+ 'description',
305
+ 'whenChanged',
306
+ 'adminCount',
307
+ ];
308
+ const results = await this.ldapProvider.search(baseDN, {
309
+ filter,
310
+ attributes,
311
+ scope: 'sub',
312
+ sizeLimit: maxComputers,
313
+ paged: true,
314
+ });
315
+ return results.map((entry) => ({
316
+ ...entry,
317
+ dn: entry.dn,
318
+ sAMAccountName: entry.sAMAccountName,
319
+ dNSHostName: entry.dNSHostName,
320
+ operatingSystem: entry.operatingSystem,
321
+ operatingSystemVersion: entry.operatingSystemVersion,
322
+ lastLogon: convertFiletimeToDate(entry.lastLogon),
323
+ pwdLastSet: convertFiletimeToDate(entry.pwdLastSet),
324
+ enabled: !(entry.userAccountControl & 0x2),
325
+ memberOf: !entry.memberOf ? [] : Array.isArray(entry.memberOf) ? entry.memberOf : [entry.memberOf],
326
+ servicePrincipalName: !entry.servicePrincipalName
327
+ ? []
328
+ : Array.isArray(entry.servicePrincipalName)
329
+ ? entry.servicePrincipalName
330
+ : [entry.servicePrincipalName],
331
+ }));
332
+ }
333
+ async fetchDomain() {
334
+ try {
335
+ const baseDN = this.ldapProvider.getBaseDN();
336
+ const filter = '(objectClass=domain)';
337
+ const attributes = [
338
+ 'dn',
339
+ 'name',
340
+ 'msDS-Behavior-Version',
341
+ 'minPwdLength',
342
+ 'maxPwdAge',
343
+ 'pwdHistoryLength',
344
+ 'ms-DS-MachineAccountQuota',
345
+ ];
346
+ const results = await this.ldapProvider.search(baseDN, {
347
+ filter,
348
+ attributes,
349
+ scope: 'base',
350
+ });
351
+ if (results.length === 0)
352
+ return null;
353
+ const entry = results[0];
354
+ const domainFunctionalLevel = entry['msDS-Behavior-Version'] !== undefined
355
+ ? parseInt(entry['msDS-Behavior-Version'], 10)
356
+ : undefined;
357
+ let forestFunctionalLevel;
358
+ try {
359
+ const configDN = `CN=Partitions,CN=Configuration,${baseDN}`;
360
+ const forestResults = await this.ldapProvider.search(configDN, {
361
+ filter: '(objectClass=crossRefContainer)',
362
+ attributes: ['msDS-Behavior-Version'],
363
+ scope: 'base',
364
+ });
365
+ if (forestResults.length > 0 && forestResults[0]['msDS-Behavior-Version'] !== undefined) {
366
+ forestFunctionalLevel = parseInt(forestResults[0]['msDS-Behavior-Version'], 10);
367
+ }
368
+ }
369
+ catch (e) {
370
+ }
371
+ return {
372
+ dn: entry.dn,
373
+ name: entry.name,
374
+ domainFunctionalLevel,
375
+ forestFunctionalLevel,
376
+ ...entry,
377
+ };
378
+ }
379
+ catch (error) {
380
+ logger_1.logger.error('Failed to fetch domain:', error);
381
+ return null;
382
+ }
383
+ }
384
+ async fetchOUCount() {
385
+ try {
386
+ const baseDN = this.ldapProvider.getBaseDN();
387
+ const filter = '(objectClass=organizationalUnit)';
388
+ const results = await this.ldapProvider.search(baseDN, {
389
+ filter,
390
+ attributes: ['dn'],
391
+ scope: 'sub',
392
+ paged: true,
393
+ });
394
+ return results.length;
395
+ }
396
+ catch (error) {
397
+ logger_1.logger.warn('Failed to fetch OU count', { error });
398
+ return 0;
399
+ }
400
+ }
401
+ async fetchAcls(users, groups, computers, jobId) {
402
+ const allAclEntries = [];
403
+ const baseDN = this.ldapProvider.getBaseDN();
404
+ try {
405
+ (0, acl_parser_1.resetParseStats)();
406
+ const totalObjects = users.length + groups.length + computers.length + 3;
407
+ let processed = 0;
408
+ const userDns = users.map((u) => u.dn);
409
+ const userAcls = await this.fetchAclsForObjects(userDns, (count) => {
410
+ processed += count;
411
+ this.jobStore.updateStepProgress(jobId, 'FETCHING_ACLS', {
412
+ progress: Math.round((processed / totalObjects) * 100),
413
+ description: `Fetching ACLs: ${processed}/${totalObjects} objects`,
414
+ });
415
+ });
416
+ for (const entry of userAcls) {
417
+ allAclEntries.push(entry);
418
+ }
419
+ const groupDns = groups.map((g) => g.dn);
420
+ const groupAcls = await this.fetchAclsForObjects(groupDns, (count) => {
421
+ processed += count;
422
+ this.jobStore.updateStepProgress(jobId, 'FETCHING_ACLS', {
423
+ progress: Math.round((processed / totalObjects) * 100),
424
+ description: `Fetching ACLs: ${processed}/${totalObjects} objects`,
425
+ });
426
+ });
427
+ for (const entry of groupAcls) {
428
+ allAclEntries.push(entry);
429
+ }
430
+ const computerDns = computers.map((c) => c.dn);
431
+ const computerAcls = await this.fetchAclsForObjects(computerDns, (count) => {
432
+ processed += count;
433
+ this.jobStore.updateStepProgress(jobId, 'FETCHING_ACLS', {
434
+ progress: Math.round((processed / totalObjects) * 100),
435
+ description: `Fetching ACLs: ${processed}/${totalObjects} objects`,
436
+ });
437
+ });
438
+ for (const entry of computerAcls) {
439
+ allAclEntries.push(entry);
440
+ }
441
+ const systemObjects = [baseDN, `CN=AdminSDHolder,CN=System,${baseDN}`, `CN=Policies,CN=System,${baseDN}`];
442
+ const systemAcls = await this.fetchAclsForObjects(systemObjects, (count) => {
443
+ processed += count;
444
+ this.jobStore.updateStepProgress(jobId, 'FETCHING_ACLS', {
445
+ progress: Math.round((processed / totalObjects) * 100),
446
+ description: `Fetching ACLs: ${processed}/${totalObjects} objects`,
447
+ });
448
+ });
449
+ for (const entry of systemAcls) {
450
+ allAclEntries.push(entry);
451
+ }
452
+ return allAclEntries;
453
+ }
454
+ catch (error) {
455
+ logger_1.logger.warn('Failed to fetch ACL entries - insufficient permissions or unsupported configuration');
456
+ return [];
457
+ }
458
+ }
459
+ async fetchAclsForObjects(objectDns, onProgress) {
460
+ const allAclEntries = [];
461
+ const BATCH_SIZE = 100;
462
+ for (let i = 0; i < objectDns.length; i += BATCH_SIZE) {
463
+ const batch = objectDns.slice(i, i + BATCH_SIZE);
464
+ const batchPromises = batch.map(async (dn) => {
465
+ try {
466
+ const results = await this.ldapProvider.search(dn, {
467
+ filter: '(objectClass=*)',
468
+ attributes: ['nTSecurityDescriptor'],
469
+ scope: 'base',
470
+ controls: [createSDFlagsControl()],
471
+ });
472
+ if (results.length > 0 && results[0].nTSecurityDescriptor) {
473
+ const secDescriptor = results[0].nTSecurityDescriptor;
474
+ const buffer = Buffer.isBuffer(secDescriptor)
475
+ ? secDescriptor
476
+ : Buffer.from(secDescriptor, 'binary');
477
+ const entries = (0, acl_parser_1.parseSecurityDescriptor)(buffer, dn);
478
+ return entries;
479
+ }
480
+ }
481
+ catch (error) {
482
+ return [];
483
+ }
484
+ return [];
485
+ });
486
+ const batchResults = await Promise.all(batchPromises);
487
+ batchResults.forEach((entries) => allAclEntries.push(...entries));
488
+ if (onProgress) {
489
+ onProgress(batch.length);
490
+ }
491
+ }
492
+ return allAclEntries;
493
+ }
494
+ async fetchDomainConfig(domain) {
495
+ const baseDN = this.ldapProvider.getBaseDN();
496
+ const config = {
497
+ passwordPolicy: {
498
+ minPasswordLength: 0,
499
+ passwordHistoryLength: 0,
500
+ maxPasswordAge: 'Not configured',
501
+ minPasswordAge: 'Not configured',
502
+ lockoutThreshold: 0,
503
+ lockoutDuration: 'Not configured',
504
+ lockoutObservationWindow: 'Not configured',
505
+ complexity: false,
506
+ },
507
+ kerberosPolicy: (0, smb_provider_1.getDefaultKerberosPolicy)(),
508
+ domainInfo: {
509
+ forestName: '',
510
+ domainName: '',
511
+ domainMode: 'Unknown',
512
+ forestMode: 'Unknown',
513
+ domainControllers: [],
514
+ fsmoRoles: {},
515
+ },
516
+ trusts: [],
517
+ gpoSummary: {
518
+ totalGPOs: 0,
519
+ linkedGPOs: 0,
520
+ },
521
+ };
522
+ try {
523
+ const policyResults = await this.ldapProvider.search(baseDN, {
524
+ filter: '(objectClass=domain)',
525
+ attributes: [
526
+ 'minPwdLength',
527
+ 'pwdHistoryLength',
528
+ 'maxPwdAge',
529
+ 'minPwdAge',
530
+ 'lockoutThreshold',
531
+ 'lockoutDuration',
532
+ 'lockOutObservationWindow',
533
+ 'pwdProperties',
534
+ 'name',
535
+ ],
536
+ scope: 'base',
537
+ });
538
+ if (policyResults.length > 0) {
539
+ const policy = policyResults[0];
540
+ config.passwordPolicy.minPasswordLength = parseInt(policy.minPwdLength || '0', 10);
541
+ config.passwordPolicy.passwordHistoryLength = parseInt(policy.pwdHistoryLength || '0', 10);
542
+ config.passwordPolicy.maxPasswordAge = this.formatFiletimeDuration(policy.maxPwdAge);
543
+ config.passwordPolicy.minPasswordAge = this.formatFiletimeDuration(policy.minPwdAge);
544
+ config.passwordPolicy.lockoutThreshold = parseInt(policy.lockoutThreshold || '0', 10);
545
+ config.passwordPolicy.lockoutDuration = this.formatFiletimeDuration(policy.lockoutDuration);
546
+ config.passwordPolicy.lockoutObservationWindow = this.formatFiletimeDuration(policy.lockOutObservationWindow);
547
+ config.passwordPolicy.complexity = (parseInt(policy.pwdProperties || '0', 10) & 1) === 1;
548
+ config.domainInfo.domainName = policy.name || '';
549
+ }
550
+ if (domain) {
551
+ config.domainInfo.domainMode = this.getDomainModeName(domain.domainFunctionalLevel);
552
+ config.domainInfo.forestMode = this.getDomainModeName(domain.forestFunctionalLevel);
553
+ config.domainInfo.forestName = this.extractDomainNameFromDN(baseDN);
554
+ config.domainInfo.domainName = this.extractDomainNameFromDN(baseDN);
555
+ }
556
+ const dcResults = await this.ldapProvider.search(baseDN, {
557
+ filter: '(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))',
558
+ attributes: ['dNSHostName', 'name'],
559
+ scope: 'sub',
560
+ });
561
+ config.domainInfo.domainControllers = dcResults
562
+ .map((dc) => dc.dNSHostName || dc.name)
563
+ .filter((name) => name);
564
+ await this.fetchFSMORoles(config, baseDN);
565
+ await this.fetchTrusts(config, baseDN);
566
+ await this.fetchGPOCount(config, baseDN);
567
+ const dcHostname = config.domainInfo.domainControllers[0];
568
+ if (dcHostname) {
569
+ const domainDnsName = this.extractDomainNameFromDN(baseDN);
570
+ config.kerberosPolicy = await this.fetchKerberosPolicyViaSMB(domainDnsName, dcHostname);
571
+ }
572
+ else {
573
+ config.kerberosPolicy = (0, smb_provider_1.getDefaultKerberosPolicy)();
574
+ }
575
+ }
576
+ catch (error) {
577
+ logger_1.logger.warn('Failed to fetch some domain configuration', { error });
578
+ }
579
+ return config;
580
+ }
581
+ formatFiletimeDuration(filetime) {
582
+ if (!filetime)
583
+ return 'Not configured';
584
+ const value = typeof filetime === 'string' ? parseInt(filetime, 10) : filetime;
585
+ if (value === 0 || isNaN(value))
586
+ return 'Not configured';
587
+ const minutes = Math.abs(value) / (10000000 * 60);
588
+ if (minutes < 60) {
589
+ return `${Math.round(minutes)} min`;
590
+ }
591
+ else if (minutes < 1440) {
592
+ const hours = Math.round(minutes / 60);
593
+ return `${hours} hour${hours > 1 ? 's' : ''}`;
594
+ }
595
+ else {
596
+ const days = Math.round(minutes / 1440);
597
+ return `${days} day${days > 1 ? 's' : ''}`;
598
+ }
599
+ }
600
+ getDomainModeName(level) {
601
+ if (level === undefined)
602
+ return 'Unknown';
603
+ const levels = {
604
+ 0: 'Windows2000Domain',
605
+ 1: 'Windows2003InterimDomain',
606
+ 2: 'Windows2003Domain',
607
+ 3: 'Windows2008Domain',
608
+ 4: 'Windows2008R2Domain',
609
+ 5: 'Windows2012Domain',
610
+ 6: 'Windows2012R2Domain',
611
+ 7: 'Windows2016Domain',
612
+ };
613
+ return levels[level] || `Unknown (${level})`;
614
+ }
615
+ extractDomainNameFromDN(dn) {
616
+ const parts = dn.match(/DC=([^,]+)/gi);
617
+ if (!parts)
618
+ return dn;
619
+ return parts.map((p) => p.replace(/DC=/i, '')).join('.');
620
+ }
621
+ async fetchFSMORoles(config, baseDN) {
622
+ try {
623
+ const domainRoles = await this.ldapProvider.search(baseDN, {
624
+ filter: '(objectClass=domain)',
625
+ attributes: ['fSMORoleOwner'],
626
+ scope: 'base',
627
+ });
628
+ if (domainRoles.length > 0 && domainRoles[0].fSMORoleOwner) {
629
+ config.domainInfo.fsmoRoles.pdcEmulator = this.extractServerFromDN(domainRoles[0].fSMORoleOwner);
630
+ }
631
+ const ridResults = await this.ldapProvider.search(`CN=RID Manager$,CN=System,${baseDN}`, {
632
+ filter: '(objectClass=*)',
633
+ attributes: ['fSMORoleOwner'],
634
+ scope: 'base',
635
+ });
636
+ if (ridResults.length > 0 && ridResults[0].fSMORoleOwner) {
637
+ config.domainInfo.fsmoRoles.ridMaster = this.extractServerFromDN(ridResults[0].fSMORoleOwner);
638
+ }
639
+ const infraResults = await this.ldapProvider.search(`CN=Infrastructure,${baseDN}`, {
640
+ filter: '(objectClass=*)',
641
+ attributes: ['fSMORoleOwner'],
642
+ scope: 'base',
643
+ });
644
+ if (infraResults.length > 0 && infraResults[0].fSMORoleOwner) {
645
+ config.domainInfo.fsmoRoles.infrastructureMaster = this.extractServerFromDN(infraResults[0].fSMORoleOwner);
646
+ }
647
+ }
648
+ catch (error) {
649
+ logger_1.logger.debug('Could not fetch all FSMO roles', { error });
650
+ }
651
+ }
652
+ extractServerFromDN(dn) {
653
+ const match = dn.match(/CN=NTDS Settings,CN=([^,]+)/i);
654
+ return match && match[1] ? match[1] : dn;
655
+ }
656
+ async fetchTrusts(config, baseDN) {
657
+ try {
658
+ const trustResults = await this.ldapProvider.search(`CN=System,${baseDN}`, {
659
+ filter: '(objectClass=trustedDomain)',
660
+ attributes: ['name', 'trustDirection', 'trustType', 'trustAttributes'],
661
+ scope: 'one',
662
+ });
663
+ config.trusts = trustResults.map((trust) => {
664
+ const direction = parseInt(trust.trustDirection || '0', 10);
665
+ const trustType = parseInt(trust.trustType || '0', 10);
666
+ const attributes = parseInt(trust.trustAttributes || '0', 10);
667
+ return {
668
+ name: trust.name || 'Unknown',
669
+ direction: this.getTrustDirection(direction),
670
+ type: this.getTrustType(trustType),
671
+ transitive: (attributes & 1) === 1,
672
+ };
673
+ });
674
+ }
675
+ catch (error) {
676
+ logger_1.logger.debug('Could not fetch trust relationships', { error });
677
+ }
678
+ }
679
+ getTrustDirection(direction) {
680
+ switch (direction) {
681
+ case 1:
682
+ return 'inbound';
683
+ case 2:
684
+ return 'outbound';
685
+ case 3:
686
+ return 'bidirectional';
687
+ default:
688
+ return 'inbound';
689
+ }
690
+ }
691
+ getTrustType(type) {
692
+ switch (type) {
693
+ case 1:
694
+ return 'external';
695
+ case 2:
696
+ return 'external';
697
+ case 3:
698
+ return 'realm';
699
+ case 4:
700
+ return 'external';
701
+ default:
702
+ return 'external';
703
+ }
704
+ }
705
+ async fetchGPOCount(config, baseDN) {
706
+ try {
707
+ const gpoResults = await this.ldapProvider.search(`CN=Policies,CN=System,${baseDN}`, {
708
+ filter: '(objectClass=groupPolicyContainer)',
709
+ attributes: ['cn', 'gPCFileSysPath'],
710
+ scope: 'one',
711
+ });
712
+ config.gpoSummary.totalGPOs = gpoResults.length;
713
+ const linkedResults = await this.ldapProvider.search(baseDN, {
714
+ filter: '(gPLink=*)',
715
+ attributes: ['gPLink'],
716
+ scope: 'sub',
717
+ sizeLimit: 1000,
718
+ });
719
+ const linkedGPOs = new Set();
720
+ linkedResults.forEach((obj) => {
721
+ const gpLink = obj.gPLink;
722
+ if (gpLink) {
723
+ const matches = gpLink.match(/cn=\{[^}]+\}/gi);
724
+ if (matches) {
725
+ matches.forEach((m) => linkedGPOs.add(m.toLowerCase()));
726
+ }
727
+ }
728
+ });
729
+ config.gpoSummary.linkedGPOs = linkedGPOs.size;
730
+ }
731
+ catch (error) {
732
+ logger_1.logger.debug('Could not fetch GPO count', { error });
733
+ }
734
+ }
735
+ async fetchKerberosPolicyViaSMB(domainDnsName, dcHostname) {
736
+ if (!this.smbConfig || !this.smbConfig.smb.enabled) {
737
+ logger_1.logger.debug('SMB is disabled, returning default Kerberos policy values');
738
+ return (0, smb_provider_1.getDefaultKerberosPolicy)();
739
+ }
740
+ const { smb, ldap } = this.smbConfig;
741
+ const username = smb.username || ldap.bindDN.split(',')[0]?.replace(/^CN=/i, '') || '';
742
+ const password = smb.password || ldap.bindPassword;
743
+ const baseDNMatch = ldap.baseDN.match(/DC=([^,]+)/i);
744
+ const smbProviderConfig = {
745
+ host: dcHostname,
746
+ share: 'SYSVOL',
747
+ domain: baseDNMatch?.[1] || '',
748
+ username,
749
+ password,
750
+ timeout: smb.timeout,
751
+ };
752
+ const smbProvider = new smb_provider_1.SMBProvider(smbProviderConfig);
753
+ try {
754
+ await smbProvider.connect();
755
+ const kerberosPolicy = await smbProvider.readKerberosPolicy(domainDnsName);
756
+ if (kerberosPolicy) {
757
+ logger_1.logger.debug('Successfully fetched Kerberos policy from SYSVOL', { domainDnsName });
758
+ return (0, smb_provider_1.formatKerberosPolicy)(kerberosPolicy, false);
759
+ }
760
+ logger_1.logger.debug('GptTmpl.inf not found, using Windows default Kerberos policy values');
761
+ return (0, smb_provider_1.getDefaultKerberosPolicy)();
762
+ }
763
+ catch (error) {
764
+ logger_1.logger.warn('Failed to fetch Kerberos policy via SMB, using defaults', { error, dcHostname });
765
+ return (0, smb_provider_1.getDefaultKerberosPolicy)();
766
+ }
767
+ finally {
768
+ await smbProvider.disconnect();
769
+ }
770
+ }
771
+ async fetchCertificateTemplates() {
772
+ try {
773
+ const baseDN = this.ldapProvider.getBaseDN();
774
+ const templatesDN = `CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,${baseDN}`;
775
+ const results = await this.ldapProvider.search(templatesDN, {
776
+ filter: '(objectClass=pKICertificateTemplate)',
777
+ attributes: [
778
+ 'dn',
779
+ 'cn',
780
+ 'name',
781
+ 'displayName',
782
+ 'msPKI-Certificate-Name-Flag',
783
+ 'msPKI-Enrollment-Flag',
784
+ 'pKIExtendedKeyUsage',
785
+ 'nTSecurityDescriptor',
786
+ ],
787
+ scope: 'one',
788
+ controls: [createSDFlagsControl()],
789
+ });
790
+ return results.map((entry) => ({
791
+ dn: entry.dn,
792
+ cn: entry.cn || entry.name,
793
+ name: entry.name || entry.cn,
794
+ displayName: entry.displayName,
795
+ 'msPKI-Certificate-Name-Flag': entry['msPKI-Certificate-Name-Flag']
796
+ ? parseInt(entry['msPKI-Certificate-Name-Flag'], 10)
797
+ : 0,
798
+ 'msPKI-Enrollment-Flag': entry['msPKI-Enrollment-Flag']
799
+ ? parseInt(entry['msPKI-Enrollment-Flag'], 10)
800
+ : 0,
801
+ pKIExtendedKeyUsage: !entry.pKIExtendedKeyUsage
802
+ ? []
803
+ : Array.isArray(entry.pKIExtendedKeyUsage)
804
+ ? entry.pKIExtendedKeyUsage
805
+ : [entry.pKIExtendedKeyUsage],
806
+ nTSecurityDescriptor: entry.nTSecurityDescriptor,
807
+ }));
808
+ }
809
+ catch (error) {
810
+ logger_1.logger.debug('Could not fetch certificate templates (ADCS may not be configured)', { error });
811
+ return [];
812
+ }
813
+ }
814
+ async fetchCertificateAuthorities() {
815
+ try {
816
+ const baseDN = this.ldapProvider.getBaseDN();
817
+ const enrollmentDN = `CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,${baseDN}`;
818
+ const results = await this.ldapProvider.search(enrollmentDN, {
819
+ filter: '(objectClass=pKIEnrollmentService)',
820
+ attributes: [
821
+ 'dn',
822
+ 'cn',
823
+ 'name',
824
+ 'dNSHostName',
825
+ 'certificateTemplates',
826
+ 'nTSecurityDescriptor',
827
+ ],
828
+ scope: 'one',
829
+ controls: [createSDFlagsControl()],
830
+ });
831
+ return results.map((entry) => ({
832
+ dn: entry.dn,
833
+ cn: entry.cn || entry.name,
834
+ name: entry.name || entry.cn,
835
+ dNSHostName: entry.dNSHostName,
836
+ certificateTemplates: !entry.certificateTemplates
837
+ ? []
838
+ : Array.isArray(entry.certificateTemplates)
839
+ ? entry.certificateTemplates
840
+ : [entry.certificateTemplates],
841
+ nTSecurityDescriptor: entry.nTSecurityDescriptor,
842
+ }));
843
+ }
844
+ catch (error) {
845
+ logger_1.logger.debug('Could not fetch certificate authorities (ADCS may not be configured)', { error });
846
+ return [];
847
+ }
848
+ }
849
+ async fetchGPOsWithAcls() {
850
+ const baseDN = this.ldapProvider.getBaseDN();
851
+ const gpos = [];
852
+ const links = [];
853
+ try {
854
+ const gpoResults = await this.ldapProvider.search(`CN=Policies,CN=System,${baseDN}`, {
855
+ filter: '(objectClass=groupPolicyContainer)',
856
+ attributes: [
857
+ 'dn',
858
+ 'cn',
859
+ 'displayName',
860
+ 'gPCFileSysPath',
861
+ 'flags',
862
+ 'gPCMachineExtensionNames',
863
+ 'nTSecurityDescriptor',
864
+ ],
865
+ scope: 'one',
866
+ controls: [createSDFlagsControl()],
867
+ });
868
+ for (const entry of gpoResults) {
869
+ const flags = entry.flags ? parseInt(entry.flags, 10) : 0;
870
+ gpos.push({
871
+ dn: entry.dn,
872
+ cn: entry.cn,
873
+ displayName: entry.displayName,
874
+ gPCFileSysPath: entry.gPCFileSysPath,
875
+ flags,
876
+ gPCMachineExtensionNames: entry.gPCMachineExtensionNames,
877
+ nTSecurityDescriptor: entry.nTSecurityDescriptor,
878
+ });
879
+ }
880
+ const linkResults = await this.ldapProvider.search(baseDN, {
881
+ filter: '(gPLink=*)',
882
+ attributes: ['dn', 'gPLink'],
883
+ scope: 'sub',
884
+ sizeLimit: 1000,
885
+ });
886
+ for (const entry of linkResults) {
887
+ const gpLink = entry.gPLink;
888
+ if (!gpLink)
889
+ continue;
890
+ const linkMatches = gpLink.matchAll(/\[LDAP:\/\/([^\]]+);(\d+)\]/gi);
891
+ for (const match of linkMatches) {
892
+ const gpoDn = match[1];
893
+ const options = parseInt(match[2], 10);
894
+ const guidMatch = gpoDn.match(/cn=(\{[^}]+\})/i);
895
+ if (guidMatch) {
896
+ links.push({
897
+ gpoGuid: guidMatch[1],
898
+ linkedTo: entry.dn,
899
+ enforced: (options & 2) !== 0,
900
+ disabled: (options & 1) !== 0,
901
+ });
902
+ }
903
+ }
904
+ }
905
+ }
906
+ catch (error) {
907
+ logger_1.logger.debug('Could not fetch GPOs with ACLs', { error });
908
+ }
909
+ return { gpos, links };
910
+ }
911
+ async fetchTrustsExtended() {
912
+ try {
913
+ const baseDN = this.ldapProvider.getBaseDN();
914
+ const results = await this.ldapProvider.search(`CN=System,${baseDN}`, {
915
+ filter: '(objectClass=trustedDomain)',
916
+ attributes: [
917
+ 'dn',
918
+ 'name',
919
+ 'trustDirection',
920
+ 'trustType',
921
+ 'trustAttributes',
922
+ 'flatName',
923
+ 'securityIdentifier',
924
+ ],
925
+ scope: 'one',
926
+ });
927
+ return results.map((entry) => {
928
+ const trustDirection = parseInt(entry.trustDirection || '0', 10);
929
+ const trustType = parseInt(entry.trustType || '0', 10);
930
+ const trustAttributes = parseInt(entry.trustAttributes || '0', 10);
931
+ const parsed = (0, trust_types_1.parseTrustAttributes)(trustAttributes);
932
+ return {
933
+ dn: entry.dn,
934
+ name: entry.name,
935
+ flatName: entry.flatName,
936
+ trustDirection,
937
+ trustType,
938
+ trustAttributes,
939
+ direction: (0, trust_types_1.parseTrustDirection)(trustDirection),
940
+ type: (0, trust_types_1.parseTrustType)(trustType, trustAttributes),
941
+ ...parsed,
942
+ };
943
+ });
944
+ }
945
+ catch (error) {
946
+ logger_1.logger.debug('Could not fetch extended trust information', { error });
947
+ return [];
948
+ }
949
+ }
950
+ }
951
+ exports.JobRunner = JobRunner;
952
+ //# sourceMappingURL=job-runner.js.map