Sekiro 简介
“开抄!以下简介部分来自https://sekiro.virjar.com/sekiro-doc/index.html,
SEKIRO 是一个 android 下的 API 服务暴露框架,可以用在 app 逆向、app 数据抓取、android 群控等场景。同时 Sekiro 也是目前公开方案唯一稳定的 JSRPC 框架。
- 对网络环境要求低,sekiro 使用长链接管理服务(可以理解为每个 APP 内置内网穿透功能),使得 Android 手机可以分布于全国各地,甚至全球各地。手机掺合在普通用户群体,方便实现反抓突破,更加适合获取下沉数据。
- 不依赖 hook 框架,就曾经的 Hermes 系统来说,和 xposed 框架深度集成,在当今 hook 框架遍地开花的环境下,框架无法方便迁移。所以在 Sekiro 的设计中,只提供了 RPC 功能了。
- 纯异步调用,在 Hermes 和其他曾经出现过的框架中,基本都是同步调用。虽然说签名计算可以达到上百 QPS,但是如果用来做业务方法调用的话,由于调用过程穿透到目标 app 的服务器,会有大量请求占用线程。系统吞吐存在上线(hermes 系统达到 2000QPS 的时候,基本无法横向扩容和性能优化了)。但是 Sekiro 全程使用 NIO,理论上其吞吐可以把资源占满。
- client 实时状态,在 Hermes 系统我使用 http 进行调用转发,通过手机上报心跳感知手机存活状态。心跳时间至少 20s,这导致服务器调度层面对手机在线状态感知不及时,请求过大的时候大量转发调用由于 client 掉线 timeout。在 Sekiro 长链接管理下,手机掉线可以实时感知。不再出现由于框架层面机制导致 timeout
- 群控能力,一台 Sekiro 服务器可以轻松管理上万个手机节点或者浏览器节点,且保证他们的 RPC 调用没有资源干扰。你不需要关心这些节点的物理网络拓扑结构。不需要管理这些手机什么时候上线和下线。如果你是用 naohttpd 方案,你可能需要为手机提供一个内网环境,然后配置一套内网穿透。一个内网一个机房,你需要管理哪些机房有哪些手机。当你的手机达到一百台之后,对应的物理网络环境就将会比较复杂,且需要开发一个独立系统管理了。如果你使用的时 FridaRPC 方案,你可能还需要为每几个手机配置一台电脑。然后电脑再配置内网穿透,这让大批量机器管理的拓扑结构更加复杂。这也会导致手机天然集中在一个机房,存在 IP、基站、Wi-Fi、定位等环境本身对抗。
- 多语言扩展能力。Sekiro 的客户端 lib 库,目前已知存在 Android(java)、IOS(objective-c)、js(浏览器)、易语言等多种客户端(不是所有的都是 Sekiro 官方实现)。Sekiro 本身提供一个二进制协议(非常简单的二进制协议规则),只要你的语言支持 socket(应该所有语言都支持),那么你就可以轻松为 Sekiro 实现对应客户端。接入 Sekiro,享受 Sekiro 本身统一机群管理的好处。在 Sekiro 的 roadmap 中,我们会基于 frida Socket 实现 frida 的客户端,完成 Frida 分析阶段的代码平滑迁移到 Sekiro 的生产环境。尽请期待
- 客户端接入异步友好。Sekiro 全程异步 IO 设计,这一方面保证整个框架的性能,另一方面更加贴近一般的 app 或者浏览器本身的异步环境。如果 rpc 调用用在签名计算上面,大部分签名仅仅是一个算法或者一个 so 的函数调用。那么同步调用就可以达到非常高的并发。但是如果你想通过 rpc 调用业务的 API(如直接根据参数调用最网络框架的上层 API,把参数编解码、加解密都,逻辑拼装都看作黑盒)。此时普通同步调用将会非常麻烦和非常消耗客户端性能。异步转同步的 lock 信号量机制、同步线程等待导致的线程资源占用和处理任务挤压等风险。FridaRPC 支持异步,但是由于他的跨语言问题,并不好去构造异步的 callback。目前 nanohttpd 或者 FridaPRC,均大部分情况用在简单的签名函数计算上面。而 Sekiro 大部分用在上游业务逻辑的直接 RPC 场景上。
- API 友好(仅对 AndroidAPI),我们为了编程方面和代码优雅,封装了一套开箱即用的 API,基于 SekiroAPI 开发需求将会是非常快乐的。
简而言之呢,Sekiro 是一个 virjar 开发的一款强大稳定的 rpc 服务暴露框架
Kubernetes 上部署
首先,我们需要有一个 Kubernetes 集群,可以自己搭建,也可以使用 Minikube 或者用阿里云、腾讯云、Azure 等服务商直接提供的 Kubernetes 服务。另外我们需要能使用 kubectl
连接和控制当前的集群,
- 搭建 Kubernetes 集群:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
- 基于 Kubeadmin 实现 Kubernetes 集群搭建:https://paynewu.com/18864.html
上面的内容准备就绪之后,就可以开始 Kubernetes 搭建。搭建完成之后就开始部署 Sekiro 吧
在 Kubernetes 中容器环境部署那就离不开 image,Sekiro 的 image 为
registry.cn-beijing.aliyuncs.com/virjar/sekiro-server:latest
“无论是 Docker、还是 podman、亦或者是其他的容器。现成的景象就用这个
Kubernetes 部署服务的常用的有三种形式
- kubectl cli 部署
- 基于 YAML 文件格式部署
- 基于 JSON 文件格式部署
部署服务
首先为此创建一个名为crawleruntil
的 namespace
kubectl create namespace crawleruntil
image-20220410033511352
“因为我已经有
crawleruntil
这个 namespace 以及其他的服务,为了方便就不删了在演示了,将图中的 sekiro 即可
至此已经完成四分之一了,接下来进行 Sekiro 的部署,yaml 文件如下
apiVersion: apps/v1 kind: Deployment metadata: name: sekiro namespace: crawleruntil labels: app: sekiro spec: replicas: 3 selector: matchLabels: app: sekiro template: metadata: labels: app: sekiro spec: containers: - name: sekiro image: registry.cn-beijing.aliyuncs.com/virjar/sekiro-server:latest imagePullPolicy: Always ports: - containerPort: 5601 - containerPort: 5602 - containerPort: 5603 resources: requests: memory: "1Gi" cpu: "0.5" limits: memory: "2Gi" cpu: "1" restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: sekiro namespace: crawleruntil spec: selector: app: sekiro type: ClusterIP ports: - port: 5601 name: nio targetPort: 5601 protocol: TCP - port: 5602 name: server targetPort: 5602 - port: 5603 name: ws targetPort: 5603
将其复制到服务器上,然后使用命令kubectl apply -f 此文件名
,当然kubectl create -f 此文件名
也可以大差不差。
稍等几秒甚至是一两分钟,看看
image-20220410034203246
确认使用kubectl get all -n crawleruntil
中显示的内容中有 STATUS 均为Running
, 代表就部署成功了
当然这还并不足以使服务可用,因为 sekiro 它运行在容器内的网络,暂时还无法在本地、或者远程反问服务。此时就需要将服务暴露出去。以便于使用
服务暴露
暴露服务有 NotePort, LoadBalance, 此外 externalIPs 也可以使各类 service 对外提供服务。当然最推荐的还是Ingress
, 关于 Ingress 是什么感兴趣的请自行搜索。
首先先需要部署 ingress collector,请搜索。部署完成后可采用如下 YAML 进行 ingress 服务暴露
# https apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: sekiro-ingress namespace: crawleruntil annotations: kubernetes.io/ingress.class: traefik spec: rules: - http: paths: - pathType: Prefix path: / backend: service: name: sekiro port: name: server - pathType: Prefix path: /asyncInvoke backend: service: name: sekiro port: name: nio - pathType: Prefix path: /websocket backend: service: name: sekiro port: name: ws
此时访问你外网地址, 就会发现。(80 需要有权限打开访问哦)
image-20220410035421312
ok,部署完成了!sekiro 就可以食用啦。
以上明显还不够,主要是两个问题
没有身份验证:那么就意味着任何人都可以调用你的这个接口,岂不是...
某些网页端的 JS 有证书,这样部署的 sekiro 无法使用此场景,需要为之加上 tls 证书。
Ingress 网页添加认证
想偷懒的可以直接使用这三条命令。认证令牌创建一步到位
yum -y install httpd echo `echo $(hostname) | base64` | htpasswd -ic ./auth `echo $(echo $(hostname) | base64)` kubectl create secret generic basic-auth-secret --from-file auth --namespace=crawleruntil
我这里默认采用机器的 hostname base64 后的字符为用户名与密码。
echo `echo $(hostname) | base64` :密码改这里面的内容 ./auth `echo $(echo $(hostname) | base64)`: 用户名这里面的内容
然后直接使用kubectl create secret generic basic-auth-secret --from-file auth --namespace=crawleruntil
创建一个名为basic-auth-secret
generic
类型的 secret。
“注意需要将 namespace 指定为 crawleruntil,实现同意命名空间
将它挂到 Ingress 上去,
Ingress YAML 如下
# https apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: sekiro-ingress namespace: crawleruntil annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/auth-type: "basic" traefik.ingress.kubernetes.io/auth-secret: "basic-auth-secret" spec: rules: - http: paths: - pathType: Prefix path: / backend: service: name: sekiro port: name: server - pathType: Prefix path: /asyncInvoke backend: service: name: sekiro port: name: nio - pathType: Prefix path: /websocket backend: service: name: sekiro port: name: ws
打开一个无痕浏览器,此时你就可以发现
image-20220410040928885
这玩意需要认证了,cool ~
域名解析与 TLS 网络证书
域名:首先你得需要有域名,这个去阿里云、腾讯云、华为云还是等等买就是咯。
证书:将你申请点 TLS 证书下载到本地,具体请搜索
创建证书的 secret, 如下
kubectl create secret tls tls-sekiro-paynewu-com --key sekiro.paynewu.com.key --cert=sekiro.paynewu.com_bundle.crt --namespace crawleruntil
最终的 Ingress YAML 如下
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: sekiro-ingress namespace: crawleruntil annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/auth-type: "basic" traefik.ingress.kubernetes.io/auth-secret: "basic-auth-secret" traefik.frontend.rule.type: PathPrefixStrip traefik.ingress.kubernetes.io/redirect-entry-point: https traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" spec: tls: - hosts: - sekiro.paynewu.com secretName: tls-sekiro-paynewu-com rules: - host: sekiro.paynewu.com http: paths: - pathType: Prefix path: / backend: service: name: sekiro port: name: server - pathType: Prefix path: /asyncInvoke backend: service: name: sekiro port: name: nio - pathType: Prefix path: /websocket backend: service: name: sekiro port: name: ws
根路径
image-20220410041714078
image-20220410043120299
注入验证
将 https://sekiro.virjar.com/sekiro-doc/assets/sekiro_web_client.js 中的文件复制到控制台,执行
然后在控制台调用
var client = new SekiroClient("wss://域名/websocket?group=ws-group-test&clientId=" + guid());
校验
image-20220410043429585
完成~,
有了Sekiro之后,咱抓取数据的🦶步,蹭蹭蹭~。
Referer
Sekiro GitHub[1]
basic-authentication[2]
security-headers-annotations[3]
[1]Sekiro GitHub: https://github.com/virjar/sekiro
[2]basic-authentication: https://doc.traefik.io/traefik/v1.7/user-guide/kubernetes/#basic-authentication
[3]security-headers-annotations: https://doc.traefik.io/traefik/v1.7/configuration/backends/kubernetes/#security-headers-annotations