automating ios blackbox security scanning - zeronights · automating ios blackbox security scanning...
TRANSCRIPT
Automating iOS blackbox security scanningMikhail Sosonkin [email protected]
SYNACK Inc.
ME!
“leverages the best combination of humans and technology to discover security vulnerabilities in our customers’ web apps, mobile apps, IoT devices and infrastructure endpoints”
Employer!
- SYNACK.com
Why do we care?
Our privacy. Our money.Our freedoms.
Wouldn’t want to lose any of those things!
Pangu TaiG
Step 1: Jailbreak
Step 2: Apply IDAPro
For those that don’t know Aarch64IdaRef documentation plugin: https://github.com/nologic/idaref
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylibThanks Stephan Esser!
In-process• Frida• Cycrypt• LLDB
• Tracing Objective-C calls and mach port messages• https://github.com/nologic/objc_trace
External
• FileMon• MiTM proxy
SSL Kill Switch
Step 3: Dynamic Analysis
• Objective-C messages• On iOS, more meaningful than strace• Might want to hit/fuzz a particular method• In case of Swift, we see runtime library interactions
• Swift Reversing by Ryan Stortz
• Mach Port Messages• Any sort of IPC• CFMessagePort, etc
Collecting Coverage Information
1. Allocate a page - a jump page
2. Set objc_msgSend readable and writable
3. Copy preamble bytes from objc_msgSend
4. Check for branch instructions in preamble
5. Modify objc_msgSend preamble
6. Set jump page to readable and executable
7. Set objc_msgSend readable and executable
Objc_Trace
Call Sequence
Hook Steps
void* hook_callback64_pre(id self, SEL op, void* a1, ...) {
Class cls = object_getClass(self);
if(cls != NULL && op != NULL)
cacheImp = c_cache_getImp(cls, op);
if(!cacheImp) {
// not in cache, never been called, record the call.
…
const struct mach_header* libobjc_base = libobjc_dylib_base();
c_cache_getImp = (p_cache_getImp)((uint8_t*)libobjc_base) + 97792 + 0x4000;
Important Optimization
Only record unseen method calls
Find the cache check function cache_getImp
What do we get out of this?
{ '_payload': { '_payload': { '_msg': '\x00\x00\x08\x00\x00\x00subsystem\x00\x00\x00\x00@\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00ha', 'type': 2048},
'magic': '!CPX',
'version': 5},
'msgh_bits': 1250579,
'msgh_id': 268435456,
'msgh_local_port': '0x30b',
'msgh_remote_port': '0x10b',
'msgh_reserved': 2819,
'msgh_size': 256}
MACH Shark
Machshark
• Attach using LLDB• Breakpoint on
• bootstrap_look_up2• Rocketbootstrap_look_up or bootstrap_look_up3• mach_msg
• Least intrusive but slow• Harder to get the responses
• Often less important• Compensate by breakpointing the server
• Detailed on debugtrap.com
Another mach_shark method
Most apps are largely user reactive in nature
The difficulty of Apps
“A little engine for driving the UI while doing
blackbox testing of an iOS App”
- CHAOTICMARCH
• Time saving• Repeatable• WebAPI Discovery• Code Coverage
• Discover Preinstalled Malware• Cameras arrived with malware from Amazon
Why automate?
Apply intelligence!
● Simulate the user ● Read and understand the UI
How does the UI look like in memory?
cy# UIApp.keyWindow
<UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray>;>
| <TiRootViewNeue; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer>>
...
<TiUITableViewCell; baseClass = UITableViewCell; text = 'Log On';
| <TiGradientLayer;> (layer)
| <UITableViewCellContentView; frame = (0 0; 256 43.5); layer = <CALayer>>
| | <UITableViewLabel; frame = (74 0; 167 43.5); text = 'Log On'>
| | <UIImageView; frame = (15 0; 44 43.5); layer = <CALayer>>
| <_UITableViewCellSeparatorView; frame = (74 43.5; 182 0.5); layer = <CALayer>>
● Lua Scriptable Logic● Standard functions for touching the device● Options for record/replay● Finding UI Components● Regulating speed of execution● Support for multiple targets● Mechanisms for generic logic● Lightweight injected module
CHAOTICMARCH
Source
Powered by:
• LibSimulateTouch• LUA• #import <UIKit/UIKit.h>
CHAOTICMARCH
while true dolocal button = getButton(clickedButtons)
-- put some info in.fill_all_fields()click_button(button)
if(button["text"] ~= nil) thenclickedButtons[button["text"]] = 1
endusleep(2 * 1000000)
end
A basic script
• Discovery• WebAPI - gives you working samples.• Local behaviour
• File accesses, IPC interactions, and code coverage
• Fuzzing• Testing kiosk type apps.• Automate the UI to trigger events.
Applications
Deadly in the right combination
MITM Proxy
Request
Fuzz
Parse
Mutator
Attack scenario
1 - Make a post
2 - Get exploited binary/XSS with phish
3 - Steal creds or tokens
4 - Put up a draft
5 - Request messages
6 - respond with attack content
AttackerUser
We focus on this
while true do
local inputs = findOfTypes("UITextField", "")
for index, inputField in pairs(inputs) do
click_button(inputField)
inputText("SomeInput!!")
end
-- touch login
touchDown(3, 138, 619);
usleep(83148.83);
touchUp(3, 141, 615);
check_alert()
end
Source
Defending apps from undesirable automation!
• Detecting hidden components is not straightforward!• Misuse
• Labels as buttons• Input forms as labels
• Trees of invisible to the user elements• Kind of like anti-debugging or anti-RE.
Anti Automation techniques
• Apps are important!• Automation of the UI• Collection of coverage information• Fuzzing of responses messages
Wrap up!
Questions?
Email: [email protected], blog: debugtrap.comTwitter: @hexlogic
Source:CHAOTICMARCH: https://github.com/synack/chaoticmarch
Machshark: https://github.com/nologic/machshark
Objc_trace: https://github.com/nologic/objc_trace
Thank you!
Images: http://iconmonstr.com/