Android 6.0 StrictController

来源:互联网 发布:php判断变量是否设置 编辑:程序博客网 时间:2024/05/17 01:52

个人邮箱:xiaokeweng@gmail.com  欢迎大家直接发邮件给我共同交流学

在学习android6.0时,发现在netd中引入了StrictController这个module,并且在运行android 6.0的设备中出现了很多StrictController相关的iptables rules如下详细学习了下关于StrictController的知识:

Chain st_OUTPUT (1 references)
target     prot opt source               destination 

Chain st_clear_caught (2 references)
target     prot opt source               destination

Chain st_clear_detect (0 references)
target     prot opt source               destination
REJECT     all --  anywhere             anywhere             connmark match  0x2000000/0x2000000 reject-withicmp-port-unreachable
RETURN     all --  anywhere             anywhere             connmark match  0x1000000/0x1000000
CONNMARK   tcp --  anywhere             anywhere             u32"0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0xffff0000=0x16030000&&0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x4&0xff0000=0x10000"CONNMARK or 0x1000000
CONNMARK   udp --  anywhere             anywhere             u32"0x0>>0x16&0x3c@0x8&0xffff0000=0x16fe0000&&0x0>>0x16&0x3c@0x14&0xff0000=0x10000"CONNMARK or 0x1000000
RETURN     all --  anywhere             anywhere             connmark match  0x1000000/0x1000000
st_clear_caught  tcp --  anywhere             anywhere             state ESTABLISHED u32"0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0x0=0x0"
st_clear_caught  udp --  anywhere             anywhere           

Chain st_penalty_log (0 references)
target     prot opt source               destination       
CONNMARK   all --  anywhere             anywhere             CONNMARK or 0x1000000
NFLOG      all --  anywhere             anywhere           

Chain st_penalty_reject (0 references)
target     prot opt source               destination       
CONNMARK   all --  anywhere             anywhere             CONNMARK or 0x2000000
NFLOG      all --  anywhere             anywhere          
REJECT     all --  anywhere             anywhere             reject-with icmp-port-unreachable

[StrictMode 是什么]

 要了解Netd/server/StrcitController,先粗略了解下什么是StrictMode
Android 2.3API Level 9)开始,Android提供了一个app程序性能诊断工具,它就是StrictModeStrictMode的能力与限制包括:

1.基于线程的对磁盘读写,网络操作,以及自定义耗时操作等的监控;
2.
基于VM进程的对对象泄露(Activity对象,SQLite对象,未反注册对象,未关闭对象)的监控;
3.
可以检测到跨进程的耗时操作(当然必须是同步操作);
4.
当前不支持在jni中发生的网络与磁盘操作。

随着Android的进化,StrictMode的功能也将越来越强大。当StrictMode检测到指定的事件发生时,它以指定的方式通知你:崩溃,弹出对话框,闪屏,logcatdropbox简言StrictMode是开发者对app的性能测试工具,通过在app中调用相应的API,来针对性诊断,所以app调用StrictMode只应出现在程序的开发版中。而在android6.0StrictMode再次扩展,引入本文主题---检测app运行网络通信是否进行SSL/TLS数据加密,暂称为[non-SSL/TLSdetect]


[AOSP non-SSL/TLS detect]

如下是在android6.0中关于[non-SSL/TLSdetect]的全部扩展的改动代码,有兴趣可以了解一下,不过可能需要翻墙。涉及framework/native/sepolicy/iptable的lib,我们只重点关注netd的iptables rule那部分。

https://android-review.googlesource.com/#/q/message:18335678

Subject

Owner

Project

Updated

Fix a property name that's longer than 31 chars.

Narayan Kamath

platform/frameworks/base

Jan 17,2015

Offer to detect non-SSL/TLS network traffic.

Jeff Sharkey

platform/frameworks/base

Jan 16,2015

Offer to detect non-SSL/TLS network traffic.

Jeff Sharkey

platform/system/netd

Jan 16,2015

Extend to receive NFLOG packets.

Jeff Sharkey

platform/system/core

Jan 16,2015

Follow StrictMode refactoring.

Jeff Sharkey

platform/frameworks/native

Jan 16,2015

Expose nflog_send_config_cmd() for netd.

Jeff Sharkey

platform/external/libpcap

Jan 16,2015

Rules to let netd read packets from NFLOG target.

Jeff Sharkey

platform/external/sepolicy

Jan 16,2015


[non-SSL/TLS detect iptables rules]
涉及的module和ndc cmd如下:
netd
     └──
server
         
├── StrictController.cpp
         
└──
StrictController.h

Cmd

Args

strict

enable/disable

strict

set_uid_cleartext_policy<uid><accept|log|reject>

 strictmode在android6.0中是system ready后默认enable的,就部署文首列出的全部rules,但这些strictmode链(st_clear_detect/ st_clear_detect/st_penalty_reject/ st_penalty_log/ st_clear_caught)没有接入到数据包规则匹配流程中,所以不会工作。 也许你会问,既然non-SSL/TLS strictmode还没有开始工作,为什么先把部分iptables rules设置?其实这样设计的目的是,在真正在app需要non-SSL/TLS strictmode时再建立v4v6约30几条iptables花费时间较多,影响效率。全部链布局如下图:

 

 -N st_OUTPUT-N st_clear_caught-N st_clear_detect-N st_penalty_log-N st_penalty_reject-A OUTPUT -j st_OUTPUT 

新建st相关链,将st_OUPUT接到OUTPUT链上:

-A st_clear_detect-m connmark --mark 0x2000000/0x2000000 -j REJECT --reject-withicmp-port-unreachable-A st_clear_detect-m connmark --mark 0x1000000/0x1000000 -j RETURN-A st_clear_detect-p tcp -m u32 --u32"0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0xffff0000=0x16030000&&0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x4&0xff0000=0x10000"-j CONNMARK --set-xmark 0x1000000/0x1000000-A st_clear_detect-p udp -m u32 --u32"0x0>>0x16&0x3c@0x8&0xffff0000=0x16fe0000&&0x0>>0x16&0x3c@0x14&0xff0000=0x10000"-j CONNMARK --set-xmark 0x1000000/0x1000000-A st_clear_detect-m connmark --mark 0x1000000/0x1000000 -j RETURN-A st_clear_detect-p tcp -m state --state ESTABLISHED -m u32 --u32"0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0x0=0x0"-j st_clear_caught-A st_clear_detect-p udp -j st_clear_caught-A st_penalty_log-j CONNMARK --set-xmark 0x1000000/0x1000000-A st_penalty_log-j NFLOG-A st_penalty_reject -j CONNMARK --set-xmark 0x2000000/0x2000000-A st_penalty_reject -j NFLOG-A st_penalty_reject -j REJECT --reject-with icmp-port-unreachable 

 以上规则就是[non-SSL/TLS detect]的精髓了:

-A st_clear_detect -p tcp -m u32 --u32"0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0xffff0000=0x16030000&&0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x4&0xff0000=0x10000"-j CONNMARK --set-xmark 0x1000000/0x1000000

 这条rule通过使用iptablesU32扩展,检索ip数据报文中tcp报文段的SSL数据段在handshake协议过程中client_hello数据被置位,并标记整条socket链接为0x1000000/0x1000000。详细分解分析:

1-p tcp 针对tcp报文
2-m u32 –u32 "0x0 >> 0x16&0x3c@0xc >>0x1a&0x3c@0x0&0xffff0000=0x16030000&&0x0 >> 0x16&0x3c@0xc>> 0x1a&0x3c@0x4&0xff0000=0x10000"

简单的讲,u32 match就是一个算式,该算式是一个由&&拼起来的多个子match的集合,每一个子match可以理解成一个标准的iptables match比如-p udp--dport 1194之类的。每一个子match4个运算符可以用,分别是:
&
   :按位与操作。该操作可以过滤出一个IP数据报中我们需要的最多四个字节。
<<
:左移操作。该操作的含义和C语言一致。
>>
:右移操作。同上
@
   :向前推进操作。该操作允许你将匹配向前skip掉你不感兴趣的字节数

0x0 >> 0x16&0x3c

以上
ipv4包头的0x0字节处,共4字节,32位,右移>>0x16=22位,剩余的10位,位操作&0x3c=00111100,得到的是ip包中ip头长度字段IHL4倍,这里的4倍是为了后续按照IHL继续移位的便捷,IHL中记录的是ip报头长度是多少个字节,也就是Byte4倍,参考下图:(https://tools.ietf.org/rfc/rfc791.txt)


IHL@0xc >> 0x1a&0x3c

将上述的
IHL4倍作为相对偏移,加上绝对偏移0xc=12,取出32位,右移0x1a=26位,剩余6位,位操作&0x3c=00111100,得到tcp的数据偏移Data_Offset4倍数,参考下图:https://tools.ietf.org/rfc/rfc793.txt:




Data_Offset@0x0&0xffff0000=0x16030000
将上述的Data_Offset4作为相对偏移,0x0为绝对偏移,到达tcp包含的数据部分,取前32位,位操作&0xffff0000并判断是否=0x16030000。这里就是判断tcp报文data部分是否为SSL/TLS报文协议中的握手协议handshake(0x16)SSL_version0x03,参考TLSrfchttps://tools.ietf.org/rfc/rfc6101.txt中附录A:(具体的协议规范内容不再叙述)

 

&&0x0 >> 0x16&0x3c@0xc >>0x1a&0x3c@0x4&0xff0000=0x10000
并列的&&条件,同样0x0 >> 0x16&0x3c=IHL×4@0xc >> 0x1a&0x3c=Data_Offset×4,接下来0x4&0xff0000=0x10000,相对偏移4字节取32位,位操作&0xff0000判断是否=0x10000,这里检索的是SSL的握手协议中的client_hello是否置位。https://tools.ietf.org/rfc/rfc6101.txt

 

3-j CONNMARK --set-xmark 0x1000000/0x1000000
将该报文所在的整条连接做连接
0x1000000/0x1000000


[strictmode policy 用例]
上述的链关系和流程粗略理解是st_clear_detect链标价检测经过数据包所在链接是否SSL/TLS加密,捕获到未加密的packet定向到st_clear_caught,并根据上层的debug策略再次选路到st_penalty_logst_penalty_rejectreject为例子,在UID=10038apptrigernon-SSL/TLS detect】,流程如下,经过framework (ActivityMangeràNetworkManagementService)到达netd的命令为:

    “strict set_uid_cleartext_policy 10038 reject”


执行后,
iptable中新增加两条规则:

-A st_OUTPUT -m owner --uid-owner 10038 -jst_clear_detect-A st_clear_caught -m owner --uid-owner 10038 -jst_penalty_reject  

最终流程如下


 

参考:
strict mode
简介:http://jimpai.blogspot.tw/2012/02/androidstrictmode.html

iptablesCONNMARK的使用:http://blog.chinaunix.net/uid-10167808-id-26001.html

iptablesu32扩展的使用:http://blog.csdn.net/dog250/article/details/9258607

SSL体系结构:http://www.cnblogs.com/xuanhun/archive/2012/06/23/2559607.html

SSL v3 RFChttps://tools.ietf.org/rfc/rfc6101.txt

0 0