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

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

  0×00、业务需求

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

  根据权威数据分析:

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

外卖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漏洞评估平台技术

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

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

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

  具体流程图如下:

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

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

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

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

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

  (1)是否被反编译

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

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

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

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

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

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

  2.1、内置组件:

  ?

  1

  2

  3

  4

  5

  6Com.alibaba.fastjson 阿里巴巴开源高性能JSON开发包

  com.android.volley Android官方通信框架Volley

  com.nostra13.universalimageloader 开源 图片库加载。

  com.sina.sso 新浪微博登陆SSO组件

  com.squareup.okhttp 高效http客户端 (网络拥堵)

  okio 开源基本工具库

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

  2.2、第三方SDK组件

  ?

  1

  2

  3

  4

  5com.baidu.mapapi 百度地图

  com.baidu.android.pushservice 百度消息推送服务

  com.google.analytics google分析API让我们知道用户如何与我们的应用进行交互

  com.tencent 访问腾讯openapi 认证等功能

  com.umeng.analytics 应用统计分析

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

  友盟:

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

  百度地图:

  (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漏洞评估平台技术

外卖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漏洞评估平台技术

外卖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漏洞评估平台技术

外卖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漏洞评估平台技术

外卖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测试。

  ?

  1sqlmap -r “/root/desktop/daojia.txt” –threads=3 –risk=3 –level=3 –random-agent –time-sec=15 –timeout=15 –beep Cdbs

外卖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漏洞评估平台技术

外卖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团队做安全运营?或者采用众测的形式花钱买漏洞?

发表评论