WithSecureLabs / needle

The iOS Security Testing Framework
https://mobiletools.mwrinfosecurity.com/
Other
1.34k stars 284 forks source link

Fix how the module "cycript_touchid.py" finds running processes via "ps ax | grep" #214

Closed Yogehi closed 6 years ago

Yogehi commented 6 years ago

question regarding more needle stuff / hooking / cycript.

the module "hooking/cycript/cycript_shell" does the following commands on the iphone to launch a cycript shell:

iphone root# ps ax | grep -i '<app name' iphone root# cycript -p

now i found an interesting issue when using this module with the app "LINE". the following is the output from "ps ax | grep -i 'LINE':

983 ?? Ss 0:00.11 /usr/libexec/online-auth-agent 1563 ?? Ss 0:00.72 /var/containers/Bundle/Application/95376AF3-237B-49B2-98EB-DEDF50984CB7/LINE.app/LINE 1583 s000 R+ 0:00.00 grep -i LINE

notice how the first process (983) is for a different process than the app. what i found is that the needle module will attach the cycript program to the first process and not the actual LINE app:

[D] [REMOTE CMD] Remote Interactive TTY Command: cycript -p 983

this patch addresses the above issue by making the "ps" command look for the binary directory instead of the app name.

marco-lancini commented 6 years ago

@Yogehi on what versions of iOS have you tested this modifications? Are you sure replace("/private","") works for both system and 3rd party apps? And on iOS 8,9, and 10?

Yogehi commented 6 years ago

I don't have an iOS 8 device on me. I'll have to ask someone else to do that.

I can try iOS 9 tomorrow. Our current iOS 9 device is in use.

I'm currently using iOS 10. I can use Cycript on the Camera app. Needle output below:

[needle] > set debug true
DEBUG => true
[needle] > set app com.apple.camera
APP => com.apple.camera
[needle] > use hooking/cycript/cycript_touchid
[needle][cycript_touchid] > run
[D] Setup local output folder: /root/.needle/output
[D] Setting up issues database...
[D] [DB] QUERY: CREATE TABLE IF NOT EXISTS issues (app TEXT, module TEXT, name TEXT, content TEXT, confidence TEXT, outfile TEXT)
[*] Checking connection with device...
[V] Connection not present, creating a new instance
[D] Setting up USB port forwarding on port 2222
[D] [LOCAL CMD] Local Subprocess Command: /root/Programs/needle/needle/libs/usbmuxd/tcprelay.py -t 22:2222
[D] [AGENT] Setting up port forwarding on port 4444
[V] [AGENT] Connecting to agent (127.0.0.1:4444)...
[+] [AGENT] Successfully connected to agent (127.0.0.1:4444)...
[D] [AGENT] Executing command: os_version
[V] [SSH] Connecting (127.0.0.1:2222)...
[+] [SSH] Connected (127.0.0.1:2222)
[D] Creating temp folder: /var/root/needle/
[D] [REMOTE CMD] Remote Command: if [ -d /var/root/needle/ ]; then echo "yes"; else echo "no" ; fi
[D] [REMOTE CMD] Remote Command: mkdir /var/root/needle/
[D] [AGENT] Executing command: os_version
[+] Target app: com.apple.camera
[*] Retrieving app's metadata...
[D] [AGENT] Executing command: list_apps
[D] Copying the plist to temp: /Applications/Camera.app/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /Applications/Camera.app/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/Applications/Camera.app/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/Applications/Camera.app/Info.plist" /root/.needle/tmp/plist
[D] [REMOTE CMD] Remote Command: lipo -info /Applications/Camera.app/Camera
[D] [REMOTE CMD] Remote Command: if [ -d /Applications/Camera.app/PlugIns ]; then echo "yes"; else echo "no" ; fi
[D] No Plugins found
[*] Launching the app...
[D] [REMOTE CMD] Remote Command: open com.apple.camera
[V] Retrieving the PID...
[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 2477
[D] [REMOTE CMD] Remote Command: echo "@import com.saurik.substrate.MS; var oldm = {}; MS.hookMessage(LAContext, @selector(evaluatePolicy:localizedReason:reply:), function(self, reason, block) { block(YES, nil); }, oldm);" > /var/root/needle/hook.cy
[*] Spawning a Cycript shell...
[D] [REMOTE CMD] Remote Interactive TTY Command: cycript -p 2477 /var/root/needle/hook.cy
Warning: Permanently added '[127.0.0.1]:2222' (ECDSA) to the list of known hosts.
throw new ReferenceError("Can't find variable: LAContext")
Connection to 127.0.0.1 closed.

To verify, I SShed into the iPhone to verify that the Camera app was at PID 2477:

root@YayComputerYay:~/Programs/needle/needle# ssh root@localhost -p 2222
root@localhost's password: 
Yay-iPhone-SE-Yay:~ root# ps ax | grep -i '/Applications/Camera.app/Camera'
 2477   ??  Ss     0:00.97 /Applications/Camera.app/Camera
 2524 s000  R+     0:00.00 grep -i /Applications/Camera.app/Camera
Yay-iPhone-SE-Yay:~ root# ps ax | grep -i 'Camera'
 2477   ??  Ss     0:00.97 /Applications/Camera.app/Camera
 2526 s000  R+     0:00.00 grep -i Camera
HenryHoggard commented 6 years ago

Not sure what the purposes of removing /private are, but in theory this fix should work, since the process name will always be the binary_path. Have you tested it with applications with spaces in the name?

Yogehi commented 6 years ago

I can test it with apps with spaces in their name.

I told it to strip "/private" because Needle reports the binary path in ios10 as /private/var/so-and-so" instead of just "/var/so-and-so". But if you run the"ps" command, you'll see that the binary is running from the "/var/so-and-so" directory. So you need to remove "/private/" from "binary path" before you can "ps ax | grep <binary path.strip "/private".

Also this comment was made on my phone so if it doesn't make sense, I can give a better explanation later.

HenryHoggard commented 6 years ago

Makes sense. If we can get this tested on iOS 9 and system apps today. I'm happy to merge it in.

Yogehi commented 6 years ago

test results as follows:

ios 9 user app with a name that is one word: pass system app with a name that is one word: pass user app with a name that is more than one word: fail system app with a name that is more than one word: fail

with my proposed fix, the 'PS' command now looks like this (used the system app Game Center as an example):

ps ax | grep -i ''/Applications/Game Center.app/Game Center''

i've come up with the following solutions for this, all of which looks ugly.

option 1) escape all spaces.

