Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Accenture/jenkins-attack-framework
https://github.com/Accenture/jenkins-attack-framework
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/Accenture/jenkins-attack-framework
- Owner: Accenture
- License: mit
- Created: 2021-05-04T20:01:00.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2021-05-11T13:47:56.000Z (over 3 years ago)
- Last Synced: 2024-04-29T23:05:20.194Z (6 months ago)
- Language: Python
- Size: 97.7 KB
- Stars: 545
- Watchers: 17
- Forks: 63
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-cicd-attacks - Jenkins Attack Framework
- awesome-cicd-security - Jenkins Attack Framework
- awesome-hacking-lists - Accenture/jenkins-attack-framework - (Python)
README
Jenkins Attack Framework
============================## Description
This project can currently perform the following tasks:
* **AccessCheck:** Test credentials and provide a rough overview of their access levels
* **ConsoleOutput:** Dump the console output of the last build of every job on the server (Can be Gigabytes of data, but good for finding credentials)
* **CreateAPIToken:** Creates an API Token for the current user (Or another user if you have administrative credentials)
* **DeleteAPIToken:** Deletes an API Token for the current user (Or another user if you have administrative credentials. Lists existing ones if no token supplied)
* **DeleteJob:** Delete a Job, or failing that, attempt a number of follow-up mitigations from most-to-least effective.
* **DumpCreds:** Dump credentials (Uses administrative credentials to dump credentials via Jenkins Console)
* **DumpCredsViaJob:** Dump credentials via job creation and explicit enumeration (User needs at least Add Job permissions)
* **ListAPITokens:** List existing API tokens for the current user (Or another user if you have administrative credentials)
* **ListJobs:** List existing Jenkins Jobs (Good For finding specific jobs)
* **RunCommand:** Run system command and get output/errors back (Uses administrative credentials and Jenkins Console)
* **RunJob:** Upload a script and run it as a job. Also run "Ghost Jobs" that don't terminate or show up in Jenkins (after launch)
* **RunScript:** Run Groovy scripts (Uses administrative credentials to run a Groovy Script via Jenkins Console)
* **UploadFile:** Upload a file (Uses administrative credentials and chunked uploading via Jenkins Console)
* **WhoAmI:** Get the credentialed user's Jenkins groups (Usually contains their domain groups)
* More things are in the works...
## Installing
Run the following commands:
git clone [email protected]:Accenture/jenkins-attack-framework.git
cd jaf
chmod +x jaf
sudo ./jaf --install
./jaf --installBefore you can use the RunJob "ghost job" feature against Windows Jenkins Slaves, you will need to compile the following file `data/cpp/windows_ghost_job_helper.cpp` using Visual Studio's cl tool (see compile arguments in comment at the top of that file), and then drop the compiled file in `data/exe/windows_ghost_job_helper.exe`.
## Command Line Help
The commandline help should be pretty straight forward, but is provided here with additional notes:
usage: jaf.py [-h]
Jenkins Attack Framework
positional arguments:
Subcommand to run (pass sub command for more detailed help):
AccessCheck ConsoleOutput CreateAPIToken DeleteAPIToken
DeleteJob DumpCreds DumpCredsViaJob ListAPITokens ListJobs
RunCommand RunJob RunScript UploadFile WhoAmIoptional arguments:
-h, --help show this help message and exit### Common Usage Notes
For every subcommand, you can get more detailed help by calling JAF with the subcommand and no additional options (or the `-h` option).
#### Server URL
For every command (other than requesting help), the `-s` command is required. This should be the full, base URL to the Jenkins instance.
#### User Agent
JAF will use the following user agent with each request: `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36`. This was chosen, at least at the time of this release to fit in. If you wish to use a different user-agent, one can be specified with the `-u` option.
#### Output Redirection
For every command, you may pass the `-o` option with a file path. If passed, JAF will write all output (with the exception of some fatal or critical errors) to the file instead of stdout. This option is particularly useful on Windows where console redirection tends to break on random bytes unless you change the code page.
#### Credentials
If no credentials are provided, JAF will attempt to connect with anonymous credentials.
Credentials can be provided via two methods. To provide a single set of credentials use the `-a` option.
Credentials can take three forms: `user:password`, `user:apitoken`, or a Cookie string.In the case of the latter option, the cookie should include the entire cookie (everthing after "Cookie: " in the browser header).
Cookie authentication is particularly useful when the Jenkin server uses federation with another Jenkins server for authentication.
In this scenario, normal `user:password` auth will not work. API tokens _may_ still work. If not, authenticate in your browser, then pass the cookie.
Cookie authentication can also include a `Jenkins Crumb`, which should be concatenated to the end of the cookie string to look something like: `JSESSIONID.9922756a=node0rhre4wjrdcjz9m4tbqx0qwqn1567.node0|Jenkins-Crumb=f5cb5472851aad76fc45568ef1e4160928d075376fd78c436a58d39b99aae09a`Though JAF can usually determine your authentication type by parsing the string, you can also hint the correct type by prepending your credential string with one of the following (self-explanatory) tags: `{USERPASS}`, `{APITOKEN}`, `{COOKIE}`
For the following two commands, you may pass a single set of credentials using the `-a` option or you may pass multiple credentials with the `-c` option: `AccessCheck` and `WhoAmI`.
The `-c` option takes either the path to a file which contains one of the aforementioned credential forms per line, or `-`. If `-` is passed, JAF will take credentials via stdin instead of from a file (formatting remains the same).#### Timeouts, Threads, and Waiting
HTTP Request Timeouts default to 30 seconds. If you would like a shorter or longer timeout, one can be configured with the `-n` option.
For certain multi-request methods (`ConsoleOutput`, `AccessCheck`, or `WhoAmI`), the number of threads (and thus number of simultaneous requests) can be configured. By default 4 threads are used. To specify a different number of threads pass the `-t` option.
For the `RunCommand`, `RunJob`, and `RunScript` methods, in addition to setting a total request timeout, you may pass the `-x` option to explicitly not wait for the request to return. This can be valuable when starting a SOCKS Proxy or similar long running task.
### AccessCheck
This method provides a number of heuristic checks for access levels which are useful for an attacker. A negative result should be accurate. A positive result means that the user potentially has the access, but you will need to perform additonal validation. There are simply too many ways to restrict access in Jenkins and no API for determining granular access levels, so results are not always prefectly accurate. Currently this method checks for the following access: `Basic Read Access (read)`, `Create Job Access (build)`, `Some level of Admin Access (admin)`, `Script Console Access (script)`, `Scriptler Groovy Script Plugin Access (scriptler)`
usage: jaf.py AccessCheck [-h] -s [-u ] [-n ]
[-o Output File] [-t ]
[-a [:[|]|]]
[-c ]Jenkins Attack Framework
positional arguments:
AccessCheck Get Users Rough Level of Access on Jenkins Serveroptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-t , --threads
Number of max concurrent HTTP requests. Defaults to: 4
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string
-c , --credentialfile
Credential File ("-" for stdin). Creds in form
":" or ":"### ConsoleOutput
This method dumps the console output for the last build of every job that the user can see. You need at least job viewing privileges which is not always possible to determine. This can and often does result in gigabytes (or even terabytes) of output.
usage: jaf.py ConsoleOutput [-h] -s [-u ] [-n ]
[-o Output File] [-t ]
[-a [:[|]|]]Jenkins Attack Framework
positional arguments:
ConsoleOutput Get Latest Console Output from All Jenkins Jobsoptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-t , --threads
Number of max concurrent HTTP requests. Defaults to: 4
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string### CreateAPIToken
Used to create an API Token for the user who's credentials are supplied. If the `--user` option is passed, this command will instead create an API token for the supplied user (but you must have administrative `/script` console access to do this).
`Token Name` is entirely optional and can be anything even a duplicate of an existing token name. Tokens are shown under the user's `configure` page (`/user//configure`), so pick a name that will blend in (or no name). If no `Token Name` is specified and you are creating the token for the current user, Jenkins will pick the name `Token Created on `. If creating a token with no `Token Name` as an admin for another user (or even yourself while using the `--user` option, the name will actually be blank, and the Jenkins API actually makes this kind of difficult to notice).
On successful token creation, the new API Token will be printed to the screen. You should capture this, as this token can never be viewed again.
usage: jaf.py CreateAPIToken [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]
[-U ] []Jenkins Attack Framework
positional arguments:
CreateAPIToken Create an API Token for your user
Token Name which is shown under the user's
configuration page (so pick something that is not too
suspicious). Can be duplicated (There do not appear to
be any restrictions on token names). If not provided,
only token creation date will be shown on user's page.optional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string
-U , --user
If provided, will use Jenkins Script Console to add
token for this user. (Requires Admin "/script"
permissions)### DeleteAPIToken
Used to delete an API Token for the user who's credentials are supplied. If the `--user` option is passed, this command will instead delete the API token for the supplied user (but you must have administrative `/script` console access to do this).
Token Name or UUID is required to actually delete a token. If not supplied, this function effectively acts like `ListAPITokens` and returns a list of existing tokens. If a `Token Name` is supplied this command will try to delete that token and alert you on success or failure. If the name matches multiple tokens, no token will be deleted, and you will receive an error message. In that case, you should instead list tokens (either by calling `DeleteAPIToken` with no additional arguments, or via calling `ListAPITokens`), then try again with a `Token UUID`. Deleted tokens cannot be restored, so make sure you are certain before attempting.
usage: jaf.py DeleteAPIToken [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]
[-U ] []Jenkins Attack Framework
positional arguments:
DeleteAPIToken Delete an API Token for your user
If not specified, command will return list of tokens
for subsequent calls.optional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string
-U , --user
If provided, will use Jenkins Script Console to delete
token for this user. (Requires Admin "/script"
permissions)### DeleteJob
Attempts to delete a Jenkins job. If the user does not have the rights, this will instead, attempt to delete all build logs, overwrite the job with a blank job, and then disable the job.
usage: jaf.py DeleteJob [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]
Jenkins Attack Framework
positional arguments:
DeleteJob Delete Jenkins Jobs
Task to Deleteoptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string### DumpCreds
Should be self explanatory, but this does require administrative credentials with `/script` access.
usage: jaf.py DumpCreds [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]
[-N ]Jenkins Attack Framework
positional arguments:
DumpCreds Dump all Stored Credentials on Jenkinsoptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string
-N , --node
Node (Slave) to execute against. Executes against
"master" if not specified.### DumpCredsViaJob
Dump credentials by creating a Job and explicitly enumerating echoing out all the credentials that are
stored and accessible to the user. These credentials are then Base64 encoded so as to prevent Jenkins from
redacting them. The credentials are retrieved and formatted. User must have at least Job creation privileges.usage: jaf.py DumpCredsViaJob [-h] -s [-u ]
[-n ] [-o Output File]
[-a [:[|]|]] [-N ]
[-T ]Jenkins Attack Framework
positional arguments:
DumpCredsViaJob Dump credentials via explicit enumeration of shared
credentials in a job (Only requires job creation
permissions and some shared credentials)
Task to Create, must be unique (may not be deleted if
user doesn't have job deletion permissions, so pick
something that blends in)optional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string
-N , --node
Node to execute against. If specified, you must also
pass -T
-T , --nodetype
Node Type, either: "posix" or "windows". If specified,
you must also pass -N### ListAPITokens
Method simply lists all existing API Tokens for the user who's creds you supplied. If the `--user` option is passed, this command will instead list the API tokens for the supplied user (but you must have administrative `/script` console access to do this).
The actual API Tokens cannot be recovered as only a hash is stored, and only Admin users can even access these hashes. So this method is really only useful for getting a list before trying to use `CreateAPIToken` or `DeleteAPIToken`.
usage: jaf.py ListAPITokens [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]
[-U ]Jenkins Attack Framework
positional arguments:
ListAPITokens List API Tokens for your useroptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string
-U , --user
If provided, will use Jenkins Script Console to query
tokens for this user. (Requires Admin "/script"
permissions)### ListJobs
Method simply lists all jobs on the server, recursively.
usage: jaf.py ListJobs [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]Jenkins Attack Framework
positional arguments:
ListJobs Get List of All Jenkins Job Namesoptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|]
User + Password or API Token, or full JSESSIONID
cookie string### RunCommand
This method wraps passed system commands to capture stdout and stderr and return it. Requires administrative credentials with `/script` access.
usage: jaf.py RunCommand [-h] -s [-u ] [-n ]
[-o Output File] [-a [:[|]|]]
[-x] [-N ]Jenkins Attack Framework
positional arguments:
RunCommand Run System Command on Jenkins via Jenkins Console
System Command To Runoptional arguments:
-h, --help show this help message and exit
-s , --server
Jenkins Server
-u , --useragent
JAF User-Agent. Defaults to: Mozilla/5.0 (Windows NT
10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/80.0.3987.149 Safari/537.36
-n , --timeout
HTTP Request Timeout (in seconds). Defaults to: 30
-o Output File, --output Output File
Write Output to File
-a [:[|]|], --authentication [:[|]|