Flareon是主要题目为逆向的一场CTF比赛,已经是第四届了,比赛时间一个月左右。
这是第一次参加这个比赛,今年没拿到牌子,明年再战!
https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/2017-flare-on-result.jpg
ROT13 题面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <!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; int i; unsigned int ia; char key; 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 ]])
Greektome
![](https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/17-flare-on-greektome-01.jpg)
这是一个使用套接字从另一台机器接收数据的程序。看看代码我们可以看到IP地址=’127.0.0.1’和端口= 0x8AE = 2222的程序是开放的。Buf 接收4个字节=> len(data_send)<= 4
收到数据后,程序使用loc_40107c []数组中的元素将Buf [0]替换为xor, 并添加22h ,然后将其保存到数组。
![](https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/17-flare-on-greektome-02.jpg)
实质上 输入被分成多组,每组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 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 for i in range (0x79 ): ida_bytes.patch_byte(0x40107c +i, ida_bytes.get_byte(0x40107c +i)^j)
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函数
![](https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/17-flare-on-pewpewboat-01.jpg)
该函数genInitialSeed (0x403C85)生成用于“解密”游戏数据的初始种子。我会让你读它,但它本质上MD5是”loading… %d%%”一个循环中的字符串,%d每次递增。 然后,我们将看到99个级别的循环,每次迭代从576个字节的表复制游戏数据,然后使用以下命令解密它seed
我们可以进看一下他的循环
![](https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/17-flare-on-pewpewboat-02.jpg)
从drawGrid (0x403263)功能上我们可以看到,我们输入的坐标和“船”的实际位置都存储在gameState。该代码将根据用户输入的坐标来检查正确的坐标,并且只有在有匹配的情况下才绘制
![](https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/17-flare-on-pewpewboat-03.jpg)
我们继续process (0x04038D6)处理从用户输入的功能,检查命中并根据需要提前游戏状态。在这个功能中,你将会看到游戏状态中的更多内容,比如你的排名(例如“Seaman Recruit”):
解题 回到游戏流程。每轮游戏中,你的输入值除了会影响DiskStatus外,还会被原样放到上面结构体的LastInputUpperCase中。如果对应的点在GoodStatus中为True,那么就算击中。此外,每轮游戏中,checksum值都会变,用来解密下一轮游戏。
所以我们通过解数据的方式解决
![](https://blog-1252049492.cos.ap-hongkong.myqcloud.com/img/17-flare-on-pewpewboat-04.jpg)
这个程序算出来的值的前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了。。
y0u__sUnK_mY__P3Wp3w_b04t@flare-on.com
今晚先写到这。。明天继续写
Payload 突然发现国内有有人写的挺完整的 我就不继续往下写了 突然发现国内有有人写的挺完整的 我就不继续往下写了 附上连接http://blog.nsfocus.net/flare-onchallenge4th/