吾愛破解 - LCG - LSG |安卓破解|病毒分析|破解軟件|jn-dxmm.com

 找回密碼
 注冊[Register]

QQ登錄

只需一步,快速開始

搜索
查看: 1660|回復: 12

[Android CTF] ISC訓練賽 CrazyAndroid Writeup

[復制鏈接]
buzhifou01 發表于 2020-3-26 10:47

脫殼">1.查殼脫殼


1.使用 PKID查殼,發現加了360的殼
2345截圖20200319114632.png
2.我在逍遙模擬器中進行脫殼操作,先是運行genymotion,隨后運行模擬器,在cmd中輸入adb shell,會提示超過了一個設備,關閉genymotion,就能在cmd中操作模擬器。
2345截圖20200321105415.png
2345截圖20200319161756.png
3.接著使用drizzleDumper進行脫殼,下載好git軟件,選中某個文件夾,右鍵Git bash here,輸入git clone http://github.com/DrizzleRisk/drizzleDumper.git就可下載。
2345截圖20200319161245.png
4.下好后再x86文件夾可以看到drizzleDumper文件,該文件就為脫殼的關鍵文件,在說它脫殼的原理前,先簡單介紹一下Dex文件,apk程序第一次加載時,系統會把class.dex文件進行優化生成odex文件,這樣做是為了提高程序的運行效率。
2345截圖20200319173347.png
下面是dex的頭部結構:
[Asm] 純文本查看 復制代碼
struct DexOptHeader {
    u1  magic[8];
    u4  dexOffset;
    u4  dexLength;
    u4  depsOffset;
    u4  depsLength;
    u4  optOffset;
    u4  optLength;
    u4  flags;
    u4  checksum;
};

