parent
d713659b6b
commit
f5a7afdd85
@ -1,2 +1,158 @@ |
|||||||
# AppInfoScanner |
### AppInfoScanner |
||||||
|
|
||||||
一款适用于(Android、iOS、WEB、H5、静态网站),信息检索的工具,可以帮助渗透测试人员快速获取App或者WEB中的有用资产信息。 |
一款适用于(Android、iOS、WEB、H5、静态网站),信息检索的工具,可以帮助渗透测试人员快速获取App或者WEB中的有用资产信息。 |
||||||
|
|
||||||
|
### 适用场景 |
||||||
|
- 日常渗透测试中对APP中的URL地址、IP地址、关键信息进行采集 |
||||||
|
- 大型攻防演练场景中对APP中URL地址、IP地址、关键信息进行采集 |
||||||
|
- 对WEB网站源代码进行URL地址、IP地址、关键信息进行采集(可以是开源的代码也可以是右击网页源代码另存为) |
||||||
|
|
||||||
|
|
||||||
|
### 功能介绍: |
||||||
|
- 支持目录批量扫描 |
||||||
|
- 支持DEX、APK、IPA、HTML、JS、Smali等文件的静态资源采集 |
||||||
|
- 支持自定义扫描规则 |
||||||
|
- 支持IP地址信息采集 |
||||||
|
- 支持URL地址信息采集 |
||||||
|
- 支持中间件信息采集 |
||||||
|
- 支持多线程 |
||||||
|
- 支持忽略资源文件采集 |
||||||
|
- 支持Android包名采集 |
||||||
|
|
||||||
|
### 环境说明 |
||||||
|
|
||||||
|
- Apk文件解析需要使用JAVA环境,JAVA版本1.8及以下 |
||||||
|
- Python3的运行环境 |
||||||
|
|
||||||
|
### 目录说明 |
||||||
|
|
||||||
|
AppInfoScanner |
||||||
|
|-- libs 程序的核心代码 |
||||||
|
|-- core |
||||||
|
|-- parses.py 用于解析文件中的静态信息 |
||||||
|
|-- task |
||||||
|
|-- android_task.py 用于处理Android相关的文件 |
||||||
|
|-- ios_task.py 用于处理iOS相关的文件 |
||||||
|
|-- web_task.py 用于处理Web相关的文件,比如网页右键源代码、H5相关的静态信息 |
||||||
|
|-- tools 程序需要依赖的工具 |
||||||
|
|-- apktool.jar 用于反编译apk文件 |
||||||
|
|-- baksmali.jar 用于反编译dex文件 |
||||||
|
|-- strings.exe 用于windows 32下获取iPA的字符串信息 |
||||||
|
|-- strings64.exe 用于windows 64的系统获取iPA的字符串信息 |
||||||
|
|-- app.py 主运行程序 |
||||||
|
|-- config.py 用于自定义相关规则 |
||||||
|
|-- readme.md 程序使用说明 |
||||||
|
|
||||||
|
|
||||||
|
### Android 相关操作说明 |
||||||
|
|
||||||
|
#### 扫描指定的apk |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk file> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描指定的dex |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your dex file> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描一个目录下所有的APK或者dex |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk or dex directory> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描指定关键字(临时) |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk or dex directory> -r <the keyword> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描的时候忽略资源文件 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk or dex directory> -n |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描指定包下的内容 |
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk or dex directory> -p <package1.package2> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描所有的字符串 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk or dex directory> -a |
||||||
|
``` |
||||||
|
|
||||||
|
#### 指定线程数量 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py android -i <Your apk or dex directory> -t 10 |
||||||
|
``` |
||||||
|
|
||||||
|
### iOS 相关操作说明 |
||||||
|
|
||||||
|
#### 扫描指定的iPA文件 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py ios -i <Your ipa file> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描指定关键字(临时) |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py ios -i <Your ipa file> -r <the keyword> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描的时候忽略资源文件 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py ios -i <Your ipa file> -n |
||||||
|
``` |
||||||
|
|
||||||
|
#### 输出所有的字符串 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py ios -i <Your ipa file> -a |
||||||
|
``` |
||||||
|
|
||||||
|
#### 指定线程数量 |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py ios -i <Your ipa file> -t 10 |
||||||
|
``` |
||||||
|
|
||||||
|
### Web 相关操作说明 |
||||||
|
|
||||||
|
#### 扫描指定的Web网站目录或者html相关文件 |
||||||
|
``` |
||||||
|
python3 app.py web -i <Your website directory> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 扫描指定关键字(临时) |
||||||
|
|
||||||
|
``` |
||||||
|
python3 app.py web -i <Your website directory> -r <the keyword> |
||||||
|
``` |
||||||
|
|
||||||
|
#### 输出所有的字符串 |
||||||
|
``` |
||||||
|
python3 app.py web -i <Your website directory> -a |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
#### 指定线程数量 |
||||||
|
``` |
||||||
|
python3 app.py web -i <Your website directory> -t 10 |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
### 常见问题 |
||||||
|
|
||||||
|
- 1. 信息检索垃圾数据过多? |
||||||
|
|
||||||
|
> 方法1: 根据实际情况调整config.py中的规则信息 |
||||||
|
> 方法2: 忽略资源文件 |
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
@ -0,0 +1,68 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
||||||
|
|
||||||
|
|
||||||
|
# 此处用于搜索组件信息,如fastjson、gson等 |
||||||
|
filter_components = [ |
||||||
|
'com.alibaba.fastjson', |
||||||
|
'com.google.gson', |
||||||
|
'com.fasterxml.jackson', |
||||||
|
'net.sf.json' |
||||||
|
] |
||||||
|
|
||||||
|
# 此处目前支持过滤 |
||||||
|
# 1. https://以及http://开头的 |
||||||
|
# 2. IPv4的ip地址 |
||||||
|
# 3. URI地址 |
||||||
|
filter_strs =[ |
||||||
|
r'.*(http://.*)', |
||||||
|
r'.*(https://.*)', |
||||||
|
r'.*((?:[0-9]{1,3}\.){3}[0-9]{1,3}).*', |
||||||
|
# r'/[a-z0-9A-Z]+/.*' |
||||||
|
] |
||||||
|
|
||||||
|
# 过滤无用的内容 |
||||||
|
filter_no = [ |
||||||
|
u'127.0.0.1', |
||||||
|
u'0.0.0.0', |
||||||
|
u'localhost', |
||||||
|
u'http://schemas.android.com/apk/res/android', |
||||||
|
u"https://", |
||||||
|
u"http://", |
||||||
|
r"^http://www.w3.org" |
||||||
|
r"L.*/", |
||||||
|
r"/.*;", |
||||||
|
r"/.*<" |
||||||
|
] |
||||||
|
|
||||||
|
# 此处配置壳信息 |
||||||
|
shell_list =[ |
||||||
|
'com.stub.StubApp', |
||||||
|
's.h.e.l.l.S', |
||||||
|
'com.Kiwisec.KiwiSecApplication', |
||||||
|
'com.Kiwisec.ProxyApplication', |
||||||
|
'com.secshell.secData.ApplicationWrapper', |
||||||
|
'com.secneo.apkwrapper.ApplicationWrapper', |
||||||
|
'com.tencent.StubShell.TxAppEntry', |
||||||
|
'c.b.c.b', |
||||||
|
'MyWrapperProxyApplication', |
||||||
|
'cn.securitystack.stee.AppStub', |
||||||
|
'com.linchaolong.apktoolplus.jiagu.ProxyApplication', |
||||||
|
'com.coral.util.StubApplication', |
||||||
|
'com.mogosec.AppMgr' |
||||||
|
] |
||||||
|
|
||||||
|
# 此处配置需要扫描的web文件后缀 |
||||||
|
web_file_suffix =[ |
||||||
|
"html", |
||||||
|
"js", |
||||||
|
"html", |
||||||
|
"xml", |
||||||
|
"php", |
||||||
|
"jsp", |
||||||
|
"class", |
||||||
|
"asp", |
||||||
|
"aspx", |
||||||
|
"py" |
||||||
|
] |
@ -0,0 +1,3 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
@ -0,0 +1,81 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
||||||
|
|
||||||
|
import platform |
||||||
|
import os |
||||||
|
import shutil |
||||||
|
|
||||||
|
# smali 所在路径 |
||||||
|
smali_path = "" |
||||||
|
|
||||||
|
# backsmli 所在路径 |
||||||
|
backsmali_path = "" |
||||||
|
|
||||||
|
# apktool 所在路径 |
||||||
|
apktool_path = "" |
||||||
|
|
||||||
|
# 系统类型 |
||||||
|
os_type = "" |
||||||
|
|
||||||
|
# 输出路径 |
||||||
|
output_path = "" |
||||||
|
|
||||||
|
class Bootstrapper(object): |
||||||
|
|
||||||
|
def __init__(self, path): |
||||||
|
global smali_path |
||||||
|
global backsmali_path |
||||||
|
global apktool_path |
||||||
|
global os_type |
||||||
|
global output_path |
||||||
|
global script_root_dir |
||||||
|
global result_path |
||||||
|
global strings_path |
||||||
|
|
||||||
|
script_root_dir = os.path.dirname(os.path.abspath(path)) |
||||||
|
tools_dir = os.path.join(script_root_dir,"tools") |
||||||
|
|
||||||
|
if platform.system() == "Windows": |
||||||
|
machine2bits = {'AMD64':64, 'x86_64': 64, 'i386': 32, 'x86': 32} |
||||||
|
machine2bits.get(platform.machine()) |
||||||
|
|
||||||
|
if platform.machine() == 'i386' or platform.machine() == 'x86': |
||||||
|
strings_path = os.path.join(script_root_dir,"strings.exe") |
||||||
|
else: |
||||||
|
strings_path = os.path.join(script_root_dir,"strings64.exe") |
||||||
|
else: |
||||||
|
strings_path ="strings" |
||||||
|
# os_type = "win" |
||||||
|
# smali_str = "smali.bat" |
||||||
|
# back_smali_str = "backsmali.bat" |
||||||
|
# apktool_path_str = "apktool.bat" |
||||||
|
# elif platform.system() == "Linux": |
||||||
|
# os_type = "lin" |
||||||
|
# smali_str = "smali" |
||||||
|
# back_smali_str = "backsmali" |
||||||
|
# apktool_path_str = "apktool" |
||||||
|
# else: |
||||||
|
# os_type = "mac" |
||||||
|
# smali_str = "smali" |
||||||
|
|
||||||
|
|
||||||
|
# smali_path = os.path.join(tools_dir,str(os_type) + os.sep + smali_str) |
||||||
|
backsmali_path = os.path.join(tools_dir,"baksmali.jar") |
||||||
|
apktool_path = os.path.join(tools_dir, "apktool.jar") |
||||||
|
output_path = os.path.join(script_root_dir,"out") |
||||||
|
result_path = os.path.join(script_root_dir,"result.txt") |
||||||
|
|
||||||
|
def init(self): |
||||||
|
if os.path.exists(output_path): |
||||||
|
shutil.rmtree(output_path) |
||||||
|
os.makedirs(output_path) |
||||||
|
|
||||||
|
if os.path.exists(result_path): |
||||||
|
os.remove(result_path) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
||||||
|
|
||||||
|
|
||||||
|
import threading |
||||||
|
import config |
||||||
|
import re |
||||||
|
import os |
||||||
|
import libs.core as cores |
||||||
|
|
||||||
|
class ParsesThreads(threading.Thread): |
||||||
|
|
||||||
|
def __init__(self,threadID,name,file_queue,all,result_dict): |
||||||
|
threading.Thread.__init__(self) |
||||||
|
self.file_queue = file_queue |
||||||
|
self.name = name |
||||||
|
self.threadID = threadID |
||||||
|
self.result_list = [] |
||||||
|
self.all = all |
||||||
|
self.result_dict=result_dict |
||||||
|
|
||||||
|
def __regular_parse__(self,threadLock): |
||||||
|
while True: |
||||||
|
try: |
||||||
|
file_path = self.file_queue.get(timeout = 5) |
||||||
|
scan_str = ("Scan file : %s" % file_path) |
||||||
|
print(scan_str) |
||||||
|
|
||||||
|
try: |
||||||
|
os.path.basename(file_path).split(".")[1] |
||||||
|
except Exception as e: |
||||||
|
self.__get_string__(file_path,threadLock) |
||||||
|
continue |
||||||
|
self.__file_parse__(file_path,threadLock) |
||||||
|
|
||||||
|
result_set = set(self.result_list) |
||||||
|
if len(result_set) !=0: |
||||||
|
self.result_dict[file_path] = result_set |
||||||
|
|
||||||
|
if self.file_queue.empty(): |
||||||
|
break |
||||||
|
except Exception as e: |
||||||
|
break |
||||||
|
|
||||||
|
def __file_parse__(self,file_path,threadLock): |
||||||
|
with open(file_path,"r",encoding="utf8") as file : |
||||||
|
file_content = file.read() |
||||||
|
# 获取到所有的字符串 |
||||||
|
pattern = re.compile(r'\"(.*?)\"') |
||||||
|
results = pattern.findall(file_content) |
||||||
|
|
||||||
|
# 遍历所有的字符串 |
||||||
|
for result in set(results): |
||||||
|
self.__parse_string__(result,threadLock) |
||||||
|
|
||||||
|
def __get_string__(self,dir_file_path,threadLock): |
||||||
|
temp = os.path.join(cores.output_path,"temp.txt") |
||||||
|
cmd_str = ("%s %s > %s") % (cores.strings_path,dir_file_path,temp) |
||||||
|
if os.system(cmd_str) == 0: |
||||||
|
with open(temp,"r") as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
self.__parse_string__(line,threadLock) |
||||||
|
|
||||||
|
def __parse_string__(self,result,threadLock): |
||||||
|
# 通过正则筛选需要过滤的字符串 |
||||||
|
for filter_str in config.filter_strs: |
||||||
|
filter_str_pat = re.compile(filter_str) |
||||||
|
filter_resl = filter_str_pat.findall(result) |
||||||
|
# print(filter_resl) |
||||||
|
# 过滤掉未搜索到的内容 |
||||||
|
if len(filter_resl)!=0: |
||||||
|
# 提取第一个字符 |
||||||
|
resl_str = filter_resl[0] |
||||||
|
# 过滤 |
||||||
|
if self.__filter__(resl_str) == 0: |
||||||
|
continue |
||||||
|
|
||||||
|
threadLock.acquire() |
||||||
|
self.result_list.append(filter_resl[0]) |
||||||
|
threadLock.release() |
||||||
|
continue |
||||||
|
|
||||||
|
def __filter__(self,resl_str): |
||||||
|
resl_str = resl_str.replace("\r","").replace("\n","").replace(" ","") |
||||||
|
if len(resl_str) == 0: |
||||||
|
return 0 |
||||||
|
|
||||||
|
for filte in config.filter_no: |
||||||
|
resl_str = resl_str.replace(filte,"") |
||||||
|
if len(resl_str) == 0: |
||||||
|
return 0 |
||||||
|
|
||||||
|
if re.match(filte,resl_str): |
||||||
|
return 0 |
||||||
|
return 1 |
||||||
|
|
||||||
|
def run(self): |
||||||
|
threadLock = threading.Lock() |
||||||
|
self.__regular_parse__(threadLock) |
@ -0,0 +1,3 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
@ -0,0 +1,172 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
||||||
|
|
||||||
|
|
||||||
|
import os |
||||||
|
import re |
||||||
|
import config |
||||||
|
import threading |
||||||
|
from queue import Queue |
||||||
|
import libs.core as cores |
||||||
|
from libs.core.parses import ParsesThreads |
||||||
|
|
||||||
|
class AndroidTask(object): |
||||||
|
comp_list =[] |
||||||
|
thread_list =[] |
||||||
|
result_dict = {} |
||||||
|
|
||||||
|
def __init__(self, input, rules, net_sniffer,no_resource,package,all,threads): |
||||||
|
self.net_sniffer = net_sniffer |
||||||
|
self.path = input |
||||||
|
if rules: |
||||||
|
config.filter_strs.append(r'.*'+str(rules)+'.*') |
||||||
|
self.no_resource = no_resource |
||||||
|
self.package = package |
||||||
|
self.all = all |
||||||
|
self.threads = threads |
||||||
|
self.file_queue = Queue() |
||||||
|
self.shell_falg=False |
||||||
|
self.packagename="" |
||||||
|
|
||||||
|
|
||||||
|
def start(self): |
||||||
|
# 检查java环境是否存在 |
||||||
|
if os.system("java -version") !=0 : |
||||||
|
raise Exception("Please install the Java environment!") |
||||||
|
|
||||||
|
# 根据不同的文件后缀进行文件解析 |
||||||
|
if os.path.isfile(self.path): |
||||||
|
if self.path.split(".")[1] == "apk": |
||||||
|
self.__decode_apk__(self.path) |
||||||
|
elif self.path.split(".")[1] == "dex": |
||||||
|
self.__decode_dex__(self.path) |
||||||
|
else: |
||||||
|
# 抛出异常 |
||||||
|
raise Exception("Retrieval of this file type is not supported. Select APK file or DEX file.") |
||||||
|
else: |
||||||
|
self.__get_file_type__(self.path) |
||||||
|
self.__start_threads() |
||||||
|
|
||||||
|
for thread in self.thread_list: |
||||||
|
thread.join() |
||||||
|
|
||||||
|
self.__print__() |
||||||
|
|
||||||
|
# if self.net_sniffer: |
||||||
|
# self.__start_net__() |
||||||
|
|
||||||
|
# 分解apk |
||||||
|
def __decode_apk__(self,path): |
||||||
|
if self.no_resource: |
||||||
|
self.__decode_dex__(path) |
||||||
|
else: |
||||||
|
cmd_str = ("java -jar %s d -f %s -o %s") % (cores.apktool_path,path,cores.output_path) |
||||||
|
if os.system(cmd_str) == 0: |
||||||
|
self.__scanner_file_by_apktool__(cores.output_path) |
||||||
|
else: |
||||||
|
raise Exception("The Apktool tool was not found.") |
||||||
|
|
||||||
|
# 分解dex |
||||||
|
def __decode_dex__(self,path): |
||||||
|
cmd_str = ("java -jar %s d %s") % (cores.backsmali_path,path) |
||||||
|
if os.system(cmd_str) == 0: |
||||||
|
self.__get_scanner_file__(cores.output_path,"smali") |
||||||
|
else: |
||||||
|
raise Exception("The baksmali tool was not found.") |
||||||
|
|
||||||
|
|
||||||
|
# 初始化检测文件信息 |
||||||
|
def __scanner_file_by_apktool__(self,output): |
||||||
|
|
||||||
|
# shell检测 |
||||||
|
self.__shell_test__(output) |
||||||
|
|
||||||
|
scanner_dir_list = ["smali","assets"] |
||||||
|
scanner_file_suffix = ["smali","js","xml"] |
||||||
|
|
||||||
|
for dir in scanner_dir_list: |
||||||
|
scanner_dir = os.path.join(output,dir) |
||||||
|
self.__get_scanner_file__(scanner_dir,scanner_file_suffix) |
||||||
|
|
||||||
|
def __get_scanner_file__(self,scanner_dir,file_suffix): |
||||||
|
dir_or_files = os.listdir(scanner_dir) |
||||||
|
for dir_file in dir_or_files: |
||||||
|
dir_file_path = os.path.join(scanner_dir,dir_file) |
||||||
|
if os.path.isdir(dir_file_path): |
||||||
|
self.__get_scanner_file__(dir_file_path,file_suffix) |
||||||
|
else: |
||||||
|
if "." not in dir_file: |
||||||
|
continue |
||||||
|
if len(dir_file.split("."))>1: |
||||||
|
if dir_file.split(".")[1] in file_suffix: |
||||||
|
self.file_queue.put(dir_file_path) |
||||||
|
for component in config.filter_components: |
||||||
|
comp = component.replace(".","/") |
||||||
|
if( comp in dir_file_path): |
||||||
|
if(component not in self.comp_list): |
||||||
|
self.comp_list.append(component) |
||||||
|
|
||||||
|
|
||||||
|
def __get_file_type__(self,root_path): |
||||||
|
dir_or_files = os.listdir(root_path) |
||||||
|
for dir_file in dir_or_files: |
||||||
|
dir_file_path = os.path.join(root_path,dir_file) |
||||||
|
if os.path.isdir(dir_file_path): |
||||||
|
self.__get_file_type__(dir_file_path) |
||||||
|
else: |
||||||
|
if dir_file.split(".")[1] == "apk": |
||||||
|
self.__decode_apk__(dir_file) |
||||||
|
elif dir_file.split(".")[1] == "dex": |
||||||
|
self.__decode_dex__(dir_file) |
||||||
|
else: |
||||||
|
continue |
||||||
|
|
||||||
|
def __print__(self): |
||||||
|
if self.packagename: |
||||||
|
print("========= The package name of this APP is: ===============") |
||||||
|
print(self.packagename) |
||||||
|
|
||||||
|
if len(self.comp_list) != 0: |
||||||
|
print("========= Component information is as follows :===============") |
||||||
|
for json in self.comp_list: |
||||||
|
print(json) |
||||||
|
|
||||||
|
print("=========The result set for the static scan is shown below:===============") |
||||||
|
with open(cores.result_path,"a+") as f: |
||||||
|
for key,value in self.result_dict.items(): |
||||||
|
f.write(key+"\r") |
||||||
|
for result in value: |
||||||
|
print(result) |
||||||
|
f.write("\t"+result+"\r") |
||||||
|
print("For more information about the search, see: %s" %(cores.result_path)) |
||||||
|
|
||||||
|
if self.shell_falg: |
||||||
|
print('\033[1;33mWarning: This application has shell, the retrieval results may not be accurate, Please remove the shell and try again!') |
||||||
|
|
||||||
|
def __start_threads(self): |
||||||
|
for threadID in range(1,self.threads) : |
||||||
|
name = "Thread - " + str(threadID) |
||||||
|
thread = ParsesThreads(threadID,name,self.file_queue,self.all,self.result_dict) |
||||||
|
thread.start() |
||||||
|
self.thread_list.append(thread) |
||||||
|
|
||||||
|
def __shell_test__(self,output): |
||||||
|
am_path = os.path.join(output,"AndroidManifest.xml") |
||||||
|
|
||||||
|
with open(am_path,"r") as f: |
||||||
|
am_str = f.read() |
||||||
|
|
||||||
|
am_package= re.compile(r'<manifest.*package=\"(.*?)\".*') |
||||||
|
apackage = am_package.findall(am_str) |
||||||
|
if len(apackage >=1): |
||||||
|
self.packagename = apackage |
||||||
|
|
||||||
|
am_name = re.compile(r'<application.*android:name=\"(.*?)\".*>') |
||||||
|
aname = am_name.findall(am_str) |
||||||
|
if aname[0] in config.shell_list: |
||||||
|
self.shell_falg = True |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,94 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
||||||
|
|
||||||
|
|
||||||
|
import os |
||||||
|
import re |
||||||
|
import zipfile |
||||||
|
import libs.core as cores |
||||||
|
from queue import Queue |
||||||
|
from libs.core.parses import ParsesThreads |
||||||
|
|
||||||
|
|
||||||
|
class iOSTask(object): |
||||||
|
thread_list =[] |
||||||
|
result_dict = {} |
||||||
|
|
||||||
|
def __init__(self,input, rules, net_sniffer,no_resource,all,threads): |
||||||
|
self.path = input |
||||||
|
self.rules = rules |
||||||
|
self.net_sniffer = net_sniffer |
||||||
|
self.no_resource = no_resource |
||||||
|
self.all = all |
||||||
|
self.threads = threads |
||||||
|
if rules: |
||||||
|
config.filter_strs.append(r'.*'+str(rules)+'.*') |
||||||
|
self.file_queue = Queue() |
||||||
|
self.shell_falg=False |
||||||
|
|
||||||
|
def start(self): |
||||||
|
# ipa 文件 |
||||||
|
if self.path.split(".")[1] == 'ipa': |
||||||
|
# 对ipa进行解包 |
||||||
|
self.__decode_ipa__(cores.output_path) |
||||||
|
|
||||||
|
#文件提取 |
||||||
|
self.__scanner_file_by_ipa__(cores.output_path) |
||||||
|
|
||||||
|
self.__start_threads() |
||||||
|
|
||||||
|
for thread in self.thread_list: |
||||||
|
thread.join() |
||||||
|
|
||||||
|
self.__print__() |
||||||
|
|
||||||
|
|
||||||
|
def __scanner_file_by_ipa__(self,output): |
||||||
|
scanner_file_suffix = ["plist","js","xml","html"] |
||||||
|
scanner_dir = os.path.join(output,"Payload") |
||||||
|
self.__get_scanner_file__(scanner_dir,scanner_file_suffix) |
||||||
|
|
||||||
|
def __get_scanner_file__(self,scanner_dir,file_suffix): |
||||||
|
dir_or_files = os.listdir(scanner_dir) |
||||||
|
for dir_file in dir_or_files: |
||||||
|
dir_file_path = os.path.join(scanner_dir,dir_file) |
||||||
|
if os.path.isdir(dir_file_path): |
||||||
|
if dir_file.endswith(".app"): |
||||||
|
self.elf_file_name = dir_file.split(".")[0] |
||||||
|
self.__get_scanner_file__(dir_file_path,file_suffix) |
||||||
|
else: |
||||||
|
if self.elf_file_name == dir_file: |
||||||
|
self.file_queue.put(dir_file_path) |
||||||
|
continue |
||||||
|
if self.no_resource: |
||||||
|
dir_file_suffix = dir_file.split(".") |
||||||
|
if len(dir_file_suffix) > 1: |
||||||
|
if dir_file_suffix[1] in file_suffix: |
||||||
|
self.file_queue.put(dir_file_path) |
||||||
|
|
||||||
|
def __decode_ipa__(self,output_path): |
||||||
|
zip_files = zipfile.ZipFile(self.path) |
||||||
|
for zip_file in zip_files.filelist: |
||||||
|
zip_files.extract(zip_file.filename,output_path) |
||||||
|
|
||||||
|
def __start_threads(self): |
||||||
|
for threadID in range(1,self.threads) : |
||||||
|
name = "Thread - " + str(threadID) |
||||||
|
thread = ParsesThreads(threadID,name,self.file_queue,self.all,self.result_dict) |
||||||
|
thread.start() |
||||||
|
self.thread_list.append(thread) |
||||||
|
|
||||||
|
|
||||||
|
def __print__(self): |
||||||
|
print("=========The result set for the static scan is shown below:===============") |
||||||
|
with open(cores.result_path,"a+") as f: |
||||||
|
for key,value in self.result_dict.items(): |
||||||
|
f.write(key+"\r") |
||||||
|
for result in value: |
||||||
|
print(result) |
||||||
|
f.write("\t"+result+"\r") |
||||||
|
print("For more information about the search, see: %s" %(cores.result_path)) |
||||||
|
|
||||||
|
if self.shell_falg: |
||||||
|
print('\033[1;33mWarning: This application has shell, the retrieval results may not be accurate, Please remove the shell and try again!') |
@ -0,0 +1,78 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Author: kelvinBen |
||||||
|
# Github: https://github.com/kelvinBen/AppInfoScanner |
||||||
|
|
||||||
|
|
||||||
|
import os |
||||||
|
import re |
||||||
|
import config |
||||||
|
import threading |
||||||
|
from queue import Queue |
||||||
|
import libs.core as cores |
||||||
|
from libs.core.parses import ParsesThreads |
||||||
|
|
||||||
|
|
||||||
|
class WebTask(object): |
||||||
|
thread_list =[] |
||||||
|
result_dict = {} |
||||||
|
|
||||||
|
def __init__(self, input, rules,all,threads): |
||||||
|
self.path = input |
||||||
|
if rules: |
||||||
|
config.filter_strs.append(r'.*'+str(rules)+'.*') |
||||||
|
self.all = all |
||||||
|
self.threads = threads |
||||||
|
self.file_queue = Queue() |
||||||
|
self.shell_falg=False |
||||||
|
|
||||||
|
def start(self): |
||||||
|
# 此处判断是文件还是目录 |
||||||
|
# 文件判断后缀 html,js,css,htm,xml等 |
||||||
|
|
||||||
|
if len(config.web_file_suffix) <=0: |
||||||
|
scanner_file_suffix = ["html","js","html","xml"] |
||||||
|
|
||||||
|
scanner_file_suffix = config.web_file_suffix |
||||||
|
if os.path.isdir(self.path): # 目录的话就提取 |
||||||
|
self.__get_scanner_file__(self.path,scanner_file_suffix) |
||||||
|
|
||||||
|
else: |
||||||
|
if not (self.path.split(".")[1] in scanner_file_suffix): # 内容包含进行下步处理 |
||||||
|
err_info = ("Retrieval of this file type is not supported. Select a file or directory with a suffix of %s" % ",".join(scanner_file_suffix)) |
||||||
|
raise Exception(err_info) |
||||||
|
self.file_queue.put(self.path) |
||||||
|
|
||||||
|
self.__start_threads() |
||||||
|
|
||||||
|
for thread in self.thread_list: |
||||||
|
thread.join() |
||||||
|
|
||||||
|
self.__print__() |
||||||
|
|
||||||
|
def __get_scanner_file__(self,scanner_dir,file_suffix): |
||||||
|
dir_or_files = os.listdir(scanner_dir) |
||||||
|
for dir_file in dir_or_files: |
||||||
|
dir_file_path = os.path.join(scanner_dir,dir_file) |
||||||
|
if os.path.isdir(dir_file_path): |
||||||
|
self.__get_scanner_file__(dir_file_path,file_suffix) |
||||||
|
else: |
||||||
|
if len(dir_file.split("."))>1: |
||||||
|
if dir_file.split(".")[1] in file_suffix: |
||||||
|
self.file_queue.put(dir_file_path) |
||||||
|
|
||||||
|
def __print__(self): |
||||||
|
print("=========The result set for the static scan is shown below:===============") |
||||||
|
with open(cores.result_path,"a+") as f: |
||||||
|
for key,value in self.result_dict.items(): |
||||||
|
f.write(key+"\r") |
||||||
|
for result in value: |
||||||
|
print(result) |
||||||
|
f.write("\t"+result+"\r") |
||||||
|
print("For more information about the search, see: %s" %(cores.result_path)) |
||||||
|
|
||||||
|
def __start_threads(self): |
||||||
|
for threadID in range(1,self.threads) : |
||||||
|
name = "Thread - " + str(threadID) |
||||||
|
thread = ParsesThreads(threadID,name,self.file_queue,self.all,self.result_dict) |
||||||
|
thread.start() |
||||||
|
self.thread_list.append(thread) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue