今天这个难度比较恐怖,只做了一个有类似题目的misc-apl,其实觉得比较接近逆向题
代码解base64后得到看起来很奇怪的apl代码
{⍵(~⍵)/('No_Please_continue')('Yes,This_is_flag')}(∊(41(41)0+140)(⎕UCS('µě»ÕĀ$#Ğ$èáËĞĞĝ`âÞĠ\x9d#"!Ġ"KE(©$#Ğ$Q<k'))146){+/⍺≠33+2⊥(1(5)×8)⍴∊{a≠8↑(1,a←(8⍴2)⊤⍵)}¨2⊥8(+/⍴⍳(7*2)-⌊9.1⌊⍴'FlagIsWhat')⍴10⊖⊖⌽(∊4(⍴⍴88888)+16)⍴(1+(|¯8)⍴1)⊤⎕UCS(a)}'YourFlagIsWhat?'
在这里找到了比较接近的题目
APL是比较古老的语言,它是从右往左
线性运行的、并且使用特殊符号来充当运算符和函数等
在这里有各个符号的文档描述
而这里可以运行apl来进行一些测试
其中比较常用一些在WP里都有讲,例如⍵
代表代码块右边的变量,α
代表代码块左边的变量,x y ⍴ a
代表将矩阵a转成x行y列的矩阵,还有比较多见的累加{+/⍵} a
对于这个题目而言,符号和运算过程太多了,我不想一个一个符号看过去理解
再者这种线性的符号语言、英文的文档,对于初见的人来说都比较吃力
于是我选择将其当做若干黑盒来猜测意义
从右端开始,根据WP描述,⍵
指的是输入变量,截取一节下来测试输入和输出的关系
多做几个输入,不同的长度和值,可以测试出这一节内容是将字符串转ASCII后,逐个字节的逐个位依次排列
例如0b1000001 0b01000010
会被转成1001000000000110
10⊖⊖⌽
这一段比较容易看,后者是矩阵沿x轴逆序,前者则是沿y轴逆序,10表示10行范围内,但仅作用于一个符号
8(+/⍴⍳(7*2)-⌊9.1⌊⍴'FlagIsWhat')⍴
中间括号内是个常量,run一下就可以知道是40
2⊥
表示将后面的矩阵以2进制转成10进制(纵向)
{a≠8↑(1,a←(8⍴2)⊤⍵)}
这一段比较复杂,幸好WP里有几乎完全一样的代码块,实质上是x^(x>>1),其中右移时左补1
(1(5)×8)
这一段经过测试是将刚才的十进制展开,再进行一次逐字节逐位排列
+/⍺≠33+2⊥
这里是再纵向转10进制后+33,与α
也就是代码块之前的变量进行异或后累加
(∊(41(41)0+140)(⎕UCS('µě»ÕĀ$#Ğ$èáËĞĞĝ`âÞĠ\x9d#"!Ġ"KE(©$#Ğ$Q<k'))146)
结果由这一段代码生成,运行以后可以得到一个40个元素的数组
–没错,是40个元素。注意中间有个\x9d
,alp可不会识别字符串中ASCII表示的字符
{⍵(~⍵)/('No_Please_continue')('Yes,This_is_flag')}
最后判断⍵
是否为0,即校验是否成功
整体而言步骤还算不太多,WP中是通过apl进行还原的,我觉得查符号怎么写会浪费我更久的时间,于是通过python来进行各种类型的转换模拟逆运算
由于\x9d的存在,所以测试是无法成功的,最后我找到了两次UCS转换的方法来规避不可见字符
(∊(41(41)0+140)(⎕UCS(⎕UCS 181 283 187 213 256 36 35 286 36 232 225 203 286 286 285 96 226 222 288 157 35 34 33 288 34 75 69 40 169 36 35 286 36 81 60 107))146){+/⍺≠33+2⊥(1(5)×8)⍴∊{a≠8↑(1,a←(8⍴2)⊤⍵)}¨2⊥8(+/⍴⍳(7*2)-⌊9.1⌊⍴'FlagIsWhat')⍴10⊖⊖⌽(∊4(⍴⍴88888)+16)⍴(1+(|¯8)⍴1)⊤⎕UCS(⍵)}'FLAG'
该代码可以运行,并显示异或累加和