有一款app需要分析其中请求数据的加密方法:
Fiddler设代理之后点击手机上的查询按钮开始抓包,看到只发送一个请求:
POST http://211.139.145.137/businessHsh/hshShop/account/accountOpen/getNumberList.jsps HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Cookie: JSESSIONID=0000LxW9a39tmaKqgwuuJCm-3T1:1ben3ht5m
User-Agent: Mozilla/5.0 (Linux; U; Android
8.1.0; zh-cn; EML-AL00 Build/HUAWEIEML-AL00) AppleWebKit/533.1 (KHTML,
like Gecko) Version/5.0 Mobile Safari/533.1
Content-Length: 695
Host: 211.139.145.137
p1=7256465744706379706a6f6f4976466f396f6343676473334e394f47666c7a5547503465517667714142766c63564741376c4d706246323676314f584f6172575948676b6c46566437656d416b2f4d57554f4b454661754a6a3855486e586c2f41714e4b3350386c4d6a793269464f775575644c7064646531444253677671673932557165475452502f7a513736646f4144317767343042473563504d6d4c78464859534759727534376f3d&p0=56494a50476a706b45724e5a6332315979314e786b3170776c6e66514d4174384a73662b394a664779664d584244706134305666774e423438464368516b4f535532732f56463046344c796b38552b59765839794d61647572614267454b2f334e426a6d64652b7961362f4954472f67434367426d397759446665674c756958565641724a647752535446314c4f30796a30305975587267445779786374476a7852626956744f4c70486b3d
响应的内容为:
HTTP/1.1 200 OK
Date: Fri, 10 Aug 2018 09:48:32 GMT
X-Powered-By: Servlet/3.0
Cache-Control: no-cache
Keep-Alive: timeout=10, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/x-json;charset=UTF-8
Content-Language: zh-CN
X-Pad: avoid browser bug
180
48626e5a44413562425247374c503578554d6a6c702f34387771374573443135515948324f4c4d613172395643703134574d49737436746b5442362b717443674a534a61516a74527a30623367646164484255696e476166726864554f72566f4d66464a526a4b356850365973336275743356694d78413259314d68526d5370466a5254434a6a62706c397a544c745366617877353442566972676b4c7355454458592b6e32326b67392f6b646a632f477173736f37676e6c6b545571524454
0
第一眼就能认出这是十六进制显示的,用winhex将他们复原。
P1 =
rVFWDpcypjooIvFo9ocCgds3N9OGflzUGP4eQvgqABvlcVGA7lMpbF26v1OXOarWYHgklFVd7emAk/MWUOKEFauJj8UHnXl/AqNK3P8lMjy2iFOwUudLpdde1DBSgvqg92UqeGTRP/zQ76doAD1wg40BG5cPMmLxFHYSGYru47o=
P0 =
VIJPGjpkErNZc21Yy1Nxk1pwlnfQMAt8Jsf+9JfGyfMXBDpa40VfwNB48FChQkOSU2s/VF0F4Lyk8U+YvX9yMaduraBgEK/3NBjmde+ya6/ITG/gCCgBm9wYDfegLuiXVVArJdwRSTF1LO0yj00YuXrgDWyxctGjxRbiVtOLpHk=
响应数据:
HbnZDA5bBRG7LP5xUMjlp/48wq7EsD15QYH2OLMa1r9VCp14WMIst6tkTB6+qtCgJSJaQjtRz0b3gdadHBUinGafrhdUOrVoMfFJRjK5hP6Ys3but3ViMxA2Y1MhRmSpFjRTCJjbpl9zTLtSfaxw54BVirgkLsUEDXY+n22kg9/kdjc/Gqsso7gnlkTUqRDT
看来请求和响应的数据都经过了加密处理。
Step2:
将apk取出来开始分析。
Apk解压之后
很明显是用了腾讯加壳,用dex2oat的方法脱壳,脱出来之后有三个dex文件,
将他们反编译之后用jd-gui查看,再整个文件中搜索关键字getNumberList,嗯,貌似没啥很大帮助,再搜索关键字”p0”,终于在com.app.jaf.nohttp的f文件中的onPreExecute里找到重要的信息
点进去查看h.a(str1, this.k);这个函数
发现是一段des加密函数,他的两个参数str1和this.k应该就是明文和密钥。
继续往上看发现密钥private String k = UUID.randomUUID().toString().substring(0, 8);是通过uuid随机生成的。
到此为止基本上看到了一点希望,如何知道明文是什么,可以继续静态查看,但是看了半天感觉很复杂,就想通过动态调试来获取。
Step3:
用idea新建工程,找到刚才分析的地方,在这里下断点:
打开ddms找到相关进程
在idea中新建一个remote:
开始运行程序。可以看到程序真的在断点位置停了下来,说明刚开始猜想的是对的。
查看寄存器中的值
可以看到需要加密的串:
JSON=1&V=A57&maxprice=10000&pattern=138________&minprice=0&token******。。。商业机密,后面不展示
参数里包含时间戳,那个pattern就是我们序号的前三位,那个token应该是登录信息。
至此p0这个值就搞定了。
Step4:
准备用相同的方法去调试p0的时候,idea出了问题,寄存器里的值无法查看。
尝试几次之后现象均相同,刚开始以为是idea版本过低造成的,将版本升到最新,发现更狗血的事情发生了,一个断点都下不了,一直提示行号不对,最后没办法又卸载了重新安装之前的版本。既然p1的值无法动态调试,只能采取hook和静态分析两种方法了,最终还是用静态方法查看。
P1的值先经过MD5算出来,取md5值得8-24位,再和@还有des加密的key组合起来,最后经过RSA的公钥加密发出去,公钥在
这个文件中可以看得到
这中间的坑特别多,一个字符弄错结果就不对。搞了2天才搞出来。
有三个坑:
des加密完之后要把\r\n去掉。
md5加密的内容不是des加密后的内容,还需要转成十六进制再进行md5
RSA同一个公钥每次加密的内容都不一样,核对起来比较麻烦。
Step5:
通过上面分析可以知道把要发送的内容和密钥经过RSA传给服务器,服务器那边用md5核对发送的内容,再用des的key将响应的内容返回回来,所以response的内容解密很容易,des解密即可。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!