Sun的逆向之路(三)——暴破15年阿里移动安全挑战赛第一题
0x01 观察题目
用模拟器运行程序,看到题目营造了一个情景让我们破解应用的登录系统,先随便输入一串数字,提示我们密码不对,请继续破解。
0x02 静态暴破
首先将AliCrackme_1.apk用apktool进行反编译。
反编译成功后得到输出文件夹:
在eclipse中新建Java Project,将反编译文件夹设为工程目录,我们来看一看工程结构。
接下来查找一下“密码”,发现没有做编码,定位到了string.xml文件中:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="abc_action_mode_done">Done</string>
<string name="abc_action_bar_home_description">Navigate home</string>
<string name="abc_action_bar_up_description">Navigate up</string>
<string name="abc_action_menu_overflow_description">More options</string>
<string name="abc_searchview_description_search">Search</string>
<string name="abc_searchview_description_query">Search query</string>
<string name="abc_searchview_description_clear">Clear query</string>
<string name="abc_searchview_description_submit">Submit query</string>
<string name="abc_searchview_description_voice">Voice search</string>
<string name="abc_activitychooserview_choose_application">Choose an app</string>
<string name="abc_activity_chooser_view_see_all">See all</string>
<string name="abc_shareactionprovider_share_with_application">Share with %s</string>
<string name="abc_shareactionprovider_share_with">Share with</string>
<string name="app_name">UFO</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="dialog_title">提示</string>
<string name="dialog_error_tips">密码不对,请继续破解</string>
<string name="dialog_good_tips">恭喜!!!破解成功!!!</string>
<string name="dialog_ok">确定</string>
</resources>
对应string name是"dialog_error_tips",顺便记录一下破解成功的string name,根据已有的线索追踪引用dialog_error_tips的位置,不难定位到public.xml文件。
可以看到其id为0x7f0a0011,而顺带记录下0x7f0a0012。顺藤摸瓜,看看哪里引用了0x7f0a0011,发现在MainActivity$1与R$String这两个文件中该字符串有出没,但显然后者没有有效信息,于是进入第一个smali文件,找到id所在位置,对应代码块如下:
发现下面一大片位于:cond_0中,而整个:cond_0位于onClick函数内,这应该就是按钮的点击事件的处理函数,先看看在这里:cond_0中都做了哪些操作。 首先new-instance新创建了一个实例,随后const v6作为中间变量,不断调用AlertDialog$Builder中的setMessage函数构造Dialog的各部分字符串,在.line 67处显示了对话框,也就是我们看到的密码不正确的提示框。再往下翻,紧接着goto :goto_0,发现goto_0处就直接return-void了。 分析完了:cond_0内的逻辑,来看看哪些地方跳到了这儿。大致浏览一番,定位到了如下代码块:
if-eqz v4, :cond_0
const-string v6, ""
invoke-virtual {v4, v6}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v6
if-nez v6, :cond_0
invoke-virtual {v4, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v6
if-eqz v6, :cond_0
.line 55
iget-object v6, p0, Lcom/example/simpleencryption/MainActivity$1;->this$0:Lcom/example/simpleencryption/MainActivity;
invoke-static {v6}, Lcom/example/simpleencryption/MainActivity;->access$1(Lcom/example/simpleencryption/MainActivity;)V
首先判断v4是否等于零,是的话跳转到:cond_0,后面连续几个判断都跳到了:cond_0,说明v4,v6的值代表了输入的密码是否正确,这里我们直接黑掉这几个判断,代码顺利执行到.line 55,这里access$1函数引起了我们的关注,于是进入MainActivity中找到access$1,函数代码如下:
.method static synthetic access$1(Lcom/example/simpleencryption/MainActivity;)V
.locals 0
.prologue
.line 73
invoke-direct {p0}, Lcom/example/simpleencryption/MainActivity;->showDialog()V
return-void
.end method
函数内部又调用了showDiglog,找到showDiglog函数,发现与onClick函数的:cond_0逻辑神似,也是构造对话框,意外发现了一串熟悉的id: 0x7f0a0012
.method private showDialog()V
.locals 3
.prologue
.line 74
new-instance v0, Landroid/app/AlertDialog$Builder;
invoke-direct {v0, p0}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 75
.local v0, "builder":Landroid/app/AlertDialog$Builder;
const v1, 0x7f0a0012
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(I)Landroid/app/AlertDialog$Builder;
.line 76
const v1, 0x7f0a0010
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(I)Landroid/app/AlertDialog$Builder;
.line 77
const v1, 0x7f0a0013
.line 78
new-instance v2, Lcom/example/simpleencryption/MainActivity$2;
invoke-direct {v2, p0}, Lcom/example/simpleencryption/MainActivity$2;-><init>(Lcom/example/simpleencryption/MainActivity;)V
.line 77
invoke-virtual {v0, v1, v2}, Landroid/app/AlertDialog$Builder;->setPositiveButton(ILandroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;
.line 84
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
.line 85
return-void
.end method
很明显我们找到了提示成功信息的地方。最后回编译apk文件,打上签名在模拟器上安装应用,随便输入密码,点击确认,可以看到已经破解成功了。
0x03 总结
考虑到暴破相对来说有点低级了,下一篇将尝试从动态调试的角度重新审视此题,并真正意义上的破解出该题的正确密码。
- 感谢你赐予我前进的力量