iOS逆向需要了解的OpenSSH

708 阅读11分钟

一、OpenSSH 概述

1.1 SSH

SSH 是一种网络协议,用于计算机之间的加密登录。

1995 年,芬兰学者 Tatu Ylonen 设计了 SSH 协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为 Linux 系统的标准配置。

1.2 OpenSSH

OpenSSHSSH (Secure SHell) 协议的免费开源实现。它是一款软件,应用非常广泛。SSH 协议可以用来进行远程控制, 或在计算机之间传送文件。

1.2.1 OpenSSH 插件安装

通过 OpenSSH 插件可以连接手机,进行远程控制, 或者传送文件。以越狱设备上的 cydia 为例,需要在软件源中添加源:


//蜜蜂源

apt.cydiami.com

//雷锋源

apt.abcydia.com

这两个源比较有名, 推荐添加。软件源可以理解为服务器, 存放了插件安装包。

image.png

然后在搜索中搜索OpenSSH,认准来自 apt.bingner.com。当然直接添加这个源也可以。

image.png

1.3 SSH 登陆过程

sequenceDiagram

客户端(Mac)->>越狱设备(iPhone): 1. 请求链接到iPhone (22端口) (root@设备IP)

越狱设备(iPhone)-->>客户端(Mac): 2.手机将公钥发送给Mac

客户端(Mac)->>越狱设备(iPhone): 3. Mac电脑通过收到的公钥加密登陆密码 (默认是: alpine)

越狱设备(iPhone)-->>客户端(Mac): 4.手机用私钥解密登陆密码, 是否允许登录

具体步骤:

  1. 请求链接到iPhone (22端口)

  2. 手机将公钥发送给Mac

在首次登录的时候会出现提示 RSA keyhash 值( hash 值是提示验证公钥的), 也就是在这里接受的 RSA 的 key(公钥), 然后保存在 ~/.ssh 目录下的 knuwn_host 文件中.(下图是我测试过程中产生的)

image.png

  1. Mac电脑通过收到的公钥加密登陆密码

  2. 手机用私钥解密登陆密码, 是否允许登录

1.4 中间人攻击(Man-in-the-middle attack)

sequenceDiagram

participant 客户端(Mac)

participant 中间人

participant 越狱设备(iPhone)

客户端(Mac)->>越狱设备(iPhone): 1. 请求链接到iPhone (22端口) (root@设备IP)

越狱设备(iPhone)-->>中间人: 2.手机将公钥发送给Mac

Note right of 中间人:手机上的公钥(被拦截)

中间人-->>客户端(Mac): 3.发送自己的的公钥发送给Mac

Note right of 客户端(Mac):中间人的公钥

客户端(Mac)->>中间人: 4. Mac电脑通过收到的公钥加密登陆密码 (默认是: alpine)

中间人->>越狱设备(iPhone): 5. 中间人通过自己的私钥解密, 然后通过拦截的公钥加密发送给iPhone

越狱设备(iPhone)-->>客户端(Mac): 6.iPhone用私钥解密登陆密码,允许登录

  1. 中间人拦截获取或者模拟电脑给手机发送登录请求获取手机端公钥(I)

  2. 然后自己生成公私钥(M)将自己生成的公钥(M)发送给电脑

  3. 电脑端密码使用公钥(M)加密后发送给中间人,中间人使用私钥(M)解密拿到密码。

  4. 中间人将密码通过公钥(I)加密从而实现登录。

1.5 了解原理, 但是怎么防止中间人的呢?

其实这个 SSH 早就解决了,

这个时候就用到了登录的时候返回的 hash 值了, 他就是用来检验公钥的.

一般服务器都会在自己的官网上公布自己公钥的 hash 值。这样就有效避免中间人攻击了。

二、 连接手机

2.1 wifi 登录查看手机

通过 OpenSSH 插件使用 WIFI 链接手机, 在 mac 终端输入格式为: ssh 用户名@手机IP


ssh root@192.168.2.186

在这里 手机是服务端, 电脑是客户端 OpenSSH 是让手机开启 SSH 登录服务。

