转载

外卖O2O App安全性分析:App漏洞评估平台技术细节

0×00、业务需求

在移动互联网和O2O大潮的席卷下,外卖市场逐渐进入的白领的视野,在BAT三巨头砸钱培育市场的情况下,白领的已经更改就餐习惯。只要是坐班的小白领基本上不会到周边商圈购物中心进餐的习惯。外加这个夏天比较热。

根据权威数据分析:

外卖O2O App安全性分析:App漏洞评估平台技术细节

那么,这个市场到底有多大,目前,根据媒体披露,美团外卖2015年上半年业绩:42.5亿。如果按照1/4市场计算,那么,外卖市场有200亿RMB。 怪不得BAT要抢占这块市场,当然分析用户的饮食习惯也是他们的另外一个目的。

然后,我们再看看中国外卖O2O鼻祖饿了么融资情况。

外卖O2O App安全性分析:App漏洞评估平台技术细节

2015年8月份占市场份额为38.75%,累计投资大约10亿美金。

那么,我们关心的是,这么大笔投资,真正使用在IT基础设施建设上面和业务系统搭建的投入是多少?业务系统搭建中,具体的安全投入是多少?如果按照涉及到IT基础设施业务系统搭建占比1%(总投资额计算),安全投入咱以上IT投资的1%的话,那就是安全相当10万美金的投入。

但是,如果你是一个极客,当然是想通过客户端漏洞用Scrapy 爬出大约每天多少单,每单赚多少钱。存储到Mongodb中,然后使用python脚本写大数据报告,用数据说话麽,大家都信,呵呵。

那么基于业务系统App安全评估如何具体做呢?下面着重描述一下。

0×01、App评估方法论

其实网上有很多方法论的东西,这里我站在自由测评人的角度上分析。

首先确定只对Android App APK进行分析,因为Android系统比较开放,模拟器比较多,业务逻辑ipa和Apk是一样的。

在网络上在线评估网站比比皆是,其实其App漏洞评估平台技术都差不多。

外卖O2O App安全性分析:App漏洞评估平台技术细节

一个Android程序上传后首先要判断其是否可以反编译。如果可以,那么就能分析到更多的数据,包括java写的源代码。

那么怎么判断是是否可以被反编译呢?其实可以通过多种方式实施,静态分析是最直接有效的办法,它主要是利用 apktol、dex2jar、jd-gui、smali2dex 等静态分析工具对应用进行反编译,并对反编译后的 java 文件、xml 文件等文件进行静态扫描分析

具体流程图如下:

外卖O2O App安全性分析:App漏洞评估平台技术细节

当然,如果反静态编译失败,就需要动态分析的方法。动态分析技术是对应用软件安装、运行过程的行为监测和分析。检测的方式使用虚拟机方式通过建立与Android手机终端软件运行环境几乎一样的虚拟执行环境,手机应用软件在其中独立运行,从外界观察应用程序的执行过程和动态,进而记录应用程序可能表现出来的恶意行为。

最后,在通过虚拟机分析线上App程序的时候,可能会遇到模拟器检查、root检测等或者IMEI标识判断等高级防调试的功能,这时候就需要人工去分析,也就是说在真实Android手机上安装App进行实地的安全评估。

那么,下面我们以到家美食汇App作为安全评估对象进行评估:

(1)是否被反编译

测试方法使用含有Apktool开源软件的发编译IDE工具测试,Android killer/ ApkIDE改之理 。本文使用Android killer。

外卖O2O App安全性分析:App漏洞评估平台技术细节

从这张图可以看出apk被编译成smali(java虚拟机文件)然后又被反编译成Java class的源代码。

(2)内置组件和外部第三方SDK评估

通过java Decompiler查看源代码发现:

2.1、内置组件:

Com.alibaba.fastjson 阿里巴巴开源高性能JSON开发包 com.android.volley  Android官方通信框架Volley com.nostra13.universalimageloader 开源 图片库加载。 com.sina.sso 新浪微博登陆SSO组件 com.squareup.okhttp 高效http客户端 (网络拥堵) okio 开源基本工具库

使用开源组件包,好处是可以提高开发效率,但是如果是开源组件安全性令人担忧,但是目前为止漏洞库中还没有以上组件安全问题。这时不时的让我想起来去年的AFNetworking组件当时引发的中间人攻击的案例。

2.2、第三方SDK组件

