LCTF (easyeasy-200)
首先安装,看看app是什么样的。
有点奇怪,没有点击确定的按钮。然后拖到JEB反编译。
要求输入的字符串的长度要在35-39之间(包括边界值),然后会调用Format().form函数。如下图。
可以看到,form函数是要返回字符串[5,38],这里可以判断出要输入字符串的长度必须要大于38,否则就会出错。结合上面的分析,那么长度可能会是38或者39了。
再往下,要求format后的字符串长度要大于等于32才会调用check函数。
接着进check函数追下去。
首先看它的构造函数, 这个函数莫名其妙。调用checkPipes,判断路径是否存在,若两个路径中存在任何一个就会被赋值为ture并返回。当两个路径都不存在时赋值为false。
接着再往下分析。调用native层函数并传入emulator,结果为真返回false,反之调用native层函数checkPasswd并传入pass。
这里推测是起迷惑作用的,反正管你emulator是什么,反正想拿到flag就必须得调用后面的checkPasswd。换句话说,checkPipes也没有分析的意义了。
那么接下来反编译app,用IDA打开下图所示的文件。(为什么选这个,我也忘了,反正选这个没错)
之后,我就在这里卡住了, checkPasswd 的 IDA反编译的代码十分晦涩,而且由于自己的畏难心理,导致静不下心来分析,所以上午只看了一会就放弃了。看了网上的WP。这些WP都很玄学,都是先找到那串base64(具体怎么找的也没说)然后解码,倒置,flag就get了。我想这样的话有什么意思,于是下午就自己硬怼了。然后我认为自己分析的还是有点东西的,而且网上对这个题的WP也不详细,于是写下自己的见解。
sub_8f7c,三个参数都与输入的str无关,这里我想了好久,一开始认为是加密函数,后来推测出这个函数作用就是为了申请内存,并且把第二参数地址传递给第一个参数。为什么原因有2.
1.如果跟进这个函数,会发现下图所示,有create
2.这个函数被多次调用,观察这些函数,就可以更加确认了。
sub_8F7C搞清楚后,接着往下分析,如下图,具体分析已在图中标明。
在分析sub_6ED0时,存在下图所示字符
所以从逻辑上看,sub_6ED0是把v7放入v17中的推论是站得住脚的。
接着往下。
encrypt代码很难懂。先把这个函数放一放,来看看secret这个变量存储的值到底是什么。
鉴于以往的经验,在IDA中双击这个值就能看到它的值。但是这里不一样,他是位于bss段的数据,并没有值。选中secret,按X,有一个520C函数也引用过这个值,点开会发下下图。
很熟悉,又见到8F7C这个函数了。上面我们分析过,这个函数的作用其实就是把第二参数传递给第一个参数。换句话说secret被赋值了这串base。
但是后面下面那个是怎么回事?
我们回头再去看encrypt加密函数就会恍然大悟了。如下图
看,1D09C中存储的是base64的那张表(对base64编码原理不清楚的可以去百度,这里就不赘述了,写了半下午好累╮(╯-╰)╭),这个encrypt就是个base64加密算法,实锤了。
到此为止。总结一下。
其实就是接受Java层的参数,倒置后base64加密,然后与内置的那串base作比较,一样返回ture,反之false。
那么为什么这个题做出来的人这么少呢?我觉着要是上面几个关键函数告诉你他是干什么用的,比如encrypt告诉你是个base64算法,我想肯定这个题难度会大大降低把。
问题的关键是不知道它的作用,只能自己去推理,面对这么多晦涩难懂的代码,去找出它的实际意义,我想这大概就是逆向的难处和魅力吧。