• Reverse Script In Script
  • Reverse Where is my 13th count?
  • Reverse simple
  • Misc Welcome to SCTF 2018
  • Misc 神秘的交易
  • Misc 肥宅快乐题
  • Misc 侧信道初探
  • Web easiest web - phpmyadmin

Script In Script

JavaScript代码全部压缩,不忍直视。在Chrome的Console中输入函数的名称可以直接看到函数代码,找出r以及相关的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
function r(r) {
var n = r;
var a = H(n);
var v = J(a, 24); //len(flag)==24
var t = K(n, 0);
var u = K(n, 1);
var i = K(n, 2);
var e = K(n, 3);
var f = D(L(t), L(i));
var o = E(L(t), L(u));
var c = K(n, 6);
var l = K(n, 7);
var h = K(n, 16);
var w = K(n, 17);
var I = J(E(L(u), L(h)), 0);
var S = J(D(L(c), L(l)), D(L(h), L(w)));
var _ = J(E(L(u), L(c)), 0);
var g = K(n, 21);
var p = K(n, 22);
var s = J(E(F(L(g), 2), G(66, L(p))), 64);
var P = Q(9, 15, n, "Pt_In_S"); //sctf{????Pt_In_S??IpT??}
var T = J(L(l), L("r"));
var b = J(f, 231);
var d = J(o, 16);
var j = M(K(n, 5));
var k = J(G(M(O(N(L(e)), "0")), j), 204);
var m = M(K(n, 8));
var q = Q(18, 20, n, "IpT");
var x = J(E(j, m), 4);
var y = J(F(m, m), m);
var z = J(D(L(K(n, 4)), D(m, m)), L(K(n, 23)));
var A = J(L(u), 99);
var B = J(L(K(n, 23)), 125);
var C = J(L(K(n, 22)), 33);
return v && I && S && _ && s && P && T && b && d && k && q && x && y && z && A && B && C
}

function H(r) { return r.length }

function J(r, n) { return !(r ^ n) }

function K(r, n) { return r[n] }

function L(r) {
if (r.length == 1) {
return r.charCodeAt(0)
}
}

function D(r, n) { return n ? D(r ^ n, (r & n) << 1) : r }

function E(r, n) { return D(r, a(n)) }

function a(r) { return D(~r, 1) }

function F(r, n) {
var a = 0;
while (n) {
if (n & 1) {
a = D(a, r)
}
r = r << 1;
n = n >> 1
}
return a
}

function Q(r, n, a, v) {
for (var t = r; t <= n; t++) {
if (a[t] != v[t - r]) {
return false
}
}
return true
}

function M(r) { return +r }

function G(r, n) {
var a = 0;
while (r >= n) {
r = E(r, n);
a = D(a, 1)
}
return a
}

function N(r) { return String(r) }

function O(r, n) { return r + n }

r的内容很简单,检查flag长度是否为24,再分别对其中的字符进行检查。J是相等,L是字符转为ascii码,Q是字符串比较,后经dydxh提醒,DEFG分别是加减乘除。有了这些就很容易能推出flag的各字符了(其实根据题目的名字也能猜出来一部分flag)。

flag:sctf{5cr1Pt_In_ScrIpT!!}

Where is my 13th count?

这道题的思路和前几周的SUCTF中的“RoughLike与期末大作业”一题思路如出一辙。看题目的名字应该是要吃到13个方块。用.NET Reflector打开Cheat Engine_Data\Managed\Assembly-CSharp.dll,找到PlayerController::OnTriggerEnter(Collider other),这就是球碰到方块时的事件处理函数了

1
2
3
4
5
6
7
8
9
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Pick Up"))
{
other.gameObject.SetActive(false);
this.count++;
this.SetCountText();
}
}

打开Reflexil插件,找到other.gameObject.SetActive(false);一行对应的IL,

OffsetOpCodeOperand
21ldarg.1
22callvirtUnityEngine.GameObject UnityEngine.Component::get_gameObject()
27ldc.i4.0
28callvirtSystem.Void UnityEngine.GameObject::SetActive(System.Boolean)



将Offset为27的那行的指令改成ldc.i4.1,相当于将原来的other.gameObject.SetActive(false);改成了other.gameObject.SetActive(true);,保存,退出。用魔改后的dll换掉原来的,再启动游戏。这回吃到方块之后方块不会消失了,绕场一周,多吃几个方块就能看到flag了

flag:SCTF{ThEFLAGGGGGGG}

simple

对安卓逆向懂得不是很多 (实际上是什么逆向都不懂),老实说这题是连蒙带猜做出来的。打开源代码之后居然连MainActivity.java都没有……看了看ProxyApplication.java里面有一行FindAssetfile.getAssetsFile(this, "test.zip", paramContext, null);,像是打开了test.zip,然而看直接解压apk找到的test.zip,虽然开头是PK,但是后面的内容显然不是zip,可能有猫腻。再看FindAssetfile.java,这段代码比较诡异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
catch (IOException paramContext)
{
paramContext.printStackTrace();
while (true)
{
return null;
if (paramMethod == null)
break;
paramContext = (byte[])paramMethod.invoke(null, new Object[] { localByteArrayOutputStream.toByteArray() });
paramString1.close();
localByteArrayOutputStream.close();
paramString1 = new FileOutputStream(new File(paramString2));
paramContext[0] = 113;
paramContext[1] = 114;
paramContext[2] = 10;
paramContext[3] = 8;
paramString1.write(crypt(paramContext, "E82038F4B30E810375C8365D7D2C1A3F"));
paramString1.close();
}
}