com.baidu.mapapi 百度地图 com.baidu.android.pushservice 百度消息推送服务 com.google.analytics google分析API让我们知道用户如何与我们的应用进行交互 com.tencent 访问腾讯openapi 认证等功能 com.umeng.analytics 应用统计分析

那么,外包第三方组件主要搜索重点是APPKey等,可能被黑客利用:

友盟:

<meta-data android:name="UMENG_APPKEY" android:value="528187ac56240bee3803bc39" /> <meta-data android:name="UMENG_CHANNEL" android:value="daojiaweb" />

百度推送:可以获取到推送服务key值以及推送消息等信息,通过修改源码,使开发商利益受到损失。

<service android:name="com.baidu.android.pushservice.CommandService" android:exported="true" /> <meta-data android:name="api_key" android:value="2qoGQfsfg5CcB9cU9PXHNBGX" />

百度地图:

<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="jGY5Ft6EuDv9gKWT9dg51UOl" />

(3)不安全的数据存储

3.1、SharedPreferences

首先检查的是SharedPreferences,这是一个可以全局访问的数据结构。经过源码查找发现。

但是,到家使用了混淆类处理:ObscuredSharedPreferences,这个类有对SharedPreferences的加解密函数,但是在源代码被反编译后,没有任何保护力度,黑客可以直接拿解密函数破解其加密数据

