0x01 前言

AndroTickler是一款用于Android应用程序渗透测试和审计的工具包。更多介绍可以参考https://github.com/ernw/AndroTickler 。本文主要记录一下在使用过程中所遇到的问题和解决的方法。

本文的测试环境如下:系统为win10 x64,jdk版本为java8,gradle版本为4.1。采用了夜神模拟器。

主要包括以下几个方面。

  1. 编译环境的准备
  2. 使用过程中遇到的问题以及解决方法

0x02 编译环境的准备

1. Gradle的安装

首先需要安装Java,我采用的是Java8(安装工具说明,需要Java7以上)。下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 。(安装过程省略)

关于gradle的安装可以参考https://gradle.org/install/ ,我这里是直接下载安装包https://services.gradle.org/distributions/gradle-4.4.1-bin.zip, 解压之后添加环境变量。
gradle安装

2. cmder工具安装

该步骤非必需,可以省略。
下载地址:https://github.com/cmderdev/cmder/releases/
解压添加环境变量即可使用。
cmder工具

使用该工具除了界面好看外,可以多个tab,也可以运行部分linux命令。当然也可以使用其他工具,如cygwin。如果没有使用这类工具的话,需要将代码中一些命令修改,如cp命令。

3. Git工具安装

该步骤非必需,可以省略。
下载地址:https://desktop.github.com/
安装即可。然后下载 AndroTickler
下载

4.其他工具安装

还需要安装adb, sqlite3, strings等工具。
adb的话安装夜神模拟器的时候自动,名字为nox_adb,功能一样。
sqlite3可以用https://www.sqlite.org/ 下载。
strings的官网,https://docs.microsoft.com/en-us/sysinternals/downloads/strings ,下载地址为:
https://download.sysinternals.com/files/Strings.zip 。解压后加入环境变量即可。

然后就是开始编译和使(入)用(坑)了。

0x03 使用过程中遇到的问题以及解决方法

上面环境已经搭建好了,代码也下载了,然后就开始入坑吧。
编译的话很简单,使用命令gradle && gradle build即可。
编译
然后会在build\libs目录下生成AndroTickler.jar文件。

软件生成了,那么看看有什么功能吧,使用命令:

1
java -jar AndroTickler.jar -h

使用帮助

貌似一切正常。下面开始查看安装的app。

使用命令

1
java -jar AndroTickler.jar -pkgs

查看安装的app1

并没有返回安装的app
已知列出已经安装的app命令是adb shell pm list package
而我用的模拟器,所以应该使用命令是nox_adb shell pm list package
查看安装的app2
所以这里要替换程序中的adb为nox_adb。
这里我用idea来打开代码
然后将命令中的adb替换为nox_adb即可
替换adb命令
替换后重新编译并查看已安装的app。
查看安装的app3

发现列出了安装过的app。虽然有警告,暂且不管。
查找特定的app并查看信息

1
2
java -jar AndroTickler.jar -findPkg com.example.simpleencryption
java -jar AndroTickler.jar -pkg com.example.simpleencryption -info

查看app信息

发现报错,提示没有连接的设备。
通过adb查看连接的设备。
nox_adb devices -l
连接的设备
发现有,但是使用工具未查看到。
通过错误的信息,定位到initialization\TicklerChecks.java的checkDevices方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void checkDevices() throws TNotFoundEx{
String command = "nox_adb devices -l";
Commando commando = new Commando();
String op = commando.executeCommand(command);

OtherUtil oU = new OtherUtil();
ArrayList<String> devices = oU.getRegexFromString(op, "(model:.*?device:.+$?)");
int eligDevices = devices.size();

if (eligDevices>1)
throw new TNotFoundEx("ERROR: 2 or more Android devices are connected to the host, please connect only one Android device.");
if (eligDevices == 0)
throw new TNotFoundEx("ERROR: No Android devices detected by the host. Execute adb devices -l to check the connected devices");

}

发现通过命令查询的结果为:

1
2
List of devices attached
127.0.0.1:62025 device

明显通过正则不能匹配,那就改正则了。
为了方便,直接改为ArrayList<String> devices = oU.getRegexFromString(op, "(.*device\\n)");

然后编译运行。
查看app信息1
这个提示libs需要和jar文件在同一目录。将Tickler.conf和libs复制到与AndroTickler.jar同一目录。
查看app信息2
竟然报同样的错误,而且该目录下出现了一个H的文件夹。
通过错误的信息,定位到initialization\TicklerChecks.java的checkExternalLibDir方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void checkExternalLibDir() throws TNotFoundEx{
String jarLoc = this.getJarLocation();
String libDirLoc=jarLoc+TicklerConst.generalLibName;
File tickLib = new File (libDirLoc);
if (tickLib.exists()){
TicklerVars.isLib = true;
TicklerVars.libDir = libDirLoc;
}
//Lib directory not found
else
{
throw new TNotFoundEx("Lib directory not found. \nMake sure that "+TicklerConst.generalLibName+" directory exists in the same directory as Tickler.jar");
}

}

