實驗吧 這個FLAG有點怪 By Assassin

首先感慨一下,感覺自己還是太菜了,這個是2014sctf的RE200,實際是400分的安卓題目,現在做出來其實也是在大佬的提示下完成的,怎麼說只能說是分析調出來了,並不算是自己做的,本題過程也很複雜(真心膜拜比賽期間可以做出來的大牛了)下面進入正題,我儘可能講的清楚一些,在此期間也會借鑑一下大佬的東西
首先肯定是安卓模擬器看一看軟件到底是幹啥的,大概就是輸入一個東西,返回一個值。然後我們將安卓apk文件拖到jeb下看一下,很快找到關鍵的代碼

這裏寫圖片描述

然後我們看到關鍵的判斷函數在func函數中,但是!這個函數是私有的,然後想到了在so文件中被調用,然後我們就準備用IDA去反彙編so文件了,而且我們發現so文件只有一個,還好還好…

這裏寫圖片描述

查找導出函數Java_com_syc_kitkat_func,但是發現這個函數並不存在!然後看了大佬的提示,so文件申明註冊函數,可以在JNI_Onload中註冊。dex文件加載so文件時,首先會在導出函數中查找JNI_Onload函數,JNI_Onload的默認情況下,不需要我們去聲明與定義,但是我們可以重寫JNI_Onload,來註冊func函數。
然後我們找到JNI_Onload這個函數
這裏寫圖片描述

點進去我們似乎發現了func函數,還有知道了字符串的處理真正位置在_cxa_begin_match中的,然後我們去看一看吧
分析一下知道這個gun_arm_fini_29函數是用來讀取輸入的字符串的
這裏寫圖片描述

中間有很多東西,是關於調用線程和檢測程序的,總的來說就是一種簡單的對抗gdb調試的思路吧!(猜的)
這裏寫圖片描述

然後繼續看,我們剛剛輸入的字符串進行了一個抑或加密,加密是以如下方式text[i]=text[i]^(i+1)進行的,比較好懂
這裏寫圖片描述

然後我們繼續看如下語句
這裏寫圖片描述

這幾個變量m_y,tempSt,tempabc貌似都沒有定義啊!然後我們如果看sctf題解會發現存在一個提示

    反調試,代碼在.init段

我們查看.init段,發現定義了個函數,_cxa_chk_fail函數,首先看一下

這裏寫圖片描述

我們發現穿件了一個線程來着,進一步打開看一下!
這裏寫圖片描述

查看發現原來這些變量是一個類似全局變量的東西,在這裏對m_y和tempabc進行了初始定義!但是這裏看貌似存在兩個結果啊如下

m_y tempabc
6   syc
9   xctf

但是我們在後面嘗試中發現只用到了第一種情況!(至今不知道是爲什麼…這個很奇怪,應該是和線程調用有關,但是我不太明白)
然後我們繼續回到 _cxa_begin_match函數,首先調用了一個函數是imp_Unwind_k

這裏寫圖片描述

進去看一下,關鍵代碼如下
這裏寫圖片描述

代碼不難,分析一下功能就是,我們把輸入的串向右移動了6位,然後將這個值賦值到了tempSt這個串中,然後我們是不是tempSt這個串的來歷也清楚了!!!

繼續回到_cxa_begin_match函數,然後進入了gun_armfini_33函數,我們看看它幹了什麼

這裏寫圖片描述

關鍵代碼如下
這裏寫圖片描述

理解起來不復雜,總之就是對不同類字符進行處理,然後繼續會進入驗證函數imp_Unwind_j
這裏寫圖片描述

注意這個v15是我們之前轉換後的字符串了,結果進去以後發現類似方程組的東西,然後我們可以得到一個字符串!
這裏寫圖片描述

小心分析求解後,發現它是驗證改變後的也就是tempSt這個串的前十一位是不是GoodCracK3R
鼓舞人心!!!並且我們還需要注意一個細節,在_cxa_begin_match函數中的s現在存儲的是經過gun_armfini_33函數轉換過得串!
我們還是回到_cxa_begin_match函數,然後我們分析,將11位以後的值賦值給dest串(爲什麼呢,我們重點看一下變量的定義!)
這裏寫圖片描述

並且這裏我們給seed賦值,他的位置正好是加密後串(s串的第9、10、11位,也就是K3R)這個seed後面有用!之後進入gun_armfini_21函數,首先是進入gun_armfini_23函數,這裏利用了seed值對v8生成了一個256長度的int數組!
這裏寫圖片描述

我用python實現了一下這個數組的功能