crypt是RC4加密算法,猜测这段代码是把test.zip的内容用RC4加密了一遍,试着解密了一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def rc4(plain,key):
s=[i for i in range(256)]
i=0
j=0
while i<256:
j=(s[i]+j+ord(key[i%len(key)]))%256
s[j],s[i]=s[i],s[j]
i+=1
k=0
cipher=list(plain)
n=len(cipher)
i=0
j=0
while i<n:
j=(j+1)%256
k=(s[j]+k)%256
s[k],s[j]=s[j],s[k]
cipher[i]=chr(ord(cipher[i])^s[(s[j]+s[k])%256])
i+=1
return ''.join(cipher)


def main():
key='E82038F4B30E810375C8365D7D2C1A3F'
plain=open('test.zip','r').read()
plain='\x71\x72\x0A\x08'+plain[4:]
open('1.dex','w').write(rc4(plain,key))


if __name__=='__main__':
main()

根据文件开头的dex推测是Dalvik字节码,再次使用dex2jar和jd-gui查看源码,这回出现了MainActivity.java,有的代码有微小的错误,但是整体上影响不大,剩下的就是逆向了。因为实在不想写java,就用python把Square和Point重新实现了一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class point:
...

class square:
...


def main():
good=[]
j=0
while j<24:
i=49
while i<112:
if square((i<<8)+828309504+255,j/2+4).check():
good.append(i)
i+=1
j+=8
print(''.join(map(lambda x:chr(x),good)))


if __name__=='__main__':
main()

运行出来结果是57=?UW]_QSUWY[]_9;=?Y[]_,要说这一堆乱七八糟的东西是flag我是打死也不会信的,然而放到安卓模拟器里试了一下,还真出来个Success,行吧,被安排的明明白白,我也不说什么了。

flag:SCTF{57=?UW]_QSUWY[]_9;=?Y[]_}

Welcome to SCTF 2018

打开题目,找到sctf开头的那一行,选中,按Ctrl+C,点击输入flag的那个文本框,按Ctrl+V,点击提交,重点是手速要快。

神秘的交易

淘宝上搜索逻辑分析仪,看里面的详情页,可以知道logicdata文件是Saleae Logic产生的,打开之,参照着看雪上的帖子[原创]用逻辑嗅探破解接触式IC卡口令,寻找0x33,看教程上数据貌似是反着的,也就是0x33是11001100,在6s900ms附近可以找到这段数据

可以看到第一段指令是0x33 0x01 0x40,所以密码第一字节是0x40,后两段命令与此类似,分别是0x33 0x02 0x31和0x33 0x03 0x10,所以密码是0x40 0x31 0x10,然而我并没有看出来这是哪门子的门牌号。

flag:SCTF{403110}

肥宅快乐题

试着玩了两局,不出3关就挂了,用SWFDecomplier逆向到一半就死机了,简单粗暴一点,把播放器的进度条直接向后拖,拖到第57帧就能看过场动画了

1
2
$ echo -ne 'U1lDe0YzaVpoYWlfa3U0aWxlX1QxMTF9'|base64 -d -
SYC{F3iZhai_ku4ile_T111}

别说做完这道题还真的想买一瓶肥宅快乐水了23333

flag:SYC{F3iZhai_ku4ile_T111}

侧信道初探

最开始的思路出现了偏差,后来想通了,不管key是0还是1,都会执行R <- [2]R这条指令,但如果key是1,还会额外执行R <- R + P这条指令,所以在能量图上只有密集的一条的是0,一条密集的一条稀疏的是1。

这里必须吐槽一下flag的格式了,首页上写的是sctf{},然而用小写字母提交是错的,甚是无奈

flag:SCTF{0110111010}

easiest web - phpmyadmin

我这种web一点也不会的人就只会做这道题了,利用phpmyadmin来产生一个webshell。密码是root:root,登录进去之后,把general log变量设置成ON,phpmyadmin入口处网址加上index.php?lang[]=1让php报错,爆出绝对地址,把general log file变量设成想生成的webshell的地址,比如C:\phpStudy\WWW\xx.php,然后执行查询语句select '<?php @eval($_GET[ddd]);?>' from mysql.user where 1=1,这样webshell就被写到xx.php里面了(实际做题的时候战斗太激烈了,general log file被改来改去,索性不改了,直接把自己的webshell写到别的队的webshell里)。祭出黑站神器——中国菜刀,连接上webshell,大肆搜刮一番,找到flag。

flag:sctf{31cf2213cc49605a30f07395d6e5b9c4}