查看代码,tickLib由jarLoc和TicklerConst.generalLibName拼接,而TicklerConst.generalLibName是常量,所以需要查看jarLoc是如何获取的。跟进getJarLocation方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String getJarLocation(){
File myJar;
try{

File myJar1 = new File(System.getProperty("java.class.path"));//获取jar路径
myJar = myJar1.getAbsoluteFile().getParentFile();//获取jar上级目录
}
catch(Exception e){
myJar = new File(".");
}

String jarLoc = this.correctJarLoc(myJar.getAbsolutePath());
return jarLoc;
}

首先获取了运行的jar的路径,然后获取其父路径并将其值赋值给myJar。然后调用了correctJarLoc方法。
进行跟进correctJarLoc方法,进去查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public String correctJarLoc(String jarLoc){
String finalLoc=jarLoc;
if (jarLoc.contains(":"))//wtf? 造成问题的代码
finalLoc = jarLoc.substring(0, jarLoc.indexOf(":"));//wtf? 造成问题的代码

Matcher m = Pattern.compile("\\s+(.+)").matcher(jarLoc);
if (m.find())
finalLoc = m.group(1);
if (finalLoc.matches(".+\\n$")){
finalLoc = finalLoc.substring(0, jarLoc.length()-1);
}
if (finalLoc.matches(".+\\.$")){
finalLoc = finalLoc.substring(0, jarLoc.length()-1);
}
if (!finalLoc.matches(".+/$")){
finalLoc = finalLoc+"/";
}

return finalLoc;
}

然后立马发现问题的所在了。这里因为是windows系统,所以路径出现:是很正常的,而这里直接截取了盘符。
这就是出现了一个名为H的文件夹的原因。
解决方法:删除这两行代码即可。
之后再编译运行。
查看app信息3
编译运行后发现警告没了,但新的错误出现了。
通过错误信息定位到apk\ApkToolClass.java的apkToolDecode方法。暂时先利用下面代码替换。

1
2
//File file = new File("/dev/null");
File file = new File("H:\\tmp\\");

从之后文件的内容来看,该文件里面会记录一些操作记录。

再次编译运行,没有任何结果信息也没有报错。
查看app信息4
而在Tickler_workspace\com.example.simpleencryption\logs.pullLog.log发现了这样的日志。
查看app信息5
安装过的app保存位置为:/data/app
安装过的app
修改Tickler.conf文件

1
2
3
Tickler_local_directory = H:/workspace/eclipse/AndroTickler/build/libs/
Tickler_sdcard_directory = /data/app/
Frida_server_path = /data/local/tmp/frida-server-10.3.14-android-arm

编译运行,没有报错,查看Tickler_workspace\com.example.simpleencryption\logs.pullLog.log文件

1
cannot create 'H:\workspace\eclipse\AndroTickler\build\libs\com.example.simpleencryption\\': Not a directory

然后通过调试,来寻找错误的地方(这里的图为之前调试的图( ╯□╰ ))

导出apk错误

执行的命令为:nox_adb pull /data/app/com.jnu.ctf2017-1.apk H:/AndroTickler/com.jnu.ctf2017//
测试后发现,使用adb pull导出文件时,pc的路径最后不能有\或者/
导出测试

直接修改base\FileUtil.java中copyDirToHost方法

1
2
//		this.pullFromSDcard(TicklerVars.sdCardPath+srcName, dest+"/"); by fuping
this.pullFromSDcard(TicklerVars.sdCardPath+srcName, dest);

修改base\FileUtil.java中pullFromSDcard方法

1
2
3
4
5
6
7
8
9
10
11
12
13
public void pullFromSDcard(String src, String dest) {
String fName = this.getFileNameFromPath(src);
this.warnOverrideAndDelete(dest+fName);
//by fuping
File f = new File(dest);
if(!f.exists()){
f.mkdirs();
}// by fuping
dest = f.getPath();
String command = "nox_adb pull "+src+" "+dest;
int pullResult=this.commando.executeProcessForAdbPull(command);
this.deleteDirFromDevice(src);
}

查看app信息6

还有一些需要更改的地方,例如将代码中调用dex2jar-2.1的.sh脚本改为.bat 。之后在编译运行。

查看app信息7
此时这个工具才能算可以使用,还有其他功能(例如Frida),我并未测试。当然还可能还会有其他问题,这里就不再深入了。

这里放上一个查看app详细信息的结果。
详细信息1
详细信息2

可以看到安装日期、使用权限、数据库存储等等信息。

0x04 总结

虽然看起来在运行的时候有很多坑,但其原因也是环境的问题(我采用的是Windows)。而且我使用了模拟器而不是真机,所以也可能造成一些问题。但是这些都是无关紧要的,都是很小的错误,修改一下就可以用了。我这里仅仅使用了查看app信息的功能,并未测试其他功能。更多功能可以参考https://github.com/ernw/AndroTickler