Flare on writeup 2017 writeup

Flareon是主要题目为逆向的一场CTF比赛,已经是第四届了,比赛时间一个月左右。
这是第一次参加这个比赛,今年没拿到牌子,明年再战!



ROT13

题面

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

<!DOCTYPE Html />
<html>
<head>
<title>FLARE On 2017</title>
</head>
<body>
<input type="text" name="flag" id="flag" value="Enter the flag" />
<input type="button" id="prompt" value="Click to check the flag" />
<script type="text/javascript">
document.getElementById("prompt").onclick = function () {
var flag = document.getElementById("flag").value;
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert("Incorrect flag, rot again");
}
}
</script>
</body>
</html>

解题

解rot13即可

1
2
alias rot13="tr '[A-Za-z]' '[N-ZA-Mn-za-m]'"
echo PyvragFvqrYbtvafNerRnfl@syner-ba.pbz | rot13

flag: ClientSideLoginsAreEasy@flare-on.com

Igniteme

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
signed int check()
{
int len; // ST04_4
int i; // [esp+4h] [ebp-8h]
unsigned int ia; // [esp+4h] [ebp-8h]
char key; // [esp+Bh] [ebp-1h]

len = strlen((int)input_cpy);
key = getkey();
for ( i = len - 1; i >= 0; --i )
{
cmpprep[i] = key ^ input_cpy[i];
key = input_cpy[i];
}
for ( ia = 0; ia < 0x27; ++ia )
{
if ( cmpprep[ia] != (unsigned __int8)cmptable[ia] )
return 0;
}
return 1;
}

程序启动后输入字符串XOR然后做对比。

解题

1
2
3
4
5
vp = [0x0D, 0x26, 0x49, 0x45, 0x2A, 0x17, 0x78, 0x44, 0x2B, 0x6C, 0x5D, 0x5E, 0x45, 0x12, 0x2F, 0x17, 0x2B, 0x44, 0x6F, 0x6E, 0x56, 0x09, 0x5F, 0x45, 0x47, 0x73, 0x26, 0x0A, 0x0D, 0x13, 0x17, 0x48, 0x42, 0x01, 0x40, 0x4D, 0x0C, 0x02, 0x69, 0x04]
for i in range(len(vp)-2, -1, -1):
vp[i] = vp[i] ^ vp[i+1]
vp = ''.join([ chr(i) for i in vp[:-1]])
# R_y0u_H0t_3n0ugH_t0_1gn1t3@flare-on.com

Greektome



这是一个使用套接字从另一台机器接收数据的程序。看看代码我们可以看到IP地址=’127.0.0.1’和端口= 0x8AE = 2222的程序是开放的。Buf 接收4个字节=> len(data_send)<= 4

收到数据后,程序使用loc_40107c []数组中的元素将Buf [0]替换为xor, 并添加22h ,然后将其保存到数组。



实质上
输入被分成多组,每组20个字符,密钥验证算法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# # Key judgement
# for &bytes in 0x40107c -> 0x40107c+0x79:
# bytes ^= key
# bytes += 0x22
# assert( 0xFB5E == sub_4011E6(0x40107C, 0x79) )

# # sub_4011E6(x,y)
# assert( y != 0)
# ebx = x
# eax = 0x14
# {
# di = (int16)var_4
# esi = min(eax, edx)
# edx -= esi
# {
# eax =
# }
# }
# // CMOVx: Conditional move according to X
# v2: 0x79 -> 0x65 -> 0x51 -> 0x3D -> 0x29 -> 0x15 -> 0x01 -> 0

解题

爆破

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
def generator(a1,a2):
v2 = a2
v3 = 0xff
v8 = 0xff
if not a2:
raise ValueError
v4 = a1
scanned = 0
while v2:
v5 = v8
v6 = 0x14 if v2>0x14 else v2
v2 = v2 - v6
for i in range(v6):
v5 = v5 + a1[scanned]
v5 = v5 & 0xFFFF
v3 = v3 + v5
v3 = v3 & 0xFFFF
scanned = scanned + 1
#print("% 3d - % 3d"%(scanned, v6))
v8 = (v5 >> 8) + (0xff&v5)
v8 = v8 & 0xFFFF
v3 = (v3 >> 8) + (0xff&v3)
v3 = v3 & 0xFFFF
print("=== % 4x = % 4x ==="%(v8,v3))
return ( (v8 >> 8) + ((0xFF) & v8) ) | ( 0xFFFF & ( (v3 << 8) + ((0xFF00) & v3) ) )

