SCTF部分题解

sctf部分题解

先看安卓题,下载后载入apkide,没有发现mainactivity,但是配置文件中说了入口点是mainactivity,所以说入口应该被藏了起来,去翻下assets文件夹下有个test.zip,无法解压,猜测就是mainactivity所在地了,

123

看下代码,

123

可以猜到对那个zip做了一系列操作之后用dexloader加载了,什么操作也不用管,只需要拿到加载进入内存的dex就行了,下面也好办,只要内存里dump出来加载后的dex就行了,直接用脱壳机取出dex

123

可以看到脱完壳的dex,导出之后放入jeb分析,可以发现输入是24位的,对之后初始化了8个点阵,然后通过输入去进行对点阵进行操作,最后最8个点阵进行检测,直接爆破就可以了

123

123

只要爆破三次循环就行了,其中对应的v5要分别修改成0,8,16

123

于是可以分三次跑出flag(每一次都选取跑出来的前8位)

再看下面一题,打开后是一个游戏文件夹,可以看到是unity的东西,一开始被名字欺骗了,cheat egine,嗯。。。各种调试器各种搞各种失败,后来才发现里面有反调,决定还是以正常的思路去做,游戏逻辑都是保存在CAssembly-CSharp.dll里的(手游也不例外),只要用dnspy去逆这个.net的东西就好了,找到判断逻辑的地方,修改就可以了

123

修改关键逻辑之后保存,再打开游戏就可以看到flag了,
123

再看下一个,js的逆向,打开后直接可以看到判断在r这个方法里,控制台输出一下

123

其实就是一个类似白盒测试的过程,看上去很复杂的东西其实只是完成了加减乘除之类的简单功能

123

贴下全部代码,本来还以为是线性方程组之类的,发现根本用不到,口算就可以出结果

function  r(r){
var n=r;
var a=H(n);  H(r){return r.length}
var v=J(a,24);            //  J(r,n){return!(r^n)}                                                       //长度等于24
var t=K(n,0);            //K(r,n){return r[n]}
var u=K(n,1);
var i=K(n,2);
var e=K(n,3);  //这里取出前四位 
var f=D(L(t),L(i));   D(r,n){return n?D(r^n,(r&n)<<1):r}   L(r){if(r.length==1){return r.charCodeAt(0)}}  //第一位和第三位的ascii码传入L方法
var o=E(L(t),L(u));   E(r,n){return D(r,a(n))}  a(r){return D(~r,1)}                                    //第一位和第二位的ascii传入复杂分析   a的功能就是取反  D就是前和  E就是差 J就是判断是否一样
var c=K(n,6);    
var l=K(n,7);
var h=K(n,16);
var w=K(n,17);  //取出7,8,17,18位
var I=J(E(L(u),L(h)),0);                                                                   //-->flag[1]==flag[16]
var S=J(D(L(c),L(l)),D(L(h),L(w)));                                                                   //-->flag[6]+flag[7]==flah[16]+flag[17] -->
var _=J(E(L(u),L(c)),0);                                                                      //-->flag[1]==flag[6]
var g=K(n,21);
var p=K(n,22); 取出两位
var s=J(E(F(L(g),2),G(66,L(p))),64);  F(r,n){var a=0;while(n){if(n&1){a=D(a,r)}r=r<<1;n=n>>1}return a} --》//flag[21]*2-66/flag[22]==64
var P=Q(9,15,n,"Pt_In_S");  Q(r,n,a,v){for(var t=r;t<=n;t++){if(a[t]!=v[t-r]){return false}}return true}   //flag[9]--flag[15]== Pt_In_S               
var T=J(L(l),L("r"));                                                                                //-->flag[7]==r
var b=J(f,231                                                                                      //  -->flag[0]+flag[2]==231
var d=J(o,16);                                                                                    //   -->flag[0]-flag[1]==16
var j=M(K(n,5));                                                                                     //-->flag[5]必定是数字
var k=J(G(M(O(ToString(L(e)),"0")),j),204);                                                        //  --》flag[3]*10/flag[5]==204
var m=M(K(n,8));                                                                                     //-->flag[8]是数字  
var q=Q(18,20,n,"IpT");                                                                              //-->flag[18]--flag[20]==IpT
var x=J(E(j,m),4);                                                                                   //--》flag[5]-flag[8]==4  
var y=J(F(m,m),m);                                                                                   //-->m*m=m  -->m=1 flag[5]='5' flag[8]='1'
var z=J(D(L(K(n,4)),D(m,m)),L(K(n,23)));
var A=J(L(u),99);                                                                                    //-->flag[1]==99
 var B=J(L(K(n,23)),125);                                                                                // -->flag[23]=}
var C=J(L(K(n,22)),33);                                                                              //-->flag[22]=!
return v&&I&&S&&_&&s&&P&&T&&b&&d&&k&&q&&x&&y&&z&&A&&B&&C
}

整理下就可以得到结果

123

肥宅快乐游,就很简单,下载后发现是flash,根据提示可以知道flag在游戏通关后的npc对话附近,直接跳帧到游戏最后

123

可以看到提示中有project之类的字样,直接用反编译flash的工具,对特征文本搜索下就能定位到关键位置,看到base64后的flag

123

解码后得到flag,密码学的第二题,一开始似乎就当成普通的大数取余问题算,发现脚本各种error,由于数太大,很麻烦,后来听说了一些数学工具,在工具的帮助下可以很轻松得到flag

123

不得不说,wolframalpha牛逼,不过感觉自己还是太垃圾了,有难度的题目都没做出来,做了一堆水题,mips逆不来,crackme2跟不起来,还是缺少耐心,积淀,和练习,慢慢来吧,也只能这样安慰自己了