Welcome, fellow hackers, to another edition of Programming Thursdays! Today, we’ll dive into the fantastic world of the Swift programming language. Swift has taken the world by storm since its introduction by Apple in 2014. With its easy-to-understand syntax and powerful capabilities, it has become a popular choice for developers working on iOS, macOS, watchOS, and even server-side applications. But what about us, the pen testers and red teamers? Can Swift be a useful tool in our arsenal? You bet it can!

In this comprehensive guide, we’ll cover the basics of the Swift language, explore its syntax, and then dive into some practical examples that demonstrate how Swift can be used in the world of cybersecurity. So, grab your hoodies and laptops, and let’s start our journey into the depths of Swift!

Introduction to Swift

Swift is a general-purpose, multi-paradigm programming language developed by Apple Inc. for its iOS, macOS, watchOS, and tvOS operating systems. The language was designed with performance, safety, and developer productivity in mind. With its modern syntax and powerful features, Swift has quickly become a favorite among developers.

Swift combines the best features of both Objective-C and C, but with a clean, modern syntax that makes it easy to learn and use. It is also an open-source language, meaning that anyone can contribute to its development and use it for their projects.

Now that we’ve covered the basics let’s dive into the syntax and basic concepts of Swift!

Variables and Data Types

In Swift, you can declare variables and constants using the var and let keywords, respectively. Variables can be changed after they are declared, while constants cannot. Swift also has strong type inference, meaning that the compiler can often infer the type of a variable or constant based on its initial value.

Here’s a quick example:

var myVariable = 42 // Declares a variable with an initial value of 42
let myConstant = 3.141592 // Declares a constant with an initial value of 3.141592

Swift has several built-in data types, including:

  • Int: Integer values
  • Double: Floating-point values
  • String: Text values
  • Bool: Boolean values (true or false)

You can explicitly specify the type of a variable or constant when you declare it:

var myInt: Int = 42 // Declares an integer variable with an initial value of 42
let myDouble: Double = 3.141592 // Declares a double constant with an initial value of 3.141592

Swift also supports collections such as arrays, dictionaries, and sets. Here’s a quick example of declaring an array and a dictionary:

var myArray: [Int] = [1, 2, 3, 4] // Declares an array of integers
var myDictionary: [String: Int] = ["one": 1, "two": 2, "three": 3] // Declares a dictionary with string keys and integer values

Operators

Swift has a variety of operators, including arithmetic, comparison, logical, and bitwise operators. Here are some examples:

Arithmetic Operators

  • Addition: +
  • Subtraction: -
  • Multiplication: *
  • Division: Division: /
  • Remainder (modulo): %

Here’s an example of using arithmetic operators:

let a = 10
let b = 3

let sum = a + b // 13
let difference = a - b // 7
let product = a * b // 30
let quotient = a / b // 3
let remainder = a % b // 1

Comparison Operators

  • Equal to: ==
  • Not equal to: !=
  • Greater than: >
  • Less than: <
  • Greater than or equal to: >=
  • Less than or equal to: <=

Here’s an example of using comparison operators:

let x = 5
let y = 10

let isEqual = x == y // false
let isNotEqual = x != y // true
let isGreater = x > y // false
let isLess = x < y // true
let isGreaterOrEqual = x >= y // false
let isLessOrEqual = x <= y // true

Logical Operators

  • Logical NOT: !
  • Logical AND: &&
  • Logical OR: ||

Here’s an example of using logical operators:

let isLoggedIn = true
let isAdmin = false

let isRegularUser = !isAdmin // true
let hasAccess = isLoggedIn && isAdmin // false
let canViewContent = isLoggedIn || isAdmin // true

Bitwise Operators

  • Bitwise NOT: ~
  • Bitwise AND: &
  • Bitwise OR: |
  • Bitwise XOR: ^
  • Left shift: <<
  • Right shift: >>

Here’s an example of using bitwise operators:

let m = 0b1100 // Binary representation of 12
let n = 0b1010 // Binary representation of 10

let bitwiseNotM = ~m // Binary representation of -13 (in two's complement form)
let bitwiseAnd = m & n // Binary representation of 8 (0b1000)
let bitwiseOr = m | n // Binary representation of 14 (0b1110)
let bitwiseXor = m ^ n // Binary representation of 6 (0b0110)
let leftShift = m << 1 // Binary representation of 24 (0b11000)
let rightShift = m >> 1 // Binary representation of 6 (0b0110)

Control Structures

Swift offers several control structures, including conditionals and loops.

Conditionals

If statement

let temperature = 30

if temperature > 20 {
    print("It's hot!")
} else {
    print("It's not that hot.")
}

Switch statement

let grade = "A"

switch grade {
case "A":
    print("Excellent!")
case "B":
    print("Good!")
case "C":
    print("Fair.")
case "D":
    print("Poor.")
default:
    print("Invalid grade.")
}

Loops

For loop

for i in 1...5 {
    print("Iteration \(i)")
}

While loop

var counter = 0

while counter < 5 {
    print("Counter: \(counter)")
    counter += 1
}

Repeat-while loop (do-while in other languages)

var count = 0

repeat {
    print("Count: \(count)")
    count += 1
} while count < 5

Functions

Functions are an essential building block in Swift, allowing you to group related code and execute it on demand. Functions can have parameters and return values, making them versatile tools for structuring your code.

Here’s an example of a simple function without parameters or a return value:

func greet() {
    print("Hello, fellow hacker!")
}

greet() // Calls the function and prints "Hello, fellow hacker!"

You can also define functions with parameters:

func greet(name: String) {
    print("Hello, \(name)!")
}

greet(name: "Alice") // Calls the function and prints "Hello, Alice!"

Functions can have multiple parameters and return values:

func add(a: Int, b: Int) -> Int {
    return a + b
}

let sum = add(a: 5, b: 3) // Calls the function and returns 8

Creating and Compiling a Swift Project from the Command Line

In this section, we’ll cover how to create a new Swift project, write a simple “Hello, World!” program, and compile it using the command line.

  1. Install Swift

    Before you can create and compile a Swift project, you’ll need to have Swift installed on your system. You can download the latest version of Swift from the official Swift website. Follow the installation instructions for your platform (macOS, Linux, or Windows).

  2. Create a New Project

    To create a new Swift project, first, create a new directory for your project:

    mkdir MySwiftProject
    cd MySwiftProject
    

    Next, create a new Swift file called main.swift in the project directory:

    touch main.swift
    

    Open the main.swift file using your favorite text editor, and add the following code:

    print("Hello, World!")
    

    Save and close the file.

  3. Compile the Swift Project

    To compile the Swift project, run the following command from the project directory:

    swiftc main.swift -o MySwiftProject
    

    This command will compile the main.swift file into an executable called MySwiftProject. The -o flag specifies the output file name.

  4. Run the Compiled Executable

    To run the compiled executable, enter the following command:

    ./MySwiftProject
    

    This will execute the compiled MySwiftProject program, and you should see the following output:

    Hello, World!
    

Congratulations! You’ve successfully created, compiled, and executed a simple Swift project using the command line. Now you can start building more complex Swift applications and tools for your penetration testing and red teaming tasks.

Swift for Pen Testing and Red Teaming

Now that we’ve covered the basics of Swift, let’s explore how we can use this powerful language in the realm of penetration testing and red teaming. Swift’s versatility and ease of use make it an excellent choice for creating custom tools and scripts that aid in our hacking endeavors.

Brute Force Password Cracking

Swift can be used to create a simple brute force password cracker. Here’s an example of how you might create a brute force cracker that checks passwords against a known hash:

import Foundation

func bruteForceCrack(hash: String, charset: String, maxLength: Int) -> String? {
    func recurse(_ prefix: String) -> String? {
        if let hashed = prefix.data(using: .utf8)?.sha256().hexString, hashed == hash {
            return prefix
        }

        if prefix.count < maxLength {
            for char in charset {
                if let result = recurse(prefix + String(char)) {
                    return result
                }
            }
        }

        return nil
    }

    return recurse("")
}

extension Data {
    func sha256() -> Data {
        var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        self.withUnsafeBytes { _ = CC_SHA256($0.baseAddress, CC_LONG(self.count), &hash) }
        return Data(hash)
    }

    var hexString: String {
        return map { String(format: "%02x", $0) }.joined()
    }
}

let charset = "abcdefghijklmnopqrstuvwxyz0123456789"
let targetHash = "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8" // "password"

if let crackedPassword = bruteForceCrack(hash: targetHash, charset: charset, maxLength: 5) {
    print("Cracked password: \(crackedPassword)")
} else {
    print("Password not found")
}

Port Scanning

Swift can also be used to create a simple port scanner to identify open ports on a target system. Here’s an example:

import Foundation
import Network

