All skills
hardw00t avatar

/ios-pentest

@f9bb3b2

iOS mobile application penetration testing with Frida and Objection on jailbroken or non-jailbroken devices. Use for static + dynamic analysis of IPAs, SSL pinning / jailbreak / biometric bypass, keychain & local-storage extraction, network interception, and OWASP MASTG iOS assessments. Triggers on requests to pentest iOS apps, analyze IPAs, bypass iOS security controls, or produce MASTG-aligned findings.

Use this Skill: https://skilld.dev/gh/hardw00t/ai-security-arsenal/ios-pentest

This session only. Nothing lands on disk.

referencesfrida_ios_snippets.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Frida iOS Code Snippets

Common Frida scripts for iOS penetration testing.

Basic Setup

Check if Objective-C is available

if (ObjC.available) {
    console.log("Objective-C runtime available");
} else {
    console.log("Objective-C runtime NOT available");
}

List all classes

for (var className in ObjC.classes) {
    console.log(className);
}

Search classes by name

for (var className in ObjC.classes) {
    if (className.toLowerCase().includes("auth")) {
        console.log(className);
    }
}

List methods of a class

var methods = ObjC.classes.ClassName.$ownMethods;
methods.forEach(function(method) {
    console.log(method);
});

Method Hooking

Hook instance method

var ClassName = ObjC.classes.ClassName;
Interceptor.attach(ClassName['- methodName:'].implementation, {
    onEnter: function(args) {
        console.log("Method called");
        // args[0] = self, args[1] = _cmd, args[2+] = actual arguments
        var arg1 = new ObjC.Object(args[2]);
        console.log("Arg1: " + arg1);
    },
    onLeave: function(retval) {
        console.log("Return: " + retval);
    }
});

Hook class method

var ClassName = ObjC.classes.ClassName;
Interceptor.attach(ClassName['+ classMethod'].implementation, {
    onEnter: function(args) {
        console.log("Class method called");
    }
});

Modify return value

Interceptor.attach(ClassName['- method'].implementation, {
    onLeave: function(retval) {
        retval.replace(1);  // Replace with YES/true
    }
});

Replace method implementation

ClassName['- method'].implementation = function() {
    console.log("Method replaced");
    return 1;  // Return YES
};

Working with ObjC Objects

Create NSString

var str = ObjC.classes.NSString.stringWithString_("Hello");

Create NSDictionary

var keys = ObjC.classes.NSArray.arrayWithObjects_("key1", "key2", null);
var values = ObjC.classes.NSArray.arrayWithObjects_("value1", "value2", null);
var dict = ObjC.classes.NSDictionary.dictionaryWithObjects_forKeys_(values, keys);

Read NSData as string

var nsdata = new ObjC.Object(ptr);
var str = nsdata.bytes().readUtf8String(nsdata.length());

Convert ObjC object to string

var obj = new ObjC.Object(args[2]);
console.log(obj.toString());

Keychain Operations

Hook all keychain operations

["SecItemAdd", "SecItemCopyMatching", "SecItemUpdate", "SecItemDelete"].forEach(function(func) {
    var f = Module.findExportByName("Security", func);
    Interceptor.attach(f, {
        onEnter: function(args) {
            console.log("[" + func + "]");
            console.log("Query: " + new ObjC.Object(args[0]));
        },
        onLeave: function(retval) {
            console.log("Result: " + retval);
        }
    });
});

Network Hooks

Hook NSURLSession requests

var NSURLSession = ObjC.classes.NSURLSession;
Interceptor.attach(NSURLSession['- dataTaskWithRequest:completionHandler:'].implementation, {
    onEnter: function(args) {
        var request = new ObjC.Object(args[2]);
        console.log("URL: " + request.URL());
        console.log("Method: " + request.HTTPMethod());
        console.log("Headers: " + request.allHTTPHeaderFields());
    }
});

Hook URLSession delegate

var resolver = new ApiResolver('objc');
resolver.enumerateMatches('-[* URLSession:dataTask:didReceiveData:]').forEach(function(match) {
    Interceptor.attach(match.address, {
        onEnter: function(args) {
            var data = new ObjC.Object(args[4]);
            console.log("Received data length: " + data.length());
        }
    });
});

File System

Hook file operations

var fopen = Module.findExportByName(null, "fopen");
Interceptor.attach(fopen, {
    onEnter: function(args) {
        console.log("fopen: " + args[0].readUtf8String());
    }
});

Hook NSFileManager

var NSFileManager = ObjC.classes.NSFileManager;
Interceptor.attach(NSFileManager['- contentsAtPath:'].implementation, {
    onEnter: function(args) {
        var path = new ObjC.Object(args[2]);
        console.log("Reading file: " + path);
    }
});

Biometric / LAContext

Hook biometric authentication

var LAContext = ObjC.classes.LAContext;
Interceptor.attach(LAContext['- evaluatePolicy:localizedReason:reply:'].implementation, {
    onEnter: function(args) {
        console.log("Biometric auth requested");
        var reply = new ObjC.Block(args[4]);
        reply.implementation(true, null);  // Simulate success
    }
});

Memory Search

Search for string in memory

Process.enumerateRanges('r--').forEach(function(range) {
    Memory.scanSync(range.base, range.size, "pattern").forEach(function(match) {
        console.log("Found at: " + match.address);
    });
});

Search for ASCII string

var pattern = "password";
var results = Memory.scanSync(ptr(0), Process.pageSize * 1000, pattern);

Useful Patterns

Log all method calls to a class

function traceClass(className) {
    var clazz = ObjC.classes[className];
    clazz.$ownMethods.forEach(function(method) {
        Interceptor.attach(clazz[method].implementation, {
            onEnter: function(args) {
                console.log(className + " " + method);
            }
        });
    });
}
traceClass("AuthManager");

Find and hook by method name pattern

for (var className in ObjC.classes) {
    var methods = ObjC.classes[className].$ownMethods;
    methods.forEach(function(method) {
        if (method.includes("password")) {
            console.log(className + " " + method);
        }
    });
}

Get instance of singleton

var instance = ObjC.classes.SingletonClass.sharedInstance();
console.log(instance.someProperty());

ObjC Blocks

Call an ObjC block

var block = new ObjC.Block(args[3]);
block.implementation(true, null);  // Call with arguments

Create custom block

var block = new ObjC.Block({
    retType: 'void',
    argTypes: ['bool', 'object'],
    implementation: function(success, error) {
        console.log("Block called: " + success);
    }
});

Debugging Tips

Print backtrace

console.log(Thread.backtrace(this.context, Backtracer.ACCURATE)
    .map(DebugSymbol.fromAddress).join('\n'));

Get module list

Process.enumerateModules().forEach(function(mod) {
    console.log(mod.name + " @ " + mod.base);
});

Find exported function

var func = Module.findExportByName("libSystem.B.dylib", "open");
console.log("open @ " + func);

Source: SKILL.md on GitHub

2 alerts16d4 checks · Risk CRITICAL
  • Gen Agent Trust Hub16d

    iOS penetration testing toolkit for security professionals. The skill provides methodologies, workflows, and Frida scripts for analyzing mobile applications on jailbroken or stock devices. It utilizes standard industry tools and well-known community repositories for its tasks.

  • Socket16d

    11 alerts: gptSecurity, gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    3/9 files flagged

Signed by skilld at f9bb3b2. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 6 months ago

README badge

README badge for hardw00t/ai-security-arsenal/ios-pentest