概述
解除CTF也有很多年了,但是真正的將網上的題目通關刷題還是沒有過的,同時感覺水平下降的太厲害,這兩個月准備把網上目前公開有的CTF環境全部刷一遍,同時收集題目做為素材,為后面的培訓及靶場搭建做好准備。本文是2018年7月8日前所有密碼類的題目通關Writeup。
Writeup
變異凱撒
普通凱撒密碼參考,https://en.wikipedia.org/wiki/Caesar_cipher。
加密密文:afZ_r9VYfScOeO_UL^RWUc 格式:flag{ }
解題過程分這幾部分,首先afZ_r9VYfScOeO_UL^RWUc
的ascii碼為
97 102 90 95 114 57 86 89 102 83 99 79 101 79 95 85 76 94 82 87 85 99
flag{ }
的前幾位ascii碼為
102 108 97 103 123
按位做一個比較就可以發現102-97=5,108-102=6,97-90=7,所以此題目凱撒的規律為第一個字符ascii加5,其他每個字符按位ascii自增1,所以解密代碼如下。解密代碼如下
#!/usr/bin/env python #-*- coding: utf-8 -*- """ @Author : darkN0te @Create date : 2018-07-07 @description : 凱撒輪轉密碼解密 @Update date : """ INIT_ADD = 5 input = raw_input() output = "" for char in input: output += chr(ord(char) + INIT_ADD) INIT_ADD += 1 print output
輸出
afZ_r9VYfScOeO_UL^RWUc
flag{Caesar_variation}
結束。
傳統知識+古典密碼
題目描述:
小明某一天收到一封密信,信中寫了幾個不同的年份
辛卯,癸巳,丙戌,辛未,庚辰,癸酉,己卯,癸巳。
信的背面還寫有“+甲子”,請解出這段密文。
key值:CTF{XXX}
根據天干地支紀年法
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.癸亥
寫出題中所給組合的數字編碼
28 30 23 8 17 10 16 30
加上一個甲子(60)
88 90 93 68 77 70 76 90
轉換成ASCII字母:
XZSDMFLZ
柵欄密碼(兩欄):
XMZFSLDZ
凱撒:
SHUANGYU
最后按格式提交CTF{SHUANGYU}
即可。
what's wrong with this
題目描述:
We managed to get this package of the robots servers. We managed to determine that it is some kind of compiled bytecode. But something is wrong with it. Our usual analysis failed - so we have to hand this over to you pros. We only know this: The program takes one parameter and it responds with "Yup" if you have found the secret code, with "Nope" else. We expect it should be obvious how to execute it. 解題鏈接: http://ctf5.shiyanbar.com/crypto/What-s-wrong-with-this/hello.tar.gz 中文題干:我們設法獲得了這個機器人服務器包。 我們設法確定它是某種編譯的字節碼。 但它有些問題。 我們通常的分析失敗了 - 所以我們不得不把它交給你們。 我們只知道這個:程序接受一個參數,如果你找到了密碼,它會以“Yup”響應,而“Nope”則是。 我們期望它應該是如何執行它的。
網站給出了一個答案pdf,請查看
http://hebin.me/wp-content/uploads/2017/09/2017090715264378.pdf
解壓題目給出的文件hello.tar.gz
,我們知道了一些程序特征會打印Yup
和Nope
,然后使用命令grep -R 'Yup\|Nope'
進行搜索,找到匹配文件。
使用uncompyle
進行反編譯不可以,使用Decompyle++
進行反編譯。安裝過程是這樣。
git clone https://github.com/zrax/pycdc.git cd pycdc cmake . make make install pycdc __main__hello__.pyc
我們用過pycdc反編譯出__main__hello__.pyc
的源碼
# Source Generated with Decompyle++ # File: __main__hello__.pyc (Python 2.7) import sys import dis import multiprocessing import UserList def encrypt_string(s): Unsupported opcode: <255> new_str = [] # WARNING: Decompyle incomplete def rot_chr(c, amount): None = chr(((ord(c) + 33) % amount) / 94 % 33) SECRET = 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M' if encrypt_string(sys.argv - 1) == SECRET: print print >>'Yup' else: print print >>'Nope' None = None
可以看到,有一部分字節碼沒有被反編譯出來,這是由於一部分字節碼沒有被識別造成的,使用pycdas
查看一下信息。
➜ what's wrong with this ~/Safe/03_tools/pycdc/pycdas __main__hello__.pyc __main__hello__.pyc (Python 2.7) [Code] File Name: chall.py Object Name: Arg Count: 0 Locals: 0 Stack Size: 3 Flags: 0x00000040 (CO_NOFREE) [Names] 'sys' 'hashlib' 'sha256' 'dis' 'multiprocessing' 'UserList' 'encrypt_string' 'rot_chr' 'SECRET' 'argv' [Var Names] [Free Vars] [Cell Vars] [Constants] -1 None ( 'sha256' ) [Code] File Name: chall.py Object Name: encrypt_string Arg Count: 1 Locals: 4 Stack Size: 8 Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE) [Names] 'enumerate' 'append' 'rot_chr' 'ord' 'join' [Var Names] 's' 'new_str' 'index' 'c' [Free Vars] [Cell Vars] [Constants] None 0 10 1 '' [Disassembly] 0 BUILD_LIST 0 3 STORE_FAST 1: new_str 6 SETUP_LOOP 99 (to 108) 9 LOAD_GLOBAL 0: enumerate 12 LOAD_FAST 0: s 15 CALL_FUNCTION 1 18 19 FOR_ITER 85 (to 107) 22 UNPACK_SEQUENCE 2 25 STORE_FAST 2: index 28 STORE_FAST 3: c 31 LOAD_FAST 2: index 34 LOAD_CONST 1: 0 37 COMPARE_OP 2 (==) 40 POP_JUMP_IF_FALSE 68 43 LOAD_FAST 1: new_str 46 LOAD_ATTR 1: append 49 LOAD_GLOBAL 2: rot_chr 52 LOAD_FAST 3: c 55 LOAD_CONST 2: 10 58 CALL_FUNCTION 2 61 CALL_FUNCTION 1 64 ROT_TWO 65 JUMP_ABSOLUTE 19 68 LOAD_FAST 1: new_str 71 LOAD_ATTR 1: append 74 LOAD_GLOBAL 2: rot_chr 77 LOAD_FAST 3: c 80 LOAD_GLOBAL 3: ord 83 LOAD_FAST 1: new_str 86 LOAD_FAST 2: index 89 LOAD_CONST 3: 1 92 BINARY_ADD 93 BINARY_SUBTRACT 94 CALL_FUNCTION 1 97 CALL_FUNCTION 2 100 CALL_FUNCTION 1 103 ROT_TWO 104 JUMP_ABSOLUTE 19 107 END_FINALLY 108 LOAD_CONST 4: '' 111 LOAD_ATTR 4: join 114 LOAD_FAST 1: new_str 117 CALL_FUNCTION 1 120 IMPORT_STAR [Code] File Name: chall.py Object Name: rot_chr Arg Count: 2 Locals: 2 Stack Size: 3 Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE) [Names] 'chr' 'ord' [Var Names] 'c' 'amount' [Free Vars] [Cell Vars] [Constants] None 33 94 [Disassembly] 0 LOAD_GLOBAL 0: chr 3 LOAD_GLOBAL 1: ord 6 LOAD_FAST 0: c 9 CALL_FUNCTION 1 12 LOAD_CONST 1: 33 15 BINARY_ADD 16 LOAD_FAST 1: amount 19 BINARY_MODULO 20 LOAD_CONST 2: 94 23 BINARY_DIVIDE 24 LOAD_CONST 1: 33 27 BINARY_MODULO 28 CALL_FUNCTION 1 31 IMPORT_STAR 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M' 1 'Yup' 'Nope' [Disassembly] 0 LOAD_CONST 0: -1 3 LOAD_CONST 1: None 6 IMPORT_NAME 0: sys 9 STORE_NAME 0: sys 12 LOAD_CONST 0: -1 15 LOAD_CONST 2: ('sha256',) 18 IMPORT_NAME 1: hashlib 21 IMPORT_FROM 2: sha256 24 STORE_NAME 2: sha256 27 ROT_TWO 28 LOAD_CONST 0: -1 31 LOAD_CONST 1: None 34 IMPORT_NAME 3: dis 37 STORE_NAME 3: dis 40 LOAD_CONST 0: -1 43 LOAD_CONST 1: None 46 IMPORT_NAME 4: multiprocessing 49 STORE_NAME 4: multiprocessing 52 LOAD_CONST 0: -1 55 LOAD_CONST 1: None 58 IMPORT_NAME 5: UserList 61 STORE_NAME 5: UserList 64 LOAD_CONST 3: <CODE> encrypt_string 67 MAKE_FUNCTION 0 70 STORE_NAME 6: encrypt_string 73 LOAD_CONST 4: <CODE> rot_chr 76 MAKE_FUNCTION 0 79 STORE_NAME 7: rot_chr 82 LOAD_CONST 5: 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M' 85 STORE_NAME 8: SECRET 88 LOAD_NAME 6: encrypt_string 91 LOAD_NAME 0: sys 94 LOAD_ATTR 9: argv 97 LOAD_CONST 6: 1 100 BINARY_SUBTRACT 101 CALL_FUNCTION 1 104 LOAD_NAME 8: SECRET 107 COMPARE_OP 2 (==) 110 POP_JUMP_IF_FALSE 121 113 LOAD_CONST 7: 'Yup' 116 PRINT_NEWLINE 117 PRINT_ITEM_TO 118 JUMP_FORWARD 5 (to 126) 121 LOAD_CONST 8: 'Nope' 124 PRINT_NEWLINE 125 PRINT_ITEM_TO 126 LOAD_CONST 1: None 129 IMPORT_STAR
在研究一下如何修復的
修復后反編譯得到的結果為
# Source Generated with Decompyle ++ # File: __main__hello__.pyc (Python 2.7) import sys from hashlib import sha256 import dis import multiprocessing import UserList def encrypt_string(s): new_str = [] for (index , c) in enumerate(s): if index == 0: new_str.append(rot_chr(c, 10)) continue new_str.append(rot_chr(c, ord(new_str[index - 1]))) return ''.join(new_str) def rot_chr(c, amount): return chr(((ord(c) - 33) + amount) % 94 + 33) SECRET = 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M' if encrypt_string(sys.argv[1]) == SECRET: print 'Yup' else: print 'Nope'
寫出解密代碼:
SECRET = 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M' def decrypt_string(s): new_str = [] for (index , c) in enumerate(s): if index == 0: new_str.append(rot_chr(c, 10)) continue new_str.append(rot_chr(c, ord(s[index - 1]))) return ''.join(new_str) def rot_chr(c, amount): return chr(((ord(c) - 33) - amount) % 94 + 33) print decrypt_string(SECRET) # output : modified_in7erpreters_are_3vil!!!
try them all
題目描述:
You have found a passwd file containing salted passwords. An unprotected configuration file has revealed a salt of 5948. The hashed password for the 'admin' user appears to be 81bdf501ef206ae7d3b92070196f7e98, try to brute force this password. 您找到了一個有鹽的密碼表。已知密碼的明文結尾為5948,密碼表中哈希值為81bdf501ef206ae7d3b92070196f7e98,嘗試暴力破解此密碼。
原題干為英文,但是感覺和題目本身的意思不一樣,寫了一段和原題目意思一致的中文。題目的意思就是一個簡單的爆破md5。難點是不知道到底這個明文到底有多少位,都包含什么字符。
這里直接使用在cmd5上查到的結果sniper5948
。
腳本
#!/usr/bin/env python #-*- coding: utf-8 -*- """ @Author : darkN0te @Create date : 2018-07-07 @description : md5爆破 單進程 @Update date : """ import string import hashlib endOutput = "5948" file=open("output.txt","a") md5input=raw_input("請輸入md5:\n") md5input=md5input.lower() # apt=string.printable[:-6] apt=string.letters def dfs(s,num): m=hashlib.md5() print s + endOutput m.update(s + endOutput) md5temp=m.hexdigest() if md5temp==md5input: file.write("md5是:"+md5input+" 明文是:"+s+"\n") file.close() exit(-1) if len(s)==num: return for i in apt: dfs(s+i,num) myinput=7 #生成字符的位數 for j in range(1,myinput): dfs("",j)