iOS自己动手篡改APP网络请求及简单防护

前言

在开始谈技术干货之前,先大概说一下这次公司APP安全风波的始末,甩锅的理由有三,其一:创业公司凡事讲究敏捷开发,快速迭代上线,因此在完成功能需求之余无暇他顾;其二:安全问题应该为技术总监着重考虑的一点,但是(按照惯例,这里省略N字,不可描述);其三:后台接口定义也没有考虑到这一点,然而,从不要随便甩锅的好习惯来说,我还是要负起责任的,毕竟自己是iOS负责人,要对APP有个全面的把握.

简单的讲下事情经过,就是突然有一天下午,一个用户打电话给客服说自己买了一张998元的机票买错了,想退票,要求公司给他取消订单退钱,然后还把支付宝的网页支付记录发了过来(后来证实是PS过的).然后财务部那边查账之后发现这个用户的支付宝账号确实付款了,但实际付款的只有1元,然后公司财务就把事情反馈给了副总,然后整个技术部就炸锅了,都在各抒己见分析这个1元钱是怎么通过APP付款到公司账户的,因为机票订单是没有1元的.而且APP和支付宝给后台的回调都是支付成功的.根据唯物主义思想来推断,支付宝出错的概率远小于我们APP出错的概率,而且后台也没有被攻入的迹象,因此就把问题锁定在APP上了,然后我们用的POST请求(一些人说比较安全,其实不加密的话,安全性和GET请求比起来相差无几),我们部门的首席科学家直接说APP肯定是被反编译了,原话是"我找我阿里的朋友帮忙,分分钟就把APP反编译了,然后随便下单."当时听了这话我是懵逼的,虽然从技术可操作性来说,存在反编译的可能,但是分分钟不费吹灰之力就反编译这种说法我是不太能接受的,然后就有了后边我自己攻击自己APP的举动.

正题

我的分析就是反编译太麻烦,不容易实施,而且即使反编译出来了,一个类名一个方法名的去解析APP也很累,所以就从相对好实施的篡改网络请求及返回数据下手!之前看过唐巧大神的一篇关于Charles的使用讲解,不过当时是用来简单的抓别人的包,用点数据就放下了,现在就拿来实践一下篡改数据这个功能,首先安装好Charles,然后按部就班的把Charles设置为自己mac电脑的代理,

img

然后手机连自己电脑wifi,或者跟电脑连接同一个wifi都可以,然后设置手机的代理,让你手机的网络请求都经过Charles,服务器里填写的是电脑的IP地址,
img
端口默认的就是8888:
img

这样就可以抓到APP跟服务器之间的网络请求了.然后在查看请求之后去使用篡改功能,这里就演示一下篡改一个页面的数据
img
这里的第一个票价是12500,下边是拦截到的请求
img
给这个IP地址对应的8080端口的请求都加上断点,点击那个Breakpoints,然后当下一次请求进来的时候,就可以直接篡改数据
img
篡改数据的步骤可以看下方的gif图:
img
之后点击"Execute",返回给APP数据,这样APP展示的页面就变成了:
img
到这里用户的骗术就被还原了,当然后边还需要篡改一些数据才能成功去下单支付这个1元订单,细节就不在赘述了
img
那个支付宝支付显示不全是因为iOS10字变宽了,当然支付成功之后的心情是很复杂的,毕竟自己的APP被这么轻易搞出问题了,大家可以设身处地想一下哈,后边重点来了,讲解一下小公司的解决方案.
因为开发压力比较大,所以要考虑性价比比较高的方案,这里就暂时舍弃了HTTPS,运用了实施起来相对简单的MD5加密,这里有两种情况,下载加密和上传加密,比如说刚才看到的订单列表就属于下载加密,要确保订单列表数据一旦被篡改就不去使用,而点击立即支付的下单动作就是上传加密,要确保传给服务器的下单参数一旦被篡改就不去使用,MD5加密的原理就不在这里讲了,因为我之前的文章JSPatch里已经讲过了,主要说一下具体的实施细节以及过程中遇到的小坑,首先是下载加密:
img

我用的网络请求是自己封装的AFN,然后这里设置一下直接字符串取值,不要转成JSON:manager.responseSerializer = [AFHTTPResponseSerializer serializer];
取出HTTP Header里的验证字串:
NSDictionary *headerDic = [operation.response allHeaderFields];
NSString *rsaValue = headerDic[@"rsaValue"];
然后取值:NSString *responseObjectStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
加密:NSString *md5Str = [NSString stringWithFormat:@"%@%@", responseObjectStr, md5SaltValue];
然后进行比对校验[[md5Str getMd5_32Bit] isEqualToString:headerDic[@"rsaValue"]]
然后是上传加密:
img

把所有参数转换为String:String *jsonString = [self.orderModel yy_modelToJSONString];
加密:NSString *md5Value = [[NSString stringWithFormat:@"%@%@",jsonString,md5SaltValue] getMd5_32Bit];
设置请求头:[manager.requestSerializer setValue:md5Value forHTTPHeaderField:@"rsaValue"];
到这里,这篇文章算是告一段落,后边应该会更新一系列安全相关的文章,不过需要一个我去学习然后理解然后实践的过程~下一篇是动手去反编译自己APP开始踩坑之旅.当然都是我自己的浅显青铜操作,欢迎同学们指点及大神们一笑而过.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,944评论 25 709
  • iOS安全攻与防 本地数据攻与防 https UIWebview 第三方sdk与xcode 反编译与代码混淆 越狱...
    天机否阅读 10,814评论 8 66
  • 我看书,这使我多活几度生命。 我写字,这使我免于说话。 我说话,这使我不必写字。 我赚钱,这使我证明能力。 我花钱...
    触角_阅读 156评论 0 0
  • 人的脑袋真是神奇的东西 每每有不一样的念头 昨天临摹的是一个简友的画 我轻轻的拿起它 走到一扇古门前 打开那扇封存...
    虚空中的兔子阅读 465评论 8 7
  • 钱,让多少相爱的人不能在一起 ! 钱,让多少原本不相爱的人睡在一起 ! 钱,让多少感情更加丰富! 钱,让多少感情走...
    正能量小贼喵阅读 1,393评论 0 1