Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,105 @@ $RECYCLE.BIN/

# Vim temporary swap files
*.swp

## ----------------------------------------------------------------------
## .NET / Visual Studio / Rider
## ----------------------------------------------------------------------

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# IDEs & Tooling
.vs/
.vscode/
.idea/
*.sln.iml
*.suo
*.user
*.userosscache
*.sln.docstates
.dockerignore
.env

# Testing
[Tt]est[Rr]esult*/
BenchmarkDotNet.Artifacts/
coverage*.json
coverage*.xml
*.coverage
*.coveragexml

## ----------------------------------------------------------------------
## Python (Red Team Tools)
## ----------------------------------------------------------------------

# Byte-compiled / Optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Virtual Environments
.venv/
venv/
ENV/
env/

# Distribution / Packaging
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

## ----------------------------------------------------------------------
## OS Specific
## ----------------------------------------------------------------------
.DS_Store
Thumbs.db

# ----------------------------------------------------------------------
# Generated gRPC Python Files (Do Not Commit)
# ----------------------------------------------------------------------
attack/*_pb2.py
attack/*_pb2_grpc.py
attack/*.pyi
25 changes: 25 additions & 0 deletions Rasp.Core.Tests/Rasp.Core.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
<PackageReference Include="xunit" Version="2.9.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4"/>
</ItemGroup>

<ItemGroup>
<Using Include="Xunit"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\Rasp.Core\Rasp.Core.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
<PackageReference Include="xunit" Version="2.9.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4"/>
</ItemGroup>

<ItemGroup>
<Using Include="Xunit"/>
</ItemGroup>

</Project>
32 changes: 32 additions & 0 deletions Rasp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibrarySystem.Domain", "mod
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibrarySystem.Persistence", "modules\dotnet-grpc-library-api\LibrarySystem.Persistence\LibrarySystem.Persistence.csproj", "{689C3555-DC1F-4A87-B349-500DF85B9F39}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7BF13981-E617-4FF6-9463-B251628BAF1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rasp.Core.Tests", "Rasp.Core.Tests\Rasp.Core.Tests.csproj", "{9FF0212B-D43D-46D7-AAD4-3793958CA197}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rasp.Instrumentation.Grpc.Tests", "Rasp.Instrumentation.Grpc.Tests\Rasp.Instrumentation.Grpc.Tests.csproj", "{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -145,6 +151,30 @@ Global
{689C3555-DC1F-4A87-B349-500DF85B9F39}.Release|x64.Build.0 = Release|Any CPU
{689C3555-DC1F-4A87-B349-500DF85B9F39}.Release|x86.ActiveCfg = Release|Any CPU
{689C3555-DC1F-4A87-B349-500DF85B9F39}.Release|x86.Build.0 = Release|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Debug|x64.ActiveCfg = Debug|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Debug|x64.Build.0 = Debug|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Debug|x86.ActiveCfg = Debug|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Debug|x86.Build.0 = Debug|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Release|Any CPU.Build.0 = Release|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Release|x64.ActiveCfg = Release|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Release|x64.Build.0 = Release|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Release|x86.ActiveCfg = Release|Any CPU
{9FF0212B-D43D-46D7-AAD4-3793958CA197}.Release|x86.Build.0 = Release|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Debug|x64.ActiveCfg = Debug|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Debug|x64.Build.0 = Debug|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Debug|x86.ActiveCfg = Debug|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Debug|x86.Build.0 = Debug|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Release|Any CPU.Build.0 = Release|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Release|x64.ActiveCfg = Release|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Release|x64.Build.0 = Release|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Release|x86.ActiveCfg = Release|Any CPU
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -160,5 +190,7 @@ Global
{D7B61D10-C142-47E1-99C6-31C582E330E9} = {87C876C9-7554-CEDF-203F-AF43B1B74702}
{BDCCB396-349D-42AF-990E-769813A6AC13} = {87C876C9-7554-CEDF-203F-AF43B1B74702}
{689C3555-DC1F-4A87-B349-500DF85B9F39} = {87C876C9-7554-CEDF-203F-AF43B1B74702}
{9FF0212B-D43D-46D7-AAD4-3793958CA197} = {7BF13981-E617-4FF6-9463-B251628BAF1E}
{6F314CAD-E989-41CA-8C9C-9FD721F5DA50} = {7BF13981-E617-4FF6-9463-B251628BAF1E}
EndGlobalSection
EndGlobal
69 changes: 69 additions & 0 deletions attack/exploit_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
print("DEBUG: Script iniciando...") # <--- Adicione isso na linha 1
import grpc
import sys
import os

# Add current directory to path to import generated stubs
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

# Import generated modules (created by the build script)
# Note: Names depend on how protoc generates files.
# Assuming library.proto generates library_pb2.py and library_pb2_grpc.py
try:
import library_pb2
import library_pb2_grpc
except ImportError:
print("❌ Error: Compiled proto files not found.")
print("Run: bash generate_protos.sh")
sys.exit(1)

def run_exploit(target):
print(f"[*] Connecting to target: {target}")

# Create insecure channel (for local PoC only)
with grpc.insecure_channel(target) as channel:
stub = library_pb2_grpc.LibraryStub(channel)

# --- SCENARIO 1: SQL Injection Payload ---
# This payload matches the regex defined in RegexDetectionEngine
payload = "' OR '1'='1"
print(f"[*] Sending malicious payload: \"{payload}\"")

try:
response = stub.CreateBook(library_pb2.CreateBookRequest(
title=payload, # <--- INJECTION POINT
author="Hacker",
publication_year=2025,
pages=100,
total_copies=10
))
print("❌ FAILURE: Server accepted the payload! RASP did not block.")
print(f" Response: ID={response.id}, Title={response.title}")
return False

except grpc.RpcError as e:
# Check if blocked by RASP (PermissionDenied)
if e.code() == grpc.StatusCode.PERMISSION_DENIED:
print("✅ SUCCESS: RASP blocked the attack!")
print(f" Status: {e.code()}")
print(f" Details: {e.details()}")
return True
else:
print(f"⚠️ UNEXPECTED ERROR: Server returned an error, but not the expected block.")
print(f" Status: {e.code()}")
print(f" Details: {e.details()}")
return False

if __name__ == '__main__':
# Default target: localhost:5001 (gRPC backend)
# Adjust if running via Docker or another port
target_url = 'localhost:5001'
if len(sys.argv) > 1:
target_url = sys.argv[1]

success = run_exploit(target_url)

if success:
sys.exit(0)
else:
sys.exit(1)
Empty file added attack/generate_protos.sh
Empty file.
3 changes: 3 additions & 0 deletions attack/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
grpcio==1.60.0
grpcio-tools==1.60.0
protobuf==4.25.1
6 changes: 0 additions & 6 deletions src/Rasp.Bootstrapper/Class1.cs

This file was deleted.

20 changes: 20 additions & 0 deletions src/Rasp.Bootstrapper/Configuration/RaspOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Rasp.Bootstrapper.Configuration;

/// <summary>
/// Global configuration options for the RASP.
/// Allows adjusting security behavior without recompilation.
/// </summary>
public class RaspOptions
{
/// <summary>
/// If true, blocks detected attacks and throws an exception.
/// If false, only logs/monitors ("Audit" Mode).
/// Default: true (Secure by default).
/// </summary>
public bool BlockOnDetection { get; set; } = true;

/// <summary>
/// If true, enables detailed telemetry (may have performance impact).
/// </summary>
public bool EnableMetrics { get; set; } = true;
}
10 changes: 10 additions & 0 deletions src/Rasp.Bootstrapper/Rasp.Bootstrapper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Rasp.Core\Rasp.Core.csproj" />
<ProjectReference Include="..\Rasp.Instrumentation.Grpc\Rasp.Instrumentation.Grpc.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.1" />
</ItemGroup>

</Project>
41 changes: 41 additions & 0 deletions src/Rasp.Bootstrapper/RaspDependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Grpc.AspNetCore.Server;
using Microsoft.Extensions.DependencyInjection;
using Rasp.Bootstrapper.Configuration;
using Rasp.Core;
using Rasp.Instrumentation.Grpc.Interceptors;

namespace Rasp.Bootstrapper;

/// <summary>
/// Provides extension methods to easily register RASP services.
/// </summary>
public static class RaspDependencyInjection
{
/// <summary>
/// Adds the RASP (Runtime Application Self-Protection) services to the DI container.
/// This method registers detection engines, telemetry, and gRPC interceptors.
/// </summary>
/// <param name="services">The application service collection.</param>
/// <param name="configureOptions">Optional delegate to configure RASP behavior.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddRasp(
this IServiceCollection services,
Action<RaspOptions>? configureOptions = null)
{
if (configureOptions != null)
{
services.Configure(configureOptions);
}

services.AddRaspCore();

services.AddSingleton<SecurityInterceptor>();

services.PostConfigure<GrpcServiceOptions>(options =>
{
options.Interceptors.Add<SecurityInterceptor>();
});

return services;
}
}
20 changes: 20 additions & 0 deletions src/Rasp.Core/Abstractions/IDetectionEngine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Rasp.Core.Models;

namespace Rasp.Core.Abstractions;

/// <summary>
/// Defines the contract for the core detection logic.
/// Implementations of this interface are responsible for analyzing payloads
/// and determining if they contain malicious patterns (e.g., SQLi, XSS).
/// </summary>
public interface IDetectionEngine
{
/// <summary>
/// Analyzes a generic text payload for potential threats.
/// This is the primary entry point for string-based inspections (gRPC fields, SQL queries).
/// </summary>
/// <param name="payload">The content to inspect (e.g., user input, SQL command text).</param>
/// <param name="context">Optional context about the source (e.g., "gRPC.BookService/CreateBook").</param>
/// <returns>A <see cref="DetectionResult"/> indicating the verdict.</returns>
DetectionResult Inspect(string? payload, string context = "Unknown");
}
Loading
Loading