5.在它的頭部結構中有一個magic[8]數組,這個數組的值是固定的,于是就可以當成特征值進行匹配,下面是find_magic_memory函數的代碼,該函數是drizzleDumper工具的關鍵函數,在該函數中可以看出:先是讀取整個內存文件,隨后判斷該文件是否為ELF文件和dex文件,然后與特征值進行匹配。
[C++] 純文本查看 復制代碼
int find_magic_memory(uint32_t clone_pid, int memory_fd, memory_region *memory , const char *file_name) {
   ......
   while(fscanf(maps_file, "%[^\n]\n", mem_line) >= 0)
   {
    ......
    //獲取內存文件的大小
    memory->start = mem_start;
    memory->end = strtoul(mem_address_end, NULL, 16);
    int len =  memory->end - memory->start;
    ......
	 //掃描內存
	  lseek64(memory_fd , 0 , SEEK_SET);	
	  off_t r1 = lseek64(memory_fd , memory->start , SEEK_SET);
   ......
   //判斷內存文件是否為ELF文件
      if(buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F')
      {
        free(buffer);
        continue;
      }
  //判斷是否為dex文件
     if(buffer[0] == 'd' && buffer[1] == 'e' && buffer[2] == 'x' && buffer[3] == '\n'  && buffer[4] == '0' && buffer[5] == '3')
      {
			  DexHeader header;
			  char real_lenstr[10]={0};
			  memcpy(&header , buffer ,sizeof(DexHeader));
			//對dex文件進行dump
	  		if(dump_memory(buffer , len , each_filename)  == 1)
			  {
			          printf(" [+] dex dump into %s\n", each_filename);
			          free(buffer);
			          continue;
			  }
			  else
			  {
			  	 printf(" [+] dex dump error \n");
			  }

	 	  }
		    free(buffer);
	   }
}

那么脫殼的原理是:在root的權限下運行該工具時,使用ptrace附加到apk程序,接著使用find_magic_memory函數遍歷讀取內存中的文件并使用ODEX的magic對每個文件進行特征值匹配,匹配好后就找到了相應的dex文件并進行內存dump。
6.開啟genymotion中的虛擬機,接下來進行如下脫殼操作:
[Asm] 純文本查看 復制代碼
C:\Users\Lenovo>cd E:\職業\github\drizzleDumper\libs\x86

C:\Users\Lenovo>e:

E:\職業\github\drizzleDumper\libs\x86>dir
 驅動器 E 中的卷是 文檔
 卷的序列號是 B8A0-6DDD

 E:\職業\github\drizzleDumper\libs\x86 的目錄

2020/03/19  11:50    <DIR>          .
2020/03/19  11:50    <DIR>          ..
2020/03/19  11:50             9,532 drizzleDumper
               1 個文件          9,532 字節
               2 個目錄 313,587,281,920 可用字節
E:\職業\github\drizzleDumper\libs\x86>adb push drizzleDumper /data/local/tmp
drizzleDumper: 1 file pushed. 0.1 MB/s (9532 bytes in 0.117s)

E:\職業\github\drizzleDumper\libs\x86>adb shell chmod 0777 /data/local/tmp/drizzleDumper

E:\職業\github\drizzleDumper\libs\x86>adb shell
root@android:/ # su
root@android:/ # pm list packages
...
package:top.phrack.ctf.crazyandroid
package:com.noshufou.android.su
...
root@android:/ # cd /data/local/tmp
root@android:/data/local/tmp # ls
...
CrazyAndroid.apk
drizzleDumper
...
root@android:/data/local/tmp #./drizzleDumper top.phrack.ctf.crazyandroid
...
[*]  Try to Find top.phrack.ctf.crazyandroid
[*]  pid is 1316
[*]  clone pid is 1327
[*]  ptrace [clone_pid] 1327
[*]  Scanning dex ...
...
[+]Done
C:\Users\Lenovo>adb pull /data/local/tmp/top.phrack.ctf.crazyandroid_dumped_5746.dex E:\0ODprogram
/data/local/tmp/top.phrack.ctf.crazyandroid_dumped_5746.dex: 1 file pulled. 3.9 MB/s (868352 bytes in 0.213s)


接著top.phrack.ctf.crazyandroid_dumped_5746.dex放入反編譯工具,就可以查看Java代碼,把不過在下面的分析中,可能用不上脫殼后的dex文件,因為解題的邏輯都會在so層,而不會在activity層,不過脫殼后可以方便調式.在第二部分涉及到動態調式,輸入的用戶名為:pctf(題目要求),通過動態調式獲取某些字符串的具體值,具體怎樣動態調式,我就不說了,比較簡單,網上有教程。

2.分析so文件



1.用IDA加載so文件,沒有找到JNI_OnLoad函數,接著尋找Java_類名_方法名的函數,找到Java_top_phrack_ctf_crazyandroid_MainActivity_CheckSerial,進去發現里面的流程圖結構非常復雜,感覺代碼混淆了。
2345截圖20200321095821.png
2.接著摁f5分析偽代碼,發現里面調用了hehe1、hehe2、hehe3、hehe4函數,感覺這四個函數應該是尋找突破的地方,從程序中可以看出當四個函數都返回1時,注冊才能成功。
2345截圖20200321100331.png
2345截圖20200321100342.png
2345截圖20200321100356.png
2345截圖20200321100404.png
3.進入這四個函數,發現它們的流程結構非常復雜,感覺也加了混淆,但內部邏輯還是看得清楚,在hehe1函數中,發現把輸入注冊碼的前40個字符賦值給某字符串,并且檢驗注冊碼前6位是否等于Pre6,從此看出:注冊碼的長度為40且前6位為Pre6。
hehe1.png
hehe11.png
hehe12.png
4.在hehe2函數中,調用了crazy函數,該函數傳入的參數為:進入crazy函數,找到關鍵代碼處,看到一些混淆代碼行,但這些混淆的代碼不影響代碼的邏輯分析,該函數主要是對某字符串進行處理新的字符串。
crazy.png
5.在下面可以看出hehe2函數,先是判斷input[23]和input[6]是否為'-',接著對input[6:23]字串進行值變換。
hehe2.png
hehe21.png
hehe23.png
6.在hehe3函數中,可以看出判斷input[25:31]是否為v2,動態調式發現v2為Java代碼傳來的參數,為170501
hehe3.png
7.在hehe4函數中,可以看到padding字符串,使用idapython腳本,可以看出該字符串的值,腳本見下。
[Python] 純文本查看 復制代碼
def Getpadding(str_addr):
	tpadding=''
	while(1):
		#判斷循環是否結束
		if hex(Byte(str_addr))=='0x0':
			break
		#疊加字符串字符生成字符串
		tpadding+=chr(Byte(str_addr))
		str_addr+=1
	return tpadding
print Getpadding(0x6046)

運行結果:
padding.png
8.動態分析發現crazy(padding, 88)返回值為'075e191fe314c1e7917d9c71f7b6ed9842090f28f649bad384d0880d103b99a8',隨后把返回拼接到input字符串的后面,通過代碼可以看出截取input的長度為30,把拼接后的字符串進行運算操作,結果為2765405600。
hehe41.png
hehe44.png
呵呵43.png
9.最后把hehe4生成的序列值拼接到input后面,隨后對input進行字符變換,生成的字符串為flag,生成的flag的代碼如下:
[Python] 純文本查看 復制代碼
# -*- coding:utf-8 -*-
from random import choice
pre6='pctfef'
hehe3_8="Pctf2016"
hehe3_8_o=[]
javastr='170501'
base='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+'
#把hehe3_8中的字符轉換成十進制數
def Hehe3_8ToOrd():
	for i in hehe3_8:
		hehe3_8_o.append(ord(i))

'''
def GetBase(str_addr):
	base=''
	while(1):
		#判斷循環是否結束
		if hex(Byte(str_addr))=='0x0':
			break
		#疊加字符串字符生成字符串
		base+=chr(Byte(str_addr))
		str_addr+=1
	return base
'''
def Getpadding(str_addr):
	tpadding=''
	while(1):
		#判斷循環是否結束
		if hex(Byte(str_addr))=='0x0':
			break
		#疊加字符串字符生成字符串
		tpadding+=chr(Byte(str_addr))
		str_addr+=1
	return tpadding
def getlast():
	#base=GetBase(0x6004)
	last=base[-12:]
	return last
def crazy(a,b):
	t1=a<<4
	t2=~b+1
	t2=0xD0-t2
	ans=(t2 ^ t1) | (t2 &t1 )
	return ans & 0xFF

def hehe2():
	AnsT=''
	AllT=[]
	AnsT=''
	Hehe3_8ToOrd()
	last=getlast()
	for i in range(0,len(hehe3_8_o)):
		t= []
		for j in last:
			for k in last:
				if crazy(ord(j), ord(k)) == hehe3_8_o[i]:
					t.append(j + k)
		AllT.append(t)
	for i in AllT:
		#在列表I中,找出任意值
		AnsT += choice(i)
	AnsTL = list(AnsT)
	index=[5,6,9,11,12,13,14,15]
	i=0
	#對列表值進行交換
	while i <len(index):
		i1=index[i]
		i2=index[i+1]
		i+=2
		t1=AnsTL[i1]
		t2=AnsTL[i2]
		AnsTL[i1]=t2
		AnsTL[i2]=t1
	str1=''.join(AnsTL)
	return str1
def hehe4():
	padding = '075e191fe314c1e7917d9c71f7b6ed9842090f28f649bad384d0880d103b99a8'
	str1=hehe2()
	#AnsCode相當于input,len為30
	AnsCode=pre6+'-'+str1+'-'+javastr
	enstr = AnsCode + padding
	ans = 0
	for i in enstr:
		t = ord(i) - (~(0x28 * ans) + 1)
		ans = t & 0xFFFFFFFF
	return AnsCode+str(ans)
keyTokey={}
def GetFlag():
	str1=hehe4()
	key1=base[26:52]+base[0:26]+base[-12:]
	key2=key1[13:26]+key1[0:13]+key1[39:52]+key1[26:39]+key1[57:62]+key1[52:57]+key1[-2:]
	#生成key的值對應字典
	for i in range(0,len(key2)):
		keyTokey[key2[i]] = key1[i]
	flag=''
	for i in str1:
		flag+=keyTokey[i]
	print 'flag: ',flag
GetFlag()

運行結果:
flag.png

CrazyAndroid.rar

1.06 MB, 下載次數: 6, 下載積分: 吾愛幣 -1 CB

售價: 1 CB吾愛幣  [記錄]

免費評分

參與人數 3威望 +2 吾愛幣 +103 熱心值 +3 收起 理由
qtfreet00 + 2 + 100 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
笙若 + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
為海爾而戰 + 2 + 1 我很贊同!

查看全部評分

發帖前要善用論壇搜索功能,那里可能會有你要找的答案或者已經有人發布過相同內容了,請勿重復發帖。

 樓主| buzhifou01 發表于 2020-3-26 11:23
52Douyin 發表于 2020-3-26 10:58
謝謝大神。
所有用到的軟件,也能打包,提供下載啊,就好了。

我用到的工具,網上都好下載,百度一搜都有的
52Douyin 發表于 2020-3-26 10:58
謝謝大神。
所有用到的軟件,也能打包,提供下載啊,就好了。
52Douyin 發表于 2020-3-26 10:57
紅人館0910 發表于 2020-3-26 11:28
nice啊 快來下載吧
hyoulin68 發表于 2020-3-26 11:34
謝謝大神。
fangcanqun 發表于 2020-3-26 13:45
不明覺厲~好好學習~
luxingyu329 發表于 2020-3-26 13:50
現在找不到了!
zoooox 發表于 2020-3-26 16:09
感謝分享,學到了一些工具
雙木成林 發表于 2020-3-26 20:01

感謝分享,學到了一些工具
您需要登錄后才可以回帖 登錄 | 注冊[Register]

本版積分規則 警告:本版塊禁止灌水或回復與主題無關內容,違者重罰!

快速回復 收藏帖子 返回列表 搜索

RSS訂閱|小黑屋|聯系我們|吾愛破解 - LCG - LSG ( )

GMT+8, 2020-4-4 22:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回復 返回頂部 返回列表
安徽快3-推荐 重庆快3-Welcome 北京快3-欢迎您 上海快3-Home 湖北快3-安全购彩 湖南快3-广西快三 河北快3-推荐 大发11选5-推荐 河南快3-Welcome 广东快3-Home