def make(str,lens):
    a=[]
    for i in range(256):
        a.append(i)
    pos=0
    pos_temp=0
    for i in range(256):
        temp = a[i]
        pos_temp=(ord(str[pos])+a[i]+pos_temp)&0xff
        a[i]=a[pos_temp]
        a[pos_temp]=temp
        pos=((pos+1)%lens)&0xff
    return a
#make('K3R',3)

然後我們這個v8數組後面還會用到。之後進入gun_armfini_36函數,這個函數主要就是對11位之後的字符串進行了處理

這裏寫圖片描述

然後我們還是回到_cxa_begin_match函數!接近尾聲了!
這裏寫圖片描述

我們看到是用sprintf函數對v18進行賦值(用11位以後,加密過的字符)然後進入gun_arm_ldiv0函數去匹配!
這裏寫圖片描述

經過gun_Unwind函數簡單加密了一下,就是簡單的-2加密
這裏寫圖片描述

最後我們看看它在做什麼?11位之後的內容,進過加密,以16進制形式輸出,需要匹配成串a8e5588f7e3f758

但是等等!a8e5588f7e3f758是15位的,也就是說一定有一位是0x01這種形式的,11位(那個GoodCracK3R)後面存在8位字符,事實上後八位加密後情況可能是如下

[[0x0a,0x8e,0x55,0x88,0xf7,0xe3,0xf7,0x58],
[0xa8,0x0e,0x55,0x88,0xf7,0xe3,0xf7,0x58],
[0xa8,0xe5,0x05,0x88,0xf7,0xe3,0xf7,0x58],
[0xa8,0xe5,0x58,0x08,0xf7,0xe3,0xf7,0x58],
[0xa8,0xe5,0x58,0x8f,0x07,0xe3,0xf7,0x58],
[0xa8,0xe5,0x58,0x8f,0x7e,0x03,0xf7,0x58],
[0xa8,0xe5,0x58,0x8f,0x7e,0x3f,0x07,0x58],
[0xa8,0xe5,0x58,0x8f,0x7e,0x3f,0x75,0x08]]

我們實驗最後正確的是這個(這也是比較坑的地方….)

[0xa8,0xe5,0x58,0x8f,0x7e,0x03,0xf7,0x58]

然後根據上面的分析,我們就可以得到gun_armfini_33加密以後後八位的字符串是啥了!
我也用python生成了一下程序如下

def make(str,lens):
    a=[]
    for i in range(256):
        a.append(i)
    pos=0
    pos_temp=0
    for i in range(256):
        temp = a[i]
        pos_temp=(ord(str[pos])+a[i]+pos_temp)&0xff
        a[i]=a[pos_temp]
        a[pos_temp]=temp
        pos=((pos+1)%lens)&0xff
    return a
#make('K3R',3)

def hehe():
    a=make('K3R',3)
    value=[0xa8,0xe5,0x58,0x8f,0x7e,0x03,0xf7,0x58]
    temp1=0
    temp2=0
    temp3=0
    flag=''
    print a
    for i in value:
        temp1=(temp1+1)&0xff
        temp2=a[temp1]
        temp3=(temp3+temp2)&0xff
        a[temp1]=a[temp3]
        a[temp3]=temp2
        flag+=chr(i^a[(a[temp1]+temp2)&0xff])
    print flag
hehe()

最後得到gun_armfini_33加密後輸入字符串爲

GoodCracK3R;{0jN|B6

之後是不是就簡單了!只需要逆向一下gun_armfini_33函數,再移位回去再抑或一下就得到答案了!解密程序如下

ppp="GoodCracK3R;{0jN|B6"
key = 'syc'
flag=[]
for i in ppp:
    flag.append(ord(i))
print flag
for j in range(len(flag)):
    if flag[j]>=ord('a') and flag[j]<=ord('z'):
        flag[j]=(flag[j]-97+26-ord(key[j%3])+97)%26+97
    elif flag[j]>=ord('A') and flag[j]<=ord('Z'):
        flag[j]=(flag[j]-65+26-ord(key[j%3])+97)%26+65

newflag=''
for i in range(6,6+len(flag)):
    newflag+=chr(flag[i%len(flag)]^(i-5))
print newflag
#xctf{hgJ7Q=|8a\wV;A~}}Wc}

至此成功解出答案!

寫的可能稍微有一些些亂,但是這題目真心的好題目,又不太懂的地方還請大神斧正,也請各位包含。題目很複雜,所以一定一定要有耐心!嗯!加油












發佈了188 篇原創文章 · 獲贊 48 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章