public class ObscuredSharedPreferences   implements SharedPreferences {   private static final char[] SEKRIT = { 23, 45, 79, 65, 98, 21, 13, 18, 64, 28 };   protected static final String UTF8 = "utf-8";   protected Context context;   protected SharedPreferences delegate;     protected String decrypt(String paramString)   {     if (paramString != null) {}     for (;;)     {       try       {         arrayOfByte = Base64.decode(paramString, 0);         SecretKey localSecretKey =  SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new  PBEKeySpec(SEKRIT)); // 使用java相关加密算法解密,秘钥是SEKRIT         Cipher localCipher = Cipher.getInstance("PBEWithMD5AndDES");         localCipher.init(2, localSecretKey, new  PBEParameterSpec(Settings.Secure.getString(this.context.getContentResolver(),  "android_id").getBytes("utf-8"), 20)); //UTF-8编码         return new String(localCipher.doFinal(arrayOfByte), "utf-8");       }       catch (Exception localException)       {         byte[] arrayOfByte;         throw new RuntimeException(localException);       }       arrayOfByte = new byte[0];     }   }       protected String encrypt(String paramString)   {     if (paramString != null) {}     for (;;)     {       try       {         arrayOfByte = paramString.getBytes("utf-8");         SecretKey localSecretKey =  SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new  PBEKeySpec(SEKRIT)); // 使用java相关加密算法加密,秘钥是SEKRIT         Cipher localCipher = Cipher.getInstance("PBEWithMD5AndDES");         localCipher.init(1, localSecretKey, new  PBEParameterSpec(Settings.Secure.getString(this.context.getContentResolver(),  "android_id").getBytes("utf-8"), 20)); //UTF-8编码         return new String(Base64.encode(localCipher.doFinal(arrayOfByte), 2), "utf-8");       }       catch (Exception localException)       {         byte[] arrayOfByte;         throw new RuntimeException(localException);       }       arrayOfByte = new byte[0];     }   }

3.2、ContentProvider

ContentProvider是android组件之一,可以提供数据的跨应用程序访问,针对其搜索关键字为:ContentResolver。因为这个函数是解析ContentProvider存储的数据的。

外卖O2O App安全性分析:App漏洞评估平台技术细节

但是里面没有什么有价值的数据,pass.

3.3、sqlite

所有的Android数据存储都是使用轻量级的sqlite数据库,在源码中有很多地方都能找到,我就不一一列举了。 同样也没什么有价值的数据 pass.

(4)敏感信息安全评估

4.1、敏感信息检测>>获取设备信息

该app中使用了获取设备信息的权限,窃取用户隐私。

DaojiaApp: {  Utils.initSomeThing(); //获取GPS数据  Globals.instance().currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; //获取App程序版本  Globals.instance().manufacturer = Build.MANUFACTURER; //Build.MANUFACTURER // 硬件制造商      Globals.instance().model = Build.MODEL; // Build.MODEL // 版本    Globals.instance().os_version = Build.VERSION.RELEASE;   //获取android系统的版本信息->版本字符串   Build.VERSION.RELEASE   WifiInfo localWifiInfo = ((WifiManager)getSystemService("wifi")).getConnectionInfo();  Globals.instance().mac = localWifiInfo.getMacAddress();  //获取wifi MAC地址  TelephonyManager localTelephonyManager = (TelephonyManager)getSystemService("phone"); //获得手机号  Globals.instance().imei = localTelephonyManager.getDeviceId(); //获取IMEI  DisplayMetrics localDisplayMetrics = new DisplayMetrics(); //屏幕大小  getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);  Globals.instance().w = localDisplayMetrics.widthPixels;  Globals.instance().h = localDisplayMetrics.heightPixels;  Globals.instance().resolution = (localDisplayMetrics.widthPixels + "_" + localDisplayMetrics.heightPixels);  ObscuredSharedPreferences localObscuredSharedPreferences = new  ObscuredSharedPreferences(this, getSharedPreferences("daojia", 0));  if (localObscuredSharedPreferences.getInt("CityID", 0) != 0) {    Globals.instance().cityID = localObscuredSharedPreferences.getInt("CityID", 0);     } 

4.2、敏感信息检测>>App服务器地址

外卖O2O App安全性分析:App漏洞评估平台技术细节

后来通过http抓包发现,这个地址只是一个获取服务器地址的中间环节,真正的服务器地址是在这个地址中存储,并且检测其连接App的属性。

4.3、敏感信息检测>>字符串初始化检测

//针对服务器提交的翻译命令   public static final String DELETEHISTORYADDRESSREQUEST = "DeleteHistoryAddress";   public static final String DELETEHISTORYORDERREQUEST = "DeleteHistoryOrder";   public static final String DOACTIVEUSER = "DoActiveUser";   public static final String DOCOMPLAINTREQUEST = "DoComplaint";   public static final String DOLOGINREQUEST = "DoLogin";   public static final String DOLOGOUT = "DoLogout";   public static final String DOREGISTERREQUEST = "DoRegister";   public static final String DOREGISTERREQUESTRESP = "DoRegisterResp";   public static final String DOURGENTREQUEST = "DoUrgent";   public static final String GETADVERTISELISTREQUEST = "GetAdvertiseList";   public static final String GETAREAANNOUNCEMENTLISTREQUEST = "GetAreaAnnouncementList";   public static final String GETAREALISTREQUEST = "GetAreaList";   public static final String GETAUTHORIZATIONCODEREQUEST = "GetAuthorizationCode";   public static final String GETCARDLISTSREQUEST = "GetCardList";   public static final String GETCITYLISTREQUEST = "GetCityList";   public static final String GETCOUPONLISTREQUEST = "GetCouponList";   public static final String GETFOODCATAGORYLISTREQUEST = "GetFoodCatagoryList";   public static final String GETFOODLISTREQUEST = "GetFoodList";   public static final String GETHISTORYADDRESSREQUEST = "GetHistoryAddress";   public static final String GETHISTORYORDERLISTREQUEST = "GetHistoryOrderList";   public static final String GETHISTORYRESTAURANTLISTREQUEST = "GetHistoryRestaurantList";   public static final String GETHOTFOODLISTREQUEST = "GetHotFoodList";   public static final String GETORDERDETAILSREQUEST = "GetOrderDetails";   public static final String GETPROFILEREQUEST = "GetProfile";   public static final String GETPROFILEREQUESTRESP = "GetProfileResp";   public static final String GETRESTAURANTCATAGORYLISTREQUEST = "GetRestaurantCatagoryList";   public static final String GETRESTAURANTLISTREQUEST = "GetRestaurantList";   public static final String GETRESTAURANTMESSAGELISTREQUEST = "GetRestaurantMessageList";   public static final String GETTODAYORDERLISTREQUEST = "GetTodayOrderList";

4.4、敏感信息检测>>密码管理

登陆密码保存使用ObscuredSharedPreferences同样的数据密码加密形式。

private void doLogin()   {     if (Upgrade.hasUpgrade(this.frameActivity)) {       return;     }     new Server(this.frameActivity, getResources().getString(2131034313))     {       protected Integer doInBackground(String… paramAnonymousVarArgs)       {         ArrayList localArrayList1 = new ArrayList();         localArrayList1.add("DoLogin");         int i = Globals.instance().interactWithServer(localArrayList1, null, null);         if (i != 0) {           return Integer.valueOf(i);         }         ArrayList localArrayList2 = new ArrayList();         localArrayList2.add("GetHistoryAddress");         localArrayList2.add("GetProfile");         localArrayList2.add("GetCardList");         return Integer.valueOf(Globals.instance().interactWithServer(localArrayList2, null, null));       }             protected void onPostExecute(Integer paramAnonymousInteger)       {         super.onPostExecute(paramAnonymousInteger);         if (paramAnonymousInteger.intValue() != 0)         {           Globals.instance().isLogined = false;           SharedPreferences.Editor localEditor = DaojiaApplication.getInstance().getSharedPreferences("token", 0).edit();           localEditor.putString("terminalToken", "");           localEditor.commit();           EditText localEditText1 = Login.this.accountEditText;           Globals.instance().mobile = "";           localEditText1.setText("");           EditText localEditText2 = Login.this.passwordEditText;           Globals.instance().passwd = "";           localEditText2.setText("");           new  AlertDialog.Builder(Login.this.frameActivity).setMessage(Globals.instance().error(paramAnonymousInteger.intValue(),   Login.this.frameActivity.getResources())).setNegativeButton(Login.this.frameActivity.getResources().getString(2131034125),  null).show().setCanceledOnTouchOutside(false);           return;         }         ObscuredSharedPreferences localObscuredSharedPreferences =  new ObscuredSharedPreferences(Login.this.frameActivity,  Login.this.frameActivity.getSharedPreferences("daojia", 0));         localObscuredSharedPreferences.edit().putString("Account", Globals.instance().mobile).commit();         localObscuredSharedPreferences.edit().putString("Passwd",  Globals.instance().passwd).commit(); //直接使用ObscuredSharedPreferences  加密方式处理         Globals.instance().isStroll = false;         int i = Globals.instance().todayOrderTotal;         if (i != 0) {           Login.this.frameActivity.tabActivity.showBadge(1, i);         }         for (;;)         {           EasyTracker localEasyTracker = EasyTracker.getInstance(Login.this.frameActivity);           localEasyTracker.set("&cd", "登录成功");           localEasyTracker.set(Fields.customDimension(1), "Yes");           localEasyTracker.send(MapBuilder.createAppView().build());           try           {             Login.this.frameActivity.getSupportFragmentManager().popBackStack();             return;           }           catch (Exception localException)           {             Login.this.isBack = true;             return;           }           Login.this.frameActivity.tabActivity.hideBadge(1);         }       }     }.execute(new String[] { "" });   }

(5)HTTP(s)分析

测试方法,在Android手机,安装到家美食汇App,然后手机上安装Fiddler证书,设置wifi代理获取http(s)数据流量

5.1、登录数据分析

Json值完全没加密

外卖O2O App安全性分析:App漏洞评估平台技术细节

建议在使用工具分析HTTP(s)的数据时,如果可以反编译java源代码的话,就可以更直观的了解其整个登录流程。

由于登录源代码在以上密码分析部分已经说过,这次看注册函数:

在daojia.fragment.Register 下,onClick动作下面。

同时,还发现在输入内容上没有做任何过滤,有SQL injection的风险。

public void onClick(View paramView) {   if (paramView.getId() == 2131492865)   {     localView = this.frameActivity.getWindow().getCurrentFocus();     if (localView != null) {       ((InputMethodManager)this.frameActivity.getSystemService("input_method")).hideSoftInputFromWindow(localView.getWindowToken(), 0);     }     this.frameActivity.getSupportFragmentManager().popBackStack();   }   while (paramView.getId() != 2131492906)   {     View localView;     return;   }   if ((this.linkman1EditText.getText().toString().trim().length() == 0) && (this.linkman2EditText.getText().toString().trim().length() == 0))   {     new AlertDialog.Builder(this.frameActivity).setMessage(getResources().getString(2131034159)).setPositiveButton(getResources().getString(2131034125), null).show().setCanceledOnTouchOutside(false);     return;   }   if (this.mobileEditText.length() == 0)   {     new AlertDialog.Builder(this.frameActivity).setMessage(getResources().getString(2131034160)).setPositiveButton(getResources().getString(2131034125), null).show().setCanceledOnTouchOutside(false);     return;   }   if (!this.mobileEditText.getText().toString().matches("^1[3,4,5,8,7]//d{9}$"))   {     new AlertDialog.Builder(this.frameActivity).setMessage(getResources().getString(2131034161)).setPositiveButton(getResources().getString(2131034125), null).show().setCanceledOnTouchOutside(false);     return;   }   if (this.passwdEditText.length() == 0)   {     new AlertDialog.Builder(this.frameActivity).setMessage(getResources().getString(2131034162)).setPositiveButton(getResources().getString(2131034125), null).show().setCanceledOnTouchOutside(false);     return;   }   if (this.passwdEditText.length() < 6)   {     new AlertDialog.Builder(this.frameActivity).setMessage(getResources().getString(2131034163)).setPositiveButton(getResources().getString(2131034125), null).show().setCanceledOnTouchOutside(false);     return;   }   if (this.passwdEditText.getText().toString().compareTo(this.confirmEditText.getText().toString()) != 0)   {     new AlertDialog.Builder(this.frameActivity).setMessage(getResources().getString(2131034164)).setPositiveButton(getResources().getString(2131034125), null).show().setCanceledOnTouchOutside(false);     return;   }   MobclickAgent.onEvent(this.frameActivity, "Step2ForRegistration");   Log.e("main", "step2ForRegistration");   Globals.instance().mobile = this.mobileEditText.getText().toString();   doGetCode(); }   public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) {   super.onCreateView(paramLayoutInflater, paramViewGroup, paramBundle);   this.rootLayout = ((ViewGroup)paramLayoutInflater.inflate(2130903096, paramViewGroup, false));   this.linkman1EditText = ((EditText)this.rootLayout.findViewById(2131492984));   this.linkman1EditText.addTextChangedListener(this);   this.linkman2EditText = ((EditText)this.rootLayout.findViewById(2131492985));   this.linkman2EditText.addTextChangedListener(this);   ((InputMethodManager)this.frameActivity.getSystemService("input_method")).toggleSoftInput(2, 0);   this.mobileEditText = ((EditText)this.rootLayout.findViewById(2131493014));   this.passwdEditText = ((EditText)this.rootLayout.findViewById(2131492994));   this.confirmEditText = ((EditText)this.rootLayout.findViewById(2131493035));   ((TextView)this.rootLayout.findViewById(2131492866)).setText(2131034143);   ImageView localImageView = (ImageView)this.rootLayout.findViewById(2131492865);   localImageView.setVisibility(0);   localImageView.setOnClickListener(this);   ((Button)this.rootLayout.findViewById(2131492906)).setOnClickListener(this);   return this.rootLayout; } 

5.2、下单业务流程

Json没加密是不是就可以刷单了,或者篡改数据了?

外卖O2O App安全性分析:App漏洞评估平台技术细节

5.3、重放攻击

这个问题,先在这里说明一下,如果要抵制App重放攻击,需要在每个请求包总添加包序列号,每次提交自动加一,如果收到的包相同就认为是重放攻击。目前到家美食汇App是做到的,虽然没有后台的源程序,但是从客户端源代码(com.daojia.ds)中可以发现:

private int getUrl()   {     Object localObject1 = "";     for (;;)     {       int j;       try       {         JSONObject localJSONObject1 = new JSONObject();         try         {           localJSONObject1.put("Command", "LookupServer");           localJSONObject1.put("SequenceID", "0");           localJSONObject1.put("CheckDigit", "0");           JSONObject localJSONObject3 = new JSONObject();           localJSONObject3.put("CityID", this.cityID);           localJSONObject1.put("Body", localJSONObject3);           JSONArray localJSONArray3 = new JSONArray();           localJSONArray3.put(localJSONObject1);           String str3 = localJSONArray3.toString();           localObject1 = str3;         }         catch (JSONException localJSONException)         { ***  continue;         }         localHttpPost = new HttpPost(DAOJIASERVER);         Log.e("afei", "request body is ===" + (String)localObject1);         localStringEntity = new StringEntity((String)localObject1, "UTF-8");         localStringEntity.setContentType("application/x-www-form-urlencoded");         localHttpPost.setEntity(localStringEntity);         localHttpPost.addHeader("Accept-Encoding", "gzip, deflate");         List localList = ((BasicCookieStore)this.localContext.getAttribute("http.cookie-store")).getCookies();         bool = localList.isEmpty();         int i = 0;         int k;         StringBuilder localStringBuilder;         String str2;         JSONArray localJSONArray1;         if (!bool)         {           k = 0;           if (k < localList.size()) {}         }         else         {           if (i == 0)           {             str1 = DaojiaApplication.getInstance().getSharedPreferences("token", 0).getString("terminalToken", "");             if (!TextUtils.isEmpty(str1)) {               localHttpPost.addHeader("Cookie", "token=" + str1 + ";");             }           }           localHttpResponse = this.httpClient.execute(localHttpPost, this.localContext);           localHttpEntity = localHttpResponse.getEntity();           localObject2 = localHttpResponse.getEntity().getContent();           localHeader = localHttpResponse.getFirstHeader("Content-Encoding");           if ((localHeader != null) && (localHeader.getValue().equalsIgnoreCase("gzip"))) {             localObject2 = new GZIPInputStream((InputStream)localObject2);           }           localInputStreamReader = new InputStreamReader((InputStream)localObject2);           localBufferedReader = new BufferedReader(localInputStreamReader, 8192);           localStringBuilder = new StringBuilder();           str2 = localBufferedReader.readLine();           if (str2 != null) {             continue;           }           localHttpEntity.consumeContent();           localJSONArray1 = new JSONArray(localStringBuilder.toString());           j = 0;           if (j < localJSONArray1.length()) {             continue;           }           return -1;         }         if (((Cookie)localList.get(k)).toString().contains("token"))         {           i = 1;           break label640;           localStringBuilder.append(str2);           continue;         }         JSONObject localJSONObject2;         JSONArray localJSONArray2;         k++;       }       catch (Exception localException)       { ***         }         localJSONArray2 = localJSONObject2.getJSONArray("Servers");         Globals.instance().host0 = localJSONArray2.optString(0, "");         Globals.instance().host1 = localJSONArray2.optString(1, "");         Globals.instance().mapping = localJSONObject2.getString("Mapping");         if (getCityV(Globals.instance().mapping) == 0) {           LOOKUPS = Globals.instance().host0;         } else {           LOOKUPS = Globals.instance().host1;         }       }       catch (ConnectTimeoutException localConnectTimeoutException)       {         return -1;       }       label640:       continue;       label646:       j++;     }   }

(6)SQL injection分析

有关 App SQL注入的攻击测试方法可以参考

原理:就是用burpsuite 设置代理记录log文件,然后,狂点App上的界面,然后通过提交的post数据,进行sqlmap测试。

sqlmap -r "/root/desktop/daojia.txt" --threads=3 --risk=3 --level=3 --random-agent --time-sec=15 --timeout=15 --beep –dbs

外卖O2O App安全性分析:App漏洞评估平台技术细节

但是经过测试目前还没有注入漏洞。

(7)签名校验

签名作用

1.发送者的身份认证:由于开发商可能通过使用相同的 Package Name 来混淆替换已经安装的程序,以此保证签名不同的包不被替换。2.保证信息传输的完整性:签名对于包中的每个文件进行处理,以此确保包中内容不被替换。

PackageInfo packageInfo = getPackageManager().getPackageInfo(   "com.daojia.xxx", PackageManager.GET_SIGNATURES);   Signature[] signs = packageInfo.signatures;

使用关键字“PackageInfo”搜索。Signature 太多,第三方和开源组件基本上都有签名校验。

外卖O2O App安全性分析:App漏洞评估平台技术细节

主程序没有做签名校验,使用resign工具可以直接打包。。

最后,还是向大家介绍一下online检测工具。具有检测内容我就不在文章中列举了。大家可以自己上传看看,星多漏洞多。

外卖O2O App安全性分析:App漏洞评估平台技术细节

这里想向大家详细介绍一下Mobile security Framework,这个用python写的开源的评估程序,这个工具加快了App程序漏洞评估速度,当然,自动化的程序特别是开源的很容易被App厂商和谐掉,还是要使用手工分析方法。或者是使用自动化分析工具先看看有什么详细漏洞,然后使用手工分析。

个人觉得MobSF在建立动态分析环境方面很快,本人通过翻墙才下载到ova虚拟化文件(oracle Virtualbox)。实现了动态分析,其实就是一个google android手机操作系统模拟器,通过python把各个手工测试工具连接起来做成自动化分析程序。

外卖O2O App安全性分析:App漏洞评估平台技术细节

外卖O2O App安全性分析:App漏洞评估平台技术细节

0×02、结论

经过检测发现美团外卖做的相对比较好,到家美食汇做的相对差一点。我想这和在安全上的投入有关系,在残酷的市场竞争环境下,首先要解决生存的问题,然后才能考虑安全的问题,当然了,如果你是互联网巨头BAT也会有先天的优势,安全性的研究会有N多NB人才立助你业务系统安全,对付开源检测工具还是绰绰有余的。那么对于创业掌门人的你,在App业务系统安全性问题上,你会选择传统互联网安全公司(爱加密、梆梆等)对你的业务系统做企业级的加固,还是建立自己SRC团队做安全运营?或者采用众测的形式花钱买漏洞?

* 作者:bt0sea,本文属FreeBuf原创奖励计划文章,未经许可禁止转载。

正文到此结束
Loading...