def check(xk):
borg = """
33 E1 C4 99
11 06 81 16 F0 32 9F C4 91 17 06 81 14 F0 06 81
15 F1 C4 91 1A 06 81 1B E2 06 81 18 F2 06 81 19
F1 06 81 1E F0 C4 99 1F C4 91 1C 06 81 1D E6 06
81 62 EF 06 81 63 F2 06 81 60 E3 C4 99 61 06 81
66 BC 06 81 67 E6 06 81 64 E8 06 81 65 9D 06 81
6A F2 C4 99 6B 06 81 68 A9 06 81 69 EF 06 81 6E
EE 06 81 6F AE 06 81 6C E3 06 81 6D EF 06 81 72
E9 06 81 73 7C """
bbs = [(0xff&((i^xk)+0x22)) for i in list(bytes.fromhex(borg.replace("\n", "")))]
return generator(bbs, 0x79)
j = 0
for i in range(0xff):
if ( check(i) == 0xFB5E ):
j=i
break

# j = 0xa2
# Now it is time to check bytes
for i in range(0x79):
ida_bytes.patch_byte(0x40107c+i, ida_bytes.get_byte(0x40107c+i)^j)
# et_tu_brute_force@flare-on.com

Notepad

这个题目就略坑了。。
此题wp参考 杜师傅 https://bbs.xdsec.club/d/116-flare-on-4-challange-problem-1-11-writeup

一道侧重于样本分析的程序。源程序是Windows的记事本,被在另一个段注入了新代码,并修改了OEP。新代码会使用ROR13获取所有加载模块的哈希,并按照如下算法比较并存储之

1
2
3
for module in PEB->LDRDATA->InMemoryOrderModuleList
if HashROR13(module.name)==HashROR13(TargetModuleName):
return module # for futher usage ;)

注意的是,在我的Windows 10中,这段程序会出问题,因为由于一些未知的原因,这段代码在我机器上获取的模块名称为大写,而ROR13的实现是区分大小写的。我们在0x10153F6下断点,断点日志为Parsing {s:edx},查看日志:

1
2
3
4
5
6

Parsing L"4_notepad.exe"
Parsing L"ntdll.DLL"
Parsing L"KERNEL32.DLL"
Parsing L"KERNELBASE.dll"
Parsing L"comdlg32.dll"

可以发现KERNEL32被跳过了。patch掉此处,便于动态调试。

对于被调用的函数,我们可以用Flare-IDA中的Shellcode-hashes脚本来辅助分析。静态分析后发现,程序在遍历%USERPROFILE%/flareon2016challenge目录下的文件,检查其时间是否符合特征值。如果符合,就提取出其中的八个字节到key.bin中,以此类推。Swings师傅提醒后,发现正确的文件是从去年的题目包中下载的(P.S 我觉得这个题设计的一般)。释放文件后再次执行程序,会弹出对话框:

bl457_fr0m_th3_p457@flare-on.com

Pewpewboat

这是一个linux下的游戏
关卡有100关,
我们在静态分析下main函数



该函数genInitialSeed (0x403C85)生成用于“解密”游戏数据的初始种子。我会让你读它,但它本质上MD5是”loading… %d%%”一个循环中的字符串,%d每次递增。
然后,我们将看到99个级别的循环,每次迭代从576个字节的表复制游戏数据,然后使用以下命令解密它seed

我们可以进看一下他的循环



从drawGrid (0x403263)功能上我们可以看到,我们输入的坐标和“船”的实际位置都存储在gameState。该代码将根据用户输入的坐标来检查正确的坐标,并且只有在有匹配的情况下才绘制



我们继续process (0x04038D6)处理从用户输入的功能,检查命中并根据需要提前游戏状态。在这个功能中,你将会看到游戏状态中的更多内容,比如你的排名(例如“Seaman Recruit”):

解题

回到游戏流程。每轮游戏中,你的输入值除了会影响DiskStatus外,还会被原样放到上面结构体的LastInputUpperCase中。如果对应的点在GoodStatus中为True,那么就算击中。此外,每轮游戏中,checksum值都会变,用来解密下一轮游戏。

所以我们通过解数据的方式解决



这个程序算出来的值的前8个字节就是这关的过关关键

依次过关之后会出现

1
Aye! You found some letters did ya? To find what you're looking for, you'll want to re-order them: 9, 1, 2, 7, 3, 5, 6, 5, 8, 0, 2, 3, 5, 6, 1, 4. Next you let 13 ROT in the sea! THE FINAL SECRET CAN BE FOUND WITH ONLY THE UPPER CASE

的提示

重新组织地图字母FHGUZREJVO得到OHGJURERVFGUREHZ
rot13之后得到BUTWHEREISTHERUM

直接输入到程序中就得到flag了。。

y0usUnK_mYP3Wp3w_b04t@flare-on.com

今晚先写到这。。明天继续写

Payload

突然发现国内有有人写的挺完整的 我就不继续往下写了

突然发现国内有有人写的挺完整的 我就不继续往下写了
附上连接
http://blog.nsfocus.net/flare-onchallenge4th/

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. ROT13
    1. 1.1. 题面
    2. 1.2. 解题
  2. 2. Igniteme
    1. 2.1. 解题
  3. 3. Greektome
    1. 3.1. 解题
  4. 4. Notepad
  5. 5. Pewpewboat
    1. 5.1. 解题
  6. 6. Payload
  7. 7. 突然发现国内有有人写的挺完整的 我就不继续往下写了
,