├── .gitignore ├── Configuration_templates ├── Get-RpcFWEvents.ps1 ├── RpcFw.conf.AuditOnly ├── RpcFw.conf.Both ├── RpcFw.conf.FiltersOnly └── RpcFw.conf.FirewallOnly ├── LICENSE ├── README.md ├── RPCFW.sln ├── rpcFirewall ├── config.hpp ├── dllmain.cpp ├── framework.h ├── packages.config ├── pch.cpp ├── pch.h ├── rpcFirewall.vcxproj ├── rpcFirewall.vcxproj.filters └── rpcWrappers.hpp ├── rpcFwManager ├── EventSink.cpp ├── EventSink.h ├── Injections.cpp ├── Injections.h ├── RPCMgr.cpp ├── RpcFw.conf ├── common.cpp ├── common.h ├── elevation.cpp ├── elevation.h ├── packages.config ├── resource.h ├── rpcFwManager.vcxproj ├── rpcFwManager.vcxproj.filters ├── rpcHooks.cpp ├── rpcfilters.cpp ├── rpcfilters.h ├── service.cpp ├── service.h └── stdafx.h └── rpcMessages ├── MSG00409.bin ├── Messages.h ├── Messages.mc ├── Messages.rc ├── Messages_ENU.bin ├── Messages_GER.bin ├── framework.h ├── pch.cpp ├── pch.h ├── resource.h ├── rpcMessages.cpp ├── rpcMessages.h ├── rpcMessages.vcxproj └── rpcMessages.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Nuget personal access tokens and Credentials 210 | nuget.config 211 | 212 | # Microsoft Azure Build Output 213 | csx/ 214 | *.build.csdef 215 | 216 | # Microsoft Azure Emulator 217 | ecf/ 218 | rcf/ 219 | 220 | # Windows Store app package directories and files 221 | AppPackages/ 222 | BundleArtifacts/ 223 | Package.StoreAssociation.xml 224 | _pkginfo.txt 225 | *.appx 226 | *.appxbundle 227 | *.appxupload 228 | 229 | # Visual Studio cache files 230 | # files ending in .cache can be ignored 231 | *.[Cc]ache 232 | # but keep track of directories ending in .cache 233 | !?*.[Cc]ache/ 234 | 235 | # Others 236 | ClientBin/ 237 | ~$* 238 | *~ 239 | *.dbmdl 240 | *.dbproj.schemaview 241 | *.jfm 242 | *.pfx 243 | *.publishsettings 244 | orleans.codegen.cs 245 | 246 | # Including strong name files can present a security risk 247 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 248 | #*.snk 249 | 250 | # Since there are multiple workflows, uncomment next line to ignore bower_components 251 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 252 | #bower_components/ 253 | 254 | # RIA/Silverlight projects 255 | Generated_Code/ 256 | 257 | # Backup & report files from converting an old project file 258 | # to a newer Visual Studio version. Backup files are not needed, 259 | # because we have git ;-) 260 | _UpgradeReport_Files/ 261 | Backup*/ 262 | UpgradeLog*.XML 263 | UpgradeLog*.htm 264 | ServiceFabricBackup/ 265 | *.rptproj.bak 266 | 267 | # SQL Server files 268 | *.mdf 269 | *.ldf 270 | *.ndf 271 | 272 | # Business Intelligence projects 273 | *.rdl.data 274 | *.bim.layout 275 | *.bim_*.settings 276 | *.rptproj.rsuser 277 | *- [Bb]ackup.rdl 278 | *- [Bb]ackup ([0-9]).rdl 279 | *- [Bb]ackup ([0-9][0-9]).rdl 280 | 281 | # Microsoft Fakes 282 | FakesAssemblies/ 283 | 284 | # GhostDoc plugin setting file 285 | *.GhostDoc.xml 286 | 287 | # Node.js Tools for Visual Studio 288 | .ntvs_analysis.dat 289 | node_modules/ 290 | 291 | # Visual Studio 6 build log 292 | *.plg 293 | 294 | # Visual Studio 6 workspace options file 295 | *.opt 296 | 297 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 298 | *.vbw 299 | 300 | # Visual Studio LightSwitch build output 301 | **/*.HTMLClient/GeneratedArtifacts 302 | **/*.DesktopClient/GeneratedArtifacts 303 | **/*.DesktopClient/ModelManifest.xml 304 | **/*.Server/GeneratedArtifacts 305 | **/*.Server/ModelManifest.xml 306 | _Pvt_Extensions 307 | 308 | # Paket dependency manager 309 | .paket/paket.exe 310 | paket-files/ 311 | 312 | # FAKE - F# Make 313 | .fake/ 314 | 315 | # CodeRush personal settings 316 | .cr/personal 317 | 318 | # Python Tools for Visual Studio (PTVS) 319 | __pycache__/ 320 | *.pyc 321 | 322 | # Cake - Uncomment if you are using it 323 | # tools/** 324 | # !tools/packages.config 325 | 326 | # Tabs Studio 327 | *.tss 328 | 329 | # Telerik's JustMock configuration file 330 | *.jmconfig 331 | 332 | # BizTalk build output 333 | *.btp.cs 334 | *.btm.cs 335 | *.odx.cs 336 | *.xsd.cs 337 | 338 | # OpenCover UI analysis results 339 | OpenCover/ 340 | 341 | # Azure Stream Analytics local run output 342 | ASALocalRun/ 343 | 344 | # MSBuild Binary and Structured Log 345 | *.binlog 346 | 347 | # NVidia Nsight GPU debugger configuration file 348 | *.nvuser 349 | 350 | # MFractors (Xamarin productivity tool) working folder 351 | .mfractor/ 352 | 353 | # Local History for Visual Studio 354 | .localhistory/ 355 | 356 | # BeatPulse healthcheck temp database 357 | healthchecksdb 358 | 359 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 360 | MigrationBackup/ 361 | 362 | # Ionide (cross platform F# VS Code tools) working folder 363 | .ionide/ 364 | 365 | # Fody - auto-generated XML schema 366 | FodyWeavers.xsd 367 | 368 | # VS Code files for those working on multiple tools 369 | .vscode/* 370 | !.vscode/settings.json 371 | !.vscode/tasks.json 372 | !.vscode/launch.json 373 | !.vscode/extensions.json 374 | *.code-workspace 375 | 376 | # Local History for Visual Studio Code 377 | .history/ 378 | 379 | # Windows Installer files from build outputs 380 | *.cab 381 | *.msi 382 | *.msix 383 | *.msm 384 | *.msp 385 | 386 | # JetBrains Rider 387 | .idea/ 388 | *.sln.iml 389 | /rpcFwManager/syshooks.h 390 | /rpcFwManager/syshooks.cpp 391 | -------------------------------------------------------------------------------- /Configuration_templates/Get-RpcFWEvents.ps1: -------------------------------------------------------------------------------- 1 | # Function to parse RPCFW logs 2 | function Parse-RPCFWLog { 3 | param ($Event) 4 | $action = if($Event.Keywords -band 0x10000000000000) {'Audit Failure'} elseif($Event.Keywords -band 0x20000000000000) {'Audit Success'} else {'Unknown'} 5 | return New-Object PSObject -Property @{ 6 | 'Log Source' = 'RPCFW' 7 | 'TimeCreated' = $Event.TimeCreated 8 | 'Endpoint' = [regex]::Match($Event.Message, 'Endpoint:\s*(.*?)($|\r\n)').Groups[1].Value 9 | 'InterfaceUuid' = [regex]::Match($Event.Message, 'InterfaceUuid:\s*(.*?)($|\r\n)').Groups[1].Value 10 | 'OpNum' = [regex]::Match($Event.Message, 'OpNum:\s*(.*?)($|\r\n)').Groups[1].Value 11 | 'Security ID' = [regex]::Match($Event.Message, 'Security ID:\s*(.*?)($|\r\n)').Groups[1].Value 12 | 'Client Network Address' = [regex]::Match($Event.Message, 'Client Network Address:\s*(.*?)($|\r\n)').Groups[1].Value 13 | 'Client Port' = [regex]::Match($Event.Message, 'Client Port:\s*(.*?)($|\r\n)').Groups[1].Value 14 | 'Protocol' = [regex]::Match($Event.Message, 'Protocol:\s*(.*?)($|\r\n)').Groups[1].Value 15 | 'Action' = $action 16 | } 17 | } 18 | 19 | function Parse-RPCFWSecurityLog { 20 | param ($Event) 21 | $action = if($Event.Keywords -band 0x10000000000000) {'Audit Failure'} elseif($Event.Keywords -band 0x20000000000000) {'Audit Success'} else {'Unknown'} 22 | return New-Object PSObject -Property @{ 23 | 'Log Source' = 'Security' 24 | 'TimeCreated' = $Event.TimeCreated 25 | 'Endpoint' = "" 26 | 'InterfaceUuid' = [regex]::Match($Event.Message, 'Interface UUID:\s*(.*?)($|\r\n)').Groups[1].Value 27 | 'OpNum' = "" 28 | 'Security ID' = [regex]::Match($Event.Message, 'SID:\s*(.*?)($|\r\n)').Groups[1].Value 29 | 'Client Network Address' = [regex]::Match($Event.Message, 'Remote IP Address:\s*(.*?)($|\r\n)').Groups[1].Value 30 | 'Client Port' = [regex]::Match($Event.Message, 'Remote Port:\s*(.*?)($|\r\n)').Groups[1].Value 31 | 'Protocol' = [regex]::Match($Event.Message, 'Protocol Sequence:\s*(.*?)($|\r\n)').Groups[1].Value 32 | 'Action' = $action 33 | } 34 | } 35 | 36 | # Retrieve and parse RPCFW events 37 | $RPCFWEvents = Get-WinEvent -LogName RPCFW -ErrorAction SilentlyContinue | ForEach-Object { Parse-RPCFWLog $_ } 38 | 39 | $RPCFWSecurityEvents = Get-WinEvent -FilterHashtable @{LogName='Security';ID=5712} -ErrorAction SilentlyContinue | ForEach-Object { Parse-RPCFWSecurityLog $_ } 40 | 41 | $CombinedEvents = $RPCFWSecurityEvents + $RPCFWEvents 42 | 43 | # Sort combined events by time 44 | $SortedEvents = $CombinedEvents | Sort-Object -Property TimeCreated 45 | 46 | # Export combined events to CSV 47 | $SortedEvents | Export-Csv -Path "RPCFW.csv" -NoTypeInformation 48 | 49 | 50 | # Retrieve and parse RPCFW events 51 | $RPCFWEvents = Get-WinEvent -LogName RPCFW -ErrorAction SilentlyContinue | ForEach-Object { Parse-RPCFWLog $_ } 52 | 53 | $RPCFWSecurityEvents = Get-WinEvent -FilterHashtable @{LogName='Security';ID=5712} -ErrorAction SilentlyContinue | ForEach-Object { Parse-RPCFWSecurityLog $_ } 54 | 55 | $CombinedEvents = $RPCFWSecurityEvents + $RPCFWEvents 56 | 57 | # Sort combined events by time 58 | $SortedEvents = $CombinedEvents | Sort-Object -Property TimeCreated 59 | 60 | # Export combined events to CSV 61 | $SortedEvents | Export-Csv -Path "RPCFW.csv" -NoTypeInformation 62 | -------------------------------------------------------------------------------- /Configuration_templates/RpcFw.conf.AuditOnly: -------------------------------------------------------------------------------- 1 | fw:action:allow audit:true 2 | flt:uuid:338cd001-2244-31f1-aaaa-900038001003 action:allow audit:true 3 | flt:uuid:99fcfec4-5260-101b-bbcb-00aa0021347a action:allow audit:true 4 | flt:uuid:000001A0-0000-0000-C000-000000000046 action:allow audit:true 5 | flt:uuid:00000131-0000-0000-C000-000000000046 action:allow audit:true 6 | flt:uuid:00000143-0000-0000-C000-000000000046 action:allow audit:true 7 | flt:uuid:1FF70682-0A51-30E8-076D-740BE8CEE98B action:allow audit:true 8 | flt:uuid:378E52B0-C0A9-11CF-822D-00AA0051E40F action:allow audit:true 9 | flt:uuid:86D35949-83C9-4044-B424-DB363231FD0C action:allow audit:true 10 | flt:uuid:f6beaff7-1e19-4fbb-9f8f-b89e2018337c action:allow audit:true 11 | flt:uuid:82273FDC-E32A-18C3-3F78-827929DC23EA action:allow audit:true 12 | flt:uuid:50abc2a4-574d-40b3-9d66-ee4fd5fba076 action:allow audit:true 13 | flt:uuid:76f03f96-cdfd-44fc-a22c-64950a001209 action:allow audit:true 14 | flt:uuid:12345678-1234-abcd-ef00-0123456789ab action:allow audit:true 15 | flt:uuid:0b6edbfa-4a24-4fc6-8a23-942b1eca65d1 action:allow audit:true 16 | flt:uuid:ae33069b-a2a8-46ee-a235-ddfd339be281 action:allow audit:true 17 | flt:uuid:88143fd0-c28d-4b2b-8fef-8d882f6a9390 action:allow audit:true 18 | flt:uuid:5ca4a760-ebb1-11cf-8611-00a0245420ed action:allow audit:true 19 | flt:uuid:484809d6-4239-471b-b5bc-61df8c23ac48 action:allow audit:true 20 | flt:uuid:bde95fdf-eee0-45de-9e12-e5a61cd0d4fe action:allow audit:true 21 | flt:uuid:497d95a6-2d27-4bf5-9bbd-a6046957133c action:allow audit:true 22 | flt:uuid:367ABB81-9844-35F1-AD32-98F038001003 action:allow audit:true 23 | flt:uuid:8f09f000-b7ed-11ce-bbd2-00001a181cad action:allow audit:true 24 | flt:uuid:20610036-fa22-11cf-9823-00a0c911e5df action:allow audit:true 25 | flt:uuid:66a2db1b-d706-11d0-a37b-00c04fc9da04 action:allow audit:true 26 | flt:uuid:66a2db20-d706-11d0-a37b-00c04fc9da04 action:allow audit:true 27 | flt:uuid:66a2db21-d706-11d0-a37b-00c04fc9da04 action:allow audit:true 28 | flt:uuid:66a2db22-d706-11d0-a37b-00c04fc9da04 action:allow audit:true 29 | flt:uuid:67e08fc2-2984-4b62-b92e-fc1aae64bbbb action:allow audit:true 30 | flt:uuid:6139d8a4-e508-4ebb-bac7-d7f275145897 action:allow audit:true 31 | flt:uuid:5ff9bdf6-bd91-4d8b-a614-d6317acc8dd8 action:allow audit:true 32 | flt:uuid:df1941c5-fe89-4e79-bf10-463657acf44d action:allow audit:true 33 | flt:uuid:c681d488-d850-11d0-8c52-00c04fd90f7e action:allow audit:true 34 | flt:uuid:11899a43-2b68-4a76-92e3-a3d6ad8c26ce action:allow audit:true 35 | flt:uuid:53b46b02-c73b-4a3e-8dee-b16b80672fc0 action:allow audit:true 36 | flt:uuid:1257B580-CE2F-4109-82D6-A9459D0BF6BC action:allow audit:true 37 | flt:uuid:12345778-1234-abcd-ef00-0123456789ac action:allow audit:true 38 | flt:uuid:f5cc5a18-4264-101a-8c59-08002b2f8426 action:allow audit:true 39 | flt:uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 action:allow audit:true 40 | flt:uuid:6bffd098-a112-3610-9833-46c3f87e345a action:allow audit:true 41 | flt:uuid:f5cc59b4-4264-101a-8c59-08002b2f8426 action:allow audit:true 42 | flt:uuid:5b821720-f63b-11d0-aad2-00c04fc324db action:allow audit:true 43 | flt:uuid:6BFFD098-A112-3610-9833-46C3F874532D action:allow audit:true 44 | flt:uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 action:allow audit:true 45 | flt:uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b action:allow audit:true 46 | flt:uuid:6bffd098-a112-3610-9833-012892020162 action:allow audit:true 47 | flt:uuid:e1af8308-5d1f-11c9-91a4-08002b14a0fa action:allow audit:true 48 | flt:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 action:allow audit:true 49 | flt:uuid:3919286a-b10c-11d0-9ba8-00c04fd92ef5 action:allow audit:true 50 | -------------------------------------------------------------------------------- /Configuration_templates/RpcFw.conf.Both: -------------------------------------------------------------------------------- 1 | Blocked to Any - RRP, DCOM, EVEN(6), DNSP, PAN, PAR, TSTS, SCMR,TSCH, EFSRPC,FSRVP: 2 | --------------------------------------------------------------------------------------------- 3 | flt:action:block audit:true uuid:338cd001-2244-31f1-aaaa-900038001003 4 | flt:action:block audit:true uuid:99fcfec4-5260-101b-bbcb-00aa0021347a 5 | flt:action:block audit:true uuid:000001A0-0000-0000-C000-000000000046 6 | flt:action:block audit:true uuid:00000131-0000-0000-C000-000000000046 7 | flt:action:block audit:true uuid:00000143-0000-0000-C000-000000000046 8 | flt:action:block audit:true uuid:1FF70682-0A51-30E8-076D-740BE8CEE98B 9 | flt:action:block audit:true uuid:378E52B0-C0A9-11CF-822D-00AA0051E40F 10 | flt:action:block audit:true uuid:86D35949-83C9-4044-B424-DB363231FD0C 11 | flt:action:block audit:true uuid:f6beaff7-1e19-4fbb-9f8f-b89e2018337c 12 | flt:action:block audit:true uuid:82273FDC-E32A-18C3-3F78-827929DC23EA 13 | flt:action:block audit:true uuid:50abc2a4-574d-40b3-9d66-ee4fd5fba076 14 | flt:action:block audit:true uuid:76f03f96-cdfd-44fc-a22c-64950a001209 15 | flt:action:block audit:true uuid:12345678-1234-abcd-ef00-0123456789ab 16 | flt:action:block audit:true uuid:0b6edbfa-4a24-4fc6-8a23-942b1eca65d1 17 | flt:action:block audit:true uuid:ae33069b-a2a8-46ee-a235-ddfd339be281 18 | flt:action:block audit:true uuid:88143fd0-c28d-4b2b-8fef-8d882f6a9390 19 | flt:action:block audit:true uuid:5ca4a760-ebb1-11cf-8611-00a0245420ed 20 | flt:action:block audit:true uuid:484809d6-4239-471b-b5bc-61df8c23ac48 21 | flt:action:block audit:true uuid:bde95fdf-eee0-45de-9e12-e5a61cd0d4fe 22 | flt:action:block audit:true uuid:497d95a6-2d27-4bf5-9bbd-a6046957133c 23 | flt:action:block audit:true uuid:367ABB81-9844-35F1-AD32-98F038001003 24 | flt:action:block audit:true uuid:8f09f000-b7ed-11ce-bbd2-00001a181cad 25 | flt:action:block audit:true uuid:20610036-fa22-11cf-9823-00a0c911e5df 26 | flt:action:block audit:true uuid:66a2db1b-d706-11d0-a37b-00c04fc9da04 27 | flt:action:block audit:true uuid:66a2db20-d706-11d0-a37b-00c04fc9da04 28 | flt:action:block audit:true uuid:66a2db21-d706-11d0-a37b-00c04fc9da04 29 | flt:action:block audit:true uuid:66a2db22-d706-11d0-a37b-00c04fc9da04 30 | flt:action:block audit:true uuid:67e08fc2-2984-4b62-b92e-fc1aae64bbbb 31 | flt:action:block audit:true uuid:6139d8a4-e508-4ebb-bac7-d7f275145897 32 | flt:action:block audit:true uuid:5ff9bdf6-bd91-4d8b-a614-d6317acc8dd8 33 | flt:action:block audit:true uuid:df1941c5-fe89-4e79-bf10-463657acf44d 34 | flt:action:block audit:true uuid:c681d488-d850-11d0-8c52-00c04fd90f7e 35 | flt:action:block audit:true uuid:11899a43-2b68-4a76-92e3-a3d6ad8c26ce 36 | flt:action:block audit:true uuid:53b46b02-c73b-4a3e-8dee-b16b80672fc0 37 | flt:action:block audit:true uuid:1257B580-CE2F-4109-82D6-A9459D0BF6BC 38 | flt:action:block audit:true uuid:a8e0653c-2744-4389-a61d-7373df8b2292 39 | flt:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 40 | flt:action:block audit:true uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b 41 | 42 | Block to BA - LSAD, SAMR, NPSO, SRVS, WKST,FRS,DFSNM,BRWSA: 43 | ---------------------------------------------------------------------------------------- 44 | flt:action:block audit:true sid:BA uuid:f5cc5a18-4264-101a-8c59-08002b2f8426 45 | flt:action:block audit:true sid:BA uuid:f5cc59b4-4264-101a-8c59-08002b2f8426 46 | flt:action:block audit:true sid:BA uuid:5b821720-f63b-11d0-aad2-00c04fc324db 47 | flt:action:block audit:true sid:BA uuid:6BFFD098-A112-3610-9833-46C3F874532D 48 | flt:action:block audit:true sid:BA uuid:6bffd098-a112-3610-9833-012892020162 49 | 50 | Open to Any - NRPC,EPM, BKRP, DRSR, DSSP, NPSO, SRVS, WKST,FRS,DFSNM,BRWSA: 51 | ------------------------------------------------------------------- 52 | fw:action:allow audit:true uuid:f5cc5a18-4264-101a-8c59-08002b2f8426 53 | fw:action:allow audit:true uuid:f5cc59b4-4264-101a-8c59-08002b2f8426 54 | fw:action:allow audit:true uuid:5b821720-f63b-11d0-aad2-00c04fc324db 55 | fw:action:allow audit:true uuid:6BFFD098-A112-3610-9833-46C3F874532D 56 | fw:action:allow audit:true uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b 57 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-012892020162 58 | fw:action:allow audit:true uuid:e1af8308-5d1f-11c9-91a4-08002b14a0fa 59 | fw:action:allow audit:true uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b 60 | 61 | Common DSSP operation 62 | -------------------------- 63 | fw:action:allow audit:true uuid:3919286a-b10c-11d0-9ba8-00c04fd92ef5 opnum:0 64 | 65 | BackupKey allow 66 | ----------------- 67 | fw:action:allow audit:true uuid:3dde7c30-165d-11d1-ab8f-00805f14db40 opnum:0 68 | 69 | Block write operations NRPC 70 | ---------------------------- 71 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:6 72 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:8 73 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:10 74 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:16 75 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:41 76 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:48 77 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:49 78 | fw:action:allow audit:true uuid:12345678-1234-abcd-ef00-01234567cffb 79 | 80 | Block corercive DFSNM operations 81 | ------------------------------------ 82 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:12 83 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:13 84 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:23 85 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:24 86 | fw:action:allow audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 87 | 88 | Allow Common WKST operations 89 | ---------------------------- 90 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-46c3f87e345a sid:BA 91 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-46c3f87e345a opnum:0 92 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-46c3f87e345a opnum:20 93 | 94 | Allow Common SRVS operations 95 | ---------------------------- 96 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 sid:BA 97 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:15 98 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:16 99 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:21 100 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:28 101 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:45 102 | 103 | Block LSAD write operations 104 | -------------------------------------------- 105 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:4 106 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:8 107 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:10 108 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:12 109 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:16 110 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:19 111 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:20 112 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:24 113 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:27 114 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:29 115 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:30 116 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:34 117 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:37 118 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:38 119 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:40 120 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:41 121 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:43 122 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:47 123 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:49 124 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:51 125 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:59 126 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:74 127 | fw:action:allow audit:true uuid:12345778-1234-abcd-ef00-0123456789ab 128 | 129 | Block SAMR write operations, Allow the rest 130 | -------------------------------------------- 131 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:2 132 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:9 133 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:10 134 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:12 135 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:14 136 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:21 137 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:22 138 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:23 139 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:24 140 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:26 141 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:29 142 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:30 143 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:31 144 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:32 145 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:35 146 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:37 147 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:38 148 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:45 149 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:50 150 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:52 151 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:53 152 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:54 153 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:55 154 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:58 155 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:66 156 | fw:action:allow audit:true uuid:12345778-1234-abcd-ef00-0123456789ac 157 | 158 | DCSync Protecion: : 159 | ----------------------------------------------- 160 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: action:allow audit:true 161 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: action:allow audit:true 162 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:0 action:allow audit:true 163 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:1 action:allow audit:true 164 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:13 action:allow audit:true 165 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:16 action:allow audit:true 166 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:12 action:allow audit:true 167 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:19 action:allow audit:true 168 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:29 action:allow audit:true 169 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:30 action:allow audit:true 170 | 171 | Default block: 172 | ----------------------------------------------- 173 | fw:action:block audit:true 174 | -------------------------------------------------------------------------------- /Configuration_templates/RpcFw.conf.FiltersOnly: -------------------------------------------------------------------------------- 1 | Blocked to Any - RRP, DCOM, EVEN(6), DNSP, PAN, PAR, TSTS, SCMR,TSCH, EFSRPC: 2 | --------------------------------------------------------------------------------------------- 3 | flt:action:block audit:true uuid:338cd001-2244-31f1-aaaa-900038001003 4 | flt:action:block audit:true uuid:99fcfec4-5260-101b-bbcb-00aa0021347a 5 | flt:action:block audit:true uuid:000001A0-0000-0000-C000-000000000046 6 | flt:action:block audit:true uuid:00000131-0000-0000-C000-000000000046 7 | flt:action:block audit:true uuid:00000143-0000-0000-C000-000000000046 8 | flt:action:block audit:true uuid:1FF70682-0A51-30E8-076D-740BE8CEE98B 9 | flt:action:block audit:true uuid:378E52B0-C0A9-11CF-822D-00AA0051E40F 10 | flt:action:block audit:true uuid:86D35949-83C9-4044-B424-DB363231FD0C 11 | flt:action:block audit:true uuid:f6beaff7-1e19-4fbb-9f8f-b89e2018337c 12 | flt:action:block audit:true uuid:82273FDC-E32A-18C3-3F78-827929DC23EA 13 | flt:action:block audit:true uuid:50abc2a4-574d-40b3-9d66-ee4fd5fba076 14 | flt:action:block audit:true uuid:76f03f96-cdfd-44fc-a22c-64950a001209 15 | flt:action:block audit:true uuid:12345678-1234-abcd-ef00-0123456789ab 16 | flt:action:block audit:true uuid:0b6edbfa-4a24-4fc6-8a23-942b1eca65d1 17 | flt:action:block audit:true uuid:ae33069b-a2a8-46ee-a235-ddfd339be281 18 | flt:action:block audit:true uuid:88143fd0-c28d-4b2b-8fef-8d882f6a9390 19 | flt:action:block audit:true uuid:5ca4a760-ebb1-11cf-8611-00a0245420ed 20 | flt:action:block audit:true uuid:484809d6-4239-471b-b5bc-61df8c23ac48 21 | flt:action:block audit:true uuid:bde95fdf-eee0-45de-9e12-e5a61cd0d4fe 22 | flt:action:block audit:true uuid:497d95a6-2d27-4bf5-9bbd-a6046957133c 23 | flt:action:block audit:true uuid:367ABB81-9844-35F1-AD32-98F038001003 24 | flt:action:block audit:true uuid:8f09f000-b7ed-11ce-bbd2-00001a181cad 25 | flt:action:block audit:true uuid:20610036-fa22-11cf-9823-00a0c911e5df 26 | flt:action:block audit:true uuid:66a2db1b-d706-11d0-a37b-00c04fc9da04 27 | flt:action:block audit:true uuid:66a2db20-d706-11d0-a37b-00c04fc9da04 28 | flt:action:block audit:true uuid:66a2db21-d706-11d0-a37b-00c04fc9da04 29 | flt:action:block audit:true uuid:66a2db22-d706-11d0-a37b-00c04fc9da04 30 | flt:action:block audit:true uuid:67e08fc2-2984-4b62-b92e-fc1aae64bbbb 31 | flt:action:block audit:true uuid:6139d8a4-e508-4ebb-bac7-d7f275145897 32 | flt:action:block audit:true uuid:5ff9bdf6-bd91-4d8b-a614-d6317acc8dd8 33 | flt:action:block audit:true uuid:df1941c5-fe89-4e79-bf10-463657acf44d 34 | flt:action:block audit:true uuid:c681d488-d850-11d0-8c52-00c04fd90f7e 35 | flt:action:block audit:true uuid:11899a43-2b68-4a76-92e3-a3d6ad8c26ce 36 | flt:action:block audit:true uuid:53b46b02-c73b-4a3e-8dee-b16b80672fc0 37 | flt:action:block audit:true uuid:1257B580-CE2F-4109-82D6-A9459D0BF6BC 38 | 39 | Block to BA - SAMR, NPSO, WKST,FRS,DFSNM,BRWSA: 40 | ---------------------------------------------------------------------------------------- 41 | flt:action:block audit:true sid:BA uuid:f5cc5a18-4264-101a-8c59-08002b2f8426 42 | flt:action:block audit:true sid:BA uuid:6bffd098-a112-3610-9833-46c3f87e345a 43 | flt:action:block audit:true sid:BA uuid:f5cc59b4-4264-101a-8c59-08002b2f8426 44 | flt:action:block audit:true sid:BA uuid:5b821720-f63b-11d0-aad2-00c04fc324db 45 | flt:action:block audit:true sid:BA uuid:6BFFD098-A112-3610-9833-46C3F874532D 46 | flt:action:block audit:true sid:BA uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 47 | flt:action:block audit:true sid:BA uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b 48 | flt:action:block audit:true sid:BA uuid:6bffd098-a112-3610-9833-012892020162 49 | 50 | Open to Any - NRPC,EPM, BKRP, DRSR, DSSP, SRVS 51 | ---------------------------------------------------------------------------------------- 52 | flt:action:allow audit:true uuid:e1af8308-5d1f-11c9-91a4-08002b14a0fa 53 | flt:action:allow audit:true uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 54 | flt:action:allow audit:true uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b 55 | flt:action:allow audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 56 | flt:action:allow audit:true uuid:3919286a-b10c-11d0-9ba8-00c04fd92ef5 57 | flt:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 58 | -------------------------------------------------------------------------------- /Configuration_templates/RpcFw.conf.FirewallOnly: -------------------------------------------------------------------------------- 1 | Open to Any - NRPC,EPM, BKRP, DRSR, DSSP, NPSO, SRVS, WKST,FRS,DFSNM,BRWSA: 2 | ------------------------------------------------------------------- 3 | fw:action:allow audit:true uuid:f5cc5a18-4264-101a-8c59-08002b2f8426 4 | fw:action:allow audit:true uuid:f5cc59b4-4264-101a-8c59-08002b2f8426 5 | fw:action:allow audit:true uuid:5b821720-f63b-11d0-aad2-00c04fc324db 6 | fw:action:allow audit:true uuid:6BFFD098-A112-3610-9833-46C3F874532D 7 | fw:action:allow audit:true uuid:51b836e8-484d-4d03-b0fc-22e265cb3f7b 8 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-012892020162 9 | fw:action:allow audit:true uuid:e1af8308-5d1f-11c9-91a4-08002b14a0fa 10 | 11 | Common DSSP operation 12 | -------------------------- 13 | fw:action:allow audit:true uuid:3919286a-b10c-11d0-9ba8-00c04fd92ef5 opnum:0 14 | 15 | BackupKey allow 16 | ----------------- 17 | fw:action:allow audit:true uuid:3dde7c30-165d-11d1-ab8f-00805f14db40 opnum:0 18 | 19 | Block write operations NRPC 20 | ---------------------------- 21 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:6 22 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:8 23 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:10 24 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:16 25 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:41 26 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:48 27 | fw:action:block audit:true uuid:12345678-1234-abcd-ef00-01234567cffb opnum:49 28 | fw:action:allow audit:true uuid:12345678-1234-abcd-ef00-01234567cffb 29 | 30 | Block corercive DFSNM operations 31 | ------------------------------------ 32 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:12 33 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:13 34 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:23 35 | fw:action:block audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 opnum:24 36 | fw:action:allow audit:true uuid:4fc742e0-4a10-11cf-8273-00aa004ae673 37 | 38 | Allow Common WKST operations 39 | ---------------------------- 40 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-46c3f87e345a opnum:0 41 | fw:action:allow audit:true uuid:6bffd098-a112-3610-9833-46c3f87e345a opnum:20 42 | 43 | Allow Common SRVS operations 44 | ---------------------------- 45 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 sid:BA 46 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:16 47 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:21 48 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:28 49 | fw:action:allow audit:true uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 opnum:45 50 | 51 | Block LSAD write operations 52 | -------------------------------------------- 53 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:4 54 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:8 55 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:10 56 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:12 57 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:16 58 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:19 59 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:20 60 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:24 61 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:27 62 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:29 63 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:30 64 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:34 65 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:37 66 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:38 67 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:40 68 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:41 69 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:43 70 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:47 71 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:49 72 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:51 73 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:59 74 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ab opnum:74 75 | fw:action:allow audit:true uuid:12345778-1234-abcd-ef00-0123456789ab 76 | 77 | Block SAMR write operations, Allow the rest 78 | -------------------------------------------- 79 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:2 80 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:9 81 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:10 82 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:12 83 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:14 84 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:21 85 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:22 86 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:23 87 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:24 88 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:26 89 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:29 90 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:30 91 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:31 92 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:32 93 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:35 94 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:37 95 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:38 96 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:45 97 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:50 98 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:52 99 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:53 100 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:54 101 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:55 102 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:58 103 | fw:action:block audit:true uuid:12345778-1234-abcd-ef00-0123456789ac opnum:66 104 | fw:action:allow audit:true uuid:12345778-1234-abcd-ef00-0123456789ac 105 | 106 | DCSync Protecion: : 107 | ----------------------------------------------- 108 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: action:allow audit:true 109 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: action:allow audit:true 110 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:0 action:allow audit:true 111 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:1 action:allow audit:true 112 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:13 action:allow audit:true 113 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:16 action:allow audit:true 114 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:12 action:allow audit:true 115 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:19 action:allow audit:true 116 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:29 action:allow audit:true 117 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:30 action:allow audit:true 118 | 119 | Default block: 120 | ----------------------------------------------- 121 | fw:action:block audit:true 122 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Work: RPC Firewall 2 | License: RPC Firewall License 3 | 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean Zero Networks Ltd., the copyright owner, and any entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 16 | 17 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 18 | 19 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 20 | 21 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 22 | 23 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 24 | 25 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 26 | 27 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work. 28 | 29 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 30 | 31 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 32 | 33 | 3. Grant of License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) license to make, have made, use, import, and otherwise transfer free of charge the Work. For clarification purposes, the License does not grant You the right to sale the Work or to make any commercial use of the Work. 34 | 35 | 36 | 4. If You institute litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory intellectual property infringement, then any licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 37 | 38 | 5. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 39 | 40 | (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and 41 | 42 | (b) You must cause any modified files to carry prominent notices stating that You changed the files; and 43 | 44 | (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 45 | 46 | (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained 47 | within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 48 | 49 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 50 | 51 | 6. It is hereby agreed and acknowledged that Contributions to the Work can be made exclusively under the terms of this license agreement, free of charge, and any use made in such Contributions by any party, including Licensor, may be made under the terms of this license agreement. 52 | 53 | 7. Submission of Contributions. Any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 54 | 55 | 8. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 56 | 57 | 9. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 58 | 59 | 10. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 60 | 61 | 11. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 62 | 63 | 12. Licensor may change the terms of this License from time to time, at its own discretion, by 64 | publishing the amended License or a notice notifying of such changes, on the same place where this License is published by Licensor. Your continued use of the Work after the changes have been implemented will constitute Your acceptance of the changes. 65 | 66 | 67 | END OF TERMS AND CONDITIONS 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/zeronetworks/rpcfirewall)](https://github.com/zeronetworks/rpcfirewall/releases/latest) 2 | ![GitHub all releases](https://img.shields.io/github/downloads/zeronetworks/rpcfirewall/total) 3 | 4 | # I Need More Information 5 | Check out our [RPC Firewall](https://zeronetworks.com/blog/the-ransomware-kill-switch-becomes-even-more-deadly-the-rpc-firewall-2-0-released/) blog post or our [BlackHat talk](https://www.youtube.com/watch?v=hz_YPIMeBMI) to gain better understanding of RPC, RPC attacks, and the solution: RPC Firewall. 6 | 7 | Join our [|Zero| Labs](https://join.slack.com/t/minus273celsius/shared_invite/zt-1ulg46s8x-N0P9sEzmv3SbYTlDXVSf2g) Slack Community workspace for any questions, issues, or simply to shout out. 8 | 9 | We would love to hear from you also via email (if you are that type of person). Contact us at [support@zeronetworks.com](mailto:support@zeronetworks.com) 10 | 11 | # Get Started 12 | The following tutorial shows basic installation and setup of RPC Firewall, as well as a demo of how it protects against various RPC-based attacks. 13 | 14 | [![RPC Firewall 2.0 Tutorial](https://img.youtube.com/vi/BNzfmYwkioY/0.jpg)](https://www.youtube.com/watch?v=BNzfmYwkioY) 15 | 16 | 17 | # Why should I care? 18 | RPC is the underlying mechanism which is used for numerous **lateral movement** techniques, **reconnaissance**, **relay** attacks, or simply to **exploit vulnerable RPC services**. 19 | 20 | DCSync attack? over RPC. Remote DCOM? over RPC. WMIC? over RPC. SharpHound? over RPC. PetitPotam? over RPC. PsExec? over RPC. ZeroLogon? over RPC... well, you get the idea :) 21 | 22 | # Terminology? 23 | Throughout this document, we will use the following terms: 24 | * **RPC Firewall**: Refers to the actual RpcFirewall.dll, which is loaded into various RPC servers in order to protect them. 25 | * **RPC Filters**: Refers to the native Windows RPC filtering mechanism. 26 | * **RPCFW Configuration**: Refers to the RpcFw.conf file, which is used to control how *RPC Firewall* and *RPC Filters* behave. 27 | * **RPCFW Manager**: The command line interface, which gives users access to both *RPC Firewall* and *RPC Filters* 28 | 29 | # What is it used for? 30 | ## Research 31 | Can be used to to **audit** all remote RPC calls. 32 | Once executing any remote attack tools, you will see which RPC UUIDs and Opnums were called remotely. 33 | 34 | See an example configuration [here](./Configuration_templates/RpcFw.conf.AuditOnly). 35 | 36 | ## Remote RPC Attacks Detection 37 | When the *RPCFW Configuration* is configured to audit, events are written to the Windows Event Log. 38 | *RPC Filter* events are written to the security log, with event ID 5712. *RPC Firewall* logs are written at *Application/RPCFW*. 39 | 40 | Users can forward these logs to their SIEM, and use it to create baselines of remote RPC traffic for various servers. 41 | Once an abnormal RPC call is audited, use it to trigger an alert for your SOC team. 42 | 43 | We integrated several [Sigma rules](https://github.com/SigmaHQ/sigma/tree/master/rules/application/rpc_firewall) which can be used to detect unusual RPC activities and attacks. 44 | 45 | ## Remote RPC Attacks Prevention 46 | The *RPCFW Configuration* can be configured to block & audit only potentially malicious RPC calls. All other RPC calls are not audited to reduce noise and improve performance. 47 | 48 | Once a potentially malicious RPC call is detected, it is blocked and audited. This could be used to alert your SOC team, while keeping your servers protected. 49 | 50 | To supplement protection, you can use the RPC Filtering capabilities, which are also supported via the RpcFwManager.exe. 51 | 52 | An example of such configuration can be found [here](./Configuration_templates/RpcFw.conf.FiltersOnly). 53 | 54 | # What are the RPC Firewall Components? 55 | It is made up from 3 components: 56 | 1. **RpcFwManager.exe** - Acts as a standalone command line management tool for RPC Filters and Firewall deployment. Also acts as the installed service for deploying the RPC Firewall. 57 | 2. **RpcFirewall.dll** - Injected DLL which performs the audit & filtering of RPC calls. 58 | 3. **RpcMessages.dll** - A common library for sharing functions, and logic that writes data into Windows Event Viewer. 59 | 60 | # Using RPC Firewall or RPC Filters? 61 | While there are pros and cons for using each method, there are a couple of major benefits for using *RPC Firewall* which require special attention. These are: 62 | 1. **Granularity**: The RPC Firewall is applied for each RPC call, and can be used to create more granular controls for specific RPC functions. 63 | 2. **Source Address Identification**: *RPC Firewall* is better at determining the source address of the caller. *RPC Filters* cannot identify the source address of calls made over named pipes (SMB), which means **RPC filtering rules will fail for RPC calls made over named pipes!!!** 64 | 3. **Bugs!**: RPC Filters suffers from various bugs which Microsoft are not enthusiastic on fixing. A couple of examples are: IP ranges don't work, and you can't apply a "catch all" filter, as it could damadge several Domain Controller services such as NetLogon. 65 | 66 | On the other hand, *RPC Filters* are greate for bulk allow or deny of entire UUIDs, as they do so without any issues. 67 | 68 | # How to use? 69 | ## What's the status? 70 | Prior to running any command, it is recommended to check the status of the deployment. This is done by issuing the '/status' command: 71 | ```bash 72 | RpcFwManager.exe /status 73 | ``` 74 | 75 | This will show the status of both the *RPC Firewall* and the *RPC Filters*. This will output detailed information about the installation status, and also the running status of the deployment. 76 | 77 | ## The 'fw' / 'flt' suffixes 78 | Almost every command can be suffixed with *fw* or *flt* at the end. This tells *RPCFW Manager* whether the command is applied to *RPC Firewall* ('fw'), *RPC Filters* ('flt') or both when not using any suffix. 79 | 80 | ## Installing / Uninstalling 81 | Peform installation of the relevant feature (*RPC Filters* / *RPC FIrewall* / both). 82 | * **RPC Firewall Installation**: Configures the event log, drop relevant dlls into the %SystemRoot%\System32 folder, and configures the **RPCFW** application log for the Event Viewer. It also installs the "RPC Firewall" service, which will be used for persistence. 83 | * **RPC Filters Installation**: Enables the security audit of RPC events. These can be found under the Securit log, with event ID 5712. 84 | 85 | _Make sure the event viewer is closed during install/uninstall._ Also, it is good practice to stop & uninstall before installation, to make sure there aren't any previous versions installed. 86 | ```bash 87 | RpcFwManager.exe /stop 88 | RpcFwManager.exe /uninstall 89 | RpcFwManager.exe /install 90 | ``` 91 | 92 | Uninstalling does the opposite. Also here it is good practice to ensure the service is stopped prior to uninstallation. 93 | ```bash 94 | RpcFwManager.exe /stop 95 | RpcFwManager.exe /uninstall 96 | ``` 97 | 98 | ## Starting / Stopping 99 | *RPC Filters*, by their nature, are applied system-wide, to any RPC server. Applying such filters is also persistent across reboots. 100 | Any new or old process will be protected by *RPC Filters*, according to the *RPCFW Configuration*. 101 | 102 | *RPC Firewall* is injected and protects any RPC server process which is listening for remote RPC calls. 103 | This is done by injecting *RPC Firewall* into processes which load the RPCRT4.DLL (the RPC Runtime). Once loaded, *RPC Firewall* will detect whether the RPC server is listening for remote RPC calls. If not, it unloads itself. 104 | If the process is a valid RPC server, the rpcFirewall starts to audit & monitor incoming RPC calls, according to the *RPCFW Configuration*. 105 | 106 | The recommended method to protect RPC services is by using the *'/start'* command. This starts the *RPC Firewall* service (for 'fw' or no suffix), and creates *RPC Filters* (for 'flt' or no suffix). 107 | ```bash 108 | RpcFwManager.exe /start 109 | ``` 110 | 111 | It is also possible to use *RPC Firewall* ad-hoc, to protect specific processes. This will not start the *RPC Firewall* service, and will not persist across reboots. 112 | 113 | To protect a single process by Process ID (PID): 114 | ```bash 115 | RpcFwManager.exe /start pid 116 | ``` 117 | To protect a single process by name: 118 | ```bash 119 | RpcFwManager.exe /start process 120 | ``` 121 | 122 | To stop the protection, simply issue the *'/stop'* command with the appropriate suffix (it is not possible to stop protection for a specific process). 123 | ```bash 124 | RpcFwManager.exe /stop 125 | ``` 126 | According to the suffix used ('fw' or 'flt' or none), this will stop the *RPC Firewall* service and unload the *RPC Firewall* dll from all processes. For *RPC Filters*, it will delete all filters generated by the *RPCFW Manager*. 127 | 128 | ## Persistency 129 | Once started, the *RPC Firewall* will persiste across reboots. 130 | *RPC Filters* are also persistent. 131 | 132 | ## Configuration 133 | The *RPCFW Manager * looks for a *RpcFw.conf* file, in the same directory of the executable. 134 | This file uses the following configuration options: 135 | 136 | *Important*: Each each configuration line should be prefixed with either *'fw:'* or *'flt:'* to indicate whether the line is applied for *RPC Firewall* or *RPC Filter*. 137 | 138 | |Parameter Name | Explanation | Supported by ...| 139 | |---------- | ----------- | ------------ | 140 | |opnum:| Match a RPC opnum | RPC Firewall| 141 | |verbose:| Can be either **true** or *false*. When true, outputs debug informaiton for specific RPC calls (default false)| RPC Firewall| 142 | |prot:| Matches the used protocol to any of the [protocol sequence constants](https://docs.microsoft.com/en-us/windows/win32/rpc/protocol-sequence-constants)| both RPC Firewall and Filters| 143 | |addr:| Match a remote IP address (IPv4 or IPv6, including CIDR)| RPC Firewall and partially by RPC Filters, [read more here](#using-rpc-firewall-or-rpc-filters)| 144 | |uuid:| Match a specific uuid | both RPC Firewall and Filters| 145 | |action:| Can be either **allow** or **block** (default allow)| both RPC Firewall and Filters| 146 | |audit:| Can be either **true** or *false*. Controls whether events are written to the *RPCFW* log (default false)| both RPC Firewall and Filters| 147 | |sid:| matches an authenticated user to a [security identifier](https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/security-identifiers). Could be specific user or group. | both RPC Firewall and Filters 148 | 149 | ## Seeing More Things 150 | To see more RPC related "things", there is a _show_ command. For now, it only shows protected processes, which cannot be protected with the RPC firewall module. 151 | ```bash 152 | RpcFwManager.exe /show 153 | ``` 154 | 155 | The configuration order is important, as the first match determines the outcome of the RPC call. 156 | 157 | For example, the following configuration snippet will protect a DC from a DCSync using *RPC Firewall*. 158 | It does so by enabling the "dangerous" opnum 3 [DRSGetNCChanges](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/b63730ac-614c-431c-9501-28d6aca91894) of the MS-DRSR UUID only from other domain controllers. 159 | ```bash 160 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: opnum:3 action:allow 161 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: opnum:3 action:allow 162 | fw:uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 opnum:3 action:block 163 | ``` 164 | 165 | Whenever the configuration changes, you need to notify the rpcFirewall.dll via the update command: 166 | ```bash 167 | RpcFwManager.exe /update 168 | ``` 169 | 170 | ## Viewing Logs 171 | For *RPC Firewall*, open the Event Viewer -> Applications and Services Logs -> RPCFW. 172 | Event Ids 1 and 2 refer to 'protect' and 'unprotect' events. Event 3 audits the actual RPC calls. 173 | Also, add the Keywords column. This column would contain Audit Success/Failure, implying whether the RPC call was blocked or not. 174 | 175 | For *RPC Filters*, open the Event Viewer -> Security-> RPCFW. Filter for event ID 5712. 176 | 177 | # Can I Contribute? 178 | Yes! Don't be shy to do a pull request. 179 | 180 | # I want RPC Firewall to do more things! 181 | We want this also! Please reach out to us with any thoughts, ideas or issues you are having: [support@zeronetworks.com](mailto:support@zeronetworks.com) 182 | 183 | # Is there a License? 184 | For more details see [LICENSE](LICENSE). 185 | -------------------------------------------------------------------------------- /RPCFW.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.32014.148 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcFwManager", "rpcFwManager\rpcFwManager.vcxproj", "{E8206BB0-87FA-4723-B993-D1859D7F15DE}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcFireWall", "rpcFirewall\rpcFirewall.vcxproj", "{2AFEC22C-BD0B-4617-804D-3F6093E5079C}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcMessages", "rpcMessages\rpcMessages.vcxproj", "{48DC6DD2-92B9-49D9-AD47-A014E863FE60}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FF4F31A5-70EE-41AF-B6B6-D867FB7BC515}" 13 | ProjectSection(SolutionItems) = preProject 14 | LICENSE = LICENSE 15 | README.md = README.md 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|x64 = Debug|x64 21 | Debug|x86 = Debug|x86 22 | Release|x64 = Release|x64 23 | Release|x86 = Release|x86 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Debug|x64.ActiveCfg = Debug|x64 27 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Debug|x64.Build.0 = Debug|x64 28 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Debug|x86.ActiveCfg = Debug|Win32 29 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Debug|x86.Build.0 = Debug|Win32 30 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Release|x64.ActiveCfg = Release|x64 31 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Release|x64.Build.0 = Release|x64 32 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Release|x86.ActiveCfg = Release|Win32 33 | {E8206BB0-87FA-4723-B993-D1859D7F15DE}.Release|x86.Build.0 = Release|Win32 34 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Debug|x64.ActiveCfg = Debug|x64 35 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Debug|x64.Build.0 = Debug|x64 36 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Debug|x86.ActiveCfg = Debug|Win32 37 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Debug|x86.Build.0 = Debug|Win32 38 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Release|x64.ActiveCfg = Release|x64 39 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Release|x64.Build.0 = Release|x64 40 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Release|x86.ActiveCfg = Release|Win32 41 | {2AFEC22C-BD0B-4617-804D-3F6093E5079C}.Release|x86.Build.0 = Release|Win32 42 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Debug|x64.ActiveCfg = Debug|x64 43 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Debug|x64.Build.0 = Debug|x64 44 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Debug|x86.ActiveCfg = Debug|Win32 45 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Debug|x86.Build.0 = Debug|Win32 46 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Release|x64.ActiveCfg = Release|x64 47 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Release|x64.Build.0 = Release|x64 48 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Release|x86.ActiveCfg = Release|Win32 49 | {48DC6DD2-92B9-49D9-AD47-A014E863FE60}.Release|x86.Build.0 = Release|Win32 50 | EndGlobalSection 51 | GlobalSection(SolutionProperties) = preSolution 52 | HideSolutionNode = FALSE 53 | EndGlobalSection 54 | GlobalSection(ExtensibilityGlobals) = postSolution 55 | SolutionGuid = {A3A3EB5A-B72A-4B38-9F16-AF9A36E2EED9} 56 | EndGlobalSection 57 | EndGlobal 58 | -------------------------------------------------------------------------------- /rpcFirewall/config.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | struct AddressRangeIpv4 { 7 | uint32_t minAddr; 8 | uint32_t maxAddr; 9 | }; 10 | 11 | struct AddressRangeIpv6 { 12 | std::array minAddr; 13 | std::array maxAddr; 14 | }; 15 | 16 | 17 | struct AddressRange { 18 | std::optional ipv4; 19 | std::optional ipv6; 20 | }; 21 | 22 | 23 | using OpNumFilter = std::optional; 24 | using UUIDFilter = std::optional; 25 | using AddressRangeFilter = std::optional; 26 | using protocolFilter = std::optional; 27 | using SIDFilter = std::optional; 28 | 29 | struct RpcCallPolicy 30 | { 31 | bool allow = true; 32 | bool audit = false; 33 | }; 34 | 35 | struct LineConfig 36 | { 37 | UUIDFilter uuid; 38 | OpNumFilter opnum; 39 | AddressRangeFilter addr; 40 | RpcCallPolicy policy; 41 | protocolFilter protocol; 42 | SIDFilter sid; 43 | bool verbose; 44 | }; 45 | 46 | using ConfigVector = std::vector; 47 | 48 | 49 | class DoubleBufferedConfig 50 | { 51 | public: 52 | size_t getPassiveConfBufferNumber() const { return 1 - activeConfBufferNumber; } 53 | 54 | void changeActiveConfigurationNumber() { activeConfBufferNumber = getPassiveConfBufferNumber(); } 55 | 56 | const ConfigVector& getActiveConfigurationVector() const { return configVectors[activeConfBufferNumber]; } 57 | 58 | void setPassiveConfigurationVector(const ConfigVector& config) { configVectors[getPassiveConfBufferNumber()] = config; } 59 | 60 | private: 61 | ConfigVector configVectors[2]; 62 | size_t activeConfBufferNumber = 0; 63 | }; 64 | -------------------------------------------------------------------------------- /rpcFirewall/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | //#include 6 | -------------------------------------------------------------------------------- /rpcFirewall/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /rpcFirewall/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | 6 | 7 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 8 | -------------------------------------------------------------------------------- /rpcFirewall/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // add headers that you want to pre-compile here 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /rpcFirewall/rpcFirewall.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {2afec22c-bd0b-4617-804d-3f6093e5079c} 25 | rpcDetours 26 | 10.0 27 | rpcFireWall 28 | 29 | 30 | 31 | DynamicLibrary 32 | true 33 | v142 34 | Unicode 35 | 36 | 37 | DynamicLibrary 38 | false 39 | v142 40 | true 41 | Unicode 42 | 43 | 44 | DynamicLibrary 45 | true 46 | v143 47 | Unicode 48 | 49 | 50 | DynamicLibrary 51 | false 52 | v143 53 | true 54 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | 77 | 78 | false 79 | 80 | 81 | true 82 | $(OutDir);$(LibraryPath) 83 | 84 | 85 | false 86 | $(OutDir);$(LibraryPath) 87 | 88 | 89 | 90 | Level3 91 | true 92 | WIN32;_DEBUG;RPCDETOURS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 93 | true 94 | Use 95 | pch.h 96 | 97 | 98 | Windows 99 | true 100 | false 101 | 102 | 103 | 104 | 105 | Level3 106 | true 107 | true 108 | true 109 | WIN32;NDEBUG;RPCDETOURS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 110 | true 111 | Use 112 | pch.h 113 | 114 | 115 | Windows 116 | true 117 | true 118 | true 119 | false 120 | 121 | 122 | 123 | 124 | Level3 125 | true 126 | _DEBUG;RPCDETOURS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 127 | true 128 | Use 129 | pch.h 130 | $(SolutionDir)rpcMessages\ 131 | stdcpp20 132 | MultiThreadedDebugDLL 133 | 134 | 135 | Windows 136 | true 137 | false 138 | rpcrt4.lib;%(AdditionalDependencies) 139 | 140 | 141 | 142 | 143 | Level3 144 | true 145 | true 146 | true 147 | NDEBUG;RPCDETOURS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 148 | true 149 | Use 150 | pch.h 151 | MultiThreaded 152 | $(SolutionDir)rpcMessages\ 153 | stdcpp20 154 | 155 | 156 | Windows 157 | true 158 | true 159 | true 160 | false 161 | Rpcrt4.lib;%(AdditionalDependencies) 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | Create 174 | Create 175 | Create 176 | Create 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | {48dc6dd2-92b9-49d9-ad47-a014e863fe60} 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /rpcFirewall/rpcFirewall.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /rpcFirewall/rpcWrappers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct RpcStringWrapper 6 | { 7 | RPC_WSTR* getRpcPtr() 8 | { 9 | return (RPC_WSTR*)&str; 10 | } 11 | 12 | ~RpcStringWrapper() 13 | { 14 | if (str != nullptr) 15 | { 16 | RpcStringFree(getRpcPtr()); 17 | } 18 | } 19 | 20 | wchar_t* str = nullptr; 21 | }; 22 | 23 | struct RpcBindingWrapper 24 | { 25 | ~RpcBindingWrapper() 26 | { 27 | if (binding != nullptr) 28 | { 29 | RpcBindingFree(&binding); 30 | } 31 | } 32 | 33 | RPC_BINDING_HANDLE binding = nullptr; 34 | }; 35 | -------------------------------------------------------------------------------- /rpcFwManager/EventSink.cpp: -------------------------------------------------------------------------------- 1 | // EventSink.cpp 2 | #include "stdafx.h" 3 | #include "EventSink.h" 4 | #include "common.h" 5 | #include "Injections.h" 6 | 7 | ULONG EventSink::AddRef() 8 | { 9 | outputMessage(L"Called EventSink::AddRef()"); 10 | return InterlockedIncrement(&m_lRef); 11 | } 12 | 13 | ULONG EventSink::Release() 14 | { 15 | outputMessage(L"Called EventSink::Release()"); 16 | LONG lRef = InterlockedDecrement(&m_lRef); 17 | if (lRef == 0) 18 | delete this; 19 | return lRef; 20 | } 21 | 22 | HRESULT EventSink::QueryInterface(REFIID riid, void** ppv) 23 | { 24 | outputMessage(L"Called EventSink::QueryInterface"); 25 | 26 | if (riid == IID_IUnknown || riid == IID_IWbemObjectSink) 27 | { 28 | *ppv = (IWbemObjectSink*)this; 29 | AddRef(); 30 | return WBEM_S_NO_ERROR; 31 | } 32 | else return E_NOINTERFACE; 33 | } 34 | 35 | 36 | HRESULT EventSink::Indicate(long lObjectCount, 37 | IWbemClassObject** apObjArray) 38 | { 39 | HRESULT hres = S_OK; 40 | 41 | outputMessage(L"Indicate method called!"); 42 | 43 | for (int i = 0; i < lObjectCount; i++) 44 | { 45 | //VARIANT v; 46 | _variant_t vtProp; 47 | hres = apObjArray[i]->Get(L"TargetInstance", 0, &vtProp, 0, 0); 48 | if (!FAILED(hres)) 49 | { 50 | IWbemClassObject* pClassObj = nullptr; 51 | IUnknown* pIUnknown = (IUnknown*)vtProp; 52 | 53 | hres = pIUnknown->QueryInterface(IID_IWbemClassObject, reinterpret_cast(&pClassObj)); 54 | if (!FAILED(hres)) 55 | { 56 | outputMessage(L"QueryInterface worked!"); 57 | _variant_t cn; 58 | 59 | hres = pClassObj->Get(L"ProcessId", 0, &cn, NULL, NULL); 60 | if (!FAILED(hres)) 61 | { 62 | if ((cn.vt != VT_NULL) || (cn.vt != VT_EMPTY)) 63 | { 64 | outputMessage(L"New process detected", cn.uintVal); 65 | crawlProcesses(cn.uintVal); 66 | } 67 | } 68 | VariantClear(&cn); 69 | pClassObj->Release(); 70 | } 71 | pIUnknown->Release(); 72 | } 73 | VariantClear(&vtProp); 74 | } 75 | 76 | return WBEM_S_NO_ERROR; 77 | } 78 | 79 | HRESULT EventSink::SetStatus( 80 | /* [in] */ LONG lFlags, 81 | /* [in] */ HRESULT hResult, 82 | /* [in] */ BSTR strParam, 83 | /* [in] */ IWbemClassObject __RPC_FAR* pObjParam 84 | ) 85 | { 86 | outputMessage(L"Called EventSink::SetStatus()"); 87 | if (lFlags == WBEM_STATUS_COMPLETE) 88 | { 89 | _tprintf(_T("Call complete. hResult = 0x%X\n"), hResult); 90 | } 91 | else if (lFlags == WBEM_STATUS_PROGRESS) 92 | { 93 | _tprintf(_T("Call in progress.\n")); 94 | } 95 | 96 | return WBEM_S_NO_ERROR; 97 | } // end of EventSink.cpp 98 | 99 | wmiEventRegistrant::wmiEventRegistrant() 100 | { 101 | outputMessage(L"Called wmiEventRegistrant::wmiEventRegistrant()"); 102 | this->pSink = new EventSink; 103 | } 104 | 105 | wmiEventRegistrant::~wmiEventRegistrant() 106 | { 107 | outputMessage(L"Called wmiEventRegistrant::~wmiEventRegistrant()"); 108 | HRESULT hres; 109 | hres = pSvc->CancelAsyncCall(pStubSink); 110 | 111 | this->pSvc->Release(); 112 | this->pLoc->Release(); 113 | this->pUnsecApp->Release(); 114 | this->pStubUnk->Release(); 115 | this->pSink->Release(); 116 | this->pStubSink->Release(); 117 | CoUninitialize(); 118 | 119 | } 120 | 121 | bool wmiEventRegistrant::registerForProcessCreatedEvents() 122 | { 123 | 124 | outputMessage(L"Called wmiEventRegistrant::registerForProcessCreatedEvents()"); 125 | HRESULT hres; 126 | 127 | // Initialize COM 128 | hres = CoInitializeEx(0, COINIT_MULTITHREADED); 129 | if (FAILED(hres)) 130 | { 131 | _tprintf(_T("Failed to initialize COM library. Error code = 0x%x\n"), hres); 132 | return false; 133 | } 134 | 135 | // Set general COM security levels -------------------------- 136 | hres = CoInitializeSecurity( 137 | NULL, 138 | -1, // COM negotiates service 139 | NULL, // Authentication services 140 | NULL, // Reserved 141 | RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication 142 | RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation 143 | NULL, // Authentication info 144 | EOAC_NONE, // Additional capabilities 145 | NULL // Reserved 146 | ); 147 | 148 | 149 | if (FAILED(hres)) 150 | { 151 | _tprintf(_T("Failed to initialize security. Error code = 0x%x\n"), hres); 152 | CoUninitialize(); 153 | return false; 154 | } 155 | 156 | // Obtain the initial locator to WMI 157 | 158 | hres = CoCreateInstance( 159 | CLSID_WbemLocator, 160 | 0, 161 | CLSCTX_INPROC_SERVER, 162 | IID_IWbemLocator, (LPVOID*)&pLoc); 163 | 164 | if (FAILED(hres)) 165 | { 166 | _tprintf(_T("Failed to create IWbemLocator object. Err code = 0x%x\n"), hres); 167 | CoUninitialize(); 168 | return false; // Program has failed. 169 | } 170 | 171 | 172 | // Connect to the local root\cimv2 namespace 173 | // and obtain pointer pSvc to make IWbemServices calls. 174 | hres = pLoc->ConnectServer( 175 | _bstr_t(L"ROOT\\CIMV2"), 176 | NULL, 177 | NULL, 178 | 0, 179 | NULL, 180 | 0, 181 | 0, 182 | &pSvc 183 | ); 184 | 185 | if (FAILED(hres)) 186 | { 187 | _tprintf(_T("Could not connect. Error code = 0x%x\n"), hres); 188 | pLoc->Release(); 189 | CoUninitialize(); 190 | return false; 191 | } 192 | 193 | _tprintf(_T("Connected to ROOT\\CIMV2 WMI namespace\n")); 194 | 195 | 196 | // Set security levels on the proxy 197 | 198 | hres = CoSetProxyBlanket( 199 | pSvc, // Indicates the proxy to set 200 | RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx 201 | RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx 202 | NULL, // Server principal name 203 | RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx 204 | RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx 205 | NULL, // client identity 206 | EOAC_NONE // proxy capabilities 207 | ); 208 | 209 | if (FAILED(hres)) 210 | { 211 | _tprintf(_T("Could not set proxy blanket. Error code = 0x%x\n"), hres); 212 | pSvc->Release(); 213 | pLoc->Release(); 214 | CoUninitialize(); 215 | return false; 216 | } 217 | 218 | // Receive event notifications 219 | 220 | hres = CoCreateInstance(CLSID_UnsecuredApartment, NULL, 221 | CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, 222 | (void**)&pUnsecApp); 223 | 224 | pSink->AddRef(); 225 | 226 | pUnsecApp->CreateObjectStub(pSink, &pStubUnk); 227 | 228 | pStubUnk->QueryInterface(IID_IWbemObjectSink, 229 | (void**)&pStubSink); 230 | 231 | // The ExecNotificationQueryAsync method will call 232 | // The EventQuery::Indicate method when an event occurs 233 | hres = pSvc->ExecNotificationQueryAsync(_bstr_t("WQL"), _bstr_t("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'"), 234 | WBEM_FLAG_SEND_STATUS, 235 | NULL, 236 | pStubSink); 237 | 238 | // Check for errors. 239 | if (FAILED(hres)) 240 | { 241 | printf("ExecNotificationQueryAsync failed " 242 | "with = 0x%X\n", hres); 243 | pSvc->Release(); 244 | pLoc->Release(); 245 | pUnsecApp->Release(); 246 | pStubUnk->Release(); 247 | pSink->Release(); 248 | pStubSink->Release(); 249 | CoUninitialize(); 250 | return false; 251 | } 252 | 253 | return true; 254 | } 255 | -------------------------------------------------------------------------------- /rpcFwManager/EventSink.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef EVENTSINK_H 3 | #define EVENTSINK_H 4 | #endif 5 | 6 | #define _WIN32_DCOM 7 | #include 8 | #include 9 | #include 10 | 11 | #pragma comment(lib, "wbemuuid.lib") 12 | #pragma comment(lib, "onecore.lib") 13 | 14 | #ifndef _CreationEvent_h__ 15 | class EventSink : public IWbemObjectSink 16 | { 17 | LONG m_lRef; 18 | bool bDone; 19 | 20 | public: 21 | EventSink() { m_lRef = 0; } 22 | ~EventSink() { bDone = true; } 23 | 24 | virtual ULONG STDMETHODCALLTYPE AddRef(); 25 | virtual ULONG STDMETHODCALLTYPE Release(); 26 | virtual HRESULT 27 | STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); 28 | 29 | virtual HRESULT STDMETHODCALLTYPE Indicate( 30 | LONG lObjectCount, 31 | IWbemClassObject __RPC_FAR* __RPC_FAR* apObjArray 32 | ); 33 | 34 | virtual HRESULT STDMETHODCALLTYPE SetStatus( 35 | /* [in] */ LONG lFlags, 36 | /* [in] */ HRESULT hResult, 37 | /* [in] */ BSTR strParam, 38 | /* [in] */ IWbemClassObject __RPC_FAR* pObjParam 39 | ); 40 | }; 41 | 42 | class wmiEventRegistrant 43 | { 44 | IWbemServices* pSvc = NULL; 45 | IWbemObjectSink* pStubSink = NULL; 46 | IWbemLocator* pLoc = NULL; 47 | IUnsecuredApartment* pUnsecApp = NULL; 48 | IUnknown* pStubUnk = NULL; 49 | EventSink* pSink = NULL; 50 | 51 | public: 52 | wmiEventRegistrant(); 53 | ~wmiEventRegistrant(); 54 | 55 | bool registerForProcessCreatedEvents(); 56 | 57 | }; 58 | #endif -------------------------------------------------------------------------------- /rpcFwManager/Injections.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | typedef LONG KPRIORITY; 5 | 6 | #ifndef NT_SUCCESS 7 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 8 | #endif 9 | 10 | struct RpcStringWrapper 11 | { 12 | RPC_WSTR* getRpcPtr() 13 | { 14 | return (RPC_WSTR*)&str; 15 | } 16 | 17 | ~RpcStringWrapper() 18 | { 19 | if (str != nullptr) 20 | { 21 | RpcStringFree(getRpcPtr()); 22 | } 23 | } 24 | 25 | wchar_t* str = nullptr; 26 | }; 27 | 28 | struct RpcBindingWrapper 29 | { 30 | ~RpcBindingWrapper() 31 | { 32 | if (binding != nullptr) 33 | { 34 | RpcBindingFree(&binding); 35 | } 36 | } 37 | 38 | RPC_BINDING_HANDLE binding = nullptr; 39 | }; 40 | 41 | 42 | typedef enum _SYSTEM_INFORMATION_CLASS { 43 | SystemBasicInformation = 0, 44 | SystemPerformanceInformation = 2, 45 | SystemTimeOfDayInformation = 3, 46 | SystemProcessInformation = 5, 47 | SystemProcessorPerformanceInformation = 8, 48 | SystemInterruptInformation = 23, 49 | SystemExceptionInformation = 33, 50 | SystemRegistryQuotaInformation = 37, 51 | SystemLookasideInformation = 45, 52 | SystemCodeIntegrityInformation = 103, 53 | SystemPolicyInformation = 134, 54 | } SYSTEM_INFORMATION_CLASS; 55 | 56 | typedef struct _CLIENT_ID { 57 | HANDLE UniqueProcess; 58 | HANDLE UniqueThread; 59 | } CLIENT_ID; 60 | 61 | typedef NTSTATUS(NTAPI* PFN_NtQuerySystemInformation)( 62 | _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, 63 | _Inout_ PVOID SystemInformation, 64 | _In_ ULONG SystemInformationLength, 65 | _Out_opt_ PULONG ReturnLength 66 | ); 67 | 68 | // Define the SYSTEM_EXTENDED_THREAD_INFORMATION structure 69 | typedef struct _SYSTEM_THREAD_INFORMATION { 70 | LARGE_INTEGER Reserved1[3]; 71 | ULONG Reserved2; 72 | PVOID StartAddress; 73 | CLIENT_ID ClientId; 74 | KPRIORITY Priority; 75 | LONG BasePriority; 76 | ULONG Reserved3; 77 | ULONG ThreadState; 78 | ULONG WaitReason; 79 | } SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; 80 | 81 | typedef struct _UNICODE_STRING_X { 82 | USHORT Length; 83 | USHORT MaximumLength; 84 | PWSTR Buffer; 85 | } UNICODE_STRING_X; 86 | 87 | typedef struct _SYSTEM_PROCESS_INFORMATION { 88 | ULONG NextEntryOffset; 89 | ULONG NumberOfThreads; 90 | BYTE Reserved1[48]; 91 | UNICODE_STRING_X ImageName; 92 | KPRIORITY BasePriority; 93 | HANDLE UniqueProcessId; 94 | PVOID Reserved2; 95 | ULONG HandleCount; 96 | ULONG SessionId; 97 | PVOID Reserved3; 98 | SIZE_T PeakVirtualSize; 99 | SIZE_T VirtualSize; 100 | ULONG Reserved4; 101 | SIZE_T PeakWorkingSetSize; 102 | SIZE_T WorkingSetSize; 103 | PVOID Reserved5; 104 | SIZE_T QuotaPagedPoolUsage; 105 | PVOID Reserved6; 106 | SIZE_T QuotaNonPagedPoolUsage; 107 | SIZE_T PagefileUsage; 108 | SIZE_T PeakPagefileUsage; 109 | SIZE_T PrivatePageCount; 110 | LARGE_INTEGER Reserved7[6]; 111 | } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 112 | 113 | HANDLE hookProcessLoadLibrary(HANDLE hProcess, WCHAR* dllToInject); 114 | 115 | bool ContainsRPCModule(DWORD dwPID); 116 | 117 | void classicHookRPCProcesses(DWORD processID, wchar_t* dllToInject); 118 | 119 | bool PESelfInjectToRemoteProcess(DWORD processID, wchar_t* procName); 120 | 121 | void crawlProcesses(DWORD, std::wstring& ); 122 | 123 | void crawlProcesses(DWORD); 124 | 125 | void printProcessesWithRPCFW(); 126 | 127 | void printRPCEndpoints(); 128 | 129 | void printProtectedProcesses(); -------------------------------------------------------------------------------- /rpcFwManager/RPCMgr.cpp: -------------------------------------------------------------------------------- 1 | // RPCrawler.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include 6 | 7 | 8 | #include "stdafx.h" 9 | #include "rpcfilters.h" 10 | #include 11 | #include "common.h" 12 | #include "service.h" 13 | 14 | enum class eventSignal {signalSetEvent, signalResetEvent}; 15 | 16 | std::wstring extractKeyValueFromConfigLineInner(const std::wstring& confLine, const std::wstring& key) 17 | { 18 | const size_t keyOffset = confLine.find(key); 19 | 20 | if (keyOffset == std::string::npos) return _T("\0"); 21 | 22 | const size_t nextKeyOffset = confLine.find(_T(" "), keyOffset + 1); 23 | 24 | if (nextKeyOffset == std::string::npos) return _T("\0"); 25 | 26 | std::wstring val = confLine.substr(keyOffset + key.size(), nextKeyOffset - keyOffset - key.size()); 27 | 28 | return val; 29 | } 30 | 31 | std::wstring extractKeyValueFromConfigLine(const std::wstring& confLine, const std::wstring& key) 32 | { 33 | std::wstring fixedConfLine = confLine; 34 | 35 | std::size_t newLinePos = fixedConfLine.rfind(_T("\n")); 36 | std::size_t carrigeReturnPos = fixedConfLine.rfind(_T("\r")); 37 | 38 | 39 | //std::basic_string::replace(fixedConfLine.begin(), fixedConfLine.end(), _T("\r"), _T(" ")); 40 | if (newLinePos != std::wstring::npos) fixedConfLine.replace(fixedConfLine.rfind(_T("\n")), 1, _T(" ")); 41 | if (carrigeReturnPos != std::wstring::npos) fixedConfLine.replace(fixedConfLine.rfind(_T("\r")), 1, _T(" ")); 42 | 43 | fixedConfLine.replace(fixedConfLine.size() - 1, 1, _T(" ")); 44 | 45 | return extractKeyValueFromConfigLineInner(fixedConfLine, key); 46 | } 47 | 48 | UUIDFilter extractUUIDFilterFromConfigLine(const std::wstring& confLine) 49 | { 50 | std::wstring uuid = extractKeyValueFromConfigLine(confLine, _T("uuid:")); 51 | 52 | std::transform(uuid.begin(), uuid.end(), uuid.begin(), ::tolower); 53 | 54 | return uuid.empty() ? UUIDFilter{} : UUIDFilter{ uuid }; 55 | } 56 | 57 | AddressFilter extractAddressFromConfigLine(const std::wstring& confLine) 58 | { 59 | const std::wstring address = extractKeyValueFromConfigLine(confLine, _T("addr:")); 60 | 61 | return address.empty() ? AddressFilter{} : AddressFilter{ address }; 62 | } 63 | 64 | OpNumFilter extractOpNumFilterFromConfigLine(const std::wstring& confLine) 65 | { 66 | const std::wstring opnumString = extractKeyValueFromConfigLine(confLine, _T("opnum:")); 67 | 68 | if (opnumString.empty()) 69 | { 70 | return {}; 71 | } 72 | 73 | try { 74 | return std::stoi(opnumString); 75 | } 76 | catch (const std::invalid_argument&) { 77 | return {}; 78 | } 79 | } 80 | 81 | SIDFilter extractSIDFromConfigLine(const std::wstring& confLine) 82 | { 83 | const std::wstring sidString = extractKeyValueFromConfigLine(confLine, _T("sid:")); 84 | 85 | return sidString.empty() ? SIDFilter{} : SIDFilter{ sidString}; 86 | } 87 | 88 | bool extractActionFromConfigLine(const std::wstring& confLine) 89 | { 90 | std::wstring action = extractKeyValueFromConfigLine(confLine, _T("action:")); 91 | 92 | return action.find(_T("block")) == std::string::npos; 93 | } 94 | 95 | protocolFilter extractProtoclFromConfigLine(const std::wstring& confLine) 96 | { 97 | const std::wstring protocol = extractKeyValueFromConfigLine(confLine, _T("prot")); 98 | 99 | return protocol.empty() ? protocolFilter{} : protocolFilter{ protocol}; 100 | } 101 | 102 | bool extractAuditFromConfigLine(const std::wstring& confLine) 103 | { 104 | std::wstring audit = extractKeyValueFromConfigLine(confLine, _T("audit:")); 105 | 106 | return audit.find(_T("true")) != std::string::npos; 107 | } 108 | 109 | RpcCallPolicy extractPolicyFromConfigLine(const std::wstring& confLine) 110 | { 111 | return RpcCallPolicy 112 | { 113 | .allow = extractActionFromConfigLine(confLine), 114 | .audit = extractAuditFromConfigLine(confLine), 115 | }; 116 | } 117 | 118 | bool checkIfFilterConfiguLine(const std::wstring& confLine) 119 | { 120 | std::wstring flt = extractKeyValueFromConfigLine(confLine, _T("flt:")); 121 | 122 | return !flt.empty(); 123 | 124 | } 125 | 126 | void concatArguments(int argc, wchar_t* argv[], wchar_t command[]) 127 | { 128 | _tcscpy_s(command, MAX_PATH *2, argv[0]); 129 | 130 | for (int i = 1; i < argc; i++) 131 | { 132 | _tcscat_s(command, MAX_PATH * 2, TEXT(" ")); 133 | _tcscat_s(command, MAX_PATH * 2, argv[i]); 134 | } 135 | 136 | _tcscat_s(command, MAX_PATH * 2, TEXT(" /elevated")); 137 | } 138 | 139 | void getHelp() 140 | { 141 | _tprintf(TEXT("Usage: rpcFwManager / [options] \n\n")); 142 | _tprintf(TEXT("command:\n")); 143 | _tprintf(TEXT("----------\n")); 144 | _tprintf(TEXT("show\t\t - print various rpc related info (protected processes, for now...).\n")); 145 | _tprintf(TEXT("install\t\t - configure EventLogs, auditing, put DLLs in the %%SystemRoot%%\\system32 folder.\n")); 146 | _tprintf(TEXT("uninstall\t - undo installation changes.\n")); 147 | _tprintf(TEXT("start [options/pid/process]\t- Apply RPC protections according to the configuration file.\n")); 148 | _tprintf(TEXT("\tpid \t- Protect specified process ID with RPCFWP (no pid protects ALL processes!).\n")); 149 | _tprintf(TEXT("\tprocess \t- Protect specified process by name with RPCFWP (no name protects ALL processes!).\n")); 150 | _tprintf(TEXT("stop\t - Remove protections.\n")); 151 | _tprintf(TEXT("update\t\t - Notify rpcFirewall.dll on configuration changes.\n")); 152 | _tprintf(TEXT("\noptions:\n")); 153 | _tprintf(TEXT("--------------\n")); 154 | _tprintf(TEXT("fw: apply command for RPC Firewall only (excluding ).\n")); 155 | _tprintf(TEXT("flt: apply command for RPC Filters only (excluding ).\n")); 156 | _tprintf(TEXT("all: apply command for RPC Firewall & Filters (excluding ).\n")); 157 | } 158 | 159 | void deleteFileFromSysfolder(std::wstring fileName) 160 | { 161 | 162 | wchar_t destPath[INFO_BUFFER_SIZE]; 163 | DWORD bufCharCount = INFO_BUFFER_SIZE; 164 | 165 | if (!GetSystemDirectory(destPath, INFO_BUFFER_SIZE)) 166 | { 167 | _tprintf(TEXT("ERROR: Couldn't get the system directory [%d].\n"), GetLastError()); 168 | return; 169 | } 170 | 171 | std::wstring destPathStr = destPath; 172 | destPathStr += TEXT("\\"); 173 | destPathStr += fileName; 174 | 175 | if (!DeleteFile(destPathStr.c_str())) 176 | { 177 | DWORD LastError = GetLastError(); 178 | if (LastError != ERROR_FILE_NOT_FOUND) 179 | { 180 | _tprintf(TEXT("ERROR: %s delete operation from system folder failed [%d].\n"), destPathStr.c_str(), GetLastError()); 181 | return; 182 | } 183 | } 184 | } 185 | 186 | void writeFileToSysfolder(const std::wstring& sourcePath, const std::wstring& sourceFileName) 187 | { 188 | wchar_t destPath[INFO_BUFFER_SIZE]; 189 | DWORD bufCharCount = INFO_BUFFER_SIZE; 190 | 191 | if (!GetSystemDirectory(destPath, INFO_BUFFER_SIZE)) 192 | { 193 | _tprintf(TEXT("ERROR: Couldn't get the system directory [%d].\n"), GetLastError()); 194 | return; 195 | } 196 | 197 | std::wstring destPathStr = destPath; 198 | destPathStr += TEXT("\\"); 199 | destPathStr += sourceFileName; 200 | 201 | if (!CopyFile(sourcePath.c_str(), destPathStr.c_str(), false)) 202 | { 203 | _tprintf(TEXT("ERROR: %s copy to system folder failed [%d].\n"), sourcePath.c_str(), GetLastError()); 204 | return; 205 | } 206 | } 207 | 208 | 209 | bool checkIfFileInSysFolder(const std::wstring& sourceFileName) 210 | { 211 | wchar_t destPath[INFO_BUFFER_SIZE]; 212 | DWORD bufCharCount = INFO_BUFFER_SIZE; 213 | 214 | if (!GetSystemDirectory(destPath, INFO_BUFFER_SIZE)) 215 | { 216 | _tprintf(TEXT("ERROR: Couldn't get the system directory [%d].\n"), GetLastError()); 217 | return false; 218 | } 219 | 220 | std::wstring destPathStr = destPath; 221 | destPathStr += TEXT("\\"); 222 | destPathStr += sourceFileName; 223 | 224 | std::ifstream ifile; 225 | ifile.open(destPathStr.c_str()); 226 | 227 | if (ifile) 228 | { 229 | ifile.close(); 230 | return true; 231 | } 232 | ifile.close(); 233 | return false; 234 | 235 | } 236 | 237 | void sendSignalToGlobalEvent(wchar_t* globalEventName, eventSignal eSig) 238 | { 239 | HANDLE hEvent = createGlobalEvent(true, false, globalEventName); 240 | if (hEvent == nullptr) 241 | { 242 | _tprintf(TEXT("Could not get handle to event %s, error: %d\n"), globalEventName, GetLastError()); 243 | return; 244 | } 245 | 246 | if (eSig == eventSignal::signalSetEvent) 247 | { 248 | if (SetEvent(hEvent) == 0) 249 | { 250 | _tprintf(TEXT("Setting the event %s failed: %d.\n"), globalEventName, GetLastError()); 251 | } 252 | } 253 | else 254 | { 255 | if (ResetEvent(hEvent) == 0) 256 | { 257 | _tprintf(TEXT("Resetting the event %s failed: %d.\n"), globalEventName, GetLastError()); 258 | } 259 | } 260 | } 261 | 262 | void runCommandBasedOnParam(std::wstring ¶m, void funcFilter(void), void funcFireWall(void), std::wstring &errMsg) 263 | { 264 | if (param.empty() || (param.find(_T("all")) != std::string::npos)) 265 | { 266 | funcFilter(); 267 | funcFireWall(); 268 | } 269 | else 270 | { 271 | if ((param.find(_T("all")) != std::string::npos) || (param.find(_T("flt")) != std::string::npos)) 272 | { 273 | funcFilter(); 274 | } 275 | else if ((param.find(_T("all")) != std::string::npos) || (param.find(_T("fw")) != std::string::npos)) 276 | { 277 | funcFireWall(); 278 | } 279 | else 280 | { 281 | _tprintf(errMsg.c_str()); 282 | } 283 | } 284 | } 285 | 286 | void cmdUpdateRPCFW() 287 | { 288 | readConfigAndMapToMemory(); 289 | WaitForSingleObject(globalUnprotectEvent, 1000); 290 | } 291 | 292 | void cmdUnprotectRPCFLT() 293 | { 294 | _tprintf(_T("Removing RPC Filters...\n")); 295 | if (!setSecurityPrivilege(_T("SeSecurityPrivilege"))) 296 | { 297 | _tprintf(_T("Error: could not obtain SeSecurityPrivilege.\n")); 298 | return; 299 | } 300 | deleteAllRPCFilters(); 301 | } 302 | 303 | void createRPCFiltersFromConfiguration() 304 | { 305 | _tprintf(_T("Creating RPC Filters...\n")); 306 | DWORD bytesRead = 0; 307 | std::string confBuf(readConfigFile(&bytesRead)); 308 | 309 | unsigned int lineNum = 0; 310 | 311 | if (bytesRead > 0) 312 | { 313 | std::stringstream configStream(confBuf); 314 | std::wstring confLineString; 315 | char configLine[256]; 316 | 317 | configLinesVector confLines; 318 | 319 | while (configStream.getline(configLine, 256)) 320 | { 321 | confLineString = StringToWString(configLine); 322 | confLineString += L" "; 323 | LineConfig lineConfig = {}; 324 | 325 | if (checkIfFilterConfiguLine(confLineString)) 326 | { 327 | lineConfig.opnum = extractOpNumFilterFromConfigLine(confLineString); 328 | lineConfig.uuid = extractUUIDFilterFromConfigLine(confLineString); 329 | lineConfig.min_addr = extractAddressFromConfigLine(confLineString); 330 | lineConfig.policy = extractPolicyFromConfigLine(confLineString); 331 | lineConfig.sid = extractSIDFromConfigLine(confLineString); 332 | lineConfig.protocol = extractProtoclFromConfigLine(confLineString); 333 | 334 | confLines.push_back(std::make_pair(confLineString, lineConfig)); 335 | } 336 | } 337 | 338 | createRPCFilterFromTextLines(confLines); 339 | } 340 | } 341 | 342 | void recreateRPCFilters() 343 | { 344 | cmdUnprotectRPCFLT(); 345 | createRPCFiltersFromConfiguration(); 346 | } 347 | 348 | void cmdProtectRPCFLT() 349 | { 350 | recreateRPCFilters(); 351 | } 352 | 353 | void cmdUpdateRPCFLT() 354 | { 355 | recreateRPCFilters(); 356 | } 357 | 358 | void cmdUpdate(std::wstring& param) 359 | { 360 | std::wstring errMsg = _T("usage: /update \n"); 361 | runCommandBasedOnParam(param, cmdUpdateRPCFLT, cmdUpdateRPCFW, errMsg); 362 | } 363 | 364 | void cmdPid(int procNum) 365 | { 366 | elevateCurrentProcessToSystem(); 367 | createAllGloblEvents(); 368 | readConfigAndMapToMemory(); 369 | 370 | if (procNum > 0) 371 | { 372 | _tprintf(TEXT("Enabling RPCFW for process : %d\n"), procNum); 373 | crawlProcesses(procNum); 374 | } 375 | else 376 | { 377 | _tprintf(TEXT("Enabling RPCFW for ALL processes\n")); 378 | crawlProcesses(0); 379 | } 380 | } 381 | 382 | void cmdUnprotectRPCFW() 383 | { 384 | _tprintf(TEXT("Dispatching unprotect request...\n")); 385 | sendSignalToGlobalEvent((wchar_t*)GLOBAL_RPCFW_EVENT_UNPROTECT, eventSignal::signalSetEvent); 386 | serviceStop(); 387 | } 388 | 389 | void cmdUnprotect(std::wstring& param) 390 | { 391 | std::wstring errMsg = _T("usage: /unprotect \n"); 392 | runCommandBasedOnParam(param, cmdUnprotectRPCFLT , cmdUnprotectRPCFW, errMsg); 393 | } 394 | 395 | void cmdInstallRPCFLT() 396 | { 397 | _tprintf(TEXT("installing RPCFLT Provider...\n")); 398 | installRPCFWProvider(); 399 | _tprintf(TEXT("enabling RPCFLT...\n")); 400 | if (!setSecurityPrivilege(TEXT("SeSecurityPrivilege"))) 401 | { 402 | _tprintf(TEXT("Error: could not obtain SeSecurityPrivilege.\n")); 403 | return; 404 | } 405 | enableAuditingForRPCFilters(); 406 | } 407 | 408 | void cmdInstallRPCFW() 409 | { 410 | _tprintf(TEXT("installing RPCFW...\n")); 411 | elevateCurrentProcessToSystem(); 412 | 413 | writeFileToSysfolder(getFullPathOfFile(std::wstring(RPC_FW_DLL_NAME)), RPC_FW_DLL_NAME); 414 | writeFileToSysfolder(getFullPathOfFile(std::wstring(RPC_MESSAGES_DLL_NAME)), RPC_MESSAGES_DLL_NAME); 415 | 416 | addEventSource(); 417 | 418 | serviceInstall(SERVICE_DEMAND_START); 419 | } 420 | 421 | void cmdProtectRPCFW() 422 | { 423 | serviceMakeAutostart(); 424 | serviceStart(); 425 | } 426 | 427 | void cmdProtect(std::wstring ¶m) 428 | { 429 | std::wstring errMsg = _T("usage: /protect \n"); 430 | runCommandBasedOnParam(param, cmdProtectRPCFLT, cmdProtectRPCFW, errMsg); 431 | } 432 | 433 | void cmdStatusRPCFLT() 434 | { 435 | outputMessage(L"\n----------------------"); 436 | outputMessage(L"RPC Filter status:"); 437 | outputMessage(L"----------------------"); 438 | 439 | /*bool isInstalled = isProviderInstalled(); 440 | std::wstring providerStat = isInstalled ? L"Provider installed" : L"Provider not installed"; 441 | outputMessage(providerStat.c_str());*/ 442 | 443 | outputMessage(L"\n\tinstallation:"); 444 | outputMessage(L"\t----------------------"); 445 | 446 | std::wstring auditing = isAuditingEnabledForRPCFilters() ? L"\tAuditing enabled" : L"\tAuditing not enabled"; 447 | outputMessage(auditing.c_str()); 448 | 449 | outputMessage(L"\n\tFilters:"); 450 | outputMessage(L"\t----------------------"); 451 | printAllRPCFilters(); 452 | 453 | } 454 | 455 | void cmdStatusRPCFW() 456 | { 457 | elevateCurrentProcessToSystem(); 458 | outputMessage(L"\n----------------------"); 459 | outputMessage(L"RPC Firewall status:"); 460 | outputMessage(L"----------------------"); 461 | 462 | std::wstringstream RPCFWFileState; 463 | RPCFWFileState << L"\t" << RPC_FW_DLL_NAME << (checkIfFileInSysFolder(RPC_FW_DLL_NAME) ? L" installed" : L" not installed"); 464 | std::wstringstream RPCMSGFileState; 465 | RPCMSGFileState << L"\t" << RPC_MESSAGES_DLL_NAME << (checkIfFileInSysFolder(RPC_MESSAGES_DLL_NAME) ? L" installed" : L" not installed"); 466 | std::wstringstream serviceInstalledState; 467 | serviceInstalledState << L"\t" << L"RPC Firewall Service" << (isServiceInstalled() ? L" installed" : L" not installed"); 468 | std::wstringstream eventState; 469 | eventState << L"\t" << L"RPC Firewall Event" << (checkIfEventConfiguredInReg() ? L" configured" : L" not configured"); 470 | 471 | outputMessage(RPCFWFileState.str().c_str()); 472 | outputMessage(RPCMSGFileState.str().c_str()); 473 | outputMessage(serviceInstalledState.str().c_str()); 474 | outputMessage(eventState.str().c_str()); 475 | if (isServiceInstalled()) printServiceState(); 476 | 477 | outputMessage(L"\n"); 478 | printProcessesWithRPCFW(); 479 | 480 | 481 | outputMessage(L"\n\tconfiguration:"); 482 | outputMessage(L"\t----------------------"); 483 | printMappedMeomryConfiguration(); 484 | 485 | } 486 | 487 | void cmdShowInterfaces() 488 | { 489 | elevateCurrentProcessToSystem(); 490 | outputMessage(L"\n"); 491 | printRPCEndpoints(); 492 | // printProtectedProcesses(); 493 | } 494 | 495 | void cmdStatus(std::wstring& param) 496 | { 497 | std::wstring errMsg = _T("usage: /status \n"); 498 | runCommandBasedOnParam(param, cmdStatusRPCFLT, cmdStatusRPCFW, errMsg); 499 | } 500 | 501 | void cmdProcess(std::wstring &processName) 502 | { 503 | createAllGloblEvents(); 504 | elevateCurrentProcessToSystem(); 505 | readConfigAndMapToMemory(); 506 | if (!processName.empty()) 507 | { 508 | std::wstring msg = L"Enabling RPCFW for process :"; 509 | msg += processName.c_str(); 510 | outputMessage(msg.c_str()); 511 | crawlProcesses(17, processName); 512 | } 513 | else 514 | { 515 | outputMessage(TEXT("Enabling RPCFW for ALL processes")); 516 | crawlProcesses(0, processName); 517 | } 518 | 519 | WaitForSingleObject(globalUnprotectEvent, 1000); 520 | } 521 | 522 | void cmdUninstallRPCFW() 523 | { 524 | outputMessage(TEXT("Uninstalling RPCFW ...")); 525 | elevateCurrentProcessToSystem(); 526 | serviceStop(); 527 | serviceMakeManual(); 528 | 529 | serviceUninstall(); 530 | 531 | deleteFileFromSysfolder(RPC_FW_DLL_NAME); 532 | deleteFileFromSysfolder(RPC_MESSAGES_DLL_NAME); 533 | 534 | if (deleteEventSource()) 535 | { 536 | outputMessage(TEXT("Event Log successfully removed...")); 537 | } 538 | else 539 | { 540 | outputMessage(TEXT("deleteEventSource failed: %d \n"), GetLastError()); 541 | } 542 | } 543 | 544 | void cmdUninstallRPCFLT() 545 | { 546 | cmdUnprotectRPCFLT(); 547 | disableAuditingForRPCFilters(); 548 | } 549 | 550 | void cmdUninstall(std::wstring ¶m) 551 | { 552 | std::wstring errMsg = _T("usage: /uninstall \n"); 553 | runCommandBasedOnParam(param, cmdUninstallRPCFLT, cmdUninstallRPCFW, errMsg); 554 | } 555 | 556 | void cmdInstall(std::wstring ¶m) 557 | { 558 | std::wstring errMsg = _T("usage: /install \n"); 559 | runCommandBasedOnParam(param, cmdInstallRPCFLT, cmdInstallRPCFW, errMsg); 560 | } 561 | 562 | int _tmain(int argc, wchar_t* argv[]) 563 | { 564 | interactive = !setupService(); 565 | 566 | if (interactive) 567 | { 568 | _tprintf(TEXT("RPCFW Manager started manually...\n")); 569 | } 570 | 571 | if (argc > 1) 572 | { 573 | std::wstring cmmd(argv[1]); 574 | std::wstring param; 575 | if (argc > 2) 576 | { 577 | param = std::wstring(argv[2]); 578 | } 579 | if (cmmd.find(_T("/uninstall")) != std::string::npos) 580 | { 581 | cmdUninstall(param); 582 | } 583 | else if (cmmd.find(_T("/stop")) != std::string::npos) 584 | { 585 | cmdUnprotect(param); 586 | } 587 | else if (cmmd.find(_T("/start")) != std::string::npos) 588 | { 589 | if (param.find(_T("pid")) != std::string::npos) 590 | { 591 | if (argc > 3) { 592 | int procNum = std::stoi((std::wstring)argv[3], nullptr, 10); 593 | cmdPid(procNum); 594 | } 595 | else 596 | { 597 | cmdPid(0); 598 | } 599 | } 600 | else if (param.find(_T("process")) != std::string::npos) 601 | { 602 | std::wstring processName; 603 | if (argc > 3) { 604 | processName = argv[3]; 605 | } 606 | cmdProcess(processName); 607 | } 608 | else 609 | { 610 | cmdProtect(param); 611 | } 612 | WaitForSingleObject(globalUnprotectEvent, 1000); 613 | } 614 | else if (cmmd.find(_T("/update")) != std::string::npos) 615 | { 616 | cmdUpdate(param); 617 | } 618 | else if (cmmd.find(_T("/install")) != std::string::npos) 619 | { 620 | cmdInstall(param); 621 | } 622 | else if (cmmd.find(_T("/status")) != std::string::npos) 623 | { 624 | cmdStatus(param); 625 | } 626 | else if (cmmd.find(_T("/int")) != std::string::npos) 627 | { 628 | cmdShowInterfaces(); 629 | } 630 | else 631 | { 632 | getHelp(); 633 | } 634 | } 635 | else 636 | { 637 | getHelp(); 638 | } 639 | return 0; 640 | } 641 | -------------------------------------------------------------------------------- /rpcFwManager/RpcFw.conf: -------------------------------------------------------------------------------- 1 | flt:action:block audit:true uuid:367ABB81-9844-35F1-AD32-98F038001003 2 | flt:addr:192.168.64.1 action:block audit:true uuid:1ff70682-0a51-30e8-076d-740be8cee98b 3 | uuid:df1941c5-fe89-4e79-bf10-463657acf44d action:block audit:true 4 | fw:uuid:c681d488-d850-11d0-8c52-00c04fd90f7e action:block audit:true 5 | flt:uuid:82273fdc-e32a-18c3-3f78-827929dc23ea action:block audit:true 6 | uuid:f6beaff7-1e19-4fbb-9f8f-b89e2018337c action:block audit:true 7 | fw:uuid:86d35949-83c9-4044-b424-db363231fd0c action:block audit:true 8 | fw:uuid:12345678-1234-abcd-ef00-0123456789ab action:block audit:true 9 | fw:uuid:76f03f96-cdfd-44fc-a22c-64950a001209 action:block audit:true 10 | fw:uuid:0b6edbfa-4a24-4fc6-8a23-942b1eca65d1 action:block audit:true 11 | fw:uuid:ae33069b-a2a8-46ee-a235-ddfd339be281 action:block audit:true 12 | fw:uuid:4d9f4ab8-7d1c-11cf-861e-0020af6e7c57 action:block audit:true 13 | uuid:99fcfec4-5260-101b-bbcb-00aa0021347a action:block audit:true 14 | uuid:000001a0-0000-0000-c000-000000000046 action:block audit:true 15 | uuid:00000131-0000-0000-c000-000000000046 action:block audit:true 16 | uuid:00000143-0000-0000-c000-000000000046 action:block audit:true 17 | uuid:00000000-0000-0000-c000-000000000046 action:block audit:true 18 | uuid:338cd001-2244-31f1-aaaa-900038001003 action:block audit:true 19 | uuid:367abb81-9844-35f1-ad32-98f038001003 action:block audit:true 20 | uuid:378e52b0-c0a9-11cf-822d-00aa0051e40f action:block audit:true 21 | uuid:6bffd098-a112-3610-9833-46c3f87e345a action:allow audit:true 22 | uuid:4b324fc8-1670-01d3-1278-5a47bf6ee188 action:allow audit:true 23 | uuid:12345778-1234-abcd-ef00-0123456789ac action:block audit:true 24 | uuid:12345778-1234-abcd-ef00-0123456789ab action:block audit:true 25 | uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: action:block audit:true 26 | uuid:e3514235-4b06-11d1-ab04-00c04fc2dcd2 addr: action:block audit:true 27 | -------------------------------------------------------------------------------- /rpcFwManager/common.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "common.h" 3 | 4 | bool interactive; 5 | HANDLE globalMappedMemory = nullptr; 6 | HANDLE globalUnprotectEvent = nullptr; 7 | 8 | CHAR configBuf[MEM_BUF_SIZE]; 9 | 10 | HANDLE mapNamedMemory() 11 | { 12 | HANDLE hMapFile = nullptr; 13 | SECURITY_ATTRIBUTES sa = { 0 }; 14 | PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 15 | 16 | if (createSecurityAttributes(&sa, psd)) 17 | { 18 | hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, MEM_BUF_SIZE, GLOBAL_SHARED_MEMORY); 19 | if (hMapFile == nullptr) 20 | { 21 | outputMessage(TEXT("Error calling CreateFileMapping %d.\n"), GetLastError()); 22 | } 23 | } 24 | 25 | LocalFree(psd); 26 | 27 | return hMapFile; 28 | } 29 | 30 | std::wstring StringToWString(const std::string& s) 31 | { 32 | std::wstring temp(s.length(), L' '); 33 | std::copy(s.begin(), s.end(), temp.begin()); 34 | return temp; 35 | } 36 | 37 | std::tuple getConfigOffsets(std::string confStr) 38 | { 39 | size_t start_pos = confStr.find("!start!"); 40 | size_t end_pos = confStr.find("!end!"); 41 | 42 | if (start_pos == std::string::npos || end_pos == std::string::npos) 43 | { 44 | outputMessage(_T("Error reading start or end markers")); 45 | return std::make_tuple(0, 0, false); 46 | } 47 | start_pos += 7; 48 | 49 | return std::make_tuple(start_pos, end_pos, true); 50 | } 51 | 52 | void printMappedMeomryConfiguration() 53 | { 54 | HANDLE hConfigurationMapFile = OpenFileMapping(FILE_MAP_READ, false, GLOBAL_SHARED_MEMORY); 55 | 56 | if (hConfigurationMapFile == nullptr) 57 | { 58 | outputMessage(L"\tNo RPC Firewall configuration loaded."); 59 | return; 60 | } 61 | 62 | char* mappedBuf = nullptr; 63 | mappedBuf = (char*)MapViewOfFile(hConfigurationMapFile, FILE_MAP_READ, 0, 0, MEM_BUF_SIZE); 64 | if (mappedBuf == nullptr) 65 | { 66 | outputMessage(TEXT("Error: Could not map view of configuration file."),GetLastError()); 67 | CloseHandle(hConfigurationMapFile); 68 | return; 69 | } 70 | 71 | std::string privateConfigBuffer = mappedBuf; 72 | 73 | auto markers = getConfigOffsets(privateConfigBuffer); 74 | size_t start_pos = std::get<0>(markers); 75 | size_t end_pos = std::get<1>(markers); 76 | 77 | std::string configurationOnly = privateConfigBuffer.substr(start_pos, end_pos - start_pos); 78 | 79 | std::basic_istringstream configStream(StringToWString(configurationOnly)); 80 | std::wstring confLineString; 81 | wchar_t configLine[256]; 82 | 83 | while (configStream.getline(configLine, 256)) 84 | { 85 | confLineString = L"\t"; 86 | confLineString += configLine; 87 | confLineString += _T(" "); 88 | 89 | if (_tcsstr(configLine, TEXT("fw:"))) 90 | { 91 | outputMessage(confLineString.c_str()); 92 | } 93 | } 94 | } 95 | 96 | std::wstring getProcessBinaryPath() 97 | { 98 | std::wstring binPath; 99 | HANDLE hProcess = GetCurrentProcess(); 100 | if (!hProcess) return binPath; 101 | 102 | wchar_t szBuffer[MAX_PATH]; 103 | ZeroMemory(szBuffer, sizeof(szBuffer)); 104 | DWORD dwSize = sizeof(szBuffer) / sizeof(szBuffer[0]) - 1; 105 | QueryFullProcessImageName(hProcess, 0, szBuffer, &dwSize); 106 | 107 | binPath = szBuffer; 108 | 109 | return binPath; 110 | } 111 | 112 | CHAR* readConfigFile(DWORD* bufLen) 113 | { 114 | std::wstring cfgFwPath = getProcessBinaryPath(); 115 | 116 | if (!cfgFwPath.empty()) 117 | { 118 | size_t offset = cfgFwPath.rfind(L"\\", cfgFwPath.length()); 119 | cfgFwPath = cfgFwPath.substr(0, offset); 120 | cfgFwPath = cfgFwPath + L"\\" + CONF_FILE_NAME; 121 | 122 | //std::wstring cfgFwPath = getFullPathOfFile(std::wstring(CONF_FILE_NAME)); 123 | HANDLE hFile = CreateFile(cfgFwPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); 124 | 125 | if (hFile == INVALID_HANDLE_VALUE) 126 | { 127 | outputMessage(TEXT("No configuration file found %d.\n"), GetLastError()); 128 | } 129 | else if (!ReadFile(hFile, configBuf, MEM_BUF_SIZE - 1, bufLen, nullptr)) 130 | { 131 | outputMessage(TEXT("ERROR: ReadFile %d.\n"), GetLastError()); 132 | 133 | } 134 | 135 | CloseHandle(hFile); 136 | } 137 | 138 | return configBuf; 139 | } 140 | 141 | std::string extractKeyValueFromConfig(std::string confLine, std::string key) 142 | { 143 | confLine += (" "); 144 | size_t keyOffset = confLine.find(key); 145 | 146 | if (keyOffset == std::string::npos) return "\0"; 147 | 148 | size_t nextKeyOffset = confLine.find(" ", keyOffset + 1); 149 | 150 | if (nextKeyOffset == std::string::npos) return "\0"; 151 | 152 | return confLine.substr(keyOffset + key.size(), nextKeyOffset - keyOffset - key.size()); 153 | } 154 | 155 | DWORD getConfigVersionNumber(CHAR* buff) 156 | { 157 | std::string buffString(buff); 158 | std::string version = extractKeyValueFromConfig(buffString, "ver:"); 159 | 160 | if (version.empty()) 161 | { 162 | return 0; 163 | } 164 | 165 | return std::stoi(version); 166 | } 167 | 168 | std::string addHeaderToBuffer(DWORD verNumber, CHAR* confBuf, DWORD bufSize) 169 | { 170 | std::string strToHash = confBuf; 171 | strToHash.resize(bufSize); 172 | size_t hashValue = std::hash{}(strToHash); 173 | 174 | return std::string("ver:" + std::to_string(verNumber) + " hash:" + std::to_string(hashValue) + "\r\n" + "!start!" + strToHash + "!end!"); 175 | } 176 | 177 | void readConfigAndMapToMemory() 178 | { 179 | outputMessage(L"About to read me some configurations..."); 180 | CHAR* pBuf; 181 | DWORD bytesRead = 0; 182 | CHAR* confBuf = readConfigFile(&bytesRead); 183 | std::string confBufHashed; 184 | 185 | if (bytesRead > 0) 186 | { 187 | globalMappedMemory = mapNamedMemory(); 188 | 189 | if (globalMappedMemory == nullptr) 190 | { 191 | outputMessage(L"No mapped memory! quitting..."); 192 | std::quick_exit(-1); 193 | } 194 | 195 | pBuf = (CHAR*)MapViewOfFile(globalMappedMemory, FILE_MAP_ALL_ACCESS, 0, 0, MEM_BUF_SIZE); 196 | if (pBuf == nullptr) 197 | { 198 | outputMessage(L"Error calling MapViewOfFile", GetLastError()); 199 | CloseHandle(globalMappedMemory); 200 | std::quick_exit(-1); 201 | } 202 | 203 | DWORD verNumber = getConfigVersionNumber(pBuf); 204 | confBufHashed = addHeaderToBuffer(verNumber + 1, confBuf, bytesRead); 205 | 206 | memset(pBuf, '\0', MEM_BUF_SIZE); 207 | const char* source = confBufHashed.c_str(); 208 | try 209 | { 210 | errno_t err = memcpy_s(pBuf, MEM_BUF_SIZE, source, confBufHashed.length()); 211 | if (err) 212 | { 213 | outputMessage(L"memcpy_s Error: failed to copy configuration to mapped memory."); 214 | } 215 | } 216 | catch (const std::exception& ex) 217 | { 218 | std::string what = ex.what(); 219 | std::wstring Wwhat = StringToWString(what); 220 | outputMessage(Wwhat.c_str()); 221 | } 222 | catch (...) 223 | { 224 | outputMessage(L"Unexpected exception!"); 225 | } 226 | outputMessage(L"Configuration mapped to memory."); 227 | } 228 | } 229 | 230 | bool createSecurityAttributes(SECURITY_ATTRIBUTES* psa, PSECURITY_DESCRIPTOR psd) 231 | { 232 | if (InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION) != 0) 233 | { 234 | if (SetSecurityDescriptorDacl(psd, true, nullptr, false) != 0) 235 | { 236 | (*psa).nLength = sizeof(*psa); 237 | (*psa).lpSecurityDescriptor = psd; 238 | (*psa).bInheritHandle = false; 239 | 240 | return true; 241 | } 242 | else 243 | { 244 | outputMessage(TEXT("SetSecurityDescriptorDacl failed : %d.\n"), GetLastError()); 245 | } 246 | } 247 | else 248 | { 249 | outputMessage(TEXT("InitializeSecurityDescriptor failed : %d.\n"), GetLastError()); 250 | } 251 | 252 | return false; 253 | } 254 | 255 | HANDLE createGlobalEvent(bool manualReset, bool initialState, wchar_t* eventName) 256 | { 257 | HANDLE gEvent = nullptr; 258 | SECURITY_ATTRIBUTES sa = { 0 }; 259 | PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 260 | 261 | //TODO: return value instead of passing as ref 262 | if (createSecurityAttributes(&sa, psd)) 263 | { 264 | gEvent = CreateEvent(&sa, manualReset, initialState, eventName); 265 | if (gEvent != nullptr) 266 | { 267 | if (ResetEvent(gEvent) == 0) 268 | { 269 | std::wstring msg = L"Error: ResetEvent for"; 270 | msg += eventName; 271 | msg += +L" failed with"; 272 | outputMessage(msg.c_str(), GetLastError()); 273 | } 274 | } 275 | else 276 | { 277 | std::wstring msg = L"Error: could not create or get a global event "; 278 | msg += eventName; 279 | outputMessage(msg.c_str(), GetLastError()); 280 | } 281 | } 282 | 283 | LocalFree(psd); 284 | 285 | return gEvent; 286 | } 287 | 288 | void createAllGloblEvents() 289 | { 290 | globalUnprotectEvent = createGlobalEvent(true, false, (wchar_t*)GLOBAL_RPCFW_EVENT_UNPROTECT); 291 | } 292 | 293 | void writeDebugMessage(const wchar_t* msg) 294 | { 295 | std::wstring dbgMsg = SERVICE_NAME; 296 | dbgMsg += L" : "; 297 | dbgMsg += msg; 298 | 299 | OutputDebugString(dbgMsg.c_str()); 300 | } 301 | 302 | void outputMessage(const wchar_t* msg) 303 | { 304 | std::wstring msgStr = msg; 305 | msgStr += L"\n"; 306 | 307 | if (interactive) _tprintf(msgStr.c_str()); 308 | else writeDebugMessage(msgStr.c_str()); 309 | } 310 | 311 | void outputMessage(const wchar_t* msg, DWORD errnum) 312 | { 313 | std::wstring msgStr = msg; 314 | msgStr += L" : "; 315 | msgStr += std::to_wstring(errnum); 316 | 317 | outputMessage(msgStr.c_str()); 318 | } 319 | 320 | std::wstring getFullPathOfFile(const std::wstring& filename) 321 | { 322 | wchar_t filePath[INFO_BUFFER_SIZE]; 323 | DWORD bufCharCount = INFO_BUFFER_SIZE; 324 | 325 | if (!GetCurrentDirectory(bufCharCount, filePath)) 326 | { 327 | outputMessage(TEXT("ERROR: Couldn't get the current directory"), GetLastError()); 328 | return std::wstring(); 329 | } 330 | 331 | return std::wstring(filePath) + _T("\\") + filename; 332 | } 333 | -------------------------------------------------------------------------------- /rpcFwManager/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | #define SERVICE_NAME _T("RPC Firewall") 5 | extern HANDLE globalMappedMemory; 6 | extern HANDLE globalUnprotectEvent; 7 | extern bool interactive; 8 | 9 | struct RpcInterface 10 | { 11 | std::wstring binding; 12 | std::wstring uuid; 13 | std::wstring szAnnot; 14 | std::wstring endpoint; 15 | std::wstring ppl; 16 | DWORD pid; 17 | }; 18 | 19 | typedef std::vector RpcInterfaceVector; 20 | 21 | std::wstring getFullPathOfFile(const std::wstring&); 22 | 23 | void writeDebugMessage(const wchar_t*); 24 | 25 | void outputMessage(const wchar_t*); 26 | 27 | void outputMessage(const wchar_t*, DWORD); 28 | 29 | bool createSecurityAttributes(SECURITY_ATTRIBUTES* , PSECURITY_DESCRIPTOR ); 30 | 31 | HANDLE createGlobalEvent(bool, bool, wchar_t*); 32 | 33 | void createAllGloblEvents(); 34 | 35 | void readConfigAndMapToMemory(); 36 | 37 | CHAR* readConfigFile(DWORD*); 38 | 39 | void printMappedMeomryConfiguration(); 40 | 41 | std::wstring StringToWString(const std::string&); 42 | 43 | std::tuple getConfigOffsets(std::string); -------------------------------------------------------------------------------- /rpcFwManager/elevation.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "elevation.h" 3 | 4 | 5 | HANDLE getAccessToken(DWORD pid, DWORD desiredAccess) 6 | { 7 | /* Retrieves an access token for a process */ 8 | HANDLE currentProcess = {}; 9 | HANDLE AccessToken = {}; 10 | DWORD LastError; 11 | try { 12 | if (pid == 0) 13 | { 14 | currentProcess = GetCurrentProcess(); 15 | } 16 | else 17 | { 18 | currentProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, true, pid); 19 | if (!currentProcess) 20 | { 21 | LastError = GetLastError(); 22 | _tprintf(TEXT("ERROR: OpenProcess %d(): %d\n"), pid,LastError); 23 | return nullptr; 24 | } 25 | } 26 | if (!OpenProcessToken(currentProcess, desiredAccess, &AccessToken)) 27 | { 28 | LastError = GetLastError(); 29 | _tprintf(TEXT("ERROR: OpenProcessToken %d: %d\n"), pid ,LastError); 30 | return nullptr; 31 | } 32 | return AccessToken; 33 | } 34 | catch (...) { 35 | LastError = GetLastError(); 36 | _tprintf(TEXT("Exception during GetAccessToken(): %d\n"), GetLastError()); 37 | } 38 | return nullptr; 39 | } 40 | 41 | DWORD getProcessIDFromName(wchar_t* procName) 42 | { 43 | PROCESSENTRY32 entry; 44 | entry.dwSize = sizeof(PROCESSENTRY32); 45 | DWORD pid = 0; 46 | 47 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 48 | 49 | if (Process32First(snapshot, &entry) == TRUE) 50 | { 51 | while (Process32Next(snapshot, &entry) == TRUE) 52 | { 53 | if (_wcsicmp(entry.szExeFile, procName) == 0) 54 | { 55 | pid = entry.th32ProcessID; 56 | } 57 | } 58 | } 59 | 60 | CloseHandle(snapshot); 61 | return pid; 62 | 63 | } 64 | 65 | bool amISYSTEM() 66 | { 67 | bool amisystem = false; 68 | 69 | HANDLE hToken; 70 | HANDLE hProcess; 71 | 72 | DWORD dwLengthNeeded; 73 | DWORD dwError = ERROR_SUCCESS; 74 | 75 | PTOKEN_MANDATORY_LABEL pTIL = nullptr; 76 | DWORD dwIntegrityLevel; 77 | 78 | hProcess = GetCurrentProcess(); 79 | if (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hToken)) 80 | { 81 | // Get the Integrity level. 82 | if (!GetTokenInformation(hToken, TokenIntegrityLevel, nullptr, 0, &dwLengthNeeded)) 83 | { 84 | dwError = GetLastError(); 85 | if (dwError == ERROR_INSUFFICIENT_BUFFER) 86 | { 87 | pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0,dwLengthNeeded); 88 | if (pTIL != nullptr) 89 | { 90 | if (GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwLengthNeeded, &dwLengthNeeded)) 91 | { 92 | dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1)); 93 | 94 | if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID) 95 | { 96 | // High Integrity 97 | amisystem = true; 98 | } 99 | } 100 | LocalFree(pTIL); 101 | } 102 | } 103 | } 104 | CloseHandle(hToken); 105 | } 106 | return amisystem; 107 | } 108 | 109 | bool setPrivilege( 110 | HANDLE hToken, // access token handle 111 | LPCTSTR lpszPrivilege, // name of privilege to enable/disable 112 | bool bEnablePrivilege // to enable or disable privilege 113 | ) 114 | { 115 | TOKEN_PRIVILEGES tp; 116 | LUID luid; 117 | 118 | if (!LookupPrivilegeValue( 119 | nullptr, // lookup privilege on local system 120 | lpszPrivilege, // privilege to lookup 121 | &luid)) // receives LUID of privilege 122 | { 123 | _tprintf(TEXT("LookupPrivilegeValue error: %u\n"), GetLastError()); 124 | return false; 125 | } 126 | 127 | tp.PrivilegeCount = 1; 128 | tp.Privileges[0].Luid = luid; 129 | if (bEnablePrivilege) 130 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 131 | else 132 | tp.Privileges[0].Attributes = 0; 133 | 134 | // Enable the privilege or disable all privileges. 135 | 136 | if (!AdjustTokenPrivileges( 137 | hToken, 138 | false, 139 | &tp, 140 | sizeof(TOKEN_PRIVILEGES), 141 | (PTOKEN_PRIVILEGES)nullptr, 142 | (PDWORD)nullptr)) 143 | { 144 | _tprintf(TEXT("AdjustTokenPrivileges error: %u\n"), GetLastError()); 145 | return false; 146 | } 147 | 148 | if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 149 | 150 | { 151 | _tprintf(TEXT("The token does not have the specified privilege. \n")); 152 | return false; 153 | } 154 | 155 | return true; 156 | } 157 | 158 | bool setSecurityPrivilege(const wchar_t* privName) 159 | { 160 | return setPrivilege(getAccessToken(0, TOKEN_ADJUST_PRIVILEGES), privName, true); 161 | } 162 | 163 | void tryAndRunElevated(DWORD pid) 164 | { 165 | // Enable core privileges 166 | if (!setSecurityPrivilege(TEXT("SeDebugPrivilege"))) 167 | { 168 | _tprintf(TEXT("Could not get debug privileges!\n")); 169 | return; 170 | } 171 | 172 | if (!amISYSTEM()) 173 | { 174 | // Retrieves the remote process token. 175 | HANDLE pToken = getAccessToken(pid, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY); 176 | if (pToken) 177 | { 178 | //These are required to call DuplicateTokenEx. 179 | SECURITY_IMPERSONATION_LEVEL seImpersonateLevel = SecurityImpersonation; 180 | 181 | if (!ImpersonateLoggedOnUser(pToken)) 182 | { 183 | _tprintf(TEXT("ERROR: Could not impersonate SYSTEM [%d]\n"), GetLastError()); 184 | return; 185 | } 186 | 187 | wchar_t Imp_usrename[200]; 188 | DWORD name_len = 200; 189 | GetUserName(Imp_usrename, &name_len); 190 | //_tprintf(TEXT("Running as: %s\n"), Imp_usrename); 191 | } 192 | } 193 | } 194 | 195 | void elevateCurrentProcessToSystem() 196 | { 197 | wchar_t sysProcessName[] = TEXT("winlogon.exe"); 198 | tryAndRunElevated(getProcessIDFromName(sysProcessName)); 199 | } 200 | -------------------------------------------------------------------------------- /rpcFwManager/elevation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void tryAndRunElevated(DWORD pid); 4 | 5 | void elevateCurrentProcessToSystem(); 6 | 7 | bool setSecurityPrivilege(const wchar_t*); -------------------------------------------------------------------------------- /rpcFwManager/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /rpcFwManager/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by RPCrawler.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /rpcFwManager/rpcFwManager.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {e8206bb0-87fa-4723-b993-d1859d7f15de} 25 | RPCrawler 26 | 10.0 27 | rpcFwManager 28 | 29 | 30 | 31 | Application 32 | true 33 | v142 34 | Unicode 35 | 36 | 37 | Application 38 | false 39 | v142 40 | true 41 | Unicode 42 | 43 | 44 | Application 45 | true 46 | v143 47 | Unicode 48 | 49 | 50 | Application 51 | false 52 | true 53 | Unicode 54 | v143 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | C:\Users\sagie\source\repos\RPCrawler\easyhook\Deploy\NetFX3.5;$(LibraryPath) 77 | C:\Users\sagie\source\repos\RPCrawler\easyhook\Deploy\NetFX3.5;$(IncludePath) 78 | 79 | 80 | false 81 | C:\Users\sagie\source\repos\RPCrawler\easyhook\Deploy\NetFX3.5;$(IncludePath) 82 | C:\Users\sagie\source\repos\RPCrawler\easyhook\Deploy\NetFX3.5;$(LibraryPath) 83 | 84 | 85 | true 86 | $(IncludePath) 87 | $(LibraryPath) 88 | 89 | 90 | false 91 | $(IncludePath) 92 | $(LibraryPath) 93 | 94 | 95 | 96 | Level3 97 | true 98 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 99 | true 100 | $(SolutionDir)rpcMessages\ 101 | 102 | 103 | Console 104 | true 105 | EasyHook32.lib;%(AdditionalDependencies) 106 | 107 | 108 | copy /Y "$(SolutionDir)easyhook\Deploy\NetFX3.5\EasyHook*.dll" $(TargetDir) 109 | copy /Y "$(SolutionDir)easyhook\Deploy\NetFX3.5\EasyHook*.lib" $(TargetDir) 110 | 111 | 112 | 113 | 114 | Level3 115 | true 116 | true 117 | true 118 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 119 | true 120 | $(SolutionDir)rpcMessages\ 121 | 122 | 123 | Console 124 | true 125 | true 126 | true 127 | EasyHook32.lib;%(AdditionalDependencies) 128 | 129 | 130 | copy /Y "$(SolutionDir)easyhook\Deploy\NetFX3.5\EasyHook*.dll" $(TargetDir) 131 | 132 | 133 | 134 | 135 | Level3 136 | true 137 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 138 | true 139 | $(SolutionDir)rpcMessages\ 140 | stdcpp20 141 | MultiThreadedDebugDLL 142 | 143 | 144 | Console 145 | true 146 | Fwpuclnt.lib;psapi.lib;Rpcrt4.lib;%(AdditionalDependencies) 147 | AsInvoker 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | Level3 157 | true 158 | true 159 | true 160 | NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) 161 | true 162 | MultiThreaded 163 | false 164 | $(SolutionDir)rpcMessages\ 165 | stdcpp20 166 | 167 | 168 | Console 169 | true 170 | true 171 | true 172 | Fwpuclnt.lib;psapi.lib;Rpcrt4.lib;%(AdditionalDependencies) 173 | HighestAvailable 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | {48dc6dd2-92b9-49d9-ad47-a014e863fe60} 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /rpcFwManager/rpcFwManager.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /rpcFwManager/rpcHooks.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | static long (WINAPI* realNdrStubCall2)(void* pThis, void* pChannel, PRPC_MESSAGE pRpcMsg, unsigned long* pdwStubPhase) = NdrStubCall2; 11 | long WINAPI myNdrStubCall2(void* pThis, void* pChannel, PRPC_MESSAGE pRpcMsg, unsigned long* pdwStubPhase); 12 | 13 | static long (WINAPI* realNdrStubCall3)(void* pThis, void* pChannel, PRPC_MESSAGE pRpcMsg, unsigned long* pdwStubPhase) = NdrStubCall3; 14 | long WINAPI myNdrStubCall3(void* pThis, void* pChannel, PRPC_MESSAGE pRpcMsg, unsigned long* pdwStubPhase); 15 | 16 | static void (WINAPI* realNdrServerCallAll)(PRPC_MESSAGE pRpcMsg) = NdrServerCallAll; 17 | void WINAPI myNdrServerCallAll(PRPC_MESSAGE pRpcMsg); 18 | 19 | static void (WINAPI* realNdrAsyncServerCall)(PRPC_MESSAGE pRpcMsg) = NdrAsyncServerCall; 20 | void WINAPI myNdrAsyncServerCall(PRPC_MESSAGE pRpcMsg); 21 | 22 | static void (WINAPI* realNdr64AsyncServerCallAll)(PRPC_MESSAGE pRpcMsg) = Ndr64AsyncServerCallAll; 23 | void WINAPI myNdr64AsyncServerCallAll(PRPC_MESSAGE pRpcMsg); 24 | 25 | static void (WINAPI* realNdr64AsyncServerCall64)(PRPC_MESSAGE pRpcMsg) = Ndr64AsyncServerCall64; 26 | void WINAPI myNdr64AsyncServerCall64(PRPC_MESSAGE pRpcMsg); 27 | 28 | static void (WINAPI* realNdrServerCallNdr64)(PRPC_MESSAGE pRpcMsg) = NdrServerCallNdr64; 29 | void WINAPI myNdrServerCallNdr64(PRPC_MESSAGE pRpcMsg); 30 | 31 | std::wofstream outfile; 32 | 33 | DWORD gFreqOffset = 0; 34 | 35 | std::ostream& hex_dump(std::ostream& os, const void* buffer, 36 | std::size_t bufsize, bool showPrintableChars = true) 37 | { 38 | if (buffer == nullptr) { 39 | return os; 40 | } 41 | auto oldFormat = os.flags(); 42 | auto oldFillChar = os.fill(); 43 | constexpr std::size_t maxline{ 8 }; 44 | // create a place to store text version of string 45 | char renderString[maxline + 1]; 46 | char* rsptr{ renderString }; 47 | // convenience cast 48 | const unsigned char* buf{ reinterpret_cast(buffer) }; 49 | 50 | for (std::size_t linecount = maxline; bufsize; --bufsize, ++buf) { 51 | os << std::setw(2) << std::setfill('0') << std::hex 52 | << static_cast(*buf) << ' '; 53 | *rsptr++ = std::isprint(*buf) ? *buf : '.'; 54 | if (--linecount == 0) { 55 | *rsptr++ = '\0'; // terminate string 56 | if (showPrintableChars) { 57 | os << " | " << renderString; 58 | } 59 | os << '\n'; 60 | rsptr = renderString; 61 | linecount = min(maxline, bufsize); 62 | } 63 | } 64 | // emit newline if we haven't already 65 | if (rsptr != renderString) { 66 | if (showPrintableChars) { 67 | for (*rsptr++ = '\0'; rsptr != &renderString[maxline + 1]; ++rsptr) { 68 | os << " "; 69 | } 70 | os << " | " << renderString; 71 | } 72 | os << '\n'; 73 | } 74 | } 75 | 76 | struct hexDump { 77 | const void* buffer; 78 | std::size_t bufsize; 79 | hexDump(const void* buf, std::size_t bufsz) : buffer{ buf }, bufsize{ bufsz } {} 80 | friend std::ostream& operator<<(std::ostream& out, const hexDump& hd) { 81 | return hex_dump(out, hd.buffer, hd.bufsize, true); 82 | } 83 | }; 84 | 85 | constexpr char hexmap[] = { '0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 86 | 87 | std::wstring hexStr(unsigned char* data, int len) 88 | { 89 | std::wstring s(len * 2, ' '); 90 | for (int i = 0; i < len; ++i) { 91 | s[2 * i] = hexmap[(data[i] & 0xF0) >> 4]; 92 | s[2 * i + 1] = hexmap[data[i] & 0x0F]; 93 | } 94 | return s; 95 | } 96 | 97 | long WINAPI myNdrStubCall2(void* pThis, void* pChannel, PRPC_MESSAGE pRpcMsg, unsigned long* pdwStubPhase) 98 | { 99 | RPC_BINDING_HANDLE serverBinding; 100 | wchar_t* szStringBinding; 101 | std::wstring szWstringBinding; 102 | UUID serverObjectUuid; 103 | RPC_CSTR szStringUuid; 104 | UUID* uuidPointer; 105 | byte* byteUuidPointer; 106 | unsigned char uuidData[20]; 107 | std::wostringstream rpcEventLine; 108 | 109 | try { 110 | 111 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 112 | if (status == RPC_S_OK) { 113 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 114 | if (status == RPC_S_OK) { 115 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 116 | rpcEventLine << "NdrStubCall2,"; 117 | szWstringBinding = std::wstring(szStringBinding); 118 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1,L",", 1); 119 | size_t pos = szWstringBinding.find(L":", 0); 120 | if (pos != std::string::npos) { 121 | szWstringBinding.replace(pos, 1, L","); 122 | } 123 | rpcEventLine << szWstringBinding << L","; 124 | 125 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 126 | if (status == RPC_S_OK) { 127 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 128 | 129 | memcpy(&uuidData, byteUuidPointer + 8, 20); 130 | rpcEventLine << hexStr(&uuidData[15], 1) << hexStr(&uuidData[14], 1) << hexStr(&uuidData[13], 1) << hexStr(&uuidData[12], 1) << "-" << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << "-" << hexStr(&uuidData[4], 2) << "-" << hexStr(&uuidData[6], 6); 131 | //outfile << "UUID: " << hexStr(&uuidData[15], 1) << hexStr(&uuidData[14], 1) << hexStr(&uuidData[13], 1) << hexStr(&uuidData[12], 1) << "-" << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << "-" << hexStr(&uuidData[4], 2) << "-" << hexStr(&uuidData[6], 6) << std::endl; 132 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 133 | outfile << rpcEventLine.str() << std::endl; 134 | } 135 | else 136 | { 137 | outfile << "RpcBindingInqObject failed....: " << std::endl; 138 | } 139 | } 140 | } 141 | else { 142 | outfile << "Not good:(\n" << std::endl; 143 | } 144 | } 145 | } 146 | catch (const std::runtime_error& re) { 147 | outfile << "ERORR: runtime " << re.what() << std::endl; 148 | } 149 | catch (const std::exception& ex) { 150 | outfile << "ERORR: exception " << ex.what() << std::endl; 151 | } 152 | catch (...) { 153 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 154 | } 155 | 156 | return realNdrStubCall2(pThis, pChannel, pRpcMsg, pdwStubPhase); 157 | } 158 | 159 | long WINAPI myNdrStubCall3(void* pThis, void* pChannel, PRPC_MESSAGE pRpcMsg, unsigned long* pdwStubPhase) 160 | { 161 | RPC_BINDING_HANDLE serverBinding; 162 | wchar_t* szStringBinding; 163 | std::wstring szWstringBinding; 164 | UUID serverObjectUuid; 165 | RPC_CSTR szStringUuid; 166 | UUID* uuidPointer; 167 | byte* byteUuidPointer; 168 | unsigned char uuidData[20]; 169 | std::wostringstream rpcEventLine; 170 | 171 | try { 172 | 173 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 174 | if (status == RPC_S_OK) { 175 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 176 | if (status == RPC_S_OK) { 177 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 178 | rpcEventLine << "myNdrStubCall3,"; 179 | szWstringBinding = std::wstring(szStringBinding); 180 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1,L",", 1); 181 | size_t pos = szWstringBinding.find(L":", 0); 182 | if (pos != std::string::npos) { 183 | szWstringBinding.replace(pos, 1, L","); 184 | } 185 | rpcEventLine << szWstringBinding << L","; 186 | 187 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 188 | if (status == RPC_S_OK) { 189 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 190 | 191 | memcpy(&uuidData, byteUuidPointer + 8, 20); 192 | rpcEventLine << hexStr(&uuidData[15], 1) << hexStr(&uuidData[14], 1) << hexStr(&uuidData[13], 1) << hexStr(&uuidData[12], 1) << "-" << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << "-" << hexStr(&uuidData[4], 2) << "-" << hexStr(&uuidData[6], 6); 193 | //outfile << "UUID: " << hexStr(&uuidData[15], 1) << hexStr(&uuidData[14], 1) << hexStr(&uuidData[13], 1) << hexStr(&uuidData[12], 1) << "-" << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << "-" << hexStr(&uuidData[4], 2) << "-" << hexStr(&uuidData[6], 6) << std::endl; 194 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 195 | outfile << rpcEventLine.str() << std::endl; 196 | } 197 | else 198 | { 199 | outfile << "RpcBindingInqObject failed....: " << std::endl; 200 | } 201 | } 202 | } 203 | else { 204 | outfile << "Not good:(\n" << std::endl; 205 | } 206 | } 207 | } 208 | catch (const std::runtime_error& re) { 209 | outfile << "ERORR: runtime " << re.what() << std::endl; 210 | } 211 | catch (const std::exception& ex) { 212 | outfile << "ERORR: exception " << ex.what() << std::endl; 213 | } 214 | catch (...) { 215 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 216 | } 217 | 218 | 219 | return realNdrStubCall3(pThis, pChannel, pRpcMsg, pdwStubPhase); 220 | } 221 | 222 | void myNdrServerCallAll(PRPC_MESSAGE pRpcMsg) 223 | { 224 | RPC_BINDING_HANDLE serverBinding; 225 | wchar_t* szStringBinding; 226 | UUID serverObjectUuid; 227 | RPC_CSTR szStringUuid; 228 | UUID* uuidPointer; 229 | byte* byteUuidPointer; 230 | unsigned char uuidData[20]; 231 | std::wostringstream rpcEventLine; 232 | std::wstring szWstringBinding; 233 | try { 234 | 235 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 236 | if (status == RPC_S_OK) { 237 | 238 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 239 | if (status == RPC_S_OK) { 240 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 241 | rpcEventLine << L"myNdrServerCallAll,"; 242 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1, L",", 1); 243 | //outfile << "myNdrServerCallAll called, ...\n" << std::endl; 244 | //outfile << szStringBinding << std::endl; 245 | szWstringBinding = std::wstring(szStringBinding); 246 | size_t pos = szWstringBinding.find(L":", 0); 247 | if (pos != std::string::npos) { 248 | szWstringBinding.replace(pos, 1, L","); 249 | } 250 | rpcEventLine << szWstringBinding << ","; 251 | 252 | 253 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 254 | if (status == RPC_S_OK) { 255 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 256 | 257 | memcpy(&uuidData, byteUuidPointer + 4, 20); 258 | //outfile << "UUID: " << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6) << std::endl; 259 | rpcEventLine << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6); 260 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 261 | outfile << rpcEventLine.str() << std::endl; 262 | } 263 | else 264 | { 265 | outfile << "RpcBindingInqObject failed....: " << std::endl; 266 | } 267 | } 268 | } 269 | else { 270 | outfile << "Not good:(\n" << std::endl; 271 | } 272 | } 273 | } 274 | catch (const std::runtime_error& re) { 275 | outfile << "ERORR: runtime " << re.what() << std::endl; 276 | } 277 | catch (const std::exception& ex) { 278 | outfile << "ERORR: exception " << ex.what() << std::endl; 279 | } 280 | catch (...) { 281 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 282 | } 283 | return realNdrServerCallAll(pRpcMsg); 284 | } 285 | 286 | void myNdrAsyncServerCall(PRPC_MESSAGE pRpcMsg) 287 | { 288 | RPC_BINDING_HANDLE serverBinding; 289 | wchar_t* szStringBinding; 290 | UUID serverObjectUuid; 291 | RPC_CSTR szStringUuid; 292 | UUID* uuidPointer; 293 | byte* byteUuidPointer; 294 | unsigned char uuidData[20]; 295 | std::wostringstream rpcEventLine; 296 | std::wstring szWstringBinding; 297 | 298 | try { 299 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 300 | if (status == RPC_S_OK) { 301 | 302 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 303 | if (status == RPC_S_OK) { 304 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 305 | rpcEventLine << L"NdrAsyncServerCall,"; 306 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1, L",", 1); 307 | //outfile << "myNdrServerCallAll called, ...\n" << std::endl; 308 | //outfile << szStringBinding << std::endl; 309 | szWstringBinding = std::wstring(szStringBinding); 310 | size_t pos = szWstringBinding.find(L":", 0); 311 | if (pos != std::string::npos) { 312 | szWstringBinding.replace(pos, 1, L","); 313 | } 314 | rpcEventLine << szWstringBinding << ","; 315 | 316 | 317 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 318 | if (status == RPC_S_OK) { 319 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 320 | 321 | memcpy(&uuidData, byteUuidPointer + 4, 20); 322 | //outfile << "UUID: " << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6) << std::endl; 323 | rpcEventLine << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6); 324 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 325 | outfile << rpcEventLine.str() << std::endl; 326 | } 327 | else 328 | { 329 | outfile << "RpcBindingInqObject failed....: " << std::endl; 330 | } 331 | } 332 | } 333 | else { 334 | outfile << "Not good:(\n" << std::endl; 335 | } 336 | } 337 | } 338 | catch (const std::runtime_error& re) { 339 | outfile << "ERORR: runtime " << re.what() << std::endl; 340 | } 341 | catch (const std::exception& ex) { 342 | outfile << "ERORR: exception " << ex.what() << std::endl; 343 | } 344 | catch (...) { 345 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 346 | } 347 | return realNdrAsyncServerCall(pRpcMsg); 348 | } 349 | 350 | void myNdr64AsyncServerCallAll(PRPC_MESSAGE pRpcMsg) 351 | { 352 | RPC_BINDING_HANDLE serverBinding; 353 | wchar_t* szStringBinding; 354 | UUID serverObjectUuid; 355 | RPC_CSTR szStringUuid; 356 | UUID* uuidPointer; 357 | byte* byteUuidPointer; 358 | unsigned char uuidData[20]; 359 | std::wostringstream rpcEventLine; 360 | std::wstring szWstringBinding; 361 | 362 | try { 363 | 364 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 365 | if (status == RPC_S_OK) { 366 | 367 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 368 | if (status == RPC_S_OK) { 369 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 370 | rpcEventLine << L"Ndr64AsyncServerCallAll,"; 371 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1, L",", 1); 372 | //outfile << "myNdrServerCallAll called, ...\n" << std::endl; 373 | //outfile << szStringBinding << std::endl; 374 | szWstringBinding = std::wstring(szStringBinding); 375 | size_t pos = szWstringBinding.find(L":", 0); 376 | if (pos != std::string::npos) { 377 | szWstringBinding.replace(pos, 1, L","); 378 | } 379 | rpcEventLine << szWstringBinding << ","; 380 | 381 | 382 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 383 | if (status == RPC_S_OK) { 384 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 385 | 386 | memcpy(&uuidData, byteUuidPointer + 4, 20); 387 | //outfile << "UUID: " << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6) << std::endl; 388 | rpcEventLine << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6); 389 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 390 | outfile << rpcEventLine.str() << std::endl; 391 | } 392 | else 393 | { 394 | outfile << "RpcBindingInqObject failed....: " << std::endl; 395 | } 396 | } 397 | } 398 | else { 399 | outfile << "Not good:(\n" << std::endl; 400 | } 401 | } 402 | } 403 | catch (const std::runtime_error& re) { 404 | outfile << "ERORR: runtime " << re.what() << std::endl; 405 | } 406 | catch (const std::exception& ex) { 407 | outfile << "ERORR: exception " << ex.what() << std::endl; 408 | } 409 | catch (...) { 410 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 411 | } 412 | return realNdr64AsyncServerCallAll(pRpcMsg); 413 | } 414 | 415 | void myNdr64AsyncServerCall64(PRPC_MESSAGE pRpcMsg) 416 | { 417 | RPC_BINDING_HANDLE serverBinding; 418 | wchar_t* szStringBinding; 419 | UUID serverObjectUuid; 420 | RPC_CSTR szStringUuid; 421 | UUID* uuidPointer; 422 | byte* byteUuidPointer; 423 | unsigned char uuidData[20]; 424 | std::wostringstream rpcEventLine; 425 | std::wstring szWstringBinding; 426 | 427 | try { 428 | 429 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 430 | if (status == RPC_S_OK) { 431 | 432 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 433 | if (status == RPC_S_OK) { 434 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 435 | rpcEventLine << L"Ndr64AsyncServerCall64,"; 436 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1, L",", 1); 437 | //outfile << "myNdrServerCallAll called, ...\n" << std::endl; 438 | //outfile << szStringBinding << std::endl; 439 | szWstringBinding = std::wstring(szStringBinding); 440 | size_t pos = szWstringBinding.find(L":", 0); 441 | if (pos != std::string::npos) { 442 | szWstringBinding.replace(pos, 1, L","); 443 | } 444 | rpcEventLine << szWstringBinding << ","; 445 | 446 | 447 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 448 | if (status == RPC_S_OK) { 449 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 450 | 451 | memcpy(&uuidData, byteUuidPointer + 4, 20); 452 | //outfile << "UUID: " << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6) << std::endl; 453 | rpcEventLine << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6); 454 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 455 | outfile << rpcEventLine.str() << std::endl; 456 | } 457 | else 458 | { 459 | outfile << "RpcBindingInqObject failed....: " << std::endl; 460 | } 461 | } 462 | } 463 | else { 464 | outfile << "Not good:(\n" << std::endl; 465 | } 466 | } 467 | } 468 | catch (const std::runtime_error& re) { 469 | outfile << "ERORR: runtime " << re.what() << std::endl; 470 | } 471 | catch (const std::exception& ex) { 472 | outfile << "ERORR: exception " << ex.what() << std::endl; 473 | } 474 | catch (...) { 475 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 476 | } 477 | return realNdr64AsyncServerCall64(pRpcMsg); 478 | } 479 | 480 | void myNdrServerCallNdr64(PRPC_MESSAGE pRpcMsg) 481 | { 482 | RPC_BINDING_HANDLE serverBinding; 483 | wchar_t* szStringBinding; 484 | UUID serverObjectUuid; 485 | RPC_CSTR szStringUuid; 486 | UUID* uuidPointer; 487 | byte* byteUuidPointer; 488 | unsigned char uuidData[20]; 489 | std::wostringstream rpcEventLine; 490 | std::wstring szWstringBinding; 491 | 492 | try { 493 | 494 | RPC_STATUS status = RpcBindingServerFromClient(0, &serverBinding); 495 | if (status == RPC_S_OK) { 496 | 497 | status = RpcBindingToStringBinding(serverBinding, (RPC_WSTR*)&szStringBinding); 498 | if (status == RPC_S_OK) { 499 | if (wcsstr(szStringBinding, L"ncacn_ip_tcp") || wcsstr(szStringBinding, L"ncacn_nb_tcp") || wcsstr(szStringBinding, L"ncacn_np")) { 500 | rpcEventLine << L"NdrServerCallNdr64,"; 501 | //wcsncpy_s(wcsstr(szStringBinding, L":"), 1, L",", 1); 502 | //outfile << "myNdrServerCallAll called, ...\n" << std::endl; 503 | //outfile << szStringBinding << std::endl; 504 | szWstringBinding = std::wstring(szStringBinding); 505 | size_t pos = szWstringBinding.find(L":", 0); 506 | if (pos != std::string::npos) { 507 | szWstringBinding.replace(pos, 1, L","); 508 | } 509 | rpcEventLine << szWstringBinding << ","; 510 | 511 | 512 | status = RpcBindingInqObject(serverBinding, &serverObjectUuid); 513 | if (status == RPC_S_OK) { 514 | byteUuidPointer = (byte*)pRpcMsg->RpcInterfaceInformation; 515 | 516 | memcpy(&uuidData, byteUuidPointer + 4, 20); 517 | //outfile << "UUID: " << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6) << std::endl; 518 | rpcEventLine << hexStr(&uuidData[3], 1) << hexStr(&uuidData[2], 1) << hexStr(&uuidData[1], 1) << hexStr(&uuidData[0], 1) << "-" << hexStr(&uuidData[5], 1) << hexStr(&uuidData[4], 1) << "-" << hexStr(&uuidData[7], 1) << hexStr(&uuidData[6], 1) << "-" << hexStr(&uuidData[8], 2) << "-" << hexStr(&uuidData[10], 6); 519 | rpcEventLine << "," << std::to_wstring(pRpcMsg->ProcNum); 520 | outfile << rpcEventLine.str() << std::endl; 521 | } 522 | else 523 | { 524 | outfile << "RpcBindingInqObject failed....: " << std::endl; 525 | } 526 | } 527 | } 528 | else { 529 | outfile << "Not good:(\n" << std::endl; 530 | } 531 | } 532 | } 533 | catch (const std::runtime_error& re) { 534 | outfile << "ERORR: runtime " << re.what() << std::endl; 535 | } 536 | catch (const std::exception& ex) { 537 | outfile << "ERORR: exception " << ex.what() << std::endl; 538 | } 539 | catch (...) { 540 | outfile << "ERORR: Unknown failure occurred. Possible memory corruption " << std::endl; 541 | } 542 | return realNdrServerCallNdr64(pRpcMsg); 543 | } 544 | 545 | void ErrorExit(LPTSTR lpszFunction) 546 | { 547 | // Retrieve the system error message for the last-error code 548 | 549 | LPVOID lpMsgBuf; 550 | LPVOID lpDisplayBuf; 551 | DWORD dw = GetLastError(); 552 | 553 | FormatMessage( 554 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 555 | FORMAT_MESSAGE_FROM_SYSTEM | 556 | FORMAT_MESSAGE_IGNORE_INSERTS, 557 | NULL, 558 | dw, 559 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 560 | (LPTSTR)&lpMsgBuf, 561 | 0, NULL); 562 | 563 | // Display the error message and exit the process 564 | 565 | lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 566 | (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 567 | StringCchPrintf((LPTSTR)lpDisplayBuf, 568 | LocalSize(lpDisplayBuf) / sizeof(TCHAR), 569 | TEXT("%s failed with error %d: %s"), 570 | lpszFunction, dw, lpMsgBuf); 571 | MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 572 | 573 | LocalFree(lpMsgBuf); 574 | LocalFree(lpDisplayBuf); 575 | ExitProcess(dw); 576 | } 577 | 578 | DWORD InjectionEntryPoint() 579 | { 580 | try { 581 | FILE* fptr; 582 | //fptr = fopen("c:\\rpcrawler.log", "a+"); 583 | //if (fptr != NULL) { 584 | // fprintf(fptr,"HELLO!\n"); 585 | //} 586 | //fclose(fptr); 587 | 588 | /*outfile.open("rpcrawler.log", std::ios_base::app); 589 | DetourTransactionBegin(); 590 | DetourUpdateThread(GetCurrentThread()); 591 | 592 | DetourAttach(&(PVOID&)realNdrStubCall2, myNdrStubCall2); 593 | DetourAttach(&(PVOID&)realNdrStubCall3, myNdrStubCall3); 594 | DetourAttach(&(PVOID&)realNdrServerCallAll, myNdrServerCallAll); 595 | DetourAttach(&(PVOID&)realNdrAsyncServerCall, myNdrAsyncServerCall); 596 | DetourAttach(&(PVOID&)realNdr64AsyncServerCallAll, myNdr64AsyncServerCallAll); 597 | DetourAttach(&(PVOID&)realNdr64AsyncServerCall64, myNdr64AsyncServerCall64); 598 | DetourAttach(&(PVOID&)realNdrServerCallNdr64, myNdrServerCallNdr64); 599 | 600 | 601 | if (DetourTransactionCommit() == NO_ERROR) 602 | OutputDebugString(TEXT("Detoured successfully"));*/ 603 | } 604 | catch (int e) { 605 | TCHAR moduleName[128] = L""; 606 | GetModuleFileName(NULL, moduleName, sizeof(moduleName)); 607 | ErrorExit(moduleName); 608 | //MessageBoxA(NULL, "An exception occurred.Exception Nr. " + e , moduleName, NULL); 609 | } 610 | 611 | return 0; 612 | } -------------------------------------------------------------------------------- /rpcFwManager/rpcfilters.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | using OpNumFilter = std::optional; 5 | using UUIDFilter = std::optional; 6 | using AddressFilter = std::optional; 7 | using SIDFilter = std::optional; 8 | using protocolFilter = std::optional; 9 | 10 | struct RpcCallPolicy 11 | { 12 | bool allow = true; 13 | bool audit = false; 14 | }; 15 | 16 | struct LineConfig 17 | { 18 | UUIDFilter uuid; 19 | OpNumFilter opnum; 20 | AddressFilter min_addr; 21 | RpcCallPolicy policy; 22 | SIDFilter sid; 23 | protocolFilter protocol; 24 | bool verbose; 25 | }; 26 | 27 | typedef std::vector> configLinesVector; 28 | 29 | void enableAuditingForRPCFilters(); 30 | 31 | void disableAuditingForRPCFilters(); 32 | 33 | void createIPBlockRPCFilter(std::string); 34 | 35 | void deleteAllRPCFilters(); 36 | 37 | void installRPCFWProvider(); 38 | 39 | void createRPCFilterFromTextLines(configLinesVector); 40 | 41 | void printAllRPCFilters(); 42 | 43 | bool isProviderInstalled(); 44 | 45 | bool isAuditingEnabledForRPCFilters(); 46 | -------------------------------------------------------------------------------- /rpcFwManager/service.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "common.h" 3 | #include "EventSink.h" 4 | #include "Injections.h" 5 | 6 | SERVICE_STATUS globalServiceStatus = { 0 }; 7 | SERVICE_STATUS_HANDLE globalServcieStatusHandle = nullptr; 8 | HANDLE globalServiceStopEvent = INVALID_HANDLE_VALUE; 9 | bool alreadyStarted = false; 10 | 11 | struct serviceHandleWrapper 12 | { 13 | serviceHandleWrapper() {} 14 | 15 | serviceHandleWrapper(serviceHandleWrapper&& other) : 16 | h(other.h) 17 | { 18 | other.h = nullptr; 19 | } 20 | 21 | ~serviceHandleWrapper() 22 | { 23 | if (h != nullptr) 24 | { 25 | CloseServiceHandle(h); 26 | } 27 | } 28 | 29 | SC_HANDLE h = nullptr; 30 | }; 31 | 32 | serviceHandleWrapper getSCManagerHandle() 33 | { 34 | serviceHandleWrapper schSCManager; 35 | // Get a handle to the SCM database. 36 | schSCManager.h = OpenSCManager( 37 | nullptr, // local computer 38 | nullptr, // ServicesActive database 39 | SC_MANAGER_ALL_ACCESS); // full access rights 40 | 41 | if (nullptr == schSCManager.h) 42 | { 43 | outputMessage(L"OpenSCManager failed", GetLastError()); 44 | } 45 | 46 | return schSCManager; 47 | } 48 | 49 | serviceHandleWrapper getServiceHandle(serviceHandleWrapper schSCManager, const wchar_t* serviceName) 50 | { 51 | serviceHandleWrapper schService; 52 | 53 | schService.h = OpenService( 54 | schSCManager.h, 55 | serviceName, 56 | SERVICE_ALL_ACCESS); 57 | 58 | /*if (schService.h == nullptr) 59 | { 60 | outputMessage(L"OpenService failed", GetLastError()); 61 | }*/ 62 | 63 | return schService; 64 | } 65 | 66 | bool isServiceInstalled() 67 | { 68 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 69 | serviceHandleWrapper schService = getServiceHandle(std::move(serviceManagerWrapper), SERVICE_NAME); 70 | 71 | return schService.h == nullptr ? false : true; 72 | } 73 | 74 | DWORD getServiceState() 75 | { 76 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 77 | serviceHandleWrapper schService = getServiceHandle(std::move(serviceManagerWrapper), SERVICE_NAME); 78 | 79 | if (schService.h != nullptr) 80 | { 81 | SERVICE_STATUS_PROCESS ssp; 82 | DWORD dwBytesNeeded; 83 | DWORD dwWaitTime; 84 | DWORD dwTimeout = 30000; 85 | DWORD dwStartTime = GetTickCount(); 86 | 87 | if (!QueryServiceStatusEx( 88 | schService.h, 89 | SC_STATUS_PROCESS_INFO, 90 | (LPBYTE)&ssp, 91 | sizeof(SERVICE_STATUS_PROCESS), 92 | &dwBytesNeeded)) 93 | { 94 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 95 | } 96 | else 97 | { 98 | return ssp.dwCurrentState; 99 | } 100 | } 101 | return 0; 102 | } 103 | 104 | void printServiceState() 105 | { 106 | switch (getServiceState()) 107 | { 108 | case SERVICE_STOPPED: 109 | outputMessage(L"\tRPC Firewall Service stopped."); 110 | break; 111 | case SERVICE_START_PENDING: 112 | outputMessage(L"\tRPC Firewall Service start pending."); 113 | break; 114 | case SERVICE_STOP_PENDING: 115 | outputMessage(L"\tRPC Firewall Service stop pending."); 116 | break; 117 | case SERVICE_RUNNING: 118 | outputMessage(L"\tRPC Firewall Service running."); 119 | break; 120 | case SERVICE_CONTINUE_PENDING: 121 | outputMessage(L"\tRPC Firewall Service continue pending."); 122 | break; 123 | case SERVICE_PAUSE_PENDING: 124 | outputMessage(L"\tRPC Firewall Service pause pending."); 125 | break; 126 | case SERVICE_PAUSED: 127 | outputMessage(L"\tRPC Firewall Service paused."); 128 | break; 129 | default: 130 | outputMessage(L"\tRPC Firewall Service status check failed!"); 131 | break; 132 | } 133 | } 134 | 135 | void serviceStop() 136 | { 137 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 138 | serviceHandleWrapper schService = getServiceHandle(std::move(serviceManagerWrapper), SERVICE_NAME); 139 | 140 | if (schService.h != nullptr) 141 | { 142 | SERVICE_STATUS_PROCESS ssp; 143 | DWORD dwBytesNeeded; 144 | DWORD dwWaitTime; 145 | DWORD dwTimeout = 30000; 146 | DWORD dwStartTime = GetTickCount(); 147 | 148 | if (!QueryServiceStatusEx( 149 | schService.h, 150 | SC_STATUS_PROCESS_INFO, 151 | (LPBYTE)&ssp, 152 | sizeof(SERVICE_STATUS_PROCESS), 153 | &dwBytesNeeded)) 154 | { 155 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 156 | return; 157 | } 158 | 159 | if (ssp.dwCurrentState == SERVICE_STOPPED) 160 | { 161 | outputMessage(L"Service is already stopped."); 162 | return; 163 | } 164 | 165 | // If a stop is pending, wait for it. 166 | 167 | while (ssp.dwCurrentState == SERVICE_STOP_PENDING) 168 | { 169 | outputMessage(L"Service stop pending...\n"); 170 | 171 | // Do not wait longer than the wait hint. A good interval is 172 | // one-tenth of the wait hint but not less than 1 second 173 | // and not more than 10 seconds. 174 | 175 | dwWaitTime = ssp.dwWaitHint / 10; 176 | 177 | if (dwWaitTime < 1000) 178 | dwWaitTime = 1000; 179 | else if (dwWaitTime > 10000) 180 | dwWaitTime = 10000; 181 | 182 | Sleep(dwWaitTime); 183 | 184 | if (!QueryServiceStatusEx( 185 | schService.h, 186 | SC_STATUS_PROCESS_INFO, 187 | (LPBYTE)&ssp, 188 | sizeof(SERVICE_STATUS_PROCESS), 189 | &dwBytesNeeded)) 190 | { 191 | outputMessage(L"QueryServiceStatusEx failed.", GetLastError()); 192 | return; 193 | } 194 | 195 | if (ssp.dwCurrentState == SERVICE_STOPPED) 196 | { 197 | outputMessage(L"Service stopped successfully."); 198 | return; 199 | } 200 | 201 | if (GetTickCount() - dwStartTime > dwTimeout) 202 | { 203 | outputMessage(L"Service stop timed out."); 204 | return; 205 | } 206 | } 207 | 208 | // Send a stop code to the service. 209 | 210 | if (!ControlService( 211 | schService.h, 212 | SERVICE_CONTROL_STOP, 213 | (LPSERVICE_STATUS)&ssp)) 214 | { 215 | outputMessage(L"ControlService failed", GetLastError()); 216 | return; 217 | } 218 | 219 | // Wait for the service to stop. 220 | 221 | while (ssp.dwCurrentState != SERVICE_STOPPED) 222 | { 223 | Sleep(ssp.dwWaitHint); 224 | if (!QueryServiceStatusEx( 225 | schService.h, 226 | SC_STATUS_PROCESS_INFO, 227 | (LPBYTE)&ssp, 228 | sizeof(SERVICE_STATUS_PROCESS), 229 | &dwBytesNeeded)) 230 | { 231 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 232 | return; 233 | } 234 | 235 | if (ssp.dwCurrentState == SERVICE_STOPPED) 236 | break; 237 | 238 | if (GetTickCount() - dwStartTime > dwTimeout) 239 | { 240 | outputMessage(L"Wait timed out"); 241 | return; 242 | } 243 | } 244 | outputMessage(L"Service stopped successfully."); 245 | } 246 | } 247 | 248 | void serviceStart() 249 | { 250 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 251 | serviceHandleWrapper schService = getServiceHandle(std::move(serviceManagerWrapper), SERVICE_NAME); 252 | 253 | if (schService.h != nullptr) 254 | { 255 | SERVICE_STATUS_PROCESS ssStatus; 256 | DWORD dwOldCheckPoint; 257 | DWORD dwStartTickCount; 258 | DWORD dwWaitTime; 259 | DWORD dwBytesNeeded; 260 | 261 | if (!QueryServiceStatusEx( 262 | schService.h, // handle to service 263 | SC_STATUS_PROCESS_INFO, // information level 264 | (LPBYTE)&ssStatus, // address of structure 265 | sizeof(SERVICE_STATUS_PROCESS), // size of structure 266 | &dwBytesNeeded)) // size needed if buffer is too small 267 | { 268 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 269 | return; 270 | } 271 | 272 | // Check if the service is already running. It would be possible 273 | // to stop the service here, but for simplicity this example just returns. 274 | 275 | if (ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING) 276 | { 277 | outputMessage(L"Cannot start the service because it is already running"); 278 | return; 279 | } 280 | 281 | // Save the tick count and initial checkpoint. 282 | 283 | dwStartTickCount = GetTickCount(); 284 | dwOldCheckPoint = ssStatus.dwCheckPoint; 285 | 286 | // Wait for the service to stop before attempting to start it. 287 | 288 | while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) 289 | { 290 | // Do not wait longer than the wait hint. A good interval is 291 | // one-tenth of the wait hint but not less than 1 second 292 | // and not more than 10 seconds. 293 | 294 | dwWaitTime = ssStatus.dwWaitHint / 10; 295 | 296 | if (dwWaitTime < 1000) 297 | dwWaitTime = 1000; 298 | else if (dwWaitTime > 10000) 299 | dwWaitTime = 10000; 300 | 301 | Sleep(dwWaitTime); 302 | 303 | // Check the status until the service is no longer stop pending. 304 | 305 | if (!QueryServiceStatusEx( 306 | schService.h, // handle to service 307 | SC_STATUS_PROCESS_INFO, // information level 308 | (LPBYTE)&ssStatus, // address of structure 309 | sizeof(SERVICE_STATUS_PROCESS), // size of structure 310 | &dwBytesNeeded)) // size needed if buffer is too small 311 | { 312 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 313 | return; 314 | } 315 | 316 | if (ssStatus.dwCheckPoint > dwOldCheckPoint) 317 | { 318 | // Continue to wait and check. 319 | 320 | dwStartTickCount = GetTickCount(); 321 | dwOldCheckPoint = ssStatus.dwCheckPoint; 322 | } 323 | else 324 | { 325 | if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint) 326 | { 327 | outputMessage(L"Timeout waiting for service to stop"); 328 | return; 329 | } 330 | } 331 | } 332 | 333 | // Attempt to start the service. 334 | 335 | if (!StartService( 336 | schService.h, // handle to service 337 | 0, // number of arguments 338 | NULL)) // no arguments 339 | { 340 | outputMessage(L"StartService failed", GetLastError()); 341 | return; 342 | } 343 | else printf("Service start pending...\n"); 344 | 345 | // Check the status until the service is no longer start pending. 346 | 347 | if (!QueryServiceStatusEx( 348 | schService.h, // handle to service 349 | SC_STATUS_PROCESS_INFO, // info level 350 | (LPBYTE)&ssStatus, // address of structure 351 | sizeof(SERVICE_STATUS_PROCESS), // size of structure 352 | &dwBytesNeeded)) // if buffer too small 353 | { 354 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 355 | return; 356 | } 357 | 358 | // Save the tick count and initial checkpoint. 359 | 360 | dwStartTickCount = GetTickCount(); 361 | dwOldCheckPoint = ssStatus.dwCheckPoint; 362 | 363 | while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 364 | { 365 | // Do not wait longer than the wait hint. A good interval is 366 | // one-tenth the wait hint, but no less than 1 second and no 367 | // more than 10 seconds. 368 | 369 | dwWaitTime = ssStatus.dwWaitHint / 10; 370 | 371 | if (dwWaitTime < 1000) 372 | dwWaitTime = 1000; 373 | else if (dwWaitTime > 10000) 374 | dwWaitTime = 10000; 375 | 376 | Sleep(dwWaitTime); 377 | 378 | // Check the status again. 379 | 380 | if (!QueryServiceStatusEx( 381 | schService.h, // handle to service 382 | SC_STATUS_PROCESS_INFO, // info level 383 | (LPBYTE)&ssStatus, // address of structure 384 | sizeof(SERVICE_STATUS_PROCESS), // size of structure 385 | &dwBytesNeeded)) // if buffer too small 386 | { 387 | outputMessage(L"QueryServiceStatusEx failed", GetLastError()); 388 | break; 389 | } 390 | 391 | if (ssStatus.dwCheckPoint > dwOldCheckPoint) 392 | { 393 | // Continue to wait and check. 394 | 395 | dwStartTickCount = GetTickCount(); 396 | dwOldCheckPoint = ssStatus.dwCheckPoint; 397 | } 398 | else 399 | { 400 | if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint) 401 | { 402 | // No progress made within the wait hint. 403 | break; 404 | } 405 | } 406 | } 407 | 408 | // Determine whether the service is running. 409 | 410 | if (ssStatus.dwCurrentState == SERVICE_RUNNING) 411 | { 412 | outputMessage(L"Service started successfully.\n"); 413 | } 414 | else 415 | { 416 | outputMessage(L"Service not started. \n"); 417 | outputMessage(L" Current State", ssStatus.dwCurrentState); 418 | outputMessage(L" Exit Code", ssStatus.dwWin32ExitCode); 419 | outputMessage(L" Check Point", ssStatus.dwCheckPoint); 420 | outputMessage(L" Wait Hint", ssStatus.dwWaitHint); 421 | } 422 | } 423 | } 424 | 425 | void serviceInstall(DWORD startType) 426 | { 427 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 428 | 429 | TCHAR szPath[MAX_PATH]; 430 | 431 | if (!GetModuleFileName(nullptr, szPath, MAX_PATH)) 432 | { 433 | outputMessage(L"GetModuleFileName failed",GetLastError()); 434 | return; 435 | } 436 | 437 | TCHAR szPathWithQuotes[MAX_PATH + 2]; // +2 for the quotes 438 | _stprintf_s(szPathWithQuotes, MAX_PATH + 2, L"\"%s\"", szPath); 439 | 440 | serviceHandleWrapper schService; 441 | 442 | schService.h = CreateService( 443 | serviceManagerWrapper.h, // SCM database 444 | SERVICE_NAME, // name of service 445 | SERVICE_NAME, // service name to display 446 | SERVICE_ALL_ACCESS, // desired access 447 | SERVICE_WIN32_OWN_PROCESS, // service type 448 | SERVICE_DEMAND_START, // start type 449 | SERVICE_ERROR_NORMAL, // error control type 450 | szPathWithQuotes, // path to service's binary 451 | NULL, // no load ordering group 452 | NULL, // no tag identifier 453 | NULL, // no dependencies 454 | NULL, // LocalSystem account 455 | NULL); // no password 456 | 457 | if (schService.h == nullptr) 458 | { 459 | outputMessage(L"CreateService failed", GetLastError()); 460 | return; 461 | } 462 | else outputMessage(L"Service installed successfully"); 463 | 464 | SERVICE_DELAYED_AUTO_START_INFO asi = {0}; 465 | asi.fDelayedAutostart = true; 466 | if (!ChangeServiceConfig2(schService.h, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &asi)) 467 | { 468 | outputMessage(L"Error: could not change service to delayed auto start",GetLastError()); 469 | } 470 | } 471 | 472 | void serviceUninstall() 473 | { 474 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 475 | serviceHandleWrapper schService = getServiceHandle(std::move(serviceManagerWrapper), SERVICE_NAME); 476 | 477 | if (schService.h == nullptr) 478 | { 479 | outputMessage(L"DeleteService failed - could not get handle to service"); 480 | return; 481 | } 482 | 483 | if (!DeleteService(schService.h)) 484 | { 485 | outputMessage(L"DeleteService failed", GetLastError()); 486 | return; 487 | } 488 | 489 | outputMessage(L"Service deleted successfully"); 490 | } 491 | 492 | void serviceUpdateStartType(DWORD startType) 493 | { 494 | serviceHandleWrapper serviceManagerWrapper = getSCManagerHandle(); 495 | serviceHandleWrapper schService = getServiceHandle(std::move(serviceManagerWrapper), SERVICE_NAME); 496 | 497 | if (!ChangeServiceConfig(schService.h, SERVICE_WIN32_OWN_PROCESS,startType, SERVICE_ERROR_NORMAL, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) 498 | { 499 | outputMessage(L"Updating service start opetion failed", GetLastError()); 500 | return; 501 | } 502 | else outputMessage(L"Service configured to start automatically."); 503 | } 504 | 505 | void serviceMakeAutostart() 506 | { 507 | serviceUpdateStartType(SERVICE_AUTO_START); 508 | } 509 | 510 | void serviceMakeManual() 511 | { 512 | serviceUpdateStartType(SERVICE_DEMAND_START); 513 | } 514 | 515 | void WINAPI serviceCtrlHandler(DWORD CtrlCode) 516 | { 517 | switch (CtrlCode) 518 | { 519 | case SERVICE_CONTROL_STOP: 520 | 521 | outputMessage(L"Service stopping..."); 522 | 523 | if (globalServiceStatus.dwCurrentState != SERVICE_RUNNING) 524 | break; 525 | 526 | globalServiceStatus.dwControlsAccepted = 0; 527 | globalServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; 528 | globalServiceStatus.dwWin32ExitCode = 0; 529 | globalServiceStatus.dwCheckPoint = 4; 530 | 531 | if (SetServiceStatus(globalServcieStatusHandle, &globalServiceStatus) == false) 532 | { 533 | writeDebugMessage(L"ServiceCtrlHandler: SetServiceStatus returned error"); 534 | } 535 | 536 | // This will signal the worker thread to start shutting down 537 | SetEvent(globalServiceStopEvent); 538 | 539 | break; 540 | 541 | default: 542 | break; 543 | } 544 | } 545 | 546 | DWORD WINAPI serviceWorkerThread(LPVOID lpParam) 547 | { 548 | wmiEventRegistrant wmiProcessRegistrant; 549 | wmiProcessRegistrant.registerForProcessCreatedEvents(); 550 | 551 | WaitForSingleObject(globalServiceStopEvent, INFINITE); 552 | 553 | outputMessage(L"Service worker stopping..."); 554 | 555 | return ERROR_SUCCESS; 556 | } 557 | 558 | void WINAPI serviceMain(DWORD argc, LPTSTR* argv) 559 | { 560 | outputMessage(_T("Service Starting...")); 561 | DWORD Status = E_FAIL; 562 | 563 | // Register our service control handler with the SCM 564 | globalServcieStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, serviceCtrlHandler); 565 | 566 | if (globalServcieStatusHandle == nullptr) 567 | { 568 | outputMessage(_T("Service handle is null, stopping...")); 569 | return; 570 | } 571 | 572 | // Tell the service controller we are starting 573 | ZeroMemory(&globalServiceStatus, sizeof(globalServiceStatus)); 574 | globalServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 575 | globalServiceStatus.dwControlsAccepted = 0; 576 | globalServiceStatus.dwCurrentState = SERVICE_START_PENDING; 577 | globalServiceStatus.dwWin32ExitCode = 0; 578 | globalServiceStatus.dwServiceSpecificExitCode = 0; 579 | globalServiceStatus.dwCheckPoint = 0; 580 | 581 | if (SetServiceStatus(globalServcieStatusHandle, &globalServiceStatus) == false) 582 | { 583 | outputMessage(_T("ServiceMain: SetServiceStatus returned error")); 584 | } 585 | 586 | // Create a service stop event to wait on later 587 | globalServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 588 | if (globalServiceStopEvent == nullptr) 589 | { 590 | // Error creating event 591 | // Tell service controller we are stopped and exit 592 | globalServiceStatus.dwControlsAccepted = 0; 593 | globalServiceStatus.dwCurrentState = SERVICE_STOPPED; 594 | globalServiceStatus.dwWin32ExitCode = GetLastError(); 595 | globalServiceStatus.dwCheckPoint = 1; 596 | 597 | if (SetServiceStatus(globalServcieStatusHandle, &globalServiceStatus) == false) 598 | { 599 | outputMessage(_T("ServiceMain: SetServiceStatus returned error")); 600 | } 601 | return; 602 | } 603 | 604 | // Tell the service controller we are started 605 | globalServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; 606 | globalServiceStatus.dwCurrentState = SERVICE_RUNNING; 607 | globalServiceStatus.dwWin32ExitCode = 0; 608 | globalServiceStatus.dwCheckPoint = 0; 609 | 610 | if (SetServiceStatus(globalServcieStatusHandle, &globalServiceStatus) == false) 611 | { 612 | outputMessage(_T("ServiceMain: SetServiceStatus returned error")); 613 | } 614 | 615 | createAllGloblEvents(); 616 | readConfigAndMapToMemory(); 617 | 618 | // Start a thread that will perform the main task of the service 619 | HANDLE hThread = CreateThread(NULL, 0, serviceWorkerThread, NULL, 0, NULL); 620 | 621 | crawlProcesses(0); 622 | 623 | // Wait until our worker thread exits signaling that the service needs to stop 624 | WaitForSingleObject(hThread, INFINITE); 625 | 626 | CloseHandle(globalServiceStopEvent); 627 | 628 | // Tell the service controller we are stopped 629 | globalServiceStatus.dwControlsAccepted = 0; 630 | globalServiceStatus.dwCurrentState = SERVICE_STOPPED; 631 | globalServiceStatus.dwWin32ExitCode = 0; 632 | globalServiceStatus.dwCheckPoint = 3; 633 | 634 | if (SetServiceStatus(globalServcieStatusHandle, &globalServiceStatus) == false) 635 | { 636 | outputMessage(_T("SetServiceStatus returned error")); 637 | } 638 | } 639 | 640 | bool setupService() 641 | { 642 | SERVICE_TABLE_ENTRY ServiceTable[] = 643 | { 644 | {(LPWSTR)SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)serviceMain}, 645 | {NULL, NULL} 646 | }; 647 | 648 | if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) 649 | { 650 | writeDebugMessage(_T("Error dispatching control to service.")); 651 | return false; 652 | } 653 | return true; 654 | } -------------------------------------------------------------------------------- /rpcFwManager/service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | void WINAPI serviceMain(DWORD, LPTSTR*); 5 | 6 | DWORD WINAPI serviceWorkerThread(LPVOID); 7 | 8 | void WINAPI serviceCtrlHandler(DWORD); 9 | 10 | void writeDebugMessage(const wchar_t*); 11 | 12 | bool setupService(); 13 | 14 | void serviceInstall(DWORD); 15 | 16 | void serviceStop(); 17 | 18 | void serviceUninstall(); 19 | 20 | void serviceStart(); 21 | 22 | void serviceMakeAutostart(); 23 | 24 | bool isServiceInstalled(); 25 | 26 | void serviceMakeManual(); 27 | 28 | void printServiceState(); -------------------------------------------------------------------------------- /rpcFwManager/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define _WIN32_WINNT 0x0602 4 | 5 | #define INFO_BUFFER_SIZE 32767 6 | #define MAX_RECORD_BUFFER_SIZE 0x10000 7 | #define LOW_INTEGRITY_SDDL_SACL_T TEXT("S:(ML;;NW;;;LW)") 8 | #define CONF_FILE_NAME TEXT("RpcFw.conf") 9 | #define RPC_FW_DLL_NAME TEXT("rpcFireWall.dll") 10 | #define RPC_MESSAGES_DLL_NAME TEXT("rpcMessages.dll") 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | //#include 21 | 22 | #include "Injections.h" 23 | #include "rpcMessages.h" 24 | #include "elevation.h" 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /rpcMessages/MSG00409.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeronetworks/rpcfirewall/38c703384dfb1d83b2a3f8a33ea46d1fa78722cf/rpcMessages/MSG00409.bin -------------------------------------------------------------------------------- /rpcMessages/Messages.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////// 2 | // Events 3 | // 4 | // 5 | // Values are 32 bit values laid out as follows: 6 | // 7 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 8 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 | // +---+-+-+-----------------------+-------------------------------+ 10 | // |Sev|C|R| Facility | Code | 11 | // +---+-+-+-----------------------+-------------------------------+ 12 | // 13 | // where 14 | // 15 | // Sev - is the severity code 16 | // 17 | // 00 - Success 18 | // 01 - Informational 19 | // 10 - Warning 20 | // 11 - Error 21 | // 22 | // C - is the Customer code flag 23 | // 24 | // R - is a reserved bit 25 | // 26 | // Facility - is the facility code 27 | // 28 | // Code - is the facility's status code 29 | // 30 | // 31 | // Define the facility codes 32 | // 33 | #define FACILITY_SYSTEM 0x0 34 | #define FACILITY_RUNTIME 0x2 35 | #define FACILITY_STUBS 0x3 36 | #define FACILITY_IO_ERROR_CODE 0x4 37 | 38 | 39 | // 40 | // Define the severity codes 41 | // 42 | #define STATUS_SEVERITY_SUCCESS 0x0 43 | #define STATUS_SEVERITY_INFORMATIONAL 0x1 44 | #define STATUS_SEVERITY_WARNING 0x2 45 | #define STATUS_SEVERITY_ERROR 0x3 46 | 47 | 48 | // 49 | // MessageId: PROCESS_PROTECTION_ADDED 50 | // 51 | // MessageText: 52 | // 53 | // RPC Firewall protection added.%n%nProcess Information:%n%tProcess ID:%t%2%n%tImage Path:%t%1 54 | // 55 | #define PROCESS_PROTECTION_ADDED ((DWORD)0x60020001L) 56 | 57 | // 58 | // MessageId: PROCESS_PROTECTION_REMOVED 59 | // 60 | // MessageText: 61 | // 62 | // RPC Firewall protection removed.%n%nProcess Information:%n%tProcess ID:%t%2%n%tImage Path:%t%1 63 | // 64 | #define PROCESS_PROTECTION_REMOVED ((DWORD)0x60020002L) 65 | 66 | // 67 | // MessageId: RPC_SERVER_CALL 68 | // 69 | // MessageText: 70 | // 71 | // An RPC server function was called.%n%nProcess Information:%n%tProcess ID:%t%2%n%tImage Path:%t%3%n%tRPCRT_Func:%t%1%n%nNetwork Information:%n%tProtocol:%t%4%n%tEndpoint:%t%5%n%tClient Network Address:%t%6%n%tClient Port:%t%12%n%tServer Network Address:%t%13%n%tServer Port:%t%14%nRPC Information:%n%tInterfaceUuid:%t%7%n%tOpNum:%t%t%8%n%nSubject:%n%tSecurity ID:%t%9%n%tSID:%t%15%n%nDetailed Authentication Information:%n%tAuthentication Level:%t%10%n%tAuthentication Service:%t%11 72 | // 73 | #define RPC_SERVER_CALL ((DWORD)0x60020003L) 74 | 75 | -------------------------------------------------------------------------------- /rpcMessages/Messages.mc: -------------------------------------------------------------------------------- 1 | SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS 2 | Informational=0x1:STATUS_SEVERITY_INFORMATIONAL 3 | Warning=0x2:STATUS_SEVERITY_WARNING 4 | Error=0x3:STATUS_SEVERITY_ERROR 5 | ) 6 | 7 | FacilityNames=(System=0x0:FACILITY_SYSTEM 8 | Runtime=0x2:FACILITY_RUNTIME 9 | Stubs=0x3:FACILITY_STUBS 10 | Io=0x4:FACILITY_IO_ERROR_CODE 11 | ) 12 | 13 | 14 | LanguageNames = 15 | ( 16 | English = 0x0409:Messages_ENU 17 | ) 18 | 19 | 20 | MessageIdTypedef=DWORD 21 | 22 | ;//////////////////////////////////////// 23 | ;// Events 24 | ;// 25 | 26 | MessageId = 0x1 27 | Severity = Informational 28 | Facility = Runtime 29 | SymbolicName = PROCESS_PROTECTION_ADDED 30 | Language = English 31 | RPC Firewall protection added.%n%nProcess Information:%n%tProcess ID:%t%2%n%tImage Path:%t%1 32 | . 33 | 34 | MessageId = 0x2 35 | Severity = Informational 36 | Facility = Runtime 37 | SymbolicName = PROCESS_PROTECTION_REMOVED 38 | Language = English 39 | RPC Firewall protection removed.%n%nProcess Information:%n%tProcess ID:%t%2%n%tImage Path:%t%1 40 | . 41 | 42 | MessageId = 0x3 43 | Severity = Informational 44 | Facility = Runtime 45 | SymbolicName = RPC_SERVER_CALL 46 | Language = English 47 | An RPC server function was called.%n%nProcess Information:%n%tProcess ID:%t%2%n%tImage Path:%t%3%n%tRPCRT_Func:%t%1%n%nNetwork Information:%n%tProtocol:%t%4%n%tEndpoint:%t%5%n%tClient Network Address:%t%6%n%tClient Port:%t%12%n%tServer Network Address:%t%13%n%tServer Port:%t%14%nRPC Information:%n%tInterfaceUuid:%t%7%n%tOpNum:%t%t%8%n%nSubject:%n%tSecurity ID:%t%9%n%tSID:%t%15%n%nDetailed Authentication Information:%n%tAuthentication Level:%t%10%n%tAuthentication Service:%t%11 48 | . 49 | -------------------------------------------------------------------------------- /rpcMessages/Messages.rc: -------------------------------------------------------------------------------- 1 | LANGUAGE 0x9,0x1 2 | 1 11 "Messages_ENU.bin" 3 | -------------------------------------------------------------------------------- /rpcMessages/Messages_ENU.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeronetworks/rpcfirewall/38c703384dfb1d83b2a3f8a33ea46d1fa78722cf/rpcMessages/Messages_ENU.bin -------------------------------------------------------------------------------- /rpcMessages/Messages_GER.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeronetworks/rpcfirewall/38c703384dfb1d83b2a3f8a33ea46d1fa78722cf/rpcMessages/Messages_GER.bin -------------------------------------------------------------------------------- /rpcMessages/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | #include 6 | -------------------------------------------------------------------------------- /rpcMessages/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /rpcMessages/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // add headers that you want to pre-compile here 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /rpcMessages/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Messages.rc 4 | // 5 | 6 | // Next default values for new objects 7 | // 8 | #ifdef APSTUDIO_INVOKED 9 | #ifndef APSTUDIO_READONLY_SYMBOLS 10 | #define _APS_NEXT_RESOURCE_VALUE 101 11 | #define _APS_NEXT_COMMAND_VALUE 40001 12 | #define _APS_NEXT_CONTROL_VALUE 1000 13 | #define _APS_NEXT_SYMED_VALUE 101 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /rpcMessages/rpcMessages.cpp: -------------------------------------------------------------------------------- 1 | #include "rpcMessages.h" 2 | #include "pch.h" 3 | #ifndef UNICODE 4 | #define UNICODE 5 | #endif 6 | #include 7 | #include 8 | #include "Messages.h" 9 | #include 10 | #include "rpcMessages.h" 11 | #include 12 | #include 13 | 14 | #pragma comment(lib, "advapi32.lib") 15 | 16 | #define PROVIDER_NAME TEXT("RPCFW") 17 | #define DLL_PATH TEXT("%SystemRoot%\\system32\\rpcMessages.dll") 18 | 19 | HANDLE hEventLog = nullptr; 20 | 21 | bool compareCharCaseInsensitive(wchar_t c1, wchar_t c2) 22 | { 23 | if (c1 == c2) 24 | return true; 25 | else if (std::toupper(c1) == std::toupper(c2)) 26 | return true; 27 | return false; 28 | } 29 | 30 | bool compareStringsCaseinsensitive(const wchar_t* str1, const wchar_t* str2) 31 | { 32 | wchar_t tcharEnd = _T("\0")[0]; 33 | 34 | for (int i = 0; i < MAX_PATH; i++) 35 | { 36 | if ((str1[i] == tcharEnd) || (str2[i] == tcharEnd)) 37 | { 38 | break; 39 | } 40 | 41 | if (!compareCharCaseInsensitive(str1[i], str2[i])) 42 | { 43 | return false; 44 | } 45 | } 46 | return true; 47 | } 48 | 49 | bool compareStringsCaseinsensitive(const wchar_t* str1, const wchar_t* str2, size_t maxLen) 50 | { 51 | wchar_t tcharEnd = _T("\0")[0]; 52 | 53 | for (size_t i = 0; i < maxLen; i++) 54 | { 55 | if ((str1[i] == tcharEnd) || (str2[i] == tcharEnd)) 56 | { 57 | break; 58 | } 59 | 60 | if (!compareCharCaseInsensitive(str1[i], str2[i])) 61 | { 62 | return false; 63 | } 64 | } 65 | return true; 66 | } 67 | 68 | bool regDelNodeRecurse(HKEY hKeyRoot, LPTSTR lpSubKey) 69 | { 70 | LPTSTR lpEnd; 71 | LONG lResult; 72 | DWORD dwSize; 73 | wchar_t szName[MAX_PATH]; 74 | HKEY hKey; 75 | FILETIME ftWrite; 76 | 77 | lResult = RegDeleteKey(hKeyRoot, lpSubKey); 78 | 79 | if (lResult == ERROR_SUCCESS) 80 | return true; 81 | 82 | lResult = RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); 83 | 84 | if (lResult != ERROR_SUCCESS) 85 | { 86 | if (lResult == ERROR_FILE_NOT_FOUND) { 87 | _tprintf(_T("Registry key already deleted.\n")); 88 | return true; 89 | } 90 | else { 91 | _tprintf(_T("Error opening key.\n")); 92 | return false; 93 | } 94 | } 95 | 96 | lpEnd = lpSubKey + lstrlen(lpSubKey); 97 | 98 | if (*(lpEnd - 1) != TEXT('\\')) 99 | { 100 | *lpEnd = TEXT('\\'); 101 | lpEnd++; 102 | *lpEnd = TEXT('\0'); 103 | } 104 | 105 | dwSize = MAX_PATH; 106 | lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, nullptr, 107 | nullptr, nullptr, &ftWrite); 108 | 109 | if (lResult == ERROR_SUCCESS) 110 | { 111 | do { 112 | 113 | *lpEnd = TEXT('\0'); 114 | StringCchCat(lpSubKey, MAX_PATH * 2, szName); 115 | 116 | if (!regDelNodeRecurse(hKeyRoot, lpSubKey)) { 117 | break; 118 | } 119 | 120 | dwSize = MAX_PATH; 121 | 122 | lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, nullptr, 123 | nullptr, nullptr, &ftWrite); 124 | 125 | } while (lResult == ERROR_SUCCESS); 126 | } 127 | 128 | lpEnd--; 129 | *lpEnd = TEXT('\0'); 130 | 131 | RegCloseKey(hKey); 132 | 133 | 134 | lResult = RegDeleteKey(hKeyRoot, lpSubKey); 135 | 136 | if (lResult == ERROR_SUCCESS) 137 | return true; 138 | 139 | return false; 140 | } 141 | 142 | bool deleteEventSource() 143 | { 144 | wchar_t szRegPath[MAX_PATH]; 145 | 146 | _stprintf_s(szRegPath, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s"), PROVIDER_NAME ); 147 | 148 | // Create the event source registry key 149 | return regDelNodeRecurse(HKEY_LOCAL_MACHINE, szRegPath); 150 | } 151 | 152 | bool checkIfEventConfiguredInReg() 153 | { 154 | HKEY hRegKey = nullptr; 155 | HKEY hRegKeyParent = nullptr; 156 | HKEY phkResult = nullptr; 157 | wchar_t szRegPathParent[MAX_PATH]; 158 | 159 | _stprintf_s(szRegPathParent, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s"), PROVIDER_NAME); 160 | 161 | LSTATUS res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegPathParent, 0, KEY_READ, &phkResult); 162 | 163 | if (res != ERROR_SUCCESS) 164 | { 165 | return false; 166 | } 167 | return true; 168 | } 169 | 170 | void addEventSource() 171 | { 172 | HKEY hRegKey = nullptr; 173 | HKEY hRegKeyParent = nullptr; 174 | DWORD dwError = 0; 175 | wchar_t szRegPath[MAX_PATH]; 176 | wchar_t szDLLPath[MAX_PATH]; 177 | wchar_t szRegPathParent[MAX_PATH]; 178 | 179 | _stprintf_s(szRegPathParent, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s"), PROVIDER_NAME); 180 | _stprintf_s(szRegPath, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s"), PROVIDER_NAME, PROVIDER_NAME); 181 | _stprintf_s(szDLLPath, _T("%s"), DLL_PATH); 182 | 183 | // Create the event source registry key 184 | if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_READ | KEY_WRITE | KEY_SET_VALUE, nullptr, &hRegKey, nullptr) != ERROR_SUCCESS) 185 | { 186 | _tprintf(TEXT("ERROR: Couldn't create event source registry key: [%d].\n"), GetLastError()); 187 | return; 188 | } 189 | // Name of the PE module that contains the message resource 190 | if (GetModuleFileName(nullptr, szRegPath, MAX_PATH) == 0) 191 | { 192 | _tprintf(TEXT("ERROR: call to GetModuleFileName failed: [%d].\n"), GetLastError()); 193 | return; 194 | } 195 | 196 | // Register EventMessageFile 197 | if (RegSetValueEx(hRegKey, _T("EventMessageFile"), 0, REG_EXPAND_SZ, (PBYTE)szDLLPath, (DWORD)((_tcslen(szDLLPath) + 1) * (DWORD)sizeof(wchar_t))) != ERROR_SUCCESS) 198 | { 199 | _tprintf(TEXT("ERROR: setting value to EventMessageFile failed: [%d].\n"), GetLastError()); 200 | return; 201 | } 202 | 203 | // Register supported event types 204 | DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; 205 | if (RegSetValueEx(hRegKey, _T("TypesSupported"), 0, REG_DWORD, (LPBYTE)&dwTypes, sizeof(dwTypes)) != ERROR_SUCCESS) 206 | { 207 | _tprintf(TEXT("ERROR: setting value to TypesSupported failed: [%d].\n"), GetLastError()); 208 | return; 209 | } 210 | 211 | if (RegOpenKeyW(HKEY_LOCAL_MACHINE, szRegPathParent, &hRegKeyParent) != ERROR_SUCCESS) 212 | { 213 | _tprintf(TEXT("ERROR: getting parent key %s : [%d].\n"), szRegPathParent,GetLastError()); 214 | return; 215 | } 216 | 217 | DWORD maxSize = 20971520; 218 | if (RegSetValueEx(hRegKeyParent, _T("MaxSize"), 0, REG_DWORD, (LPBYTE)&maxSize, sizeof(maxSize)) != ERROR_SUCCESS) 219 | { 220 | _tprintf(TEXT("ERROR: setting value to MaxSize failed: [%d].\n"), GetLastError()); 221 | return; 222 | } 223 | 224 | _tprintf(TEXT("Finished configuring the Event Log.\n")); 225 | RegCloseKey(hRegKey); 226 | 227 | } 228 | 229 | bool processProtectedEvent(bool successfulInjection, const wchar_t* processName, const wchar_t* processID) 230 | { 231 | bool bSuccess = false; 232 | WORD eventType = EVENTLOG_AUDIT_SUCCESS; 233 | LPCTSTR aInsertions[2] = { nullptr, nullptr }; 234 | 235 | if (!successfulInjection) { 236 | eventType = EVENTLOG_AUDIT_FAILURE; 237 | } 238 | 239 | // Open the eventlog 240 | HANDLE hEventLog = RegisterEventSource(nullptr, PROVIDER_NAME); 241 | aInsertions[0] = processName; 242 | aInsertions[1] = processID; 243 | 244 | if (hEventLog){ 245 | 246 | bSuccess = ReportEvent( 247 | hEventLog, 248 | eventType, 249 | 0, 250 | PROCESS_PROTECTION_ADDED, 251 | nullptr, 252 | 2, 253 | 0, 254 | aInsertions, 255 | nullptr 256 | ); 257 | } 258 | 259 | // Close eventlog 260 | DeregisterEventSource(hEventLog); 261 | return bSuccess; 262 | } 263 | 264 | bool processUnprotectedEvent(bool successfulIUnloading, const wchar_t* processName, const wchar_t* processID) { 265 | 266 | bool bSuccess = false; 267 | WORD eventType = EVENTLOG_AUDIT_SUCCESS; 268 | LPCTSTR aInsertions[2] = { nullptr, nullptr }; 269 | 270 | if (!successfulIUnloading) { 271 | eventType = EVENTLOG_AUDIT_FAILURE; 272 | } 273 | 274 | // Open the eventlog 275 | HANDLE hEventLog = RegisterEventSource(nullptr, PROVIDER_NAME); 276 | aInsertions[0] = processName; 277 | aInsertions[1] = processID; 278 | 279 | if (hEventLog) { 280 | 281 | bSuccess = ReportEvent( 282 | hEventLog, 283 | eventType, 284 | 0, 285 | PROCESS_PROTECTION_REMOVED, 286 | nullptr, 287 | 2, 288 | 0, 289 | aInsertions, 290 | nullptr 291 | ); 292 | } 293 | 294 | // Close eventlog 295 | DeregisterEventSource(hEventLog); 296 | return bSuccess; 297 | } 298 | 299 | std::wstring escapeIpv6Address(const std::wstring& sourceAddress) 300 | { 301 | std::wstring sourceAddressEscaped = sourceAddress; 302 | 303 | const std::wstring s = _T("\\:"); 304 | const std::wstring t = _T(":"); 305 | std::wstring::size_type n = 0; 306 | 307 | while ((n = sourceAddressEscaped.find(s, n)) != std::string::npos) 308 | { 309 | sourceAddressEscaped.replace(n, s.size(), t); 310 | n += t.size(); 311 | } 312 | return sourceAddressEscaped; 313 | } 314 | 315 | bool rpcFunctionCalledEvent(bool callSuccessful, const RpcEventParameters& eventParams) 316 | { 317 | bool bSuccess = false; 318 | WORD eventType = EVENTLOG_AUDIT_SUCCESS; 319 | LPCWSTR aInsertions[15] = {nullptr}; 320 | 321 | if (!callSuccessful) { 322 | eventType = EVENTLOG_AUDIT_FAILURE; 323 | } 324 | 325 | // Open the eventlog 326 | if (hEventLog == nullptr) 327 | { 328 | hEventLog = RegisterEventSource(nullptr, PROVIDER_NAME); 329 | } 330 | 331 | const std::wstring escapedSrcIp = escapeIpv6Address(eventParams.sourceAddress); 332 | 333 | aInsertions[0] = (wchar_t*)eventParams.functionName.c_str(); 334 | aInsertions[1] = (wchar_t*)eventParams.processID.c_str(); 335 | aInsertions[2] = (wchar_t*)eventParams.processName.c_str(); 336 | aInsertions[3] = (wchar_t*)eventParams.protocol.c_str(); 337 | aInsertions[4] = (wchar_t*)eventParams.endpoint.c_str(); 338 | aInsertions[5] = (wchar_t*)escapedSrcIp.c_str(); 339 | aInsertions[6] = (wchar_t*)eventParams.uuidString.c_str(); 340 | aInsertions[7] = (wchar_t*)eventParams.OpNum.c_str(); 341 | aInsertions[8] = (wchar_t*)eventParams.clientName.c_str(); 342 | aInsertions[9] = (wchar_t*)eventParams.authnLevel.c_str(); 343 | aInsertions[10] = (wchar_t*)eventParams.authnSvc.c_str(); 344 | aInsertions[11] = (wchar_t*)eventParams.srcPort.c_str(); 345 | aInsertions[12] = (wchar_t*)eventParams.destAddress.c_str(); 346 | aInsertions[13] = (wchar_t*)eventParams.dstPort.c_str(); 347 | aInsertions[14] = (wchar_t*)eventParams.clientSID.c_str(); 348 | 349 | if (hEventLog) { 350 | 351 | bSuccess = ReportEvent( 352 | hEventLog, 353 | eventType, 354 | 0, 355 | RPC_SERVER_CALL, 356 | nullptr, 357 | 15, 358 | 0, 359 | aInsertions, 360 | nullptr 361 | ); 362 | } 363 | 364 | return bSuccess; 365 | } 366 | 367 | 368 | bool APIENTRY DllMain( HMODULE hModule, 369 | DWORD ul_reason_for_call, 370 | LPVOID lpReserved 371 | ) 372 | { 373 | switch (ul_reason_for_call) 374 | { 375 | case DLL_PROCESS_ATTACH: 376 | break; 377 | case DLL_PROCESS_DETACH: 378 | // Close eventlog 379 | if (hEventLog != nullptr) DeregisterEventSource(hEventLog); 380 | break; 381 | } 382 | return true; 383 | } 384 | 385 | -------------------------------------------------------------------------------- /rpcMessages/rpcMessages.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef LIBRARY_EXPORTS 3 | # define LIBRARY_API __declspec(dllexport) 4 | #else 5 | # define LIBRARY_API __declspec(dllimport) 6 | #endif 7 | 8 | #include 9 | 10 | #define GLOBAL_RPCFW_CONFIG_UPDATE TEXT("Global\\RpcFwUpdateEvent") 11 | #define GLOBAL_RPCFW_EVENT_UNPROTECT TEXT("Global\\RpcFwUninstalledEvent") 12 | #define GLOBAL_RPCFW_MANAGER_DONE TEXT("Global\\RpcFwMgrDone") 13 | #define GLOBAL_SHARED_MEMORY TEXT("Global\\RpcFwRules") 14 | #define MEM_BUF_SIZE 0xFFFF 15 | 16 | #define DllExport __declspec( dllexport ) 17 | 18 | struct RpcEventParameters 19 | { 20 | bool rpcAllowd; 21 | std::wstring srcPort; 22 | std::wstring dstPort; 23 | std::wstring functionName; 24 | std::wstring processID; 25 | std::wstring processName; 26 | std::wstring protocol; 27 | std::wstring endpoint; 28 | std::wstring sourceAddress; 29 | std::wstring destAddress; 30 | std::wstring uuidString; 31 | std::wstring OpNum; 32 | std::wstring clientName; 33 | std::wstring authnLevel; 34 | std::wstring authnSvc; 35 | std::wstring clientSID; 36 | }; 37 | 38 | DllExport bool deleteEventSource(); 39 | 40 | DllExport void addEventSource(); 41 | 42 | DllExport bool processProtectedEvent(bool , const wchar_t*, const wchar_t* ); 43 | 44 | DllExport bool processUnprotectedEvent(bool, const wchar_t*, const wchar_t* ); 45 | 46 | DllExport bool rpcFunctionCalledEvent(bool , const RpcEventParameters& ); 47 | 48 | DllExport bool compareCharCaseInsensitive(wchar_t , wchar_t ); 49 | 50 | DllExport bool compareStringsCaseinsensitive(const wchar_t*, const wchar_t* ); 51 | 52 | DllExport bool compareStringsCaseinsensitive(const wchar_t* , const wchar_t* , size_t); 53 | 54 | DllExport bool checkIfEventConfiguredInReg(); -------------------------------------------------------------------------------- /rpcMessages/rpcMessages.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {48dc6dd2-92b9-49d9-ad47-a014e863fe60} 25 | rpcMessages 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;RPCMESSAGES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 90 | true 91 | Use 92 | pch.h 93 | 94 | 95 | Windows 96 | true 97 | false 98 | 99 | 100 | 101 | 102 | 103 | 104 | Compiling RPC Messages... 105 | 106 | 107 | $(ProjectDir)messages.rc;$(ProjectDir)messages.h;%(Outputs) 108 | 109 | 110 | mc.exe -U "$(projectDir)Messages.mc" 111 | 112 | 113 | Compiling resource file for messages... 114 | 115 | 116 | 117 | 118 | Level3 119 | true 120 | true 121 | true 122 | WIN32;NDEBUG;RPCMESSAGES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 123 | true 124 | Use 125 | pch.h 126 | 127 | 128 | Windows 129 | true 130 | true 131 | true 132 | false 133 | 134 | 135 | 136 | 137 | 138 | 139 | Compiling RPC Messages... 140 | 141 | 142 | $(ProjectDir)messages.rc;$(ProjectDir)messages.h;%(Outputs) 143 | 144 | 145 | mc.exe -U "$(projectDir)Messages.mc" 146 | 147 | 148 | Compiling resource file for messages... 149 | 150 | 151 | 152 | 153 | Level3 154 | true 155 | _DEBUG;RPCMESSAGES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 156 | true 157 | Use 158 | pch.h 159 | stdcpp20 160 | 161 | 162 | Windows 163 | true 164 | false 165 | 166 | 167 | 168 | 169 | 170 | 171 | Compiling RPC Messages... 172 | 173 | 174 | $(ProjectDir)messages.rc;$(ProjectDir)messages.h;%(Outputs) 175 | 176 | 177 | mc.exe -U "$(projectDir)Messages.mc" 178 | 179 | 180 | Compiling resource file for messages... 181 | 182 | 183 | 184 | 185 | Level3 186 | true 187 | true 188 | true 189 | NDEBUG;RPCMESSAGES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 190 | true 191 | Use 192 | pch.h 193 | MultiThreaded 194 | stdcpp20 195 | 196 | 197 | Windows 198 | true 199 | true 200 | true 201 | false 202 | 203 | 204 | 205 | 206 | 207 | 208 | Compiling RPC Messages... 209 | 210 | 211 | $(ProjectDir)messages.rc;$(ProjectDir)messages.h;%(Outputs) 212 | 213 | 214 | mc.exe -c -U "$(projectDir)Messages.mc" 215 | 216 | 217 | Compiling resource file for messages... 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | Create 231 | Create 232 | Create 233 | Create 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | -------------------------------------------------------------------------------- /rpcMessages/rpcMessages.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Resource Files 48 | 49 | 50 | --------------------------------------------------------------------------------