一、Bang
拿到手是一個APK文件,打開看一下:
題目描述簡單加殼,於是想到用frida脫殼腳本:
得到dex文件並用jeb打開:
可以看到直接得到了flag
二、Signal
vm題:
太長了,寫個腳本模擬一下流程:(這里貼上最后的腳本,驗證內容直接寫了flag,為了驗證正確性)
#include<iostream> #include<stdlib.h> using namespace std; unsigned char a[] = { 0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xA7, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; int main() { int len; int v9=v8=v7=v6=v5=0,tmp; char *v3 = "757515121f3d478"; unsigned char v4[100]; len = sizeof(a); for(int v10=0;v10<len;) { switch(a[v10]) { case 1: cout<<"[*] v4[v7] = v5"<<endl; v4[v7] = v5; cout<<"v7="<<v7<<endl; cout<<"v4["<<v7<<"]="<<v5<<endl; v10+=4; ++v7; ++v9; break; case 2: cout<<"[*] v5 = a1[v10 + 1] + v3[v9]"<<endl; v5 = v3[v9] + a[v10 + 4]; printf("a1[v10+1]=%d\n",a[v10+4]); tmp =v3[v9]; cout<<"v3[v9]="<<tmp<<endl; cout<<"v5="<<v5<<endl; v10+=8; break; case 3: cout<<"[*] v5 = v3[v9] - LOBYTE(a1[v10 + 1])"<<endl; v5 = v3[v9] - (a[v10 + 4]); printf("a1[v10+1]=%d\n",a[v10+4]); tmp =v3[v9]; cout<<"v3[v9]="<<tmp<<endl; cout<<"v5="<<v5<<endl; v10+=8; break; case 4: cout<<"[*] v5 = a1[v10 + 1] ^ v3[v9]"<<endl; v5 = a[v10 + 4] ^ v3[v9]; printf("a1[v10+1]=%d\n",a[v10+4]); tmp =v3[v9]; cout<<"v3[v9]="<<tmp<<endl; cout<<"v5="<<v5<<endl; v10+=8; break; case 5: cout<<"[*] v5 = a1[v10 + 1] * v3[v9]"<<endl; v5 = v3[v9] * a[v10 + 4]; printf("a1[v10+1]=%d\n",a[v10+4]); tmp =v3[v9]; cout<<"v3[v9]="<<tmp<<endl; cout<<"v5="<<v5<<endl; v10+=8; break; case 6: cout<<"[*] ++v10"<<endl; cout<<"v10="<<v10<<endl; v10+=4; break; case 7: cout<<"[*] compare.."<<endl; cout<<"v8="<<v8<<endl; printf("v4[v8]=%d\n",v4[v8]); printf("a1[v10+1]=%d\n",a[v10+4]); ++v8; v10+=8; break; case 8: cout<<"[*] v3[v6] = v5"<<endl; v3[v6] = v5; cout<<"v3[v6]="<<v5<<endl; cout<<"v6="<<v6<<endl; v10+=4; ++v6; break; case 10: //read(v3); cout<<"[*] read"<<endl; v10+=4; break; case 11: cout<<"[*] v5 = v3[v9] - 1"<<endl; v5 = v3[v9] - 1; tmp =v3[v9]; cout<<"v3[v9]="<<tmp<<endl; cout<<"v5="<<v5<<endl; v10+=4; break; case 12: cout<<"[*] v5 = v3[v9] + 1"<<endl; v5 = v3[v9] + 1; tmp =v3[v9]; cout<<"v3[v9]="<<tmp<<endl; cout<<"v5="<<v5<<endl; v10+=4; break; default: continue; } } return 0; }
可以清楚的看到運算過程,之后再逆着推一遍就可以了。
三、Joker
這道題是個代碼自修改的題目。
看到
修改了代碼段的encrypt函數,又看到下面進行了異或操作:
簡單修復后F5查看:
經過分析,wrong函數和omg函數沒有用。
encrypt函數把輸入和hahahaha_do_you_find_me?異或,與dword_403040比較
寫py:
可以看到少了后面幾位,看下一個函數:
這個函數邏輯明顯有問題。。。
X32dbg看這里是time(0)
而且
這里對於v8的操作也沒有正確反編譯。
后來想到字符串中的提示:
隱藏了后面幾位,並且不會成功,暗示着這個函數就是有問題的。
但是flag格式是固定的flag{}
所以根據最后一位是}來推斷,與
逐位異或71
所以得到了后面幾位:b37a}
完整拼接后得到flag{d07abccf8a410cb37a}