func scanPorts(host: String, ports: ClosedRange<Int>, completion: @escaping (Int) -> Void) {
    let queue = DispatchQueue.global(qos: .userInitiated)
    let group = DispatchGroup()

    for port in ports {
        group.enter()
        queue.async {
            let connection = NWConnection(host: NWEndpoint.Host(host), port: NWEndpoint.Port(rawValue: UInt16(port))!, using: .tcp)
            connection.stateUpdateHandler = { state in
                if state == .ready {
                    print("Port \(port) is open")
                    connection.cancel()
                } else if state == .failed || state == .cancelled {
                    group.leave()
                }
            }
            connection.start(queue: queue)
        }
    }

    group.notify(queue: .main) {
        print("Port scanning completed")
        completion(0)
    }
}

let targetHost = "example.com"
let targetPorts = 80...85

scanPorts(host: targetHost, ports: targetPorts) { _ in
    print("Scan finished")
}

This example uses the Network framework to establish TCP connections to the specified ports. Open ports will be printed to the console.

Simple HTTP Server

Swift can also be used to create a simple HTTP server, which can be useful in various penetration testing and red teaming scenarios, such as serving payloads or hosting phishing pages. Here’s an example of a basic HTTP server using the Vapor web framework:

First, install the Vapor toolbox by following the instructions on the Vapor documentation.

Next, create a new Vapor project:

vapor new SimpleHTTPServer
cd SimpleHTTPServer

Update the configure.swift file to serve a static HTML file:

import Vapor

public func configure(_ app: Application) throws {
    app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))

    app.routes.get("*") { req -> EventLoopFuture<Response> in
        let fileio = req.application.fileio
        let file = req.application.directory.publicDirectory + "index.html"
        return fileio.openFile(path: file, eventLoop: req.eventLoop).flatMap { handle, region in
            let response = Response(status: .ok, body: .stream(length: region.endIndex - region.startIndex) { writer in
                return fileio.write(fileHandle: handle, buffer: region, eventLoop: req.eventLoop).flatMap {
                    return fileio.close(fileHandle: handle, eventLoop: req.eventLoop)
                }.map { _ in
                    return writer
                }
            })
            response.headers.contentType = .html
            return req.eventLoop.makeSucceededFuture(response)
        }
    }
}

Place an index.html file in the Public directory of your project, and then run the server:

vapor run

The server will now serve the index.html file at http://localhost:8080.

Pros and Cons of Swift for Pen Testers and Red Teamers

Now that we’ve seen some examples of how Swift can be used in penetration testing and red teaming, let’s take a look at the pros and cons of using Swift in this context.

Pros

  1. Modern syntax: Swift’s clean and modern syntax makes it easy to learn and write code quickly.
  2. Strongly typed and safe: Swift’s strong typing and safety features help prevent common bugs and security vulnerabilities.
  3. Cross-platform: Swift is supported on macOS, Linux, and even Windows (via the Swift for TensorFlow project), making it a versatile choice for developing custom tools and scripts.
  4. Excellent performance: Swift is designed to provide excellent performance, which can be beneficial when writing resource-intensive tools.
  5. Large and active community: Swift has a large and active community, making it easy to find help, libraries, and resources.

Cons

  1. Not as widely used in cybersecurity: While Swift is growing in popularity, it’s not as widely used in the cybersecurity community as languages like Python, which means there may be fewer existing tools and resources available.
  2. Limited support on older systems: Since Swift is a relatively new language, support for older systems may be limited, which can be a concern when targeting legacy systems during a penetration test or red team engagement.
  3. Larger binary size: Swift executables tend to be larger in size compared to those produced by other languages like C or Rust. This may be a concern when deploying tools with size constraints, such as when embedding a payload in an exploit.
  4. Learning curve: While Swift is designed to be easy to learn, there can still be a learning curve if you are not already familiar with the language or its concepts. This may slow down your initial productivity when developing tools or scripts.
  5. Dependency on Apple platforms: Although Swift is open source and can be used on non-Apple platforms, its development and tooling are primarily driven by Apple. This may cause some concerns for those who prefer to work with more vendor-neutral technologies.

Conclusion

In this article, we’ve covered the basics of the Swift programming language, its syntax, and essential concepts such as variables, data types, operators, control structures, and functions. We’ve also explored how Swift can be used in the context of penetration testing and red teaming, including examples of a brute force password cracker, a port scanner, and a simple HTTP server.

While Swift has some drawbacks, such as not being as widely used in the cybersecurity community and limited support on older systems, it offers many benefits, such as a modern and clean syntax, strong typing and safety features, cross-platform support, excellent performance, and a large and active community.

Overall, Swift is an exciting language that has the potential to become a valuable tool in the arsenal of penetration testers and red teamers. By understanding the basics of the language and exploring its use cases in cybersecurity, you can leverage Swift to develop powerful custom tools and scripts that will aid you in your hacking endeavors.

Happy hacking!