mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-01-21 09:03:27 -08:00
Compare commits
18 Commits
feat/winpe
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1473fedcbf | ||
|
|
f8f4250b81 | ||
|
|
1fb419fa0c | ||
|
|
651dc9cd7d | ||
|
|
0808fb7f1b | ||
|
|
c332fab519 | ||
|
|
577dcc9964 | ||
|
|
b591f3d524 | ||
|
|
b3ac8c6d22 | ||
|
|
83580fcd8a | ||
|
|
ab3a5899de | ||
|
|
0fac664048 | ||
|
|
db30e3bd7d | ||
|
|
7ad87a85e6 | ||
|
|
b24694f00b | ||
|
|
e777c81eba | ||
|
|
21a86bc365 | ||
|
|
ac7cb9c73c |
28
.github/workflows/CI-master_tests.yml
vendored
28
.github/workflows/CI-master_tests.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
steps:
|
||||
# checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
@@ -36,11 +36,11 @@ jobs:
|
||||
|
||||
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
# Setup NuGet
|
||||
- name: Setup NuGet.exe
|
||||
uses: nuget/setup-nuget@v1
|
||||
uses: nuget/setup-nuget@v2
|
||||
|
||||
# Restore the packages for testing
|
||||
- name: Restore the application
|
||||
@@ -48,23 +48,23 @@ jobs:
|
||||
|
||||
# build
|
||||
- name: run MSBuild
|
||||
run: msbuild $env:Solution_Path
|
||||
run: msbuild $env:Solution_Path /p:Configuration=$env:Configuration /p:UseSharedCompilation=false
|
||||
|
||||
# Execute all unit tests in the solution
|
||||
#- name: Execute unit tests
|
||||
# run: dotnet test $env:Solution_Path
|
||||
- name: Execute unit tests
|
||||
run: dotnet test $env:Solution_Path --configuration $env:Configuration
|
||||
|
||||
# Build & update all versions
|
||||
- name: Build all versions
|
||||
run: |
|
||||
echo "build x64"
|
||||
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="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"
|
||||
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"
|
||||
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="Any CPU" /p:UseSharedCompilation=false
|
||||
|
||||
- name: Execute winPEAS -h
|
||||
shell: pwsh
|
||||
@@ -220,6 +220,7 @@ jobs:
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.23'
|
||||
cache: false
|
||||
- run: go version
|
||||
|
||||
# Build linpeas
|
||||
@@ -230,6 +231,9 @@ jobs:
|
||||
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 builder tests
|
||||
run: python3 -m unittest discover -s linPEAS/tests -p "test_*.py"
|
||||
|
||||
# Build linpeas binaries
|
||||
- name: Build linpeas binaries
|
||||
@@ -362,7 +366,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
# Download repo
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
# Build linpeas
|
||||
- name: Build macpeas
|
||||
@@ -469,11 +473,11 @@ jobs:
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "::set-output name=date::$(date +'%Y%m%d')"
|
||||
run: echo "date=$(date +'%Y%m%d')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate random
|
||||
id: random_n
|
||||
run: echo "::set-output name=some_rand::$(openssl rand -hex 4)"
|
||||
run: echo "some_rand=$(openssl rand -hex 4)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Create the release
|
||||
- name: Create Release
|
||||
|
||||
28
.github/workflows/PR-tests.yml
vendored
28
.github/workflows/PR-tests.yml
vendored
@@ -8,6 +8,8 @@ on:
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
Build_and_test_winpeas_pr:
|
||||
runs-on: windows-latest
|
||||
@@ -20,7 +22,7 @@ jobs:
|
||||
steps:
|
||||
# checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
@@ -30,11 +32,11 @@ jobs:
|
||||
|
||||
# Add MSBuild to the PATH
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
# Setup NuGet
|
||||
- name: Setup NuGet.exe
|
||||
uses: nuget/setup-nuget@v1
|
||||
uses: nuget/setup-nuget@v2
|
||||
|
||||
# Restore the packages for testing
|
||||
- name: Restore the application
|
||||
@@ -42,19 +44,23 @@ jobs:
|
||||
|
||||
# build
|
||||
- name: run MSBuild
|
||||
run: msbuild $env:Solution_Path
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="Any CPU" /p:UseSharedCompilation=false
|
||||
|
||||
- name: Execute winPEAS -h
|
||||
shell: pwsh
|
||||
@@ -105,7 +111,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
# Download repo
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
@@ -113,6 +119,7 @@ jobs:
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.23'
|
||||
cache: false
|
||||
- run: go version
|
||||
|
||||
# Build linpeas
|
||||
@@ -123,6 +130,9 @@ jobs:
|
||||
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 builder tests
|
||||
run: python3 -m unittest discover -s linPEAS/tests -p "test_*.py"
|
||||
|
||||
# Run linpeas help as quick test
|
||||
- name: Run linpeas help
|
||||
@@ -161,7 +171,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
# Download repo
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
|
||||
80
.github/workflows/codex-pr-triage.yml
vendored
80
.github/workflows/codex-pr-triage.yml
vendored
@@ -1,41 +1,94 @@
|
||||
name: Codex PR Triage
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
workflow_run:
|
||||
workflows: ["PR-tests"]
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
codex_triage:
|
||||
if: ${{ github.event.pull_request.user.login == 'carlospolop' }}
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
outputs:
|
||||
should_run: ${{ steps.gate.outputs.should_run }}
|
||||
pr_number: ${{ steps.gate.outputs.pr_number }}
|
||||
pr_title: ${{ steps.gate.outputs.pr_title }}
|
||||
pr_body: ${{ steps.gate.outputs.pr_body }}
|
||||
base_ref: ${{ steps.gate.outputs.base_ref }}
|
||||
head_ref: ${{ steps.gate.outputs.head_ref }}
|
||||
base_sha: ${{ steps.gate.outputs.base_sha }}
|
||||
head_sha: ${{ steps.gate.outputs.head_sha }}
|
||||
decision: ${{ steps.parse.outputs.decision }}
|
||||
message: ${{ steps.parse.outputs.message }}
|
||||
|
||||
steps:
|
||||
- name: Resolve PR context
|
||||
id: gate
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
pr_number="${{ github.event.workflow_run.pull_requests[0].number }}"
|
||||
if [ -z "$pr_number" ]; then
|
||||
echo "No pull request found for this workflow_run; skipping."
|
||||
echo "should_run=false" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_number=" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
author="$(gh pr view "$pr_number" --json author --jq .author.login)"
|
||||
if [ "$author" != "carlospolop" ]; then
|
||||
echo "PR author is $author; skipping."
|
||||
echo "should_run=false" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
pr_title="$(gh pr view "$pr_number" --json title --jq .title)"
|
||||
pr_body="$(gh pr view "$pr_number" --json body --jq .body)"
|
||||
base_ref="$(gh pr view "$pr_number" --json baseRefName --jq .baseRefName)"
|
||||
head_ref="$(gh pr view "$pr_number" --json headRefName --jq .headRefName)"
|
||||
base_sha="$(gh pr view "$pr_number" --json baseRefOid --jq .baseRefOid)"
|
||||
head_sha="$(gh pr view "$pr_number" --json headRefOid --jq .headRefOid)"
|
||||
|
||||
echo "should_run=true" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_title<<EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "$pr_title" >> "$GITHUB_OUTPUT"
|
||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_body<<EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "$pr_body" >> "$GITHUB_OUTPUT"
|
||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "base_ref=$base_ref" >> "$GITHUB_OUTPUT"
|
||||
echo "head_ref=$head_ref" >> "$GITHUB_OUTPUT"
|
||||
echo "base_sha=$base_sha" >> "$GITHUB_OUTPUT"
|
||||
echo "head_sha=$head_sha" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout PR merge ref
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
ref: refs/pull/${{ steps.gate.outputs.pr_number }}/merge
|
||||
if: ${{ steps.gate.outputs.should_run == 'true' }}
|
||||
|
||||
- name: Pre-fetch base and head refs
|
||||
if: ${{ steps.gate.outputs.should_run == 'true' }}
|
||||
run: |
|
||||
git fetch --no-tags origin \
|
||||
${{ github.event.pull_request.base.ref }} \
|
||||
+refs/pull/${{ github.event.pull_request.number }}/head
|
||||
${{ steps.gate.outputs.base_ref }} \
|
||||
+refs/pull/${{ steps.gate.outputs.pr_number }}/head
|
||||
|
||||
- name: Run Codex
|
||||
id: run_codex
|
||||
if: ${{ steps.gate.outputs.should_run == 'true' }}
|
||||
uses: openai/codex-action@v1
|
||||
with:
|
||||
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
|
||||
output-schema-file: .github/codex/pr-merge-schema.json
|
||||
model: gpt-5.2-codex
|
||||
prompt: |
|
||||
You are reviewing PR #${{ github.event.pull_request.number }} for ${{ github.repository }}.
|
||||
You are reviewing PR #${{ steps.gate.outputs.pr_number }} for ${{ github.repository }}.
|
||||
|
||||
Decide whether to merge or comment. Merge only if all of the following are true:
|
||||
- Changes are simple and safe (no DoS, no long operations, no backdoors).
|
||||
@@ -48,16 +101,17 @@ jobs:
|
||||
|
||||
Pull request title and body:
|
||||
----
|
||||
${{ github.event.pull_request.title }}
|
||||
${{ github.event.pull_request.body }}
|
||||
${{ steps.gate.outputs.pr_title }}
|
||||
${{ steps.gate.outputs.pr_body }}
|
||||
|
||||
Review ONLY the changes introduced by the PR:
|
||||
git log --oneline ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}
|
||||
git log --oneline ${{ steps.gate.outputs.base_sha }}...${{ steps.gate.outputs.head_sha }}
|
||||
|
||||
Output JSON only, following the provided schema.
|
||||
|
||||
- name: Parse Codex decision
|
||||
id: parse
|
||||
if: ${{ steps.gate.outputs.should_run == 'true' }}
|
||||
env:
|
||||
CODEX_MESSAGE: ${{ steps.run_codex.outputs.final-message }}
|
||||
run: |
|
||||
@@ -78,7 +132,7 @@ jobs:
|
||||
merge_or_comment:
|
||||
runs-on: ubuntu-latest
|
||||
needs: codex_triage
|
||||
if: ${{ needs.codex_triage.outputs.decision != '' }}
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && needs.codex_triage.outputs.should_run == 'true' && needs.codex_triage.outputs.decision != '' }}
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
@@ -87,7 +141,7 @@ jobs:
|
||||
if: ${{ needs.codex_triage.outputs.decision == 'merge' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_NUMBER: ${{ needs.codex_triage.outputs.pr_number }}
|
||||
run: |
|
||||
gh api \
|
||||
-X PUT \
|
||||
@@ -100,7 +154,7 @@ jobs:
|
||||
if: ${{ needs.codex_triage.outputs.decision == 'comment' }}
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_NUMBER: ${{ needs.codex_triage.outputs.pr_number }}
|
||||
CODEX_MESSAGE: ${{ needs.codex_triage.outputs.message }}
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
68
.github/workflows/pr-failure-codex-dispatch.yml
vendored
68
.github/workflows/pr-failure-codex-dispatch.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
codex_on_failure:
|
||||
resolve_pr_context:
|
||||
if: >
|
||||
${{ github.event.workflow_run.conclusion == 'failure' &&
|
||||
github.event.workflow_run.pull_requests &&
|
||||
@@ -14,11 +14,14 @@ jobs:
|
||||
!startsWith(github.event.workflow_run.head_commit.message, 'Fix CI failures for PR #') }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
actions: read
|
||||
|
||||
pull-requests: read
|
||||
issues: read
|
||||
outputs:
|
||||
number: ${{ steps.pr_context.outputs.number }}
|
||||
author: ${{ steps.pr_context.outputs.author }}
|
||||
head_repo: ${{ steps.pr_context.outputs.head_repo }}
|
||||
head_branch: ${{ steps.pr_context.outputs.head_branch }}
|
||||
should_run: ${{ steps.pr_context.outputs.should_run }}
|
||||
steps:
|
||||
- name: Resolve PR context
|
||||
id: pr_context
|
||||
@@ -35,18 +38,37 @@ jobs:
|
||||
pr_head_branch=$(gh api -H "Accept: application/vnd.github+json" \
|
||||
/repos/${{ github.repository }}/pulls/${PR_NUMBER} \
|
||||
--jq '.head.ref')
|
||||
pr_labels=$(gh api -H "Accept: application/vnd.github+json" \
|
||||
/repos/${{ github.repository }}/issues/${PR_NUMBER} \
|
||||
--jq '.labels[].name')
|
||||
if echo "$pr_labels" | grep -q "^codex-fix-attempted$"; then
|
||||
echo "codex fix already attempted for PR #${PR_NUMBER}; skipping."
|
||||
should_run=false
|
||||
else
|
||||
should_run=true
|
||||
fi
|
||||
{
|
||||
echo "number=${PR_NUMBER}"
|
||||
echo "author=${pr_author}"
|
||||
echo "head_repo=${pr_head_repo}"
|
||||
echo "head_branch=${pr_head_branch}"
|
||||
echo "should_run=${should_run}"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
codex_on_failure:
|
||||
needs: resolve_pr_context
|
||||
if: ${{ needs.resolve_pr_context.outputs.author == 'carlospolop' && needs.resolve_pr_context.outputs.should_run == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Comment on PR with failure info
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.pr_context.outputs.number }}
|
||||
PR_NUMBER: ${{ needs.resolve_pr_context.outputs.number }}
|
||||
RUN_URL: ${{ github.event.workflow_run.html_url }}
|
||||
WORKFLOW_NAME: ${{ github.event.workflow_run.name }}
|
||||
with:
|
||||
@@ -61,23 +83,30 @@ jobs:
|
||||
body,
|
||||
});
|
||||
|
||||
- name: Mark fix attempt
|
||||
env:
|
||||
PR_NUMBER: ${{ needs.resolve_pr_context.outputs.number }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh api -X POST -H "Accept: application/vnd.github+json" \
|
||||
/repos/${{ github.repository }}/issues/${PR_NUMBER}/labels \
|
||||
-f labels='["codex-fix-attempted"]'
|
||||
|
||||
- name: Checkout PR head
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: ${{ steps.pr_context.outputs.head_repo }}
|
||||
repository: ${{ needs.resolve_pr_context.outputs.head_repo }}
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
token: ${{ secrets.CODEX_FIXER_TOKEN }}
|
||||
|
||||
- name: Configure git author
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
run: |
|
||||
git config user.name "codex-action"
|
||||
git config user.email "codex-action@users.noreply.github.com"
|
||||
|
||||
- name: Fetch failure summary
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
@@ -105,11 +134,10 @@ jobs:
|
||||
PY
|
||||
|
||||
- name: Create Codex prompt
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.pr_context.outputs.number }}
|
||||
PR_NUMBER: ${{ needs.resolve_pr_context.outputs.number }}
|
||||
RUN_URL: ${{ github.event.workflow_run.html_url }}
|
||||
HEAD_BRANCH: ${{ steps.pr_context.outputs.head_branch }}
|
||||
HEAD_BRANCH: ${{ needs.resolve_pr_context.outputs.head_branch }}
|
||||
run: |
|
||||
{
|
||||
echo "You are fixing CI failures for PR #${PR_NUMBER} in ${{ github.repository }}."
|
||||
@@ -125,7 +153,6 @@ jobs:
|
||||
} > codex_prompt.txt
|
||||
|
||||
- name: Run Codex
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
id: run_codex
|
||||
uses: openai/codex-action@v1
|
||||
with:
|
||||
@@ -135,10 +162,9 @@ jobs:
|
||||
model: gpt-5.2-codex
|
||||
|
||||
- name: Commit and push if changed
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' }}
|
||||
env:
|
||||
TARGET_BRANCH: ${{ steps.pr_context.outputs.head_branch }}
|
||||
PR_NUMBER: ${{ steps.pr_context.outputs.number }}
|
||||
TARGET_BRANCH: ${{ needs.resolve_pr_context.outputs.head_branch }}
|
||||
PR_NUMBER: ${{ needs.resolve_pr_context.outputs.number }}
|
||||
run: |
|
||||
if git diff --quiet; then
|
||||
echo "No changes to commit."
|
||||
@@ -151,10 +177,10 @@ jobs:
|
||||
git push origin HEAD:${TARGET_BRANCH}
|
||||
|
||||
- name: Comment with Codex result
|
||||
if: ${{ steps.pr_context.outputs.author == 'carlospolop' && steps.run_codex.outputs.final-message != '' }}
|
||||
if: ${{ steps.run_codex.outputs.final-message != '' }}
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.pr_context.outputs.number }}
|
||||
PR_NUMBER: ${{ needs.resolve_pr_context.outputs.number }}
|
||||
CODEX_MESSAGE: ${{ steps.run_codex.outputs.final-message }}
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Title: Software Information - Browser Profiles
|
||||
# ID: SW_Browser_Profiles
|
||||
# ID: SW_Browser_profiles
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 10-03-2025
|
||||
# Description: List browser profiles that may store credentials/cookies
|
||||
|
||||
@@ -8,6 +8,7 @@ from .yamlGlobals import (
|
||||
class LinpeasModule:
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
real_path = os.path.realpath(path)
|
||||
with open(path, 'r') as file:
|
||||
self.module_text = file.read()
|
||||
|
||||
@@ -29,7 +30,7 @@ class LinpeasModule:
|
||||
self.section_info = {}
|
||||
if not (self.is_base or self.is_function or self.is_variable):
|
||||
for module in LINPEAS_PARTS["modules"]:
|
||||
if module["folder_path"] in path:
|
||||
if os.path.realpath(module["folder_path"]) in real_path:
|
||||
self.section_info = module
|
||||
self.is_check = True
|
||||
break
|
||||
|
||||
40
linPEAS/tests/test_builder.py
Normal file
40
linPEAS/tests/test_builder.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
import stat
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class LinpeasBuilderTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.repo_root = Path(__file__).resolve().parents[2]
|
||||
self.linpeas_dir = self.repo_root / "linPEAS"
|
||||
|
||||
def _run_builder(self, args, output_path):
|
||||
cmd = ["python3", "-m", "builder.linpeas_builder"] + args + ["--output", str(output_path)]
|
||||
result = subprocess.run(cmd, cwd=str(self.linpeas_dir), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise AssertionError(
|
||||
f"linpeas_builder failed:\nstdout:\n{result.stdout}\nstderr:\n{result.stderr}"
|
||||
)
|
||||
|
||||
def test_small_build_creates_executable(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_path = Path(tmpdir) / "linpeas_small.sh"
|
||||
self._run_builder(["--small"], output_path)
|
||||
self.assertTrue(output_path.exists(), "linpeas_small.sh was not created.")
|
||||
mode = output_path.stat().st_mode
|
||||
self.assertTrue(mode & stat.S_IXUSR, "linpeas_small.sh is not executable.")
|
||||
|
||||
def test_include_exclude_modules(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_path = Path(tmpdir) / "linpeas_include.sh"
|
||||
self._run_builder(["--include", "system_information,container", "--exclude", "container"], output_path)
|
||||
content = output_path.read_text(encoding="utf-8", errors="ignore")
|
||||
self.assertIn("Operative system", content)
|
||||
self.assertNotIn("Am I Containered?", content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
60
linPEAS/tests/test_modules_metadata.py
Normal file
60
linPEAS/tests/test_modules_metadata.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class LinpeasModulesMetadataTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.repo_root = Path(__file__).resolve().parents[2]
|
||||
cls.linpeas_dir = cls.repo_root / "linPEAS"
|
||||
cls.parts_dir = cls.linpeas_dir / "builder" / "linpeas_parts"
|
||||
|
||||
# Ensure `import builder.*` works when tests are run from repo root.
|
||||
sys.path.insert(0, str(cls.linpeas_dir))
|
||||
|
||||
from builder.src.linpeasModule import LinpeasModule # pylint: disable=import-error
|
||||
|
||||
cls.LinpeasModule = LinpeasModule
|
||||
|
||||
def _iter_module_files(self):
|
||||
return sorted(self.parts_dir.rglob("*.sh"))
|
||||
|
||||
def test_all_modules_parse(self):
|
||||
module_files = self._iter_module_files()
|
||||
self.assertGreater(len(module_files), 0, "No linPEAS module files were found.")
|
||||
|
||||
# Parsing a module validates its metadata and dependencies.
|
||||
for path in module_files:
|
||||
_ = self.LinpeasModule(str(path))
|
||||
|
||||
def test_check_module_id_matches_filename(self):
|
||||
for path in self._iter_module_files():
|
||||
module = self.LinpeasModule(str(path))
|
||||
if not getattr(module, "is_check", False):
|
||||
continue
|
||||
|
||||
# For checks, the filename (without numeric prefix) must match the module ID
|
||||
# (either full ID or stripping section prefix like `SI_`).
|
||||
file_base = re.sub(r"^[0-9]+_", "", path.stem)
|
||||
module_id = getattr(module, "id", "")
|
||||
module_id_tail = module_id[3:] if len(module_id) >= 3 else ""
|
||||
self.assertIn(
|
||||
file_base,
|
||||
{module_id, module_id_tail},
|
||||
f"Module ID mismatch in {path}: id={module_id} expected suffix={file_base}",
|
||||
)
|
||||
|
||||
def test_module_ids_are_unique(self):
|
||||
ids = []
|
||||
for path in self._iter_module_files():
|
||||
module = self.LinpeasModule(str(path))
|
||||
ids.append(getattr(module, "id", ""))
|
||||
|
||||
duplicates = {x for x in ids if x and ids.count(x) > 1}
|
||||
self.assertEqual(set(), duplicates, f"Duplicate module IDs found: {sorted(duplicates)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -127,7 +127,9 @@ def parse_line(line: str):
|
||||
|
||||
elif is_section(line, INFO_PATTERN):
|
||||
title = parse_title(line)
|
||||
C_SECTION["infos"].append(title)
|
||||
if C_SECTION == {}:
|
||||
return
|
||||
C_SECTION.setdefault("infos", []).append(title)
|
||||
|
||||
#If here, then it's text
|
||||
else:
|
||||
|
||||
26
winPEAS/winPEASexe/CMakeLists.txt
Normal file
26
winPEAS/winPEASexe/CMakeLists.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(winPEAS_dotnet NONE)
|
||||
|
||||
set(PROJECT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/winPEAS.csproj")
|
||||
|
||||
find_program(DOTNET_EXECUTABLE dotnet)
|
||||
find_program(MSBUILD_EXECUTABLE msbuild)
|
||||
find_program(XBUILD_EXECUTABLE xbuild)
|
||||
|
||||
if(DOTNET_EXECUTABLE)
|
||||
set(BUILD_TOOL "${DOTNET_EXECUTABLE}")
|
||||
set(BUILD_ARGS build "${PROJECT_FILE}" -c Release)
|
||||
elseif(MSBUILD_EXECUTABLE)
|
||||
set(BUILD_TOOL "${MSBUILD_EXECUTABLE}")
|
||||
set(BUILD_ARGS "${PROJECT_FILE}" /p:Configuration=Release)
|
||||
elseif(XBUILD_EXECUTABLE)
|
||||
set(BUILD_TOOL "${XBUILD_EXECUTABLE}")
|
||||
set(BUILD_ARGS "${PROJECT_FILE}" /p:Configuration=Release)
|
||||
else()
|
||||
message(FATAL_ERROR "dotnet, msbuild, or xbuild is required to build winPEAS")
|
||||
endif()
|
||||
|
||||
add_custom_target(winpeas ALL
|
||||
COMMAND ${BUILD_TOOL} ${BUILD_ARGS}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
36
winPEAS/winPEASexe/Tests/ArgumentParsingTests.cs
Normal file
36
winPEAS/winPEASexe/Tests/ArgumentParsingTests.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace winPEAS.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class ArgumentParsingTests
|
||||
{
|
||||
private static bool InvokeIsNetworkTypeValid(string arg)
|
||||
{
|
||||
var method = typeof(winPEAS.Checks.Checks).GetMethod("IsNetworkTypeValid", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
Assert.IsNotNull(method, "IsNetworkTypeValid method not found.");
|
||||
return (bool)method.Invoke(null, new object[] { arg });
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldAcceptValidNetworkTypes()
|
||||
{
|
||||
Assert.IsTrue(InvokeIsNetworkTypeValid("-network=auto"));
|
||||
Assert.IsTrue(InvokeIsNetworkTypeValid("-network=10.10.10.10"));
|
||||
Assert.IsTrue(InvokeIsNetworkTypeValid("-network=10.10.10.10/24"));
|
||||
Assert.IsTrue(InvokeIsNetworkTypeValid("-network=10.10.10.10,10.10.10.20"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldRejectInvalidNetworkTypes()
|
||||
{
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network="));
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network=10.10.10.999"));
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network=10.10.10.10/64"));
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network=999.999.999.999/24"));
|
||||
Assert.IsFalse(InvokeIsNetworkTypeValid("-network=not-an-ip"));
|
||||
}
|
||||
}
|
||||
}
|
||||
37
winPEAS/winPEASexe/Tests/ChecksArgumentEdgeCasesTests.cs
Normal file
37
winPEAS/winPEASexe/Tests/ChecksArgumentEdgeCasesTests.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace winPEAS.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class ChecksArgumentEdgeCasesTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void ShouldNotThrowOnEmptyLogFileArg()
|
||||
{
|
||||
// Should return early with a user-friendly error, not crash.
|
||||
Program.Main(new[] { "log=" });
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldNotThrowOnPortsWithoutNetwork()
|
||||
{
|
||||
// Should warn and return early because -network was not provided.
|
||||
Program.Main(new[] { "-ports=80,443" });
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldNotThrowOnInvalidNetworkArgument()
|
||||
{
|
||||
// Should warn and return early because the IP is invalid.
|
||||
Program.Main(new[] { "-network=10.10.10.999" });
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldNotThrowOnEmptyNetworkArgument()
|
||||
{
|
||||
// Should warn and return early because the value is empty.
|
||||
Program.Main(new[] { "-network=" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,11 @@
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.2.2.5\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.2.2.5\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
@@ -95,6 +97,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ArgumentParsingTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SmokeTests.cs" />
|
||||
</ItemGroup>
|
||||
@@ -108,6 +111,40 @@
|
||||
<Name>winPEAS</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyVSTestFrameworkToMSTestAdapter" AfterTargets="Build">
|
||||
<PropertyGroup>
|
||||
<_PackagesDir>$(MSBuildThisFileDirectory)..\packages\</_PackagesDir>
|
||||
<_MSTestFrameworkDir>$(_PackagesDir)MSTest.TestFramework.2.2.5\lib\net45\</_MSTestFrameworkDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="Exists('$(_MSTestFrameworkDir)')">
|
||||
<_VSTestFrameworkDlls Include="$(_MSTestFrameworkDir)Microsoft.VisualStudio.TestPlatform.TestFramework*.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_VSTestCopyDirs Include="$(TargetDir)" Condition="'$(TargetDir)' != '' AND Exists('$(TargetDir)')" />
|
||||
<_MSTestAdapterDirs Include="$(_PackagesDir)MSTest.TestAdapter.2.2.5\build\net45\" Condition="Exists('$(_PackagesDir)MSTest.TestAdapter.2.2.5\build\net45\')" />
|
||||
<_MSTestAdapterDirs Include="$(_PackagesDir)MSTest.TestAdapter.2.2.5\build\_common\" Condition="Exists('$(_PackagesDir)MSTest.TestAdapter.2.2.5\build\_common\')" />
|
||||
</ItemGroup>
|
||||
|
||||
<Message
|
||||
Condition="@(_VSTestFrameworkDlls) != ''"
|
||||
Importance="high"
|
||||
Text="CopyVSTestFrameworkToMSTestAdapter: copying @( _VSTestFrameworkDlls )" />
|
||||
|
||||
<Copy
|
||||
Condition="@(_VSTestFrameworkDlls) != '' AND @(_VSTestCopyDirs) != ''"
|
||||
SourceFiles="@(_VSTestFrameworkDlls)"
|
||||
DestinationFolder="%(_VSTestCopyDirs.Identity)"
|
||||
SkipUnchangedFiles="true" />
|
||||
|
||||
<Copy
|
||||
Condition="@(_VSTestFrameworkDlls) != '' AND @(_MSTestAdapterDirs) != ''"
|
||||
SourceFiles="@(_VSTestFrameworkDlls)"
|
||||
DestinationFolder="%(_MSTestAdapterDirs.Identity)"
|
||||
SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@@ -133,4 +170,4 @@
|
||||
<Import Project="..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.119.0\build\net451\Stub.System.Data.SQLite.Core.NetFramework.targets" Condition="Exists('..\packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.119.0\build\net451\Stub.System.Data.SQLite.Core.NetFramework.targets')" />
|
||||
<Import Project="..\packages\Fody.6.5.5\build\Fody.targets" Condition="Exists('..\packages\Fody.6.5.5\build\Fody.targets')" />
|
||||
<Import Project="..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -356,7 +356,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
var rangeParts = networkType.Split('/');
|
||||
|
||||
if (rangeParts.Length == 2 && int.TryParse(rangeParts[1], out int res) && res <= 32 && res >= 0)
|
||||
if (rangeParts.Length == 2 && IPAddress.TryParse(rangeParts[0], out _) && int.TryParse(rangeParts[1], out int res) && res <= 32 && res >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace winPEAS
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// TODO: keep Main minimal; this line was an intentional break in test PR.
|
||||
Checks.Checks.Run(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="Exists('MinimumRecommendedRules.ruleset')">MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
@@ -71,7 +71,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="Exists('MinimumRecommendedRules.ruleset')">MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn>
|
||||
@@ -84,7 +84,7 @@
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="Exists('MinimumRecommendedRules.ruleset')">MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
@@ -96,7 +96,7 @@
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="Exists('MinimumRecommendedRules.ruleset')">MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
@@ -108,7 +108,7 @@
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet Condition="Exists('MinimumRecommendedRules.ruleset')">MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
Reference in New Issue
Block a user