前几天的一个美国的比赛 因为是第一次写国外比赛的题,和国内区别还是有的,题目也不怎么难。。。但有点奇怪吧。。。
RE RE方向目前写出来7题,有一道汇编的没做。。。
Cheesy 直接放入ida 可以看到很多像base64的字符串 一个个解一下 gigem{3a5y_R3v3r51N6!}
Snakes over cheese 反编译直接
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 #!/usr/bin/env python # encoding: utf-8 # 如果觉得不错,可以推荐给你的朋友!http://tool.lu/pyc from datetime import datetime Fqaa = [ 102, 108, 97, 103, 123, 100, 101, 99, 111, 109, 112, 105, 108, 101, 125] XidT = [ 83, 117, 112, 101, 114, 83, 101, 99, 114, 101, 116, 75, 101, 121] def main(): print 'Clock.exe' input = raw_input('>: ').strip() kUIl = '' for i in XidT: kUIl += chr(i) if input == kUIl: alYe = '' for i in Fqaa: alYe += chr(i) print alYe else: print datetime.now() if __name__ == '__main__': main()
看到可疑的字符串 吧对应ASCII整出 flag{decompile} SuperSecretKey
042 用文本编辑器打开后。。。 因为以前一直看的是intel汇编 这种汇编第一次见 往下翻可以看到一堆mov操作 吧ASCII打出
1 2 3 4 5 6 flag = 'gigem{' a = [65,53,53,51,77,98,49,89] for i in range(len(a)): flag += chr(a[i]) flag += '}' print flag
gigem{A553Mb1Y}
KeyGenMe 程序主要是根据输入进行加密后再字符串匹配 一开始想用z3去解的,但是因为key可以是很多种 就直接爆破了
1 2 3 4 5 6 7 8 a = 'H[OIonU2_<__nK<KsK' for i in range(len(a)-1): key = '' for temp in range(32,128): if ord(a[i+1]) == ((temp + 12) * ord(a[i]) + 17) % 70 + 48: key += chr(temp) print key #G4Z2S09577095926
直接输入后得flag
1 2 3 4 5 6 pisanbao@pisanbao-virtual-machine:~/ctf$ nc rev.tamuctf.com 7223 Please Enter a product key to continue: G4Z2S09577095926 gigem{k3y63n_m3?_k3y63n_y0u!}
NoCCBytes 这题的话 刚刚又做了一遍,一开始有点懵逼 后来发现还是不怎么难啊 程序大概是对输入进行了一堆神奇的操作,再对里面一串字符串进行解密操作后与之相匹配 那么简单了啊 直接调试在这个解密的地方下断点 毕竟每次异或操作的数是v2,v2不会变 发现v2值为0x11 那么直接解密
1 2 3 4 5 6 a = 'Fpee~Bphb' flag = '' for i in range(len(a)): flag += chr(ord(a[i])^0x11) print flag # WattoSays
答案出现
1 2 3 4 5 6 pisanbao@pisanbao-virtual-machine:~$ nc rev.tamuctf.com 8188 Welcome. Please Enter a password to continue: WattoSays gigem{Y0urBreakpo1nt5Won7Work0nMeOnlyMon3y}
还有俩到题目虽然说是写出来了,但是方法不是那么的正常。。。 如果有些出来的希望能私信一下 我想知道咋写鸭~~~
Cr4ckZ33C0d3 虽然说题目要求用z3去写 但是呢。。。。。。。。。。。。。 没写出来 不知道为什么 z3写出来的答案总是有问题//不知道是不是因为 没办法了,只能慢慢分析然后用c去写 而且这题呢。。。输入29个字符,只对其中部分有限制 或者说?这题也有多解???像keygenme一样??? //导致z3解不出???(猜测) 程序只对17个字符进行判断 其中7个字符可以定下 让我们来解其余10个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 已知条件 a[0] = 77 a[5] = 45 a[11] = 45 a[17] = 45 a[20] = 66 a[21] = 66 a[23] = 45 限制条件 (unsigned int)(a1[1] - 48) <= 9 && (unsigned int)(a1[4] - 48) <= 9 && (unsigned int)(a1[6] - 48) <= 9 && (unsigned int)(a1[9] - 48) <= 9 && (unsigned int)(a1[15] - 48) <= 9 && (unsigned int)(a1[18] - 48) <= 9 && (unsigned int)(a1[22] - 48) <= 9 && (unsigned int)(a1[27] - 48) <= 9 && (unsigned int)(a1[28] - 48) <= 9 这边不一一列举,只把重要的写一下。
来看一下check3 a1[4] - 48 == 2 * (a1[1] - 48) + 1 && a1[4] - 48 > 7 && a1[9] == a1[4] - (a1[1] - 48) + 2 首先上面限制条件a[4] - 48 <= 9,这边又有a[4] - 48 > 7 所以a[4]只能取56,57 再看a1[4] - 48 == 2 * (a1[1] - 48) + 1 所以a[4] - 48 为奇数 a[4] = 57 所以a[1] = 52,a[9] = 55 ok,现在还剩下7个未知 再看看check4,5,6,7,8
1 2 3 4 5 6 (a1[1] + a1[4] * a1[6]) % 41 == 5; (a1 + 27) + *(char *)(a1 + 28)) % 13 == 8; (a1 + 27) + *(char *)(a1 + 22)) % 22 == 18; (a1 + 18) + *(char *)(a1 + 22)) % 11 == 5; (a1[22] + a1[28] + a1[18]) % 26 == 4; 别忘了这边涉及的所有未知数都有a[x]-48<=9的限制
c语言爆破,套个5层循环。。。//其实可以爆,毕竟范围限制在那
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int main() { char a27,a28,a22,a18,a6; for(a27=32;a27<58;a27++)//32开始为可打印字符 { for(a22=32;a22<58;a22++) { for(a28=32;a28<58;a28++) { for(a18=32;a18<58;a18++) { for(a6=32;a6<58;a6++) { if((52+57*a6)%41==5 && (a27+a28)%13==8 && (a27+a22)%22==18 && (a18+a22)%11 == 5 && (a22+a28+a18)%26==4) printf("a6=%d,a18=%d,a22=%d,a27=%d,a28=%d\n",a6,a18,a22,a27,a28); } } } } } return 0; }
头文件啥的不加了 跑出来结果
1 2 3 4 5 6 a6=56,a18=41,a22=52,a27=32,a28=41 a6=56,a18=32,a22=50,a27=34,a28=52 a6=56,a18=54,a22=39,a27=45,a28=41 a6=56,a18=45,a22=37,a27=47,a28=52 a6=56,a18=36,a22=35,a27=49,a28=37 a6=56,a18=54,a22=50,a27=56,a28=56
果断选择最后一个 下面看check9 这就可以用z3了
1 2 3 4 5 6 7 from z3 import * s = Solver() a15 = BitVec('a15',8) s.add((((((a15-56)>>31)>>30)+a15-56)&3)-(((a15-56)>>31)>>30)==1) if s.check()==sat: print s.model()#[a15 = 57]
a15 = 57 check0A是帮你验证的,因为前面有多解嘛 选择最像的,验证我就不验证了啊 看check0C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int main() { char a9; for(a9=32;a9<58;a9++) { if((56+57*a9)%10==1) printf("a9=%d\n",a9); } //a9=35 //a9=45 //a9=55 return 0; }
a9 = 55 那就ok了啊
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 int main() { char a[29]={0}; a[0] = 77; a[1] = 52; a[4] = 57; a[5] = 45; a[6] = 56; a[9] = 55; a[11] = 45; a[15] = 57; a[17] = 45; a[18] = 54; a[20] = 66; a[21] = 66; a[22] = 50; a[23] = 45; a[27] = 56; a[28] = 56; int i; for(i=0;i<29;i++) { if(a[i]) printf("%c",a[i]); else printf("0"); } return 0; }
跑一下 M4009-80070-00090-60BB2-00088 看样子就是答案了
1 2 3 4 5 6 pisanbao@pisanbao-virtual-machine:~$ nc rev.tamuctf.com 8189 Please Enter a product key to continue: M4009-80070-00090-60BB2-00088 gigem{z3_b3st_thr33}
Obfuscaxor 黑盒测试猜出来的答案 放进ida发现这部分有点奇怪,看汇编 转成代码发现strcmp 接下去就是猜了。。。 猜测加密方法 我们输入一串a进去 看输出 4个一循环 那就可以猜测异或了
1 2 3 4 5 6 7 8 a = [0xAE, 0x9E, 0xFF, 0x9C, 0xAB, 0xC7, 0xD3, 0x81, 0xE7, 0xEE, 0xFB, 0x8A, 0x9D, 0xEF, 0x8D, 0xAE] b = [0xBF, 0xCC, 0xDF, 0x8E] key = '' for i in range(len(a)): key += chr(a[i]^b[i%4]^ord('a')) print key # p3Asujmn9CEeCB3A
得到key
1 2 3 4 5 6 pisanbao@pisanbao-virtual-machine:~$ nc rev.tamuctf.com 7224 Please Enter a product key to continue: p3Asujmn9CEeCB3A gigem{x0r_64d5by}
pwn的话 有机会再总结下吧。。。