@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,637 @@
1
+ /**
2
+ * Permissions & ACL Security Vulnerability Detector
3
+ *
4
+ * Detects ACL-related vulnerabilities in AD.
5
+ * Story 1.7: AD Vulnerability Detection Engine
6
+ *
7
+ * Vulnerabilities detected (15):
8
+ * CRITICAL (1) - Phase 4:
9
+ * - ACL_DS_REPLICATION_GET_CHANGES
10
+ *
11
+ * HIGH (4):
12
+ * - ACL_GENERICALL
13
+ * - ACL_WRITEDACL
14
+ * - ACL_WRITEOWNER
15
+ * - ACL_SELF_MEMBERSHIP - Phase 4
16
+ *
17
+ * MEDIUM (10):
18
+ * - ACL_GENERICWRITE
19
+ * - ACL_FORCECHANGEPASSWORD
20
+ * - EVERYONE_IN_ACL
21
+ * - WRITESPN_ABUSE
22
+ * - GPO_LINK_POISONING
23
+ * - ADMINSDHOLDER_BACKDOOR
24
+ * - ACL_ADD_MEMBER - Phase 4
25
+ * - ACL_WRITE_PROPERTY_EXTENDED - Phase 4
26
+ * - ACL_USER_FORCE_CHANGE_PASSWORD - Phase 4
27
+ * - ACL_COMPUTER_WRITE_VALIDATED_DNS - Phase 4
28
+ */
29
+
30
+ import { Finding } from '../../../../types/finding.types';
31
+ import { AclEntry } from '../../../../types/ad.types';
32
+
33
+ /**
34
+ * Helper to get unique objects from ACL entries
35
+ */
36
+ function getUniqueObjects(entries: AclEntry[]): string[] {
37
+ return [...new Set(entries.map((ace) => ace.objectDn))];
38
+ }
39
+
40
+ /**
41
+ * Check for GenericAll permission on sensitive objects
42
+ *
43
+ * GENERIC_ALL can be stored as:
44
+ * - 0x10000000 (raw GENERIC_ALL)
45
+ * - 0x000F01FF (Full Control for AD objects - mapped rights)
46
+ */
47
+ export function detectAclGenericAll(aclEntries: AclEntry[], includeDetails: boolean): Finding {
48
+ // GENERIC_ALL raw value
49
+ const GENERIC_ALL = 0x10000000;
50
+ // Full control mask for AD objects (all specific AD rights + standard rights)
51
+ // This is what GENERIC_ALL maps to when stored in AD ACLs
52
+ const AD_FULL_CONTROL = 0x000f01ff;
53
+
54
+ const affected = aclEntries.filter((ace) => {
55
+ // Check for raw GENERIC_ALL
56
+ if ((ace.accessMask & GENERIC_ALL) !== 0) return true;
57
+ // Check for Full Control (GENERIC_ALL mapped to AD rights)
58
+ // The mask 0x000F01FF includes: DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | all DS rights
59
+ return (ace.accessMask & AD_FULL_CONTROL) === AD_FULL_CONTROL;
60
+ });
61
+
62
+ const uniqueObjects = getUniqueObjects(affected);
63
+ const totalInstances = affected.length;
64
+
65
+ return {
66
+ type: 'ACL_GENERICALL',
67
+ severity: 'high',
68
+ category: 'permissions',
69
+ title: 'ACL GenericAll',
70
+ description: 'GenericAll permission on sensitive AD objects. Full control over object (reset passwords, modify groups, etc.).',
71
+ count: uniqueObjects.length,
72
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
73
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Check for WriteDACL permission on sensitive objects
79
+ */
80
+ export function detectAclWriteDacl(aclEntries: AclEntry[], includeDetails: boolean): Finding {
81
+ const WRITE_DACL = 0x00040000;
82
+
83
+ const affected = aclEntries.filter((ace) => {
84
+ return (ace.accessMask & WRITE_DACL) !== 0;
85
+ });
86
+
87
+ const uniqueObjects = getUniqueObjects(affected);
88
+ const totalInstances = affected.length;
89
+
90
+ return {
91
+ type: 'ACL_WRITEDACL',
92
+ severity: 'high',
93
+ category: 'permissions',
94
+ title: 'ACL WriteDACL',
95
+ description: "WriteDACL permission on sensitive AD objects. Can modify object's security descriptor to grant additional permissions.",
96
+ count: uniqueObjects.length,
97
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
98
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Check for WriteOwner permission on sensitive objects
104
+ */
105
+ export function detectAclWriteOwner(aclEntries: AclEntry[], includeDetails: boolean): Finding {
106
+ const WRITE_OWNER = 0x00080000;
107
+
108
+ const affected = aclEntries.filter((ace) => {
109
+ return (ace.accessMask & WRITE_OWNER) !== 0;
110
+ });
111
+
112
+ const uniqueObjects = getUniqueObjects(affected);
113
+ const totalInstances = affected.length;
114
+
115
+ return {
116
+ type: 'ACL_WRITEOWNER',
117
+ severity: 'high',
118
+ category: 'permissions',
119
+ title: 'ACL WriteOwner',
120
+ description: 'WriteOwner permission on sensitive AD objects. Can take ownership of object and modify permissions.',
121
+ count: uniqueObjects.length,
122
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
123
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Check for GenericWrite permission on sensitive objects
129
+ */
130
+ export function detectAclGenericWrite(aclEntries: AclEntry[], includeDetails: boolean): Finding {
131
+ const GENERIC_WRITE = 0x40000000;
132
+
133
+ const affected = aclEntries.filter((ace) => {
134
+ return (ace.accessMask & GENERIC_WRITE) !== 0;
135
+ });
136
+
137
+ const uniqueObjects = getUniqueObjects(affected);
138
+ const totalInstances = affected.length;
139
+
140
+ return {
141
+ type: 'ACL_GENERICWRITE',
142
+ severity: 'medium',
143
+ category: 'permissions',
144
+ title: 'ACL GenericWrite',
145
+ description: 'GenericWrite permission on sensitive AD objects. Can modify many object attributes.',
146
+ count: uniqueObjects.length,
147
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
148
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
149
+ };
150
+ }
151
+
152
+ /**
153
+ * Check for ForceChangePassword extended right
154
+ */
155
+ export function detectAclForceChangePassword(aclEntries: AclEntry[], includeDetails: boolean): Finding {
156
+ const FORCE_CHANGE_PASSWORD_GUID = '00299570-246d-11d0-a768-00aa006e0529';
157
+
158
+ const affected = aclEntries.filter((ace) => {
159
+ return ace.objectType === FORCE_CHANGE_PASSWORD_GUID;
160
+ });
161
+
162
+ const uniqueObjects = getUniqueObjects(affected);
163
+ const totalInstances = affected.length;
164
+
165
+ return {
166
+ type: 'ACL_FORCECHANGEPASSWORD',
167
+ severity: 'medium',
168
+ category: 'permissions',
169
+ title: 'ACL Force Change Password',
170
+ description: 'ExtendedRight to force password change on user accounts. Can reset passwords without knowing current password.',
171
+ count: uniqueObjects.length,
172
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
173
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
174
+ };
175
+ }
176
+
177
+ /**
178
+ * Check for Everyone/Authenticated Users with write permissions
179
+ */
180
+ export function detectEveryoneInAcl(aclEntries: AclEntry[], includeDetails: boolean): Finding {
181
+ const EVERYONE_SID = 'S-1-1-0';
182
+ const AUTHENTICATED_USERS_SID = 'S-1-5-11';
183
+ const WRITE_MASK = 0x00020000; // ADS_RIGHT_DS_WRITE_PROP
184
+
185
+ const affected = aclEntries.filter((ace) => {
186
+ const isEveryone = ace.trustee === EVERYONE_SID || ace.trustee === AUTHENTICATED_USERS_SID;
187
+ const hasWrite = (ace.accessMask & WRITE_MASK) !== 0;
188
+ return isEveryone && hasWrite;
189
+ });
190
+
191
+ const uniqueObjects = getUniqueObjects(affected);
192
+ const totalInstances = affected.length;
193
+
194
+ return {
195
+ type: 'EVERYONE_IN_ACL',
196
+ severity: 'medium',
197
+ category: 'permissions',
198
+ title: 'Everyone in ACL',
199
+ description: 'Everyone or Authenticated Users with write permissions in ACL. Overly permissive access.',
200
+ count: uniqueObjects.length,
201
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
202
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
203
+ };
204
+ }
205
+
206
+ /**
207
+ * Check for WriteProperty permission for servicePrincipalName
208
+ */
209
+ export function detectWriteSpnAbuse(aclEntries: AclEntry[], includeDetails: boolean): Finding {
210
+ const SPN_PROPERTY_GUID = 'f3a64788-5306-11d1-a9c5-0000f80367c1';
211
+
212
+ const affected = aclEntries.filter((ace) => {
213
+ return ace.objectType === SPN_PROPERTY_GUID;
214
+ });
215
+
216
+ const uniqueObjects = getUniqueObjects(affected);
217
+ const totalInstances = affected.length;
218
+
219
+ return {
220
+ type: 'WRITESPN_ABUSE',
221
+ severity: 'medium',
222
+ category: 'permissions',
223
+ title: 'Write SPN Abuse',
224
+ description: 'WriteProperty permission for servicePrincipalName attribute. Can set SPNs for targeted Kerberoasting.',
225
+ count: uniqueObjects.length,
226
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
227
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Check for weak ACLs on Group Policy Objects
233
+ */
234
+ export function detectGpoLinkPoisoning(aclEntries: AclEntry[], includeDetails: boolean): Finding {
235
+ const GENERIC_WRITE = 0x40000000;
236
+ const GENERIC_ALL = 0x10000000;
237
+ const WRITE_DACL = 0x00040000;
238
+
239
+ const affected = aclEntries.filter((ace) => {
240
+ const isGpo = ace.objectDn.includes('CN=Policies,CN=System');
241
+ const hasDangerousPermission =
242
+ (ace.accessMask & GENERIC_ALL) !== 0 ||
243
+ (ace.accessMask & GENERIC_WRITE) !== 0 ||
244
+ (ace.accessMask & WRITE_DACL) !== 0;
245
+
246
+ return isGpo && hasDangerousPermission;
247
+ });
248
+
249
+ const uniqueObjects = getUniqueObjects(affected);
250
+ const totalInstances = affected.length;
251
+
252
+ return {
253
+ type: 'GPO_LINK_POISONING',
254
+ severity: 'medium',
255
+ category: 'permissions',
256
+ title: 'GPO Link Poisoning',
257
+ description: 'Weak ACLs on Group Policy Objects. Can modify GPO to execute code on targeted systems.',
258
+ count: uniqueObjects.length,
259
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
260
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
261
+ };
262
+ }
263
+
264
+ /**
265
+ * Check for unexpected ACL on AdminSDHolder object
266
+ */
267
+ export function detectAdminSdHolderBackdoor(aclEntries: AclEntry[], includeDetails: boolean): Finding {
268
+ const affected = aclEntries.filter((ace) => {
269
+ return ace.objectDn.includes('CN=AdminSDHolder,CN=System');
270
+ });
271
+
272
+ const uniqueObjects = getUniqueObjects(affected);
273
+ const totalInstances = affected.length;
274
+
275
+ return {
276
+ type: 'ADMINSDHOLDER_BACKDOOR',
277
+ severity: 'medium',
278
+ category: 'permissions',
279
+ title: 'AdminSDHolder Backdoor',
280
+ description: 'Unexpected ACL on AdminSDHolder object. Persistent permissions on admin accounts.',
281
+ count: uniqueObjects.length,
282
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
283
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
284
+ };
285
+ }
286
+
287
+ /**
288
+ * Detect Self-membership rights on groups
289
+ *
290
+ * Self-membership allows adding oneself to a group, enabling privilege escalation.
291
+ *
292
+ * @param aclEntries - Array of ACL entries
293
+ * @param includeDetails - Whether to include affected entity details
294
+ * @returns Finding for ACL_SELF_MEMBERSHIP
295
+ */
296
+ export function detectAclSelfMembership(aclEntries: AclEntry[], includeDetails: boolean): Finding {
297
+ // Self-membership GUID: bf9679c0-0de6-11d0-a285-00aa003049e2
298
+ const SELF_MEMBERSHIP_GUID = 'bf9679c0-0de6-11d0-a285-00aa003049e2';
299
+ const WRITE_SELF = 0x8; // ADS_RIGHT_DS_SELF
300
+
301
+ const affected = aclEntries.filter((ace) => {
302
+ const hasWriteSelf = (ace.accessMask & WRITE_SELF) !== 0;
303
+ const isSelfMembership =
304
+ ace.objectType?.toLowerCase() === SELF_MEMBERSHIP_GUID ||
305
+ ace.objectType?.toLowerCase().includes('member');
306
+ return hasWriteSelf || isSelfMembership;
307
+ });
308
+
309
+ const uniqueObjects = getUniqueObjects(affected);
310
+ const totalInstances = affected.length;
311
+
312
+ return {
313
+ type: 'ACL_SELF_MEMBERSHIP',
314
+ severity: 'high',
315
+ category: 'permissions',
316
+ title: 'Self-Membership Rights',
317
+ description:
318
+ 'Principals with self-membership rights on groups. ' +
319
+ 'Allows adding oneself to a group, potentially gaining elevated privileges.',
320
+ count: uniqueObjects.length,
321
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
322
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
323
+ };
324
+ }
325
+
326
+ /**
327
+ * Detect Add-Member rights on groups
328
+ *
329
+ * Add-Member allows adding arbitrary users to groups.
330
+ *
331
+ * @param aclEntries - Array of ACL entries
332
+ * @param includeDetails - Whether to include affected entity details
333
+ * @returns Finding for ACL_ADD_MEMBER
334
+ */
335
+ export function detectAclAddMember(aclEntries: AclEntry[], includeDetails: boolean): Finding {
336
+ // Member attribute GUID: bf9679c0-0de6-11d0-a285-00aa003049e2
337
+ const MEMBER_GUID = 'bf9679c0-0de6-11d0-a285-00aa003049e2';
338
+ const WRITE_PROPERTY = 0x20;
339
+
340
+ const affected = aclEntries.filter((ace) => {
341
+ const hasWriteProperty = (ace.accessMask & WRITE_PROPERTY) !== 0;
342
+ const isMemberProperty = ace.objectType?.toLowerCase() === MEMBER_GUID;
343
+ return hasWriteProperty && isMemberProperty;
344
+ });
345
+
346
+ const uniqueObjects = getUniqueObjects(affected);
347
+ const totalInstances = affected.length;
348
+
349
+ return {
350
+ type: 'ACL_ADD_MEMBER',
351
+ severity: 'medium',
352
+ category: 'permissions',
353
+ title: 'Add-Member Rights on Groups',
354
+ description:
355
+ 'Principals with rights to add members to groups. ' +
356
+ 'Can be abused to add accounts to privileged groups.',
357
+ count: uniqueObjects.length,
358
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
359
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
360
+ };
361
+ }
362
+
363
+ /**
364
+ * Detect extended write property rights
365
+ *
366
+ * Extended write property rights can be abused for various attacks.
367
+ *
368
+ * @param aclEntries - Array of ACL entries
369
+ * @param includeDetails - Whether to include affected entity details
370
+ * @returns Finding for ACL_WRITE_PROPERTY_EXTENDED
371
+ */
372
+ export function detectAclWritePropertyExtended(
373
+ aclEntries: AclEntry[],
374
+ includeDetails: boolean
375
+ ): Finding {
376
+ // Common dangerous extended properties
377
+ const DANGEROUS_PROPERTIES = [
378
+ '00299570-246d-11d0-a768-00aa006e0529', // User-Force-Change-Password
379
+ 'bf967a68-0de6-11d0-a285-00aa003049e2', // Script-Path
380
+ 'bf967950-0de6-11d0-a285-00aa003049e2', // Home-Directory
381
+ '5f202010-79a5-11d0-9020-00c04fc2d4cf', // ms-DS-Key-Credential-Link (Shadow Credentials)
382
+ ];
383
+
384
+ const WRITE_PROPERTY = 0x20;
385
+
386
+ const affected = aclEntries.filter((ace) => {
387
+ const hasWriteProperty = (ace.accessMask & WRITE_PROPERTY) !== 0;
388
+ const isDangerousProperty =
389
+ ace.objectType && DANGEROUS_PROPERTIES.includes(ace.objectType.toLowerCase());
390
+ return hasWriteProperty && isDangerousProperty;
391
+ });
392
+
393
+ const uniqueObjects = getUniqueObjects(affected);
394
+ const totalInstances = affected.length;
395
+
396
+ return {
397
+ type: 'ACL_WRITE_PROPERTY_EXTENDED',
398
+ severity: 'medium',
399
+ category: 'permissions',
400
+ title: 'Extended Write Property Rights',
401
+ description:
402
+ 'Principals with dangerous extended write property rights. ' +
403
+ 'Can modify script paths, home directories, or key credentials.',
404
+ count: uniqueObjects.length,
405
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
406
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
407
+ };
408
+ }
409
+
410
+ /**
411
+ * Detect DS-Replication-Get-Changes rights (DCSync capability)
412
+ *
413
+ * These rights allow extracting password hashes from the domain.
414
+ *
415
+ * @param aclEntries - Array of ACL entries
416
+ * @param includeDetails - Whether to include affected entity details
417
+ * @returns Finding for ACL_DS_REPLICATION_GET_CHANGES
418
+ */
419
+ export function detectAclDsReplicationGetChanges(
420
+ aclEntries: AclEntry[],
421
+ includeDetails: boolean
422
+ ): Finding {
423
+ // DS-Replication-Get-Changes: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
424
+ // DS-Replication-Get-Changes-All: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
425
+ const REPLICATION_GUIDS = [
426
+ '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2',
427
+ '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2',
428
+ ];
429
+
430
+ const affected = aclEntries.filter((ace) => {
431
+ return (
432
+ ace.objectType && REPLICATION_GUIDS.includes(ace.objectType.toLowerCase())
433
+ );
434
+ });
435
+
436
+ const uniqueObjects = getUniqueObjects(affected);
437
+ const totalInstances = affected.length;
438
+
439
+ return {
440
+ type: 'ACL_DS_REPLICATION_GET_CHANGES',
441
+ severity: 'critical',
442
+ category: 'permissions',
443
+ title: 'DS-Replication-Get-Changes Rights (DCSync)',
444
+ description:
445
+ 'Non-standard principals with directory replication rights. ' +
446
+ 'Enables DCSync attacks to extract all password hashes from the domain.',
447
+ count: uniqueObjects.length,
448
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
449
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
450
+ details: {
451
+ risk: 'Complete domain compromise through password hash extraction.',
452
+ recommendation: 'Remove replication rights from all non-DC accounts.',
453
+ },
454
+ };
455
+ }
456
+
457
+ /**
458
+ * Detect User-Force-Change-Password rights
459
+ *
460
+ * This right allows resetting user passwords without knowing the current password.
461
+ *
462
+ * @param aclEntries - Array of ACL entries
463
+ * @param includeDetails - Whether to include affected entity details
464
+ * @returns Finding for ACL_USER_FORCE_CHANGE_PASSWORD
465
+ */
466
+ export function detectAclUserForceChangePassword(
467
+ aclEntries: AclEntry[],
468
+ includeDetails: boolean
469
+ ): Finding {
470
+ // User-Force-Change-Password: 00299570-246d-11d0-a768-00aa006e0529
471
+ const FORCE_CHANGE_PASSWORD_GUID = '00299570-246d-11d0-a768-00aa006e0529';
472
+
473
+ const affected = aclEntries.filter((ace) => {
474
+ return ace.objectType?.toLowerCase() === FORCE_CHANGE_PASSWORD_GUID;
475
+ });
476
+
477
+ const uniqueObjects = getUniqueObjects(affected);
478
+ const totalInstances = affected.length;
479
+
480
+ return {
481
+ type: 'ACL_USER_FORCE_CHANGE_PASSWORD',
482
+ severity: 'medium',
483
+ category: 'permissions',
484
+ title: 'User-Force-Change-Password Rights',
485
+ description:
486
+ 'Principals with rights to force password change on user accounts. ' +
487
+ 'Can reset passwords to take over accounts.',
488
+ count: uniqueObjects.length,
489
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
490
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
491
+ };
492
+ }
493
+
494
+ /**
495
+ * Detect Validated-Write-DNS rights on computers
496
+ *
497
+ * This right allows modifying DNS records for computers.
498
+ *
499
+ * @param aclEntries - Array of ACL entries
500
+ * @param includeDetails - Whether to include affected entity details
501
+ * @returns Finding for ACL_COMPUTER_WRITE_VALIDATED_DNS
502
+ */
503
+ export function detectAclComputerWriteValidatedDns(
504
+ aclEntries: AclEntry[],
505
+ includeDetails: boolean
506
+ ): Finding {
507
+ // Validated-Write to DNS-Host-Name: 72e39547-7b18-11d1-adef-00c04fd8d5cd
508
+ const VALIDATED_DNS_GUID = '72e39547-7b18-11d1-adef-00c04fd8d5cd';
509
+
510
+ const affected = aclEntries.filter((ace) => {
511
+ const isComputerObject = ace.objectDn.toLowerCase().includes('cn=computers');
512
+ const hasDnsRight = ace.objectType?.toLowerCase() === VALIDATED_DNS_GUID;
513
+ return isComputerObject && hasDnsRight;
514
+ });
515
+
516
+ const uniqueObjects = getUniqueObjects(affected);
517
+ const totalInstances = affected.length;
518
+
519
+ return {
520
+ type: 'ACL_COMPUTER_WRITE_VALIDATED_DNS',
521
+ severity: 'medium',
522
+ category: 'permissions',
523
+ title: 'Validated-Write-DNS on Computers',
524
+ description:
525
+ 'Principals with rights to modify DNS host names on computer objects. ' +
526
+ 'Can be used for DNS spoofing and MITM attacks.',
527
+ count: uniqueObjects.length,
528
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
529
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
530
+ };
531
+ }
532
+
533
+ /**
534
+ * Check for GenericAll permission on computer objects
535
+ * PingCastle: Computer_ACL_GenericAll
536
+ *
537
+ * @param aclEntries - Array of ACL entries
538
+ * @param includeDetails - Whether to include affected entity details
539
+ * @param computerDns - Optional array of computer DNs for accurate matching
540
+ */
541
+ export function detectComputerAclGenericAll(
542
+ aclEntries: AclEntry[],
543
+ includeDetails: boolean,
544
+ computerDns?: string[]
545
+ ): Finding {
546
+ // GENERIC_ALL raw value
547
+ const GENERIC_ALL = 0x10000000;
548
+ // Full control mask for AD objects (all specific AD rights + standard rights)
549
+ const AD_FULL_CONTROL = 0x000f01ff;
550
+
551
+ // Build a Set of lowercase computer DNs for fast lookup
552
+ const computerDnSet = new Set(
553
+ computerDns ? computerDns.map((dn) => dn.toLowerCase()) : []
554
+ );
555
+
556
+ // Filter ACLs targeting computer objects
557
+ const computerAcls = aclEntries.filter((ace) => {
558
+ const dn = ace.objectDn.toLowerCase();
559
+
560
+ // If we have a list of computer DNs, use exact matching
561
+ if (computerDnSet.size > 0) {
562
+ return computerDnSet.has(dn);
563
+ }
564
+
565
+ // Fallback: heuristic detection (less accurate)
566
+ // Computer accounts end with $ in their sAMAccountName (which may appear in CN)
567
+ const cnMatch = dn.match(/cn=([^,]+)/i);
568
+ if (cnMatch && cnMatch[1] && cnMatch[1].endsWith('$')) {
569
+ return true;
570
+ }
571
+ // Also check for computer-related OUs
572
+ return (
573
+ dn.includes('ou=computers') ||
574
+ dn.includes('ou=workstations') ||
575
+ dn.includes('ou=servers') ||
576
+ dn.includes('cn=computers,')
577
+ );
578
+ });
579
+
580
+ const affected = computerAcls.filter((ace) => {
581
+ // Check for raw GENERIC_ALL
582
+ if ((ace.accessMask & GENERIC_ALL) !== 0) return true;
583
+ // Check for Full Control (GENERIC_ALL mapped to AD rights)
584
+ return (ace.accessMask & AD_FULL_CONTROL) === AD_FULL_CONTROL;
585
+ });
586
+
587
+ const uniqueObjects = getUniqueObjects(affected);
588
+ const totalInstances = affected.length;
589
+
590
+ return {
591
+ type: 'COMPUTER_ACL_GENERICALL',
592
+ severity: 'high',
593
+ category: 'permissions',
594
+ title: 'Computer ACL GenericAll',
595
+ description:
596
+ 'GenericAll permission on computer objects. Attacker with this permission can take over the computer, ' +
597
+ 'configure Resource-Based Constrained Delegation (RBCD), or extract credentials.',
598
+ count: uniqueObjects.length,
599
+ totalInstances: totalInstances !== uniqueObjects.length ? totalInstances : undefined,
600
+ affectedEntities: includeDetails ? uniqueObjects : undefined,
601
+ };
602
+ }
603
+
604
+ /**
605
+ * Detect all permission-related vulnerabilities
606
+ *
607
+ * @param aclEntries - Array of ACL entries
608
+ * @param includeDetails - Whether to include affected entity details
609
+ * @param computerDns - Optional array of computer DNs for accurate COMPUTER_ACL_GENERICALL detection
610
+ */
611
+ export function detectPermissionsVulnerabilities(
612
+ aclEntries: AclEntry[],
613
+ includeDetails: boolean,
614
+ computerDns?: string[]
615
+ ): Finding[] {
616
+ return [
617
+ // High
618
+ detectAclGenericAll(aclEntries, includeDetails),
619
+ detectComputerAclGenericAll(aclEntries, includeDetails, computerDns),
620
+ detectAclWriteDacl(aclEntries, includeDetails),
621
+ detectAclWriteOwner(aclEntries, includeDetails),
622
+ // Medium
623
+ detectAclGenericWrite(aclEntries, includeDetails),
624
+ detectAclForceChangePassword(aclEntries, includeDetails),
625
+ detectEveryoneInAcl(aclEntries, includeDetails),
626
+ detectWriteSpnAbuse(aclEntries, includeDetails),
627
+ detectGpoLinkPoisoning(aclEntries, includeDetails),
628
+ detectAdminSdHolderBackdoor(aclEntries, includeDetails),
629
+ // Phase 4: Advanced ACL detections
630
+ detectAclSelfMembership(aclEntries, includeDetails),
631
+ detectAclAddMember(aclEntries, includeDetails),
632
+ detectAclWritePropertyExtended(aclEntries, includeDetails),
633
+ detectAclDsReplicationGetChanges(aclEntries, includeDetails),
634
+ detectAclUserForceChangePassword(aclEntries, includeDetails),
635
+ detectAclComputerWriteValidatedDns(aclEntries, includeDetails),
636
+ ].filter((finding) => finding.count > 0);
637
+ }