默认密码: alpine

首次提示会出现保存提示, 需要输入 yes 保存后继续


➜ ~ ssh root@192.168.2.186

The authenticity of host '192.168.2.186 (192.168.2.186)' can't be established.

RSA key fingerprint is SHA256:Ae5Y7TUos3lIHFOyPSy4/HcQmYmcjeN4oxYI4goC7NBWqaf.

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

ps: 这里其实是提示公钥key 的hash值让验证有没有被篡改的。

输入密码: alpine (默认的) , 输入之后就登录成功了:


root@192.168.2.186's password:

iPhone-XS-Max:~ root#

这样就进入手机的 root 环境了, 手机还还有个 mobile 用户, 这个权限有限, sh mobile 就切换成了, (还是在 root 权限下操作的吧)

2.2 查看文件目录

root 目录下可以看到系统文件如下, 还可以通过 cd / 进入根目录:


iPhone-XS-Max:~ root# ls

Library/ Media/

iPhone-XS-Max:~ root# cd /

iPhone-XS-Max:/ root# ls

Applications/ Developer/ Library/ System/ User@ bin/ boot/ cores/ dev/ etc@ lib/ mnt/ private/ sbin/ tmp@ usr/ var@

iPhone-XS-Max:/ root#

还可以查看手机的应用列表"


iPhone-XS-Max:/ root# cd Applications/

iPhone-XS-Max:/Applications root# ls

AXUIViewService.app/ FieldTest.app/ SLGoogleAuth.app/

AccountAuthenticationDialog.app/ FindMy.app/ SLYahooAuth.app/

ActivityMessagesApp.app/ FindMyiPhone.app/ SMS\ Filter.app/

通过 ps -A 查看手机当前的进程,

你想查看手机上某个 app 的安装目录(以微信为例: 需要先把微信运行在前台): ps -A | grep WeChat


iPhone-XS-Max:/Applications root# ps -A

PID TTY TIME CMD

1 ?? 5:33.67 /sbin/launchd

299 ?? 1:46.48 /usr/libexec/substituted

300 ?? 0:00.00 (amfid)

376 ?? 0:00.00 /usr/libexec/amfid

387 ?? 0:00.30 /System/Library/PrivateFrameworks/AppleCredentialManager.framework/AppleCredentialManagerDaemon

---此处省略若干---

33511 ?? 0:00.08 /usr/libexec/gpsd

33514 ?? 0:00.17 /System/Library/PrivateFrameworks/MobileBackup.framework/backupd

33030 ttys000 0:00.07 -sh

33521 ttys000 0:00.02 ps -A

---这里分行看的更清除---

iPhone-XS-Max:/Applications root# ps -A | grep WeChat

815 ?? 2560:27.65 /var/containers/Bundle/Application/0FBC53D3-FEDF-464D-A855-7A32CC595764/WeChat.app/WeChat

33506 ?? 0:03.75 /var/containers/Bundle/Application/0FBC53D3-FEDF-464D-A855-7A32CC595764/WeChat.app/WeChat

33525 ttys000 0:00.02 grep WeChat

iPhone-XS-Max:/Applications root#

这个时候 MachO 文件路径就找到了。

2.3 退出手机查看

control+d 或者 exit 就可以退出登录了


iPhone-XS-Max:/Applications root# exit

logout

Connection to 192.168.2.186 closed.

2.4 用户

iOS 系统下有两个用户:rootmobile

image.png

  • root:最高权限用户,可以访问任意文件.

  • mobile:普通用户,只能访问改用户目录下文件 /var/Mobile

mobile 用户在自己的目录下可以创建文件,在根目录下没有权限:

image.png

root 用户就可以的, 就测试了

2.5 修改用户密码
  • root 用户可以修改所有用户的密码。

  • passwd 命令修改密码:

  • passwd 用户名

  • 输入两次新密码,确认修改。因为是登录状态所以不用输入原始密码。

ps: root 用户修改 mobile 用户密码:


~ ssh