in the file "cycript_touchid.py", lines 21-23 would look like this:

binaryPath = self.APP_METADATA['binary_path'].replace("/private","")
binaryPath = binaryPath.replace(" ","\ ")
pid = self.device.app.search_pid(binaryPath)

needle successfully finds the process "Game Center":

[D] [REMOTE CMD] Remote Command: ps ax | grep -i ''/Applications/Game\ Center.app/Game\ Center''
[V] PID found: 997
zaks-iPad:/Applications/Game Center.app root# ps ax | grep "Game Center"
  997   ??  Ss     0:18.37 /Applications/Game Center.app/Game Center
 1220 s001  R+     0:00.01 grep Game Center

needle successfully finds the application "Camera"

[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 715
zaks-iPad:/Applications/Game Center.app root# ps ax | grep "Camera"     
  715   ??  Us     0:01.83 /Applications/Camera.app/Camera
 1277 s001  R+     0:00.01 grep Camera

option 2) remove extra single quotes

in the file "cycript_touchid.py", lines 21-23 would look like this:

binaryPath = self.APP_METADATA['binary_path'].replace("/private","")
binaryPath = binaryPath.replace("'","")
pid = self.device.app.search_pid(binaryPath)

needle successfully finds the application "Game Center"

[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Game Center.app/Game Center'
[V] PID found: 997
zaks-iPad:/Applications/Game Center.app root# ps ax | grep "Game Center"
  997   ??  Ss     0:27.42 /Applications/Game Center.app/Game Center
 1272 s001  R+     0:00.01 grep Game Center

needle successfully finds the application "Camera"

[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 715
zaks-iPad:/Applications/Game Center.app root# ps ax | grep "Camera"     
  715   ??  Us     0:01.83 /Applications/Camera.app/Camera
 1277 s001  R+     0:00.01 grep Camera
Yogehi commented 6 years ago

closing pull request and remaking it to clear commit clutter.

see https://github.com/mwrlabs/needle/pull/230