mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-07-28 14:47:18 -07:00
366 lines
13 KiB
YAML
366 lines
13 KiB
YAML
name: PR-tests
|
|
|
|
on:
|
|
pull_request:
|
|
branches:
|
|
- master
|
|
- main
|
|
paths-ignore:
|
|
- '.github/**'
|
|
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
Build_and_test_winpeas_pr:
|
|
runs-on: windows-latest
|
|
|
|
# environment variables
|
|
env:
|
|
Solution_Path: 'winPEAS\winPEASexe\winPEAS.sln'
|
|
Configuration: 'Release'
|
|
|
|
steps:
|
|
# checkout
|
|
- name: Checkout
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ github.head_ref || github.ref_name }}
|
|
|
|
- name: Download regexes
|
|
run: |
|
|
powershell.exe -ExecutionPolicy Bypass -File build_lists/download_regexes.ps1
|
|
|
|
# Add MSBuild to the PATH
|
|
- name: Setup MSBuild.exe
|
|
uses: microsoft/setup-msbuild@v2
|
|
|
|
# Setup NuGet
|
|
- name: Setup NuGet.exe
|
|
uses: nuget/setup-nuget@v2
|
|
|
|
# Restore the packages for testing
|
|
- name: Restore the application
|
|
run: nuget restore $env:Solution_Path
|
|
|
|
# build
|
|
- name: run MSBuild
|
|
run: msbuild $env:Solution_Path /p:Configuration=$env:Configuration /p:UseSharedCompilation=false
|
|
|
|
# Execute unit tests in the solution
|
|
- name: Execute unit tests
|
|
run: dotnet test $env:Solution_Path --configuration $env:Configuration
|
|
|
|
# Build all versions
|
|
- name: Build all versions
|
|
run: |
|
|
echo "build x64"
|
|
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="x64" /p:UseSharedCompilation=false
|
|
|
|
echo "build x86"
|
|
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="x86" /p:UseSharedCompilation=false
|
|
|
|
echo "build Any CPU"
|
|
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="Any CPU" /p:UseSharedCompilation=false
|
|
|
|
- name: Execute winPEAS -h
|
|
shell: pwsh
|
|
run: |
|
|
$Configuration = "Release"
|
|
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
|
|
if (Test-Path $exePath) {
|
|
& $exePath -h
|
|
} else {
|
|
Write-Error "winPEAS.exe not found at $exePath"
|
|
}
|
|
|
|
- name: Execute winPEAS cloudinfo
|
|
shell: pwsh
|
|
run: |
|
|
$Configuration = "Release"
|
|
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
|
|
if (Test-Path $exePath) {
|
|
& $exePath cloudinfo
|
|
} else {
|
|
Write-Error "winPEAS.exe not found at $exePath"
|
|
}
|
|
|
|
- name: Execute winPEAS systeminfo
|
|
shell: pwsh
|
|
run: |
|
|
$Configuration = "Release"
|
|
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
|
|
if (Test-Path $exePath) {
|
|
& $exePath systeminfo
|
|
} else {
|
|
Write-Error "winPEAS.exe not found at $exePath"
|
|
}
|
|
|
|
- name: Execute winPEAS online package vulnerability lookup with mock
|
|
shell: pwsh
|
|
run: |
|
|
$Configuration = "Release"
|
|
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
|
|
if (!(Test-Path $exePath)) {
|
|
Write-Error "winPEAS.exe not found at $exePath"
|
|
}
|
|
|
|
$serverPath = Join-Path $env:RUNNER_TEMP "mock_host_checker.py"
|
|
$bodyPath = Join-Path $env:RUNNER_TEMP "host_checker_body.json"
|
|
$countPath = Join-Path $env:RUNNER_TEMP "host_checker_count.txt"
|
|
@"
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
import json
|
|
import sys
|
|
|
|
body_path = sys.argv[1]
|
|
count_path = sys.argv[2]
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
def do_POST(self):
|
|
length = int(self.headers.get("content-length", "0"))
|
|
body = self.rfile.read(length).decode("utf-8", "replace")
|
|
with open(body_path, "w", encoding="utf-8") as f:
|
|
f.write(body)
|
|
with open(count_path, "w", encoding="utf-8") as f:
|
|
f.write("1")
|
|
vulns = []
|
|
for i in range(1, 56):
|
|
severity = "low"
|
|
if i % 10 == 0:
|
|
severity = "critical"
|
|
elif i % 10 == 1:
|
|
severity = "high"
|
|
elif i % 10 == 2:
|
|
severity = "medium"
|
|
vulns.append({
|
|
"name": f"pkg{i}",
|
|
"version": f"1.{i}.0",
|
|
"manager": "windows-registry",
|
|
"severity": severity,
|
|
"vulns": [f"CVE-2026-{10000 + i}"],
|
|
})
|
|
response = {
|
|
"malicious": False,
|
|
"results": [],
|
|
"package_vulnerabilities": {
|
|
"checked": 300,
|
|
"affected": 55,
|
|
"vulnerable_packages": vulns,
|
|
},
|
|
}
|
|
data = json.dumps(response).encode("utf-8")
|
|
self.send_response(200)
|
|
self.send_header("Content-Type", "application/json")
|
|
self.send_header("Content-Length", str(len(data)))
|
|
self.end_headers()
|
|
self.wfile.write(data)
|
|
|
|
def log_message(self, fmt, *args):
|
|
pass
|
|
|
|
HTTPServer(("127.0.0.1", 18768), Handler).handle_request()
|
|
"@ | Set-Content -Path $serverPath -Encoding utf8
|
|
|
|
$pythonCandidates = @(
|
|
@{ FilePath = "py"; Arguments = @("-3", $serverPath, $bodyPath, $countPath) },
|
|
@{ FilePath = "python"; Arguments = @($serverPath, $bodyPath, $countPath) },
|
|
@{ FilePath = "python3"; Arguments = @($serverPath, $bodyPath, $countPath) }
|
|
)
|
|
$pythonCommand = $pythonCandidates |
|
|
Where-Object { Get-Command $_.FilePath -ErrorAction SilentlyContinue } |
|
|
Select-Object -First 1
|
|
if (!$pythonCommand) {
|
|
Write-Error "No Python interpreter found to launch the mock host-checker server."
|
|
}
|
|
|
|
$server = Start-Process -FilePath $pythonCommand.FilePath -ArgumentList $pythonCommand.Arguments -PassThru -NoNewWindow
|
|
try {
|
|
$serverReady = $false
|
|
$deadline = (Get-Date).AddSeconds(15)
|
|
while ((Get-Date) -lt $deadline) {
|
|
if ($server.HasExited) {
|
|
break
|
|
}
|
|
|
|
$client = $null
|
|
try {
|
|
$client = [System.Net.Sockets.TcpClient]::new()
|
|
$connectTask = $client.ConnectAsync("127.0.0.1", 18768)
|
|
if ($connectTask.Wait(500) -and $client.Connected) {
|
|
$serverReady = $true
|
|
break
|
|
}
|
|
} catch {
|
|
} finally {
|
|
if ($client) {
|
|
$client.Dispose()
|
|
}
|
|
}
|
|
|
|
Start-Sleep -Milliseconds 250
|
|
}
|
|
|
|
if (!$serverReady) {
|
|
Write-Error "Mock host-checker server did not become ready before winPEAS execution."
|
|
}
|
|
|
|
$env:HACKTRICKS_HOST_CHECKER_URL = "http://127.0.0.1:18768/api/host-checker"
|
|
$output = & $exePath applicationsinfo -vulnpackages notcolor 2>&1 | Out-String
|
|
|
|
if ($output -notmatch "Online package vulnerabilities found: 55 vulnerable package\(s\), checked 300\.") {
|
|
Write-Error "The package vulnerability summary was not printed as expected.`n$output"
|
|
}
|
|
$vulnLines = ([regex]::Matches($output, "(?m)^\s+- pkg\d+ ")).Count
|
|
if ($vulnLines -ne 50) {
|
|
Write-Error "Expected 50 vulnerable package lines, got $vulnLines.`n$output"
|
|
}
|
|
$firstVulnLine = [regex]::Match($output, "(?m)^\s+- pkg\d+ .*$").Value
|
|
if ($firstVulnLine -notmatch "pkg10 .* \[Critical\]: CVE-2026-10010") {
|
|
Write-Error "Expected critical package vulnerabilities to be printed first, got: $firstVulnLine`n$output"
|
|
}
|
|
$criticalIndex = $output.IndexOf("pkg10")
|
|
$lowIndex = $output.IndexOf("- pkg3 ")
|
|
if ($criticalIndex -lt 0 -or $lowIndex -lt 0 -or $criticalIndex -gt $lowIndex) {
|
|
Write-Error "Expected critical packages to appear before low packages.`n$output"
|
|
}
|
|
if ($output -notmatch "\.\.\. 5 more vulnerable package\(s\) not shown\.") {
|
|
Write-Error "The hidden vulnerable package count was not printed.`n$output"
|
|
}
|
|
if ($output -match "package_vulnerabilities") {
|
|
Write-Error "Raw package_vulnerabilities JSON leaked into the rendered output.`n$output"
|
|
}
|
|
|
|
$requestCount = Get-Content $countPath -Raw
|
|
if ([int]$requestCount.Trim() -ne 1) {
|
|
Write-Error "Expected exactly one host-checker request, got $requestCount"
|
|
}
|
|
$request = Get-Content $bodyPath -Raw | ConvertFrom-Json
|
|
if (!$request.hostname) {
|
|
Write-Error "The host-checker payload did not include hostname."
|
|
}
|
|
if (!$request.packages -or $request.packages.Count -lt 1) {
|
|
Write-Error "The host-checker payload did not include installed packages."
|
|
}
|
|
} finally {
|
|
if (!$server.HasExited) {
|
|
Stop-Process -Id $server.Id -Force
|
|
}
|
|
}
|
|
|
|
- name: Execute winPEAS networkinfo
|
|
shell: pwsh
|
|
run: |
|
|
$Configuration = "Release"
|
|
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
|
|
if (Test-Path $exePath) {
|
|
& $exePath networkinfo
|
|
} else {
|
|
Write-Error "winPEAS.exe not found at $exePath"
|
|
}
|
|
|
|
Build_and_test_linpeas_pr:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
# Download repo
|
|
- uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ github.head_ref || github.ref_name }}
|
|
|
|
# Setup go
|
|
- uses: actions/setup-go@v6
|
|
with:
|
|
go-version: '1.23'
|
|
cache: false
|
|
- run: go version
|
|
|
|
# Build linpeas
|
|
- name: Build linpeas
|
|
run: |
|
|
python3 -m pip install PyYAML
|
|
cd linPEAS
|
|
python3 -m builder.linpeas_builder --all --output linpeas_fat.sh
|
|
python3 -m builder.linpeas_builder --all-no-fat --output linpeas.sh
|
|
python3 -m builder.linpeas_builder --small --output linpeas_small.sh
|
|
|
|
- name: Run linPEAS module metadata tests
|
|
run: python3 -m unittest linPEAS.tests.test_modules_metadata
|
|
|
|
- name: Run linPEAS builder tests
|
|
run: python3 -m unittest discover -s linPEAS/tests -p "test_*.py"
|
|
|
|
# Run linpeas help as quick test
|
|
- name: Run linpeas help
|
|
run: linPEAS/linpeas_fat.sh -h && linPEAS/linpeas.sh -h && linPEAS/linpeas_small.sh -h
|
|
|
|
# Run linpeas as a test
|
|
- name: Run linpeas system_information
|
|
run: linPEAS/linpeas_fat.sh -o system_information -a
|
|
|
|
- name: Run linpeas container
|
|
run: linPEAS/linpeas_fat.sh -o container -a
|
|
|
|
- name: Run linpeas cloud
|
|
run: linPEAS/linpeas_fat.sh -o cloud -a
|
|
|
|
- name: Run linpeas procs_crons_timers_srvcs_sockets
|
|
run: linPEAS/linpeas_fat.sh -o procs_crons_timers_srvcs_sockets -a
|
|
|
|
- name: Run linpeas network_information
|
|
run: linPEAS/linpeas_fat.sh -o network_information -t -a
|
|
|
|
- name: Run linpeas users_information
|
|
run: linPEAS/linpeas_fat.sh -o users_information -a
|
|
|
|
- name: Run linpeas software_information
|
|
run: linPEAS/linpeas_fat.sh -o software_information -a
|
|
|
|
- name: Run linpeas interesting_perms_files
|
|
run: linPEAS/linpeas_fat.sh -o interesting_perms_files -a
|
|
|
|
- name: Run linpeas interesting_files
|
|
run: linPEAS/linpeas_fat.sh -o interesting_files -a
|
|
|
|
Build_and_test_macpeas_pr:
|
|
runs-on: macos-latest
|
|
|
|
steps:
|
|
# Download repo
|
|
- uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ github.head_ref || github.ref_name }}
|
|
|
|
# Build linpeas (macpeas)
|
|
- name: Build macpeas
|
|
run: |
|
|
python3 -m pip install PyYAML --break-system-packages
|
|
python3 -m pip install requests --break-system-packages
|
|
cd linPEAS
|
|
python3 -m builder.linpeas_builder --all --output linpeas_fat.sh
|
|
|
|
# Run linpeas help as quick test
|
|
- name: Run macpeas help
|
|
run: linPEAS/linpeas_fat.sh -h
|
|
|
|
# Run macpeas parts to test it
|
|
- name: Run macpeas system_information
|
|
run: linPEAS/linpeas_fat.sh -o system_information -a
|
|
|
|
# - name: Run macpeas container
|
|
# run: linPEAS/linpeas_fat.sh -o container -a
|
|
|
|
# - name: Run macpeas cloud
|
|
# run: linPEAS/linpeas_fat.sh -o cloud -a
|
|
|
|
# - name: Run macpeas procs_crons_timers_srvcs_sockets
|
|
# run: linPEAS/linpeas_fat.sh -o procs_crons_timers_srvcs_sockets -a
|
|
|
|
# - name: Run macpeas network_information
|
|
# run: linPEAS/linpeas_fat.sh -o network_information -t -a
|
|
|
|
# - name: Run macpeas users_information
|
|
# run: linPEAS/linpeas_fat.sh -o users_information -a
|
|
|
|
# - name: Run macpeas software_information
|
|
# run: linPEAS/linpeas_fat.sh -o software_information -a
|