iPhone-XS-Max:~ root# passwd mobile

Changing password for mobile.

New password:

Retype new password:

iPhone-XS-Max:~ root#

一般不推荐修改密码,直接配置免密登录就好了。如果修改密码后忘记了那么重新安装就好了。

2.6 密钥保存验证

通过 1.3 SSH 登录过程我们知道在首次登录的时候会提示验证公钥的 hash 值,并且保存公钥到 ~/.ssh 目录下的 known_hosts 中,那么公私钥手机中也应该是有的。

进入手机 cd /etc/ssh 目录:


iPhone-XS-Max:~ root# cd /etc/ssh

iPhone-XS-Max:/etc/ssh root# ls

moduli ssh_host_dsa_key ssh_host_rsa_key sshd_config

ssh_config ssh_host_dsa_key.pub ssh_host_rsa_key.pub

iPhone-XS-Max:/etc/ssh root#

可以看到 ssh_host_rsa_key 的公私钥。这也就验证了上面的登录过程。

image.png

对比可以看到. 如果 IP地址 改变了就无法进行访问了, 就会出现中间人攻击的提示了

2.7 免密登陆(公钥登录)
2.5.1 免密登录原理

免密码登录也称公钥登录,原理就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的直接允许登录不再要求密码。

image.png

2.5.2 免密登录配置
  1. .客户端在 ~/.ssh/ 目录下生成公私钥 ssh-keygen:

20211026084614.jpg

一路回车不设置密码(如果设置密码虽然免密登录了,但是每次都要输rsa的密码)。

  1. 拷贝公钥给 SSH 服务器:ssh-copy-id 用户名@服务器IP, 拷贝的时候需要输入 root 账户的密码

20211026084706.jpg

这个时候再登录就不需要输入密码了:


~  ssh root@192.168.2.186

iPhone-XS-Max:~ root#

ssh-copy-id 可以通过 -i 指定文件。某些系统通过指定 -i 会无效。(虽然拷贝成功,但是验证的是 ssh-copy-id 自己生成的 key )。

3.拷贝的公钥在服务器 ~/.ssh/authorized_keys中:

image.png

image.png

在某些版本中 ssh-copy-id 不需要我们生成公钥,该命令会自己生成公私钥进行拷贝。如果遇见自己生成的 公钥 key 和和拷贝到authorized_keys 中的对不上那么很可能是这个问题。

2.8 配置快捷登录

加入我们有多台手机,或者并不想输入ip那么麻烦的去登录。在 ~/.ssh 下创建一个 config 文件,对 ssh 登录配置别名:


Host iPhone7

Hostname 172.20.10.11

User root

Port 22

使用:


~  ssh iPhoneXsMax

iPhone-XS-Max:~ root#

2.9 SSH其它操作
  • 删除保存的服务器地址的key:ssh-keygen –R 服务器IP地址(当SSH登录手机,手机就是服务器)

  • know_hosts 文件:用于保存SSH登录服务器所接受的key,在系统~/.ssh 目录

  • ssh_host_rsa_key.pub文件:作为SSH服务器发送给连接者的key,在系统/etc/ssh 目录中

  • config文件:在~/.ssh 目录下创建一个config文件。内部可以配置ssh登录的别名。

三、USB登录(推荐)

上面我们都是通过 wifi 连接的,由于通过 wifi 链接存在不稳定性,有时候会断开链接,并且有速度限制。所以推荐使用 usb 链接。苹果有一个服务,叫 usbmuxd ,这个服务主要用于在 USB 协议上实现多路TCP连接。

usbmuxd目录:


/System/Library/PrivateFrameworks/MobileDevice.framework/Resources

image.png

3.1 USB 连接
3.1.1 python脚本映射端口

ssh root@192.168.2.186 其实也就是 ssh -p 22 root@172.20.10.11,默认22端口省略了,我们可以通过ssh -p 12345 root@localhost连接,只要将本地的12345端口映射到usb端口,只要usb端口连接哪个设备就相当于给哪个设备发送请求。

有个python-client工具可以映射端口:

`

python tcprelay.py -t 要映射端口:本地端口

`


python-client python tcprelay.py -t 22:12345

Forwarding local port 12345 to remote port 22

将本地的 12345 端口映射到设备的 TCP 端口 22。这样就可以通过本地的 12345 端口建立连接了。

3.1.2 通过USB进行SSH连接

映射成功后想要登录直接:


//也可以 ssh -p 12345 root@127.0.0.1

ssh -p 12345 root@localhost

这里有个注意点是映射端口成功后不能关闭窗口,否则映射就没有了。

ssh 连接本地的 12345,由于做了端口映射所以会通过 usb 连接对面设备的22端口。


 ssh -p 12345 root@localhost

The authenticity of host '[localhost]:12345 ([127.0.0.1]:12345)' can't be established.

RSA key fingerprint is SHA256:3vASLTEmYAr3ngQJ6b8MmLD82/LhxP0PuNHFQNPhBGl0.

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Warning: Permanently added '[localhost]:12345' (RSA) to the list of known hosts.

zaizai:~ root#

这里会重新进行 rsa 本地记录( ip 变了),免密登录仍然有效。(我这里为了测试其他方便, 直接使用的 2222 )

image.png

ps: ip 变了,相当于登录一个新的服务器。所以保存 rsa

3.1.3 验证中间人攻击

这个时候换一台设备进行 ssh -p 12345 root@localhost 登录就会提示中间人攻击了,由于本地 localhost 对应的 rsa 和新手机返回的hash值对应不上。如果只有一台手机可以通过修改 know_hosts 对应的 localhostrsa 公钥模拟:


 ssh -p 12345 root@localhost

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

Someone could be eavesdropping on you right now (man-in-the-middle attack)!

It is also possible that a host key has just been changed.

The fingerprint for the RSA key sent by the remote host is

SHA256:pIPlaWYd9wT2MfpRqvP/WOe1wVXfVVKiCKttyPHK3f0.

Please contact your system administrator.

Add correct host key in /Users/zaizai/.ssh/known_hosts to get rid of this message.

Offending RSA key in /Users/zaizai/.ssh/known_hosts:4

RSA host key for [localhost]:12345 has changed and you have requested strict checking.

Host key verification failed.

所以如果有两台手机可以分别通过 sh -p 12345 root@localhostssh -p 12345 root@127.0.0.1 登录,就能区分开了。

3.2 配置USB快捷登录

这个时候在 config 中取别名就不行了,因为有端口的映射,并且地址也不是真实的地址。

在自己的脚本目录创建一个 iPhoneX.sh 文件(最好给这个目录配置环境变量),脚本内容如下:

ssh -p 12345 root@localhost

那么这个时候还需要端口映射的脚本 usbConnect.sh,内容如下:

python /Users/zaizai/HPShell/python-client/tcprelay.py -t 22:12345

端口映射脚本和连接脚本分开是为了方便多个设备切换,由于映射只需要一次。

使用:


//映射端口

 usbConnect.sh

//链接

 iPhoneX.sh

这样就连接上手机了。

需要两个窗口执行,映射完窗口一直存在的。

脚本目录文件:

image.png

3.3 Iproxy 端口映射

Iproxy 也是一个映射工具。

  1. 安装 libimobiledevice

brew install libimobiledevice

  1. 映射端口

iproxy 本地端口 要映射端口


iproxy 12345 22

这个映射和 python 脚本是反过来的。左边是本地端口,右边是要映射端口。其它的使用方式相同。

映射终端:


 iproxy 12345 22

Creating listening port 12345 for device port 22

waiting for connection

New connection for 12345->22, fd = 5

waiting for connection

Requesting connecion to USB device handle 3 (serial: 5d38c0a07ffa912050c2cbc05da5436e10a2d5d7), port 22

连接终端:


 iPhoneX.sh

iPhoneX:~ root#

参看文章: www.imgeek.org/article/825…

参看文章: juejin.cn/post/696532…

最后, 有问题的地方麻烦大家指点一下的啊


End