├── .github ├── FUNDING.yml └── workflows │ ├── go.yml │ └── release_build.yml ├── .goreleaser.yml ├── LICENSE ├── README.md ├── browsing.go ├── config.go ├── config.yaml ├── email.go ├── go.mod ├── go.sum ├── litter.go ├── logger.go ├── lures.go ├── media.go ├── monitor.go ├── openai.go ├── print.go ├── redis.go ├── sinon.go ├── software.go ├── tasks.go ├── users.go ├── utils.go ├── wifi.go └── winsettings.go /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: referefref 2 | custom: ["paypal.me/referref"] 3 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: windows-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v4 21 | with: 22 | go-version: '1.18' 23 | 24 | - name: Build 25 | run: | 26 | go version 27 | go mod tidy 28 | go build -v ./... 29 | -------------------------------------------------------------------------------- /.github/workflows/release_build.yml: -------------------------------------------------------------------------------- 1 | name: Release Go project 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | permissions: 9 | contents: write 10 | 11 | jobs: 12 | build: 13 | name: sinon release 14 | runs-on: windows-latest 15 | 16 | steps: 17 | - name: Check out code into the Go module directory 18 | uses: actions/checkout@v3 19 | with: 20 | fetch-depth: 0 21 | - name: Set up Go 1.18 22 | uses: actions/setup-go@v4 23 | - name: Run GoReleaser 24 | uses: goreleaser/goreleaser-action@v5 25 | 26 | with: 27 | distribution: goreleaser 28 | version: latest 29 | args: release --clean --skip-validate 30 | env: 31 | GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }} 32 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # .goreleaser.yml 2 | project_name: sinon 3 | release: 4 | github: 5 | owner: referefref 6 | name: sinon 7 | 8 | builds: 9 | - id: sinon_windows 10 | main: ./sinon.go 11 | goos: 12 | - windows 13 | goarch: 14 | - amd64 15 | ldflags: 16 | - -s -w 17 | binary: sinon 18 | env: 19 | - CGO_ENABLED=0 20 | 21 | archives: 22 | - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" 23 | format: zip 24 | files: 25 | - LICENSE 26 | - README.md 27 | - config.yaml 28 | - "dist/sinon_windows_windows_amd64_v1/sinon.exe" 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sinon - Modular Windows Burn-In Automation with Generative AI for Deception 2 | 3 | ![image](https://github.com/referefref/sinon/assets/56499429/9c5395ac-2034-4bcb-8214-c3690013d521) 4 | 5 | Sinon is a modular tool for automatic burn-in of Windows-based deception hosts that aims to reduce the difficulty of orchestrating deception hosts at scale whilst enabling diversity and randomness through generative capabilities. It has been created as a proof-of-concept and is not intended for production deception environments. It would likely be better suited to having content pre-generated and built into a one-time script, as we wouldn't want to be storing secrets like OpenAI API keys on a decoy or deception host. 6 | - As featured on [***helpnetsecurity.com***](https://www.helpnetsecurity.com/2024/08/30/sinon-open-source-automatic-generative-burn-in-for-windows-deception-hosts), [***itsecuritynews.info***](https://www.itsecuritynews.info/sinon-open-source-automatic-generative-burn-in-for-windows-deception-hosts-2/) 7 | 8 | ## Features 9 | 10 | - Generative content including files, emails, and so on using OpenAI API (Configured for GPT-4o) 11 | - Randomness factor - select from list in config, or follow config completely 12 | - Temporal randomness - set delay to execution and delay between events including randomness factor 13 | 14 | Sinon performs the following functions, as determined by a config file: 15 | 16 | - **Install Applications**: Automatically install applications from a predefined list using Chocolatey. 17 | - **Browse Websites**: Automatically open a list of websites to simulate user activity. 18 | - **Change Preferences**: Modify system preferences such as default browser, background images, screen resolutions, and system languages. 19 | - **Add Start Menu Items**: Add shortcuts to specified applications in the start menu. 20 | - **Create and Modify Files**: Generate and modify text files with the option to use OpenAI GPT-4 for content generation. 21 | - **Send Emails**: Send emails with the option to use OpenAI GPT-4 for content generation. 22 | - **Download Decoy Files**: Download files from specified URLs to simulate decoy file activity. 23 | - **Manage Software**: Install or uninstall software applications using predefined commands. 24 | - **Perform System Updates**: Execute system update commands. 25 | - **Manage User Accounts**: Create and manage user accounts with specified attributes. 26 | - **Manage Network Settings**: Configure Wi-Fi network connections using SSID and password. 27 | - **Open Media Files**: Open media files such as images, videos, and audio files. 28 | - **Print Documents**: Print specified text documents. 29 | - **Create Scheduled Tasks**: Schedule tasks to run specified commands at defined times. 30 | - **Simulate User Interaction**: Control the duration and delay of interactions with randomness. 31 | - **Create Lures**: Generate various types of lures to deceive intruders. 32 | - Credential pairs 33 | - SSH keys 34 | - Website URLs 35 | - Registry keys 36 | - CSV documents 37 | - API keys 38 | - LNK files (shortcuts) 39 | - **Monitor File System**: Watch specified paths for file system events such as modifications and log these events. 40 | - **Redis Connectivity**: Send generated lure data to Redis server for utilisation in additional deception steps and platforms. 41 | 42 | ## Usage 43 | 44 | 1. **Clone the repository:** 45 | ```sh 46 | git clone https://github.com/yourusername/sinon.git 47 | cd sinon 48 | ``` 49 | 50 | 2. **Configure the application:** 51 | - Modify the `config.yaml` file to suit your needs. See the [Config Items](#config-items) section for details. 52 | 53 | 3. **Build the application:** 54 | ```sh 55 | go build -o sinon 56 | # building for windows on linux: GOOS=windows GOARCH=amd64 go build -o sinon.exe 57 | ``` 58 | 59 | 4. **Deploy the application to your target machine:** 60 | - This could be accomplished many ways, you may want to burn it in to an image, use SCCM/Intune etc. 61 | 62 | ## Config Items 63 | 64 | The `config.yaml` file contains all the configuration options for Sinon. Here is an example configuration file with explanations: 65 | 66 | ```yaml 67 | applications: 68 | options: 69 | - googlechrome 70 | - firefox 71 | - notepadplusplus 72 | - vlc 73 | selection_method: random 74 | 75 | websites: 76 | options: 77 | - https://www.google.com 78 | - https://www.wikipedia.org 79 | - https://www.github.com 80 | selection_method: random 81 | 82 | preferences: 83 | default_browser: 84 | options: 85 | - "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" 86 | - "C:\\Program Files\\Mozilla Firefox\\firefox.exe" 87 | selection_method: random 88 | background_images: 89 | location: "C:\\Users\\user\\Pictures" 90 | type: http 91 | selection_method: random 92 | options: 93 | - https://example.com/background1.jpg 94 | - https://example.com/background2.jpg 95 | screen_resolutions: 96 | options: 97 | - "1920x1080" 98 | - "1366x768" 99 | selection_method: random 100 | languages: 101 | options: 102 | - en-US 103 | - es-ES 104 | selection_method: random 105 | 106 | start_menu_items: 107 | options: 108 | - "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" 109 | - "C:\\Program Files\\Mozilla Firefox\\firefox.exe" 110 | selection_method: random 111 | 112 | file_operations: 113 | create_modify_files: 114 | - path: "C:\\Users\\user\\Documents\\example.txt" 115 | content: "This is an example text file." 116 | use_gpt: false 117 | gpt_prompt: "" 118 | 119 | email_operations: 120 | google_account: 121 | email: "user@gmail.com" 122 | password: "password" 123 | microsoft_account: 124 | email: "user@outlook.com" 125 | password: "password" 126 | send_receive: 127 | - send_to: "recipient@example.com" 128 | subject: "Test Email" 129 | body: "This is a test email." 130 | use_gpt: true 131 | gpt_prompt: "Write a friendly email to a colleague." 132 | 133 | software_management: 134 | options: 135 | - upgrade all 136 | - uninstall vlc 137 | selection_method: random 138 | 139 | system_updates: 140 | method: install_all 141 | specific_updates: 142 | - KB123456 143 | - KB789012 144 | selection_method: random 145 | hide_updates: 146 | - KB654321 147 | - KB210987 148 | 149 | user_accounts: 150 | - name: user1 151 | password: password1 152 | full_name: User One 153 | description: First user account 154 | - name: user2 155 | password: password2 156 | full_name: User Two 157 | description: Second user account 158 | 159 | network_settings: 160 | - ssid: ExampleSSID 161 | password: examplepassword 162 | 163 | system_logs: 164 | options: 165 | - Application 166 | - System 167 | selection_method: random 168 | 169 | media_files: 170 | location: "C:\\Users\\user\\Videos" 171 | type: http 172 | selection_method: random 173 | options: 174 | - https://example.com/video1.mp4 175 | - https://example.com/video2.mp4 176 | 177 | printing: 178 | options: 179 | - "C:\\Users\\user\\Documents\\print_me.txt" 180 | selection_method: random 181 | 182 | scheduled_tasks: 183 | options: 184 | - name: Task1 185 | path: "C:\\Windows\\System32\\notepad.exe" 186 | schedule: "daily" 187 | start_time: "14:00" 188 | - name: Task2 189 | path: "C:\\Windows\\System32\\calc.exe" 190 | schedule: "weekly" 191 | start_time: "10:00" 192 | selection_method: random 193 | 194 | decoy_files: 195 | sets: 196 | - location: 197 | - "https://example.com/decoy1.txt" 198 | - "https://example.com/decoy2.txt" 199 | type: http 200 | target_directory: 201 | - "C:\\Users\\user\\Documents" 202 | selection_method: random 203 | 204 | lures: 205 | - name: CredentialLure 206 | type: credential_pair 207 | location: "C:\\Users\\user\\Desktop\\credential.txt" 208 | generation_params: 209 | length: 12 210 | generative_type: golang 211 | openai_prompt: "" 212 | - name: SSLLure 213 | type: ssh_key 214 | location: "C:\\Users\\user\\Desktop\\id_rsa" 215 | generation_params: {} 216 | generative_type: golang 217 | openai_prompt: "" 218 | - name: URLLure 219 | type: website_url 220 | location: "C:\\Users\\user\\Desktop\\phishing_link.url" 221 | generation_params: 222 | base_url: "https://malicious.example.com" 223 | generative_type: golang 224 | openai_prompt: "" 225 | - name: RegistryLure 226 | type: registry_key 227 | location: "HKEY_CURRENT_USER\\Software\\ExampleKey" 228 | generation_params: 229 | registry_key_type: "REG_SZ" 230 | registry_key_value: "ExampleValue" 231 | generative_type: golang 232 | openai_prompt: "" 233 | - name: CSVLure 234 | type: csv 235 | location: "C:\\Users\\user\\Desktop\\financial_records.csv" 236 | generation_params: 237 | document_content: "Date,Amount,Description\n2024-01-01,1000,Salary" 238 | generative_type: golang 239 | openai_prompt: "" 240 | - name: APIKeyLure 241 | type: api_key 242 | location: "C:\\Users\\user\\Desktop\\api_key.txt" 243 | generation_params: 244 | api_key_format: "uuid" 245 | generative_type: golang 246 | openai_prompt: "" 247 | - name: LNKLure 248 | type: lnk 249 | location: "C:\\Users\\user\\Desktop\\shortcut.lnk" 250 | generation_params: 251 | target_path: "C:\\Windows\\System32\\notepad.exe" 252 | generative_type: golang 253 | openai_prompt: "" 254 | 255 | general: 256 | redis: 257 | ip: "127.0.0.1" 258 | port: 6379 259 | log_file: "C:\\Users\\user\\sinon.log" 260 | openai_api_key: "your_openai_api_key" 261 | interaction_duration: 60 262 | action_delay: 5 263 | randomness_factor: 2 264 | 265 | ``` 266 | 267 | ## Deploying Windows Deception Hosts 268 | Sinon is designed to automate the setup of deception hosts by performing a variety of actions that simulate real user activity. The goal is to create a realistic environment that can deceive potential intruders. The modular and configurable nature of Sinon allows for easy adjustments and randomization, making each deployment unique. 269 | 270 | ## Steps to Deploy 271 | - Prepare the Windows environment: Ensure that the target Windows machine is ready and accessible. 272 | - Configure Sinon: Edit the config.yaml file to define the desired behaviors and settings. 273 | - Run Sinon: Execute the compiled Sinon binary to start the automation process. 274 | - Monitor and manage: Keep an eye on the deployed deception host and make necessary adjustments to the configuration as needed. 275 | 276 | ```Note: Since Sinon is a proof-of-concept, it is recommended to use pre-generated content and avoid storing sensitive information like API keys on deception hosts in production environments.``` 277 | -------------------------------------------------------------------------------- /browsing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "math/rand" 5 | "os/exec" 6 | "time" 7 | ) 8 | 9 | func browseWebsites(config *Config) { 10 | logger := logMultiWriter(config.General.LogFile) 11 | 12 | websites := selectRandomOrHardcoded(config.Websites.Options, config.Websites.SelectionMethod) 13 | for _, website := range websites { 14 | cmd := exec.Command("cmd", "/C", "start", website) 15 | err := cmd.Run() 16 | if err != nil { 17 | logger.Printf("Failed to browse %s: %v", website, err) 18 | } else { 19 | logger.Printf("Browsing %s", website) 20 | } 21 | time.Sleep(time.Duration(config.General.ActionDelay+rand.Intn(2*config.General.RandomnessFactor+1)-config.General.RandomnessFactor) * time.Second) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | 6 | "gopkg.in/yaml.v2" 7 | ) 8 | 9 | type Config struct { 10 | Applications StringSelection `yaml:"applications"` 11 | Websites StringSelection `yaml:"websites"` 12 | Preferences Preferences `yaml:"preferences"` 13 | StartMenuItems StringSelection `yaml:"start_menu_items"` 14 | FileOperations FileOperations `yaml:"file_operations"` 15 | EmailOperations EmailOperations `yaml:"email_operations"` 16 | SoftwareManagement StringSelection `yaml:"software_management"` 17 | SystemUpdates SystemUpdates `yaml:"system_updates"` 18 | UserAccounts []UserAccount `yaml:"user_accounts"` 19 | NetworkSettings []Network `yaml:"network_settings"` 20 | SystemLogs StringSelection `yaml:"system_logs"` 21 | MediaFiles MediaLocation `yaml:"media_files"` 22 | Printing StringSelection `yaml:"printing"` 23 | ScheduledTasks ScheduledTaskSelection `yaml:"scheduled_tasks"` 24 | DecoyFiles DecoyFiles `yaml:"decoy_files"` 25 | Lures []LureConfig `yaml:"lures"` 26 | General GeneralConfig `yaml:"general"` 27 | } 28 | 29 | type StringSelection struct { 30 | Options []string `yaml:"options"` 31 | SelectionMethod string `yaml:"selection_method"` 32 | } 33 | 34 | type ScheduledTaskSelection struct { 35 | Options []ScheduledTask `yaml:"options"` 36 | SelectionMethod string `yaml:"selection_method"` 37 | } 38 | 39 | type Preferences struct { 40 | DefaultBrowser StringSelection `yaml:"default_browser"` 41 | BackgroundImages MediaLocation `yaml:"background_images"` 42 | ScreenResolutions StringSelection `yaml:"screen_resolutions"` 43 | Languages StringSelection `yaml:"languages"` 44 | } 45 | 46 | type FileOperations struct { 47 | CreateModifyFiles []FileOperation `yaml:"create_modify_files"` 48 | } 49 | 50 | type FileOperation struct { 51 | Path string `yaml:"path"` 52 | Content string `yaml:"content"` 53 | UseGPT bool `yaml:"use_gpt"` 54 | GPTPrompt string `yaml:"gpt_prompt"` 55 | } 56 | 57 | type EmailOperations struct { 58 | GoogleAccount EmailAccount `yaml:"google_account"` 59 | MicrosoftAccount EmailAccount `yaml:"microsoft_account"` 60 | SendReceive []EmailOperation `yaml:"send_receive"` 61 | } 62 | 63 | type EmailAccount struct { 64 | Email string `yaml:"email"` 65 | Password string `yaml:"password"` 66 | } 67 | 68 | type EmailOperation struct { 69 | SendTo string `yaml:"send_to"` 70 | Subject string `yaml:"subject"` 71 | Body string `yaml:"body"` 72 | UseGPT bool `yaml:"use_gpt"` 73 | GPTPrompt string `yaml:"gpt_prompt"` 74 | } 75 | 76 | type MediaLocation struct { 77 | Location string `yaml:"location"` 78 | Type string `yaml:"type"` 79 | SelectionMethod string `yaml:"selection_method"` 80 | Options []string `yaml:"options"` 81 | } 82 | 83 | type DecoyFiles struct { 84 | Sets []DecoyFileSet `yaml:"sets"` 85 | } 86 | 87 | type DecoyFileSet struct { 88 | Location []string `yaml:"location"` 89 | Type string `yaml:"type"` 90 | TargetDirectory []string `yaml:"target_directory"` 91 | SelectionMethod string `yaml:"selection_method"` 92 | } 93 | 94 | type UserAccount struct { 95 | Name string `yaml:"name"` 96 | Password string `yaml:"password"` 97 | FullName string `yaml:"full_name"` 98 | Description string `yaml:"description"` 99 | } 100 | 101 | type Network struct { 102 | SSID string `yaml:"ssid"` 103 | Password string `yaml:"password"` 104 | } 105 | 106 | type ScheduledTask struct { 107 | Name string `yaml:"name"` 108 | Path string `yaml:"path"` 109 | Schedule string `yaml:"schedule"` 110 | StartTime string `yaml:"start_time"` 111 | } 112 | 113 | type LureConfig struct { 114 | Name string `yaml:"name"` 115 | Type string `yaml:"type"` 116 | Location string `yaml:"location"` 117 | GenerationParams map[string]interface{} `yaml:"generation_params"` 118 | GenerativeType string `yaml:"generative_type"` 119 | OpenaiPrompt string `yaml:"openai_prompt,omitempty"` 120 | Responder string `yaml:"responder,omitempty"` 121 | } 122 | 123 | type SystemUpdates struct { 124 | Method string `yaml:"method"` 125 | SpecificUpdates []string `yaml:"specific_updates,omitempty"` 126 | SelectionMethod string `yaml:"selection_method"` 127 | HideUpdates []string `yaml:"hide_updates,omitempty"` 128 | } 129 | 130 | type GeneralConfig struct { 131 | Redis struct { 132 | IP string `yaml:"ip"` 133 | Port int `yaml:"port"` 134 | } `yaml:"redis"` 135 | LogFile string `yaml:"log_file,omitempty"` 136 | OpenaiApiKey string `yaml:"openai_api_key,omitempty"` 137 | InteractionDuration int `yaml:"interaction_duration"` 138 | ActionDelay int `yaml:"action_delay"` 139 | RandomnessFactor int `yaml:"randomness_factor"` 140 | Usernames []string `yaml:"usernames"` 141 | SelectionMethod string `yaml:"selection_method"` 142 | } 143 | 144 | func loadConfig(filename string) (*Config, error) { 145 | data, err := ioutil.ReadFile(filename) 146 | if err != nil { 147 | return nil, err 148 | } 149 | var config Config 150 | err = yaml.Unmarshal(data, &config) 151 | if err != nil { 152 | return nil, err 153 | } 154 | return &config, nil 155 | } 156 | -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | applications: 2 | options: 3 | - googlechrome 4 | - firefox 5 | - notepadplusplus 6 | - vlc 7 | selection_method: random 8 | 9 | websites: 10 | options: 11 | - https://www.google.com 12 | - https://www.wikipedia.org 13 | - https://www.github.com 14 | selection_method: random 15 | 16 | preferences: 17 | default_browser: 18 | options: 19 | - "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" 20 | - "C:\\Program Files\\Mozilla Firefox\\firefox.exe" 21 | selection_method: random 22 | background_images: 23 | location: "C:\\Users\\user\\Pictures" 24 | type: http 25 | selection_method: random 26 | options: 27 | - https://example.com/background1.jpg 28 | - https://example.com/background2.jpg 29 | screen_resolutions: 30 | options: 31 | - "1920x1080" 32 | - "1366x768" 33 | selection_method: random 34 | languages: 35 | options: 36 | - en-US 37 | - es-ES 38 | selection_method: random 39 | 40 | start_menu_items: 41 | options: 42 | - "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" 43 | - "C:\\Program Files\\Mozilla Firefox\\firefox.exe" 44 | selection_method: random 45 | 46 | file_operations: 47 | create_modify_files: 48 | - path: "C:\\Users\\user\\Documents\\example.txt" 49 | content: "This is an example text file." 50 | use_gpt: false 51 | gpt_prompt: "" 52 | 53 | email_operations: 54 | google_account: 55 | email: "user@gmail.com" 56 | password: "password" 57 | microsoft_account: 58 | email: "user@outlook.com" 59 | password: "password" 60 | send_receive: 61 | - send_to: "recipient@example.com" 62 | subject: "Test Email" 63 | body: "This is a test email." 64 | use_gpt: true 65 | gpt_prompt: "Write a friendly email to a colleague." 66 | 67 | software_management: 68 | options: 69 | - upgrade all 70 | - uninstall vlc 71 | selection_method: random 72 | 73 | system_updates: 74 | method: install_all 75 | specific_updates: 76 | - KB123456 77 | - KB789012 78 | selection_method: random 79 | hide_updates: 80 | - KB654321 81 | - KB210987 82 | 83 | user_accounts: 84 | - name: user1 85 | password: password1 86 | full_name: User One 87 | description: First user account 88 | - name: user2 89 | password: password2 90 | full_name: User Two 91 | description: Second user account 92 | 93 | network_settings: 94 | - ssid: ExampleSSID 95 | password: examplepassword 96 | 97 | system_logs: 98 | options: 99 | - Application 100 | - System 101 | selection_method: random 102 | 103 | media_files: 104 | location: "C:\\Users\\user\\Videos" 105 | type: http 106 | selection_method: random 107 | options: 108 | - https://example.com/video1.mp4 109 | - https://example.com/video2.mp4 110 | 111 | printing: 112 | options: 113 | - "C:\\Users\\user\\Documents\\print_me.txt" 114 | selection_method: random 115 | 116 | scheduled_tasks: 117 | options: 118 | - name: Task1 119 | path: "C:\\Windows\\System32\\notepad.exe" 120 | schedule: "daily" 121 | start_time: "14:00" 122 | - name: Task2 123 | path: "C:\\Windows\\System32\\calc.exe" 124 | schedule: "weekly" 125 | start_time: "10:00" 126 | selection_method: random 127 | 128 | decoy_files: 129 | sets: 130 | - location: 131 | - "https://example.com/decoy1.txt" 132 | - "https://example.com/decoy2.txt" 133 | type: http 134 | target_directory: 135 | - "C:\\Users\\user\\Documents" 136 | selection_method: random 137 | 138 | lures: 139 | - name: CredentialLure 140 | type: credential_pair 141 | location: "C:\\Users\\user\\Desktop\\credential.txt" 142 | generation_params: 143 | length: 12 144 | generative_type: golang 145 | openai_prompt: "" 146 | - name: SSLLure 147 | type: ssh_key 148 | location: "C:\\Users\\user\\Desktop\\id_rsa" 149 | generation_params: {} 150 | generative_type: golang 151 | openai_prompt: "" 152 | - name: URLLure 153 | type: website_url 154 | location: "C:\\Users\\user\\Desktop\\phishing_link.url" 155 | generation_params: 156 | base_url: "https://malicious.example.com" 157 | generative_type: golang 158 | openai_prompt: "" 159 | - name: RegistryLure 160 | type: registry_key 161 | location: "HKEY_CURRENT_USER\\Software\\ExampleKey" 162 | generation_params: 163 | registry_key_type: "REG_SZ" 164 | registry_key_value: "ExampleValue" 165 | generative_type: golang 166 | openai_prompt: "" 167 | - name: CSVLure 168 | type: csv 169 | location: "C:\\Users\\user\\Desktop\\financial_records.csv" 170 | generation_params: 171 | document_content: "Date,Amount,Description\n2024-01-01,1000,Salary" 172 | generative_type: golang 173 | openai_prompt: "" 174 | - name: APIKeyLure 175 | type: api_key 176 | location: "C:\\Users\\user\\Desktop\\api_key.txt" 177 | generation_params: 178 | api_key_format: "uuid" 179 | generative_type: golang 180 | openai_prompt: "" 181 | - name: LNKLure 182 | type: lnk 183 | location: "C:\\Users\\user\\Desktop\\shortcut.lnk" 184 | generation_params: 185 | target_path: "C:\\Windows\\System32\\notepad.exe" 186 | generative_type: golang 187 | openai_prompt: "" 188 | 189 | general: 190 | redis: 191 | ip: "127.0.0.1" 192 | port: 6379 193 | log_file: "C:\\Users\\user\\sinon.log" 194 | openai_api_key: "your_openai_api_key" 195 | interaction_duration: 60 196 | action_delay: 5 197 | randomness_factor: 3 198 | -------------------------------------------------------------------------------- /email.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/smtp" 6 | ) 7 | 8 | func sendEmails(config *Config) { 9 | for _, emailOp := range config.EmailOperations.SendReceive { 10 | var body string 11 | if emailOp.UseGPT { 12 | body = generateContentUsingGPT(config.General.OpenaiApiKey, emailOp.GPTPrompt, config) 13 | } else { 14 | body = emailOp.Body 15 | } 16 | sendEmail(config.EmailOperations.GoogleAccount, emailOp.SendTo, emailOp.Subject, body, config) 17 | } 18 | } 19 | 20 | func sendEmail(account EmailAccount, to, subject, body string, config *Config) { 21 | from := account.Email 22 | password := account.Password 23 | 24 | msg := "From: " + from + "\n" + 25 | "To: " + to + "\n" + 26 | "Subject: " + subject + "\n\n" + 27 | body 28 | 29 | err := smtp.SendMail("smtp.gmail.com:587", 30 | smtp.PlainAuth("", from, password, "smtp.gmail.com"), 31 | from, []string{to}, []byte(msg)) 32 | 33 | if err != nil { 34 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to send email: %v", err)) 35 | } else { 36 | logToFile(config.General.LogFile, fmt.Sprintf("Email sent to %s", to)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module sinon 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/fsnotify/fsnotify v1.7.0 7 | github.com/go-redis/redis/v8 v8.11.5 8 | github.com/iamacarpet/go-win64api v0.0.0-20240507095429-873e84e85847 9 | github.com/pkg/sftp v1.13.6 10 | golang.org/x/crypto v0.24.0 11 | gopkg.in/yaml.v2 v2.4.0 12 | ) 13 | 14 | require ( 15 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 16 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 17 | github.com/go-ole/go-ole v1.2.6 // indirect 18 | github.com/google/cabbie v1.0.2 // indirect 19 | github.com/google/glazier v0.0.0-20211029225403-9f766cca891d // indirect 20 | github.com/kr/fs v0.1.0 // indirect 21 | github.com/scjalliance/comshim v0.0.0-20190308082608-cf06d2532c4e // indirect 22 | golang.org/x/net v0.26.0 // indirect 23 | golang.org/x/sys v0.21.0 // indirect 24 | ) 25 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | bitbucket.org/creachadair/stringset v0.0.9/go.mod h1:t+4WcQ4+PXTa8aQdNKe40ZP6iwesoMFWAxPGd3UGjyY= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/StackExchange/wmi v1.2.0/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= 4 | github.com/capnspacehook/taskmaster v0.0.0-20210519235353-1629df7c85e9/go.mod h1:257CYs3Wd/CTlLQ3c72jKv+fFE2MV3WPNnV5jiroYUU= 5 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= 6 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 7 | github.com/creachadair/staticfile v0.1.3/go.mod h1:a3qySzCIXEprDGxk6tSxSI+dBBdLzqeBOMhZ+o2d3pM= 8 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 10 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= 12 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 13 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 14 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 15 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= 16 | github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 17 | github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= 18 | github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 19 | github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= 20 | github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 21 | github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= 22 | github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= 23 | github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= 24 | github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 25 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 26 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 27 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 28 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 29 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 30 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 31 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 32 | github.com/google/aukera v0.0.0-20201117230544-d145c8357fea/go.mod h1:oXqTZORBzdwQ6L32YjJmaPajqIV/hoGEouwpFMf4cJE= 33 | github.com/google/cabbie v1.0.2 h1:UtB+Nn6fPB43wGg5xs4tgU+P3hTZ6KsulgtaHtqZZfs= 34 | github.com/google/cabbie v1.0.2/go.mod h1:6MmHaUrgfabehCHAIaxdrbmvHSxUVXj3Abs08FMABSo= 35 | github.com/google/glazier v0.0.0-20210617205946-bf91b619f5d4/go.mod h1:g7oyIhindbeebnBh0hbFua5rv6XUt/nweDwIWdvxirg= 36 | github.com/google/glazier v0.0.0-20211029225403-9f766cca891d h1:GBIF4RkD4E9USvSRT4O4tBCT77JExIr+qnruI9nkJQo= 37 | github.com/google/glazier v0.0.0-20211029225403-9f766cca891d/go.mod h1:h2R3DLUecGbLSyi6CcxBs5bdgtJhgK+lIffglvAcGKg= 38 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 39 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 40 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 41 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 42 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 43 | github.com/google/logger v1.1.0/go.mod h1:w7O8nrRr0xufejBlQMI83MXqRusvREoJdaAxV+CoAB4= 44 | github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= 45 | github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 46 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 47 | github.com/google/winops v0.0.0-20210803215038-c8511b84de2b/go.mod h1:ShbX8v8clPm/3chw9zHVwtW3QhrFpL8mXOwNxClt4pg= 48 | github.com/groob/plist v0.0.0-20210519001750-9f754062e6d6/go.mod h1:itkABA+w2cw7x5nYUS/pLRef6ludkZKOigbROmCTaFw= 49 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 50 | github.com/iamacarpet/go-win64api v0.0.0-20210311141720-fe38760bed28/go.mod h1:oGJx9dz0Ny7HC7U55RZ0Smd6N9p3hXP/+hOFtuYrAxM= 51 | github.com/iamacarpet/go-win64api v0.0.0-20240507095429-873e84e85847 h1:cRHZFGwIDgQlr9abL/P93JXR7pYxzvf0xAIt0xzwrh0= 52 | github.com/iamacarpet/go-win64api v0.0.0-20240507095429-873e84e85847/go.mod h1:B7zFQPAznj+ujXel5X+LUoK3LgY6VboCdVYHZNn7gpg= 53 | github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= 54 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 55 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 56 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= 57 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 58 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 59 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= 60 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 61 | github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 62 | github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= 63 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 64 | github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= 65 | github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= 66 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 67 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 68 | github.com/rickb777/date v1.14.2/go.mod h1:swmf05C+hN+m8/Xh7gEq3uB6QJDNc5pQBWojKdHetOs= 69 | github.com/rickb777/plural v1.2.2/go.mod h1:xyHbelv4YvJE51gjMnHvk+U2e9zIysg6lTnSQK8XUYA= 70 | github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= 71 | github.com/scjalliance/comshim v0.0.0-20190308082608-cf06d2532c4e h1:+/AzLkOdIXEPrAQtwAeWOBnPQ0BnYlBW0aCZmSb47u4= 72 | github.com/scjalliance/comshim v0.0.0-20190308082608-cf06d2532c4e/go.mod h1:9Tc1SKnfACJb9N7cw2eyuI6xzy845G7uZONBsi5uPEA= 73 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 74 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 75 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 76 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 77 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 78 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 79 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 80 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 81 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 82 | golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 83 | golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= 84 | golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= 85 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 86 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 87 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 88 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 89 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 90 | golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 91 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 92 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 93 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 94 | golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= 95 | golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= 96 | golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= 97 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 98 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 99 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 100 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 101 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 102 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 103 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 104 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 105 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 106 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 107 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 108 | golang.org/x/sys v0.0.0-20200622182413-4b0db7f3f76b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 109 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 110 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 111 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 112 | golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 113 | golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 114 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 115 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 116 | golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 117 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 118 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 119 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 120 | golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= 121 | golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 122 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 123 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 124 | golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 125 | golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= 126 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 127 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 128 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 129 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 130 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 131 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 132 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 133 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 134 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 135 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 136 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 137 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 138 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 139 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 140 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 141 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 142 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 143 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 144 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 145 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 146 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 147 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 148 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 149 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 150 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 151 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 152 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 153 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 154 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 155 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 156 | -------------------------------------------------------------------------------- /litter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/base64" 6 | "fmt" 7 | "io/ioutil" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | ) 12 | 13 | func generateRandomPassword(length int, config *Config) (string, error) { 14 | bytes := make([]byte, length) 15 | if _, err := rand.Read(bytes); err != nil { 16 | logToFile(config.General.LogFile, fmt.Sprintf("Error generating random password: %v", err)) 17 | return "", err 18 | } 19 | password := base64.URLEncoding.EncodeToString(bytes)[:length] 20 | logToFile(config.General.LogFile, fmt.Sprintf("Generated random password of length %d", length)) 21 | return password, nil 22 | } 23 | 24 | func createFileAtLocation(location, content string, config *Config) error { 25 | dir := filepath.Dir(location) 26 | if _, err := os.Stat(dir); os.IsNotExist(err) { 27 | err = os.MkdirAll(dir, 0755) 28 | if err != nil { 29 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to create directory %s: %v", dir, err)) 30 | return err 31 | } 32 | logToFile(config.General.LogFile, fmt.Sprintf("Created directory %s", dir)) 33 | } 34 | err := ioutil.WriteFile(location, []byte(content), 0644) 35 | if err != nil { 36 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to create file %s: %v", location, err)) 37 | } else { 38 | logToFile(config.General.LogFile, fmt.Sprintf("Created file at %s", location)) 39 | } 40 | return err 41 | } 42 | 43 | func createLinkFile(location, targetPath string, config *Config) error { 44 | cmd := exec.Command("powershell", "-Command", fmt.Sprintf("New-Item -Path '%s' -ItemType SymbolicLink -Value '%s'", location, targetPath)) 45 | output, err := cmd.CombinedOutput() 46 | if err != nil { 47 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to create link file at %s pointing to %s: %v, output: %s", location, targetPath, err, string(output))) 48 | return err 49 | } 50 | logToFile(config.General.LogFile, fmt.Sprintf("Created link file at %s pointing to %s", location, targetPath)) 51 | return nil 52 | } 53 | 54 | func createRegistryKey(location, keyType, value string, config *Config) error { 55 | cmd := exec.Command("reg", "add", location, "/v", "ExampleValue", "/t", keyType, "/d", value, "/f") 56 | output, err := cmd.CombinedOutput() 57 | if err != nil { 58 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to create registry key at %s with type %s and value %s: %v, output: %s", location, keyType, value, err, string(output))) 59 | return err 60 | } 61 | logToFile(config.General.LogFile, fmt.Sprintf("Created registry key at %s with type %s and value %s", location, keyType, value)) 62 | return nil 63 | } 64 | 65 | func createAndModifyFiles(config *Config) { 66 | for _, fileOp := range config.FileOperations.CreateModifyFiles { 67 | var content string 68 | var err error 69 | if fileOp.UseGPT { 70 | content = generateContentUsingGPT(config.General.OpenaiApiKey, fileOp.GPTPrompt, config) 71 | } else { 72 | content = fileOp.Content 73 | } 74 | err = createFileAtLocation(fileOp.Path, content, config) 75 | if err != nil { 76 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to create/modify file %s: %v", fileOp.Path, err)) 77 | } else { 78 | logToFile(config.General.LogFile, fmt.Sprintf("Created/modified file %s", fileOp.Path)) 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /logger.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "io" 6 | "os" 7 | ) 8 | 9 | func logToFile(logFile, message string) { 10 | if logFile == "" { 11 | return 12 | } 13 | f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 14 | if err != nil { 15 | log.Println("Error opening log file:", err) 16 | return 17 | } 18 | defer f.Close() 19 | logger := log.New(f, "", log.LstdFlags) 20 | logger.Println(message) 21 | } 22 | 23 | func logMultiWriter(logFile string) *log.Logger { 24 | logFileWriter, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 25 | if err != nil { 26 | log.Fatalf("Error opening log file: %v", err) 27 | } 28 | 29 | multiWriter := io.MultiWriter(os.Stdout, logFileWriter) 30 | logger := log.New(multiWriter, "", log.LstdFlags) 31 | 32 | return logger 33 | } 34 | -------------------------------------------------------------------------------- /lures.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | "net" 7 | "os/exec" 8 | "strconv" 9 | ) 10 | 11 | func manageLures(config *Config) { 12 | for _, lure := range config.Lures { 13 | var content string 14 | var username string 15 | switch lure.GenerativeType { 16 | case "golang": 17 | switch lure.Type { 18 | case "credential_pair": 19 | if len(config.General.Usernames) > 0 { 20 | username = selectRandomOrHardcoded(config.General.Usernames, config.General.SelectionMethod)[0] 21 | } else { 22 | logToFile(config.General.LogFile, "Error: No usernames provided for credential_pair.") 23 | continue 24 | } 25 | lengthVal, ok := lure.GenerationParams["length"] 26 | if !ok { 27 | logToFile(config.General.LogFile, "Error: 'length' parameter is required for credential_pair.") 28 | continue 29 | } 30 | length, err := strconv.Atoi(fmt.Sprintf("%v", lengthVal)) 31 | if err != nil { 32 | logToFile(config.General.LogFile, fmt.Sprintf("Error: Invalid 'length' parameter: %v", err)) 33 | continue 34 | } 35 | password, err := generateRandomPassword(length, config) 36 | if err != nil { 37 | logToFile(config.General.LogFile, fmt.Sprintf("Error generating password: %v", err)) 38 | continue 39 | } 40 | content = fmt.Sprintf("Username: %s\nPassword: %s", username, password) 41 | case "ssh_key": 42 | cmd := exec.Command("ssh-keygen", "-t", "rsa", "-b", "2048", "-f", lure.Location, "-N", "") 43 | err := cmd.Run() 44 | if err != nil { 45 | logToFile(config.General.LogFile, fmt.Sprintf("Error generating SSH key: %v", err)) 46 | continue 47 | } 48 | content = fmt.Sprintf("Generated SSH Key at %s", lure.Location) 49 | case "website_url": 50 | baseURL, ok := lure.GenerationParams["base_url"].(string) 51 | if !ok { 52 | logToFile(config.General.LogFile, "Error: 'base_url' parameter is required for website_url.") 53 | continue 54 | } 55 | content = baseURL 56 | case "registry_key": 57 | registryKeyType, ok := lure.GenerationParams["registry_key_type"].(string) 58 | if !ok { 59 | logToFile(config.General.LogFile, "Error: 'registry_key_type' parameter is required for registry_key.") 60 | continue 61 | } 62 | registryKeyValue, ok := lure.GenerationParams["registry_key_value"].(string) 63 | if !ok { 64 | logToFile(config.General.LogFile, "Error: 'registry_key_value' parameter is required for registry_key.") 65 | continue 66 | } 67 | err := createRegistryKey(lure.Location, registryKeyType, registryKeyValue, config) 68 | if err != nil { 69 | logToFile(config.General.LogFile, fmt.Sprintf("Error creating registry key: %v", err)) 70 | continue 71 | } 72 | content = fmt.Sprintf("Created registry key at %s with type %s and value %s", lure.Location, registryKeyType, registryKeyValue) 73 | case "csv": 74 | documentContent, ok := lure.GenerationParams["document_content"].(string) 75 | if !ok { 76 | logToFile(config.General.LogFile, "Error: 'document_content' parameter is required for csv.") 77 | continue 78 | } 79 | content = documentContent 80 | case "api_key": 81 | apiKeyFormat, ok := lure.GenerationParams["api_key_format"].(string) 82 | if !ok { 83 | logToFile(config.General.LogFile, "Error: 'api_key_format' parameter is required for api_key.") 84 | continue 85 | } 86 | if apiKeyFormat == "uuid" { 87 | apiKey := make([]byte, 16) 88 | _, err := rand.Read(apiKey) 89 | if err != nil { 90 | logToFile(config.General.LogFile, fmt.Sprintf("Error generating API key: %v", err)) 91 | continue 92 | } 93 | content = fmt.Sprintf("Generated API Key: %x", apiKey) 94 | } else { 95 | logToFile(config.General.LogFile, "Unsupported API key format") 96 | continue 97 | } 98 | case "lnk": 99 | targetPath, ok := lure.GenerationParams["target_path"].(string) 100 | if !ok { 101 | logToFile(config.General.LogFile, "Error: 'target_path' parameter is required for lnk.") 102 | continue 103 | } 104 | err := createLinkFile(lure.Location, targetPath, config) 105 | if err != nil { 106 | logToFile(config.General.LogFile, fmt.Sprintf("Error creating link file at location: %s, error: %v", lure.Location, err)) 107 | continue 108 | } 109 | content = fmt.Sprintf("Created link file at %s pointing to %s", lure.Location, targetPath) 110 | default: 111 | logToFile(config.General.LogFile, "Unsupported lure type for Go random generation.") 112 | continue 113 | } 114 | case "openai": 115 | if config.General.OpenaiApiKey == "" { 116 | logToFile(config.General.LogFile, "Error: OpenAI API key is required for OpenAI generation.") 117 | continue 118 | } 119 | content = generateContentUsingGPT(config.General.OpenaiApiKey, lure.OpenaiPrompt, config) 120 | default: 121 | logToFile(config.General.LogFile, "Unsupported generative type.") 122 | continue 123 | } 124 | 125 | if lure.Type != "lnk" && lure.Type != "ssh_key" && lure.Type != "registry_key" { 126 | if err := createFileAtLocation(lure.Location, content, config); err != nil { 127 | logToFile(config.General.LogFile, fmt.Sprintf("Error creating file at location: %s, error: %v", lure.Location, err)) 128 | continue 129 | } 130 | } 131 | 132 | sourceIP, err := getSourceIP() 133 | if err != nil { 134 | logToFile(config.General.LogFile, fmt.Sprintf("Error getting source IP: %v", err)) 135 | continue 136 | } 137 | 138 | if err := sendMetadataToRedis(config, username, content, sourceIP); err != nil { 139 | logToFile(config.General.LogFile, fmt.Sprintf("Error sending metadata to Redis: %v", err)) 140 | continue 141 | } 142 | 143 | logToFile(config.General.LogFile, fmt.Sprintf("Generated lure: %s", content)) 144 | logToFile(config.General.LogFile, fmt.Sprintf("Lure created and metadata processed successfully.")) 145 | } 146 | } 147 | 148 | func getSourceIP() (string, error) { 149 | addrs, err := net.InterfaceAddrs() 150 | if err != nil { 151 | return "", err 152 | } 153 | for _, addr := range addrs { 154 | if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { 155 | if ipnet.IP.To4() != nil { 156 | return ipnet.IP.String(), nil 157 | } 158 | } 159 | } 160 | return "", fmt.Errorf("cannot find local IP address") 161 | } 162 | -------------------------------------------------------------------------------- /media.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | ) 7 | 8 | // Opens media files. 9 | func openMediaFiles(config *Config) { 10 | mediaFiles := selectRandomOrHardcoded(config.MediaFiles.Options, config.MediaFiles.SelectionMethod) 11 | for _, mediaFile := range mediaFiles { 12 | cmd := exec.Command("cmd", "/C", "start", mediaFile) 13 | err := cmd.Run() 14 | if err != nil { 15 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to open media file %s: %v", mediaFile, err)) 16 | } else { 17 | logToFile(config.General.LogFile, fmt.Sprintf("Opened media file %s", mediaFile)) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /monitor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/fsnotify/fsnotify" 5 | ) 6 | 7 | // Monitor interactions with lures. 8 | func monitorLures(config *Config) { 9 | logger := logMultiWriter(config.General.LogFile) 10 | 11 | // Create new watcher. 12 | watcher, err := fsnotify.NewWatcher() 13 | if err != nil { 14 | logger.Fatalf("Error creating file watcher: %v", err) 15 | } 16 | defer watcher.Close() 17 | 18 | // Start listening for events. 19 | go func() { 20 | for { 21 | select { 22 | case event, ok := <-watcher.Events: 23 | if !ok { 24 | return 25 | } 26 | logger.Println("event:", event) 27 | if event.Has(fsnotify.Write) { 28 | logger.Println("modified file:", event.Name) 29 | } 30 | if event.Has(fsnotify.Create) { 31 | logger.Println("created file:", event.Name) 32 | } 33 | if event.Has(fsnotify.Remove) { 34 | logger.Println("deleted file:", event.Name) 35 | } 36 | if event.Has(fsnotify.Rename) { 37 | logger.Println("renamed file:", event.Name) 38 | } 39 | if event.Has(fsnotify.Chmod) { 40 | logger.Println("chmod file:", event.Name) 41 | } 42 | case err, ok := <-watcher.Errors: 43 | if !ok { 44 | return 45 | } 46 | logger.Println("error:", err) 47 | } 48 | } 49 | }() 50 | 51 | // Add paths to watch. 52 | for _, lure := range config.Lures { 53 | if lure.Type != "registry_key" && lure.Type != "ssh_key" { 54 | err = watcher.Add(lure.Location) 55 | if err != nil { 56 | logger.Fatalf("Error adding watcher to path %s: %v", lure.Location, err) 57 | } 58 | } 59 | } 60 | 61 | // Block main goroutine forever. 62 | <-make(chan struct{}) 63 | } 64 | -------------------------------------------------------------------------------- /openai.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "io/ioutil" 7 | "net/http" 8 | ) 9 | 10 | // Message structure for the OpenAI chat format 11 | type Message struct { 12 | Role string `json:"role"` 13 | Content string `json:"content"` 14 | } 15 | 16 | // ChatCompletionResponse structure for parsing the response from OpenAI API 17 | type ChatCompletionResponse struct { 18 | Choices []struct { 19 | Message struct { 20 | Role string `json:"role"` 21 | Content string `json:"content"` 22 | } `json:"message"` 23 | } `json:"choices"` 24 | } 25 | 26 | func generateContentUsingGPT(apiKey string, prompt string, config *Config) string { 27 | logToFile(config.General.LogFile, "This is where the prompt goes from the config file input: "+prompt) 28 | 29 | // Prepare the messages payload for the request 30 | messages := []Message{ 31 | {"system", "You will respond exactly as requested with real information, do not wrap codeblocks like ```yaml, only return the raw yaml file."}, 32 | {"user", prompt}, 33 | } 34 | 35 | // Prepare the JSON payload for the request 36 | payload := map[string]interface{}{ 37 | "model": "gpt-4-turbo-preview", 38 | "messages": messages, 39 | "max_tokens": 2048, 40 | "temperature": 0.3, 41 | } 42 | payloadBytes, err := json.Marshal(payload) 43 | if err != nil { 44 | logToFile(config.General.LogFile, "Error marshalling payload: "+err.Error()) 45 | return "" 46 | } 47 | 48 | // Create a new request 49 | req, err := http.NewRequest("POST", "https://api.openai.com/v1/chat/completions", bytes.NewReader(payloadBytes)) 50 | if err != nil { 51 | logToFile(config.General.LogFile, "Error creating request: "+err.Error()) 52 | return "" 53 | } 54 | 55 | // Set headers 56 | req.Header.Set("Content-Type", "application/json") 57 | req.Header.Set("Authorization", "Bearer "+apiKey) 58 | 59 | // Execute the request 60 | client := &http.Client{} 61 | resp, err := client.Do(req) 62 | if err != nil { 63 | logToFile(config.General.LogFile, "Error making request to OpenAI: "+err.Error()) 64 | return "" 65 | } 66 | defer resp.Body.Close() 67 | 68 | // Read the response body 69 | respBody, err := ioutil.ReadAll(resp.Body) 70 | if err != nil { 71 | logToFile(config.General.LogFile, "Error reading response body: "+err.Error()) 72 | return "" 73 | } 74 | 75 | // Parse the response 76 | var chatResponse ChatCompletionResponse 77 | if err := json.Unmarshal(respBody, &chatResponse); err != nil { 78 | logToFile(config.General.LogFile, "Error parsing response JSON: "+err.Error()) 79 | return "" 80 | } 81 | 82 | // Extract generated content 83 | var generatedContent string 84 | for _, choice := range chatResponse.Choices { 85 | if choice.Message.Role == "assistant" { 86 | generatedContent = choice.Message.Content 87 | logToFile(config.General.LogFile, "Generated Content: "+generatedContent) 88 | break 89 | } 90 | } 91 | 92 | if generatedContent == "" { 93 | logToFile(config.General.LogFile, "No choices returned from OpenAI API") 94 | } 95 | 96 | return generatedContent 97 | } 98 | 99 | -------------------------------------------------------------------------------- /print.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | ) 7 | 8 | // Prints documents. 9 | func printDocuments(config *Config) { 10 | documents := selectRandomOrHardcoded(config.Printing.Options, config.Printing.SelectionMethod) 11 | for _, document := range documents { 12 | cmd := exec.Command("powershell", "-Command", "Start-Process", "notepad.exe", document, "-Verb", "Print") 13 | err := cmd.Run() 14 | if err != nil { 15 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to print document %s: %v", document, err)) 16 | } else { 17 | logToFile(config.General.LogFile, fmt.Sprintf("Printed document %s", document)) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /redis.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/go-redis/redis/v8" 9 | ) 10 | 11 | func sendMetadataToRedis(config *Config, username, content, sourceIP string) error { 12 | if config.General.Redis.IP == "" || config.General.Redis.Port == 0 { 13 | return nil 14 | } 15 | 16 | rdb := redis.NewClient(&redis.Options{ 17 | Addr: fmt.Sprintf("%s:%d", config.General.Redis.IP, config.General.Redis.Port), 18 | }) 19 | ctx := context.Background() 20 | loginTime := time.Now().Format(time.RFC3339) 21 | data := fmt.Sprintf("Username: %s, Content: %s, SourceIP: %s, LoginTime: %s", username, content, sourceIP, loginTime) 22 | return rdb.Set(ctx, "session_metadata", data, 0).Err() 23 | } 24 | -------------------------------------------------------------------------------- /sinon.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | configFile := "config.yaml" 10 | 11 | config, err := loadConfig(configFile) 12 | if err != nil { 13 | log.Fatalf("Error loading config file: %v", err) 14 | } 15 | 16 | logger := logMultiWriter(config.General.LogFile) 17 | 18 | if config.General.LogFile != "" { 19 | logger.Println("Starting interaction") 20 | } 21 | 22 | // Check if Chocolatey is installed 23 | if err := checkAndInstallChocolatey(config); err != nil { 24 | logger.Fatalf("Error installing Chocolatey: %v", err) 25 | } 26 | 27 | // Perform initial setup 28 | createAndModifyFiles(config) 29 | sendEmails(config) 30 | performSystemUpdates(config) 31 | installApplications(config) 32 | manageSoftware(config) 33 | addStartMenuItems(config) 34 | manageLures(config) 35 | browseWebsites(config) 36 | changePreferences(config) 37 | performScheduledTasks(config) 38 | openMediaFiles(config) 39 | manageUserAccounts(config) 40 | manageNetworkSettings(config) 41 | printDocuments(config) 42 | downloadDecoyFiles(config) 43 | 44 | // Monitor for interactions with lures 45 | go monitorLures(config) 46 | 47 | duration := config.General.InteractionDuration 48 | if duration == 0 { 49 | duration = 60 // Default duration in minutes 50 | } 51 | 52 | time.Sleep(time.Duration(duration) * time.Minute) 53 | 54 | if config.General.LogFile != "" { 55 | logger.Println("Interaction completed") 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /software.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | ) 7 | 8 | func installApplications(config *Config) { 9 | logger := logMultiWriter(config.General.LogFile) 10 | 11 | // Check and install Chocolatey if not installed 12 | err := checkAndInstallChocolatey(config) 13 | if err != nil { 14 | logger.Printf("Failed to install Chocolatey: %v", err) 15 | return 16 | } 17 | 18 | apps := selectRandomOrHardcoded(config.Applications.Options, config.Applications.SelectionMethod) 19 | for _, app := range apps { 20 | cmd := exec.Command("choco", "install", app, "-y") 21 | err := cmd.Run() 22 | if err != nil { 23 | logger.Printf("Failed to install %s: %v", app, err) 24 | } else { 25 | logger.Printf("Installed %s", app) 26 | } 27 | } 28 | } 29 | 30 | func manageSoftware(config *Config) { 31 | logger := logMultiWriter(config.General.LogFile) 32 | 33 | operations := selectRandomOrHardcoded(config.SoftwareManagement.Options, config.SoftwareManagement.SelectionMethod) 34 | for _, operation := range operations { 35 | cmd := exec.Command("choco", operation, "-y") 36 | err := cmd.Run() 37 | if err != nil { 38 | logger.Printf("Failed to perform software management operation %s: %v", operation, err) 39 | } else { 40 | logger.Printf("Performed software management operation %s", operation) 41 | } 42 | } 43 | } 44 | 45 | func addStartMenuItems(config *Config) { 46 | logger := logMultiWriter(config.General.LogFile) 47 | 48 | items := selectRandomOrHardcoded(config.StartMenuItems.Options, config.StartMenuItems.SelectionMethod) 49 | for _, item := range items { 50 | cmd := exec.Command("powershell", "-Command", fmt.Sprintf(`$s = New-Object -ComObject WScript.Shell; $shortcut = $s.CreateShortcut("C:\\Users\\Public\\Desktop\\%s.lnk"); $shortcut.TargetPath = "%s"; $shortcut.Save()`, item, item)) 51 | err := cmd.Run() 52 | if err != nil { 53 | logger.Printf("Failed to add start menu item %s: %v", item, err) 54 | } else { 55 | logger.Printf("Added start menu item %s", item) 56 | } 57 | } 58 | } 59 | 60 | func checkAndInstallChocolatey(config *Config) error { 61 | logger := logMultiWriter(config.General.LogFile) 62 | cmd := exec.Command("choco", "-v") 63 | err := cmd.Run() 64 | if err != nil { 65 | logger.Println("Chocolatey not found, installing...") 66 | cmd = exec.Command("powershell", "-Command", "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))") 67 | err = cmd.Run() 68 | if err != nil { 69 | return fmt.Errorf("failed to install Chocolatey: %v", err) 70 | } 71 | logger.Println("Chocolatey installed successfully") 72 | } 73 | return nil 74 | } 75 | 76 | func checkAndInstallPSWindowsUpdate(config *Config) error { 77 | logger := logMultiWriter(config.General.LogFile) 78 | cmd := exec.Command("powershell", "-Command", "Get-Module -ListAvailable -Name PSWindowsUpdate") 79 | err := cmd.Run() 80 | if err != nil { 81 | logger.Println("PSWindowsUpdate module not found, installing...") 82 | cmd = exec.Command("powershell", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Install-Module -Name PSWindowsUpdate -Force") 83 | err = cmd.Run() 84 | if err != nil { 85 | return fmt.Errorf("failed to install PSWindowsUpdate module: %v", err) 86 | } 87 | logger.Println("PSWindowsUpdate module installed successfully") 88 | } 89 | return nil 90 | } 91 | 92 | func performSystemUpdates(config *Config) { 93 | logger := logMultiWriter(config.General.LogFile) 94 | 95 | err := checkAndInstallPSWindowsUpdate(config) 96 | if err != nil { 97 | logger.Printf("Failed to install PSWindowsUpdate module: %v", err) 98 | return 99 | } 100 | 101 | var cmd *exec.Cmd 102 | 103 | switch config.SystemUpdates.Method { 104 | case "install_all": 105 | cmd = exec.Command("powershell", "-Command", "Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot") 106 | case "install_specific": 107 | for _, update := range config.SystemUpdates.SpecificUpdates { 108 | cmd = exec.Command("powershell", "-Command", fmt.Sprintf("Get-WindowsUpdate -Install -KBArticleID %s", update)) 109 | err = cmd.Run() 110 | if err != nil { 111 | logger.Printf("Failed to install update %s: %v", update, err) 112 | } else { 113 | logger.Printf("Installed update %s", update) 114 | } 115 | } 116 | return 117 | case "install_random": 118 | updates := selectRandomOrHardcoded(config.SystemUpdates.SpecificUpdates, config.SystemUpdates.SelectionMethod) 119 | for _, update := range updates { 120 | cmd = exec.Command("powershell", "-Command", fmt.Sprintf("Get-WindowsUpdate -Install -KBArticleID %s", update)) 121 | err = cmd.Run() 122 | if err != nil { 123 | logger.Printf("Failed to install update %s: %v", update, err) 124 | } else { 125 | logger.Printf("Installed update %s", update) 126 | } 127 | } 128 | return 129 | case "remove_random": 130 | updates := selectRandomOrHardcoded(config.SystemUpdates.HideUpdates, config.SystemUpdates.SelectionMethod) 131 | for _, update := range updates { 132 | cmd = exec.Command("powershell", "-Command", fmt.Sprintf("Remove-WindowsUpdate -KBArticleID %s -NoRestart", update)) 133 | err = cmd.Run() 134 | if err != nil { 135 | logger.Printf("Failed to remove update %s: %v", update, err) 136 | } else { 137 | logger.Printf("Removed update %s", update) 138 | } 139 | } 140 | return 141 | case "hide_updates": 142 | for _, update := range config.SystemUpdates.HideUpdates { 143 | cmd = exec.Command("powershell", "-Command", fmt.Sprintf("$HideList = '%s'; Get-WindowsUpdate -KBArticleID $HideList –Hide", update)) 144 | err = cmd.Run() 145 | if err != nil { 146 | logger.Printf("Failed to hide update %s: %v", update, err) 147 | } else { 148 | logger.Printf("Hidden update %s", update) 149 | } 150 | } 151 | return 152 | default: 153 | logger.Printf("Unknown system update method: %s", config.SystemUpdates.Method) 154 | return 155 | } 156 | 157 | err = cmd.Run() 158 | if err != nil { 159 | logger.Printf("Failed to perform system update: %v", err) 160 | } else { 161 | logger.Printf("Performed system update with method %s", config.SystemUpdates.Method) 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /tasks.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os/exec" 7 | "time" 8 | ) 9 | 10 | func performScheduledTasks(config *Config) { 11 | tasks := selectRandomOrHardcodedScheduledTasks(config.ScheduledTasks.Options, config.ScheduledTasks.SelectionMethod) 12 | for _, task := range tasks { 13 | cmd := exec.Command("schtasks", "/create", "/tn", task.Name, "/tr", task.Path, "/sc", task.Schedule, "/st", task.StartTime) 14 | err := cmd.Run() 15 | if err != nil { 16 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to create scheduled task %s: %v", task.Name, err)) 17 | } else { 18 | logToFile(config.General.LogFile, fmt.Sprintf("Created scheduled task %s", task.Name)) 19 | } 20 | time.Sleep(time.Duration(config.General.ActionDelay+rand.Intn(2*config.General.RandomnessFactor+1)-config.General.RandomnessFactor) * time.Second) 21 | } 22 | } 23 | 24 | func selectRandomOrHardcodedScheduledTasks(options []ScheduledTask, method string) []ScheduledTask { 25 | if method == "hardcoded" { 26 | return options 27 | } 28 | rand.Seed(time.Now().UnixNano()) 29 | return []ScheduledTask{options[rand.Intn(len(options))]} 30 | } 31 | -------------------------------------------------------------------------------- /users.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | wapi "github.com/iamacarpet/go-win64api" 7 | ) 8 | 9 | func manageUserAccounts(config *Config) { 10 | for _, account := range config.UserAccounts { 11 | ok, err := wapi.UserAdd(account.Name, account.FullName, account.Password) 12 | if err != nil { 13 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to manage user account %s: %v", account.Name, err)) 14 | } else if !ok { 15 | logToFile(config.General.LogFile, fmt.Sprintf("User account %s was not added successfully.", account.Name)) 16 | } else { 17 | logToFile(config.General.LogFile, fmt.Sprintf("Managed user account %s", account.Name)) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /utils.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "math/rand" 7 | "net/http" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "strings" 12 | "time" 13 | "net/url" 14 | 15 | "github.com/pkg/sftp" 16 | "golang.org/x/crypto/ssh" 17 | ) 18 | 19 | func selectRandomOrHardcoded(options []string, method string) []string { 20 | if len(options) == 0 { 21 | logToFile("config.General.LogFile", "No options provided for selection.") 22 | return options 23 | } 24 | if method == "hardcoded" { 25 | return options 26 | } 27 | rand.Seed(time.Now().UnixNano()) 28 | return []string{options[rand.Intn(len(options))]} 29 | } 30 | 31 | func downloadFile(url, dest string) error { 32 | resp, err := http.Get(url) 33 | if err != nil { 34 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to download HTTP file %s: %v", url, err)) 35 | return err 36 | } 37 | defer resp.Body.Close() 38 | 39 | out, err := os.Create(dest) 40 | if err != nil { 41 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to create file %s: %v", dest, err)) 42 | return err 43 | } 44 | defer out.Close() 45 | 46 | _, err = io.Copy(out, resp.Body) 47 | if err != nil { 48 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to copy HTTP file %s: %v", url, err)) 49 | } 50 | return err 51 | } 52 | 53 | func downloadSMBFile(smbPath, dest string) error { 54 | cmd := exec.Command("powershell", "-Command", fmt.Sprintf("New-PSDrive -Name S -PSProvider FileSystem -Root \\\\%s; Copy-Item S:\\%s -Destination %s; Remove-PSDrive -Name S", smbPath, filepath.Base(dest), dest)) 55 | output, err := cmd.CombinedOutput() 56 | if err != nil { 57 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to download SMB file %s: %v, output: %s", smbPath, err, string(output))) 58 | } 59 | return err 60 | } 61 | 62 | func downloadNFSFile(nfsPath, dest string) error { 63 | cmd := exec.Command("powershell", "-Command", fmt.Sprintf("New-PSDrive -Name N -PSProvider FileSystem -Root %s; Copy-Item N:\\%s -Destination %s; Remove-PSDrive -Name N", nfsPath, filepath.Base(dest), dest)) 64 | output, err := cmd.CombinedOutput() 65 | if err != nil { 66 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to download NFS file %s: %v, output: %s", nfsPath, err, string(output))) 67 | } 68 | return err 69 | } 70 | 71 | func downloadSFTPFile(sftpPath, dest, username, password string) error { 72 | config := &ssh.ClientConfig{ 73 | User: username, 74 | Auth: []ssh.AuthMethod{ 75 | ssh.Password(password), 76 | }, 77 | HostKeyCallback: ssh.InsecureIgnoreHostKey(), 78 | } 79 | client, err := ssh.Dial("tcp", sftpPath, config) 80 | if err != nil { 81 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to connect to SFTP server %s: %v", sftpPath, err)) 82 | return err 83 | } 84 | defer client.Close() 85 | 86 | sftpClient, err := sftp.NewClient(client) 87 | if err != nil { 88 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to create SFTP client %s: %v", sftpPath, err)) 89 | return err 90 | } 91 | defer sftpClient.Close() 92 | 93 | source, err := sftpClient.Open(filepath.Base(sftpPath)) 94 | if err != nil { 95 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to open source SFTP file %s: %v", sftpPath, err)) 96 | return err 97 | } 98 | defer source.Close() 99 | 100 | output, err := os.Create(dest) 101 | if err != nil { 102 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to create destination file %s: %v", dest, err)) 103 | return err 104 | } 105 | defer output.Close() 106 | 107 | _, err = io.Copy(output, source) 108 | if err != nil { 109 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to copy SFTP file %s: %v", sftpPath, err)) 110 | } 111 | return err 112 | } 113 | 114 | func downloadDecoyFiles(config *Config) { 115 | for _, set := range config.DecoyFiles.Sets { 116 | locations := selectRandomOrHardcoded(set.Location, set.SelectionMethod) 117 | targetDirs := selectRandomOrHardcoded(set.TargetDirectory, set.SelectionMethod) 118 | 119 | for _, location := range locations { 120 | for _, targetDir := range targetDirs { 121 | filename := filepath.Base(location) 122 | targetPath := filepath.Join(targetDir, filename) 123 | var err error 124 | switch { 125 | case strings.HasPrefix(location, "http"): 126 | err = downloadFile(location, targetPath) 127 | case strings.HasPrefix(location, "smb"): 128 | err = downloadSMBFile(location, targetPath) 129 | case strings.HasPrefix(location, "nfs"): 130 | err = downloadNFSFile(location, targetPath) 131 | case strings.HasPrefix(location, "sftp"): 132 | // Assume SFTP URL format: sftp://username:password@host:port/path 133 | url, parseErr := url.Parse(location) 134 | if parseErr != nil { 135 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to parse SFTP URL %s: %v", location, parseErr)) 136 | continue 137 | } 138 | username := url.User.Username() 139 | password, _ := url.User.Password() 140 | err = downloadSFTPFile(url.Host, targetPath, username, password) 141 | default: 142 | logToFile("config.General.LogFile", fmt.Sprintf("Unsupported protocol for decoy file %s", location)) 143 | } 144 | if err != nil { 145 | logToFile("config.General.LogFile", fmt.Sprintf("Failed to download decoy file %s: %v", location, err)) 146 | } else { 147 | logToFile("config.General.LogFile", fmt.Sprintf("Downloaded decoy file %s", location)) 148 | } 149 | } 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /wifi.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os/exec" 7 | ) 8 | 9 | // Manages network settings. 10 | func manageNetworkSettings(config *Config) { 11 | for _, network := range config.NetworkSettings { 12 | xmlContent := fmt.Sprintf(` 13 | 14 | 15 | %s 16 | 17 | 18 | %s 19 | 20 | 21 | ESS 22 | auto 23 | 24 | 25 | 26 | WPA2PSK 27 | AES 28 | false 29 | 30 | 31 | passPhrase 32 | false 33 | %s 34 | 35 | 36 | 37 | 38 | false 39 | 40 | `, network.SSID, network.SSID, network.Password) 41 | 42 | xmlFilePath := fmt.Sprintf("%s_profile.xml", network.SSID) 43 | err := ioutil.WriteFile(xmlFilePath, []byte(xmlContent), 0644) 44 | if err != nil { 45 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to write XML file for network %s: %v", network.SSID, err)) 46 | continue 47 | } 48 | 49 | cmd := exec.Command("netsh", "wlan", "add", "profile", fmt.Sprintf("filename=%s", xmlFilePath)) 50 | output, err := cmd.CombinedOutput() 51 | if err != nil { 52 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to add profile for network %s: %v, output: %s", network.SSID, err, string(output))) 53 | continue 54 | } 55 | 56 | cmd = exec.Command("netsh", "wlan", "connect", fmt.Sprintf("name=%s", network.SSID)) 57 | output, err = cmd.CombinedOutput() 58 | if err != nil { 59 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to connect to network %s: %v, output: %s", network.SSID, err, string(output))) 60 | } else { 61 | logToFile(config.General.LogFile, fmt.Sprintf("Connected to network %s", network.SSID)) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /winsettings.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os/exec" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const ( 12 | CCHDEVICENAME = 32 13 | CCHFORMNAME = 32 14 | ENUM_CURRENT_SETTINGS uint32 = 0xFFFFFFFF 15 | ENUM_REGISTRY_SETTINGS uint32 = 0xFFFFFFFE 16 | DISP_CHANGE_SUCCESSFUL uint32 = 0 17 | DISP_CHANGE_RESTART uint32 = 1 18 | DISP_CHANGE_FAILED uint32 = 0xFFFFFFFF 19 | DISP_CHANGE_BADMODE uint32 = 0xFFFFFFFE 20 | ) 21 | 22 | type DEVMODE struct { 23 | DmDeviceName [CCHDEVICENAME]uint16 24 | DmSpecVersion uint16 25 | DmDriverVersion uint16 26 | DmSize uint16 27 | DmDriverExtra uint16 28 | DmFields uint32 29 | DmOrientation int16 30 | DmPaperSize int16 31 | DmPaperLength int16 32 | DmPaperWidth int16 33 | DmScale int16 34 | DmCopies int16 35 | DmDefaultSource int16 36 | DmPrintQuality int16 37 | DmColor int16 38 | DmDuplex int16 39 | DmYResolution int16 40 | DmTTOption int16 41 | DmCollate int16 42 | DmFormName [CCHFORMNAME]uint16 43 | DmLogPixels uint16 44 | DmBitsPerPel uint32 45 | DmPelsWidth uint32 46 | DmPelsHeight uint32 47 | DmDisplayFlags uint32 48 | DmDisplayFrequency uint32 49 | DmICMMethod uint32 50 | DmICMIntent uint32 51 | DmMediaType uint32 52 | DmDitherType uint32 53 | DmReserved1 uint32 54 | DmReserved2 uint32 55 | DmPanningWidth uint32 56 | DmPanningHeight uint32 57 | } 58 | 59 | func changePreferences(config *Config) { 60 | prefs := config.Preferences 61 | browsers := selectRandomOrHardcoded(prefs.DefaultBrowser.Options, prefs.DefaultBrowser.SelectionMethod) 62 | for _, browser := range browsers { 63 | cmd := exec.Command("SetDefaultBrowser.exe", "HKLM", browser) 64 | err := cmd.Run() 65 | if err != nil { 66 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to set default browser: %v", err)) 67 | } else { 68 | logToFile(config.General.LogFile, fmt.Sprintf("Default browser set to %s", browser)) 69 | } 70 | } 71 | 72 | images := selectRandomOrHardcoded(prefs.BackgroundImages.Options, prefs.BackgroundImages.SelectionMethod) 73 | for _, image := range images { 74 | err := downloadFile(image, "C:\\path\\to\\downloaded\\image.jpg") 75 | if err != nil { 76 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to download background image: %v", err)) 77 | } 78 | cmd := exec.Command("powershell", "-Command", "(New-Object -ComObject WScript.Shell).RegWrite('HKCU\\Control Panel\\Desktop\\Wallpaper', 'C:\\path\\to\\downloaded\\image.jpg')") 79 | err = cmd.Run() 80 | if err != nil { 81 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to set background image: %v", err)) 82 | } else { 83 | logToFile(config.General.LogFile, "Background image set successfully") 84 | } 85 | } 86 | 87 | resolutions := selectRandomOrHardcoded(prefs.ScreenResolutions.Options, prefs.ScreenResolutions.SelectionMethod) 88 | for _, resolution := range resolutions { 89 | setScreenResolution(resolution) 90 | } 91 | 92 | languages := selectRandomOrHardcoded(prefs.Languages.Options, prefs.Languages.SelectionMethod) 93 | for _, language := range languages { 94 | cmd := exec.Command("powershell", "-Command", fmt.Sprintf(`Set-WinUILanguageOverride -Language "%s"; Set-WinSystemLocale -SystemLocale "%s"; Set-WinUserLanguageList -LanguageList "%s" -Force; Set-Culture -CultureInfo "%s"; Set-WinHomeLocation -GeoId 12`, language, language, language, language)) 95 | err := cmd.Run() 96 | if err != nil { 97 | logToFile(config.General.LogFile, fmt.Sprintf("Failed to set language to %s: %v", language, err)) 98 | } else { 99 | logToFile(config.General.LogFile, fmt.Sprintf("Language set to %s", language)) 100 | } 101 | } 102 | } 103 | 104 | func setScreenResolution(resolution string) { 105 | width, height := parseResolution(resolution) 106 | user32dll := syscall.NewLazyDLL("user32.dll") 107 | procEnumDisplaySettingsW := user32dll.NewProc("EnumDisplaySettingsW") 108 | procChangeDisplaySettingsW := user32dll.NewProc("ChangeDisplaySettingsW") 109 | 110 | devMode := new(DEVMODE) 111 | ret, _, _ := procEnumDisplaySettingsW.Call(uintptr(unsafe.Pointer(nil)), 112 | uintptr(ENUM_CURRENT_SETTINGS), uintptr(unsafe.Pointer(devMode))) 113 | 114 | if ret == 0 { 115 | log.Println("Couldn't extract display settings.") 116 | return 117 | } 118 | 119 | newMode := *devMode 120 | newMode.DmPelsWidth = uint32(width) 121 | newMode.DmPelsHeight = uint32(height) 122 | ret, _, _ = procChangeDisplaySettingsW.Call(uintptr(unsafe.Pointer(&newMode)), uintptr(0)) 123 | 124 | switch ret { 125 | case uintptr(DISP_CHANGE_SUCCESSFUL): 126 | log.Println("Successfully changed the display resolution.") 127 | case uintptr(DISP_CHANGE_RESTART): 128 | log.Println("Restart required to apply the resolution changes.") 129 | case uintptr(DISP_CHANGE_BADMODE): 130 | log.Println("The resolution is not supported by the display.") 131 | case uintptr(DISP_CHANGE_FAILED): 132 | log.Println("Failed to change the display resolution.") 133 | } 134 | } 135 | 136 | func parseResolution(resolution string) (int, int) { 137 | var width, height int 138 | fmt.Sscanf(resolution, "%dx%d", &width, &height) 139 | return width, height 140 | } 141 | 142 | --------------------------------------------------------------------------------