├── .gitignore ├── Crypto1 └── main.py ├── GCTF-eucalypt └── main.py ├── GCTF-wolf └── main.py ├── OTP ├── check_random.py ├── hint.c ├── hint_test.c └── sha1.py ├── README.md ├── RSA1 ├── Dockerfile ├── README.md ├── flag ├── flag.py ├── flag.pyc ├── rsa1.py ├── rsa1_payload.py └── rsa_s.py ├── RSA2 ├── Dockerfile ├── README.md ├── flag ├── flag.py ├── flag.pyc ├── rsa2.py ├── rsa2_payload.py └── rsa2_payload.sage ├── RSA3 ├── Dockerfile ├── README.md ├── flag ├── flag.py ├── flag.pyc ├── rsa3.py ├── rsa3.sage ├── rsa3_payload.py └── sage3.py ├── cf-RSA? ├── flag.enc └── public.pem ├── diy-tool ├── cbc-padding-oracle-attack.py ├── cbc-padding-oracle-attack2.py └── sha1-length-extend-attack.py ├── rabit ├── rabit.py ├── rabit_8b98cc38ab1d0597ee51a30425d34d2e.tgz └── util.py ├── re-Special-RSA ├── flag.enc ├── msg.enc ├── msg.txt └── special_rsa.py └── tonnerre └── public_server_ea2e768e20e89fb1aafbbc547cdb4636.py /.gitignore: -------------------------------------------------------------------------------- 1 | V-lazy 2 | -------------------------------------------------------------------------------- /Crypto1/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | import hashlib 5 | import time 6 | import base64 7 | import sys 8 | # import key 9 | 10 | 11 | def authcode(string, key=""): 12 | ck_len = 4 13 | 14 | key = hashlib.md5(key).hexdigest() 15 | keya = hashlib.md5(key[:16]).hexdigest() 16 | keyb = hashlib.md5(key[16:]).hexdigest() 17 | keyc = hashlib.md5(str(time.time())).hexdigest()[-ck_len:] 18 | 19 | cryptkey = keya + hashlib.md5(keya + keyc).hexdigest() 20 | key_len = len(cryptkey) 21 | 22 | sign = string + keyb 23 | string = hashlib.md5(sign).hexdigest()[:16] + string 24 | string_len = len(string) 25 | 26 | result = "" 27 | box = range(0, 256) 28 | rndkey = [] 29 | 30 | for i in range(0, 255): 31 | rndkey.append(ord(cryptkey[i % key_len])) 32 | 33 | j = 0 34 | for i in range(0, 255): 35 | j = (j + box[i] + rndkey[i]) % 256 36 | tmp = box[i] 37 | box[i] = box[j] 38 | box[j] = tmp 39 | 40 | a = j = 0 41 | for i in range(string_len): 42 | a = (a + 1) % 256 43 | j = (j + box[a]) % 256 44 | tmp = box[a] 45 | box[a] = box[j] 46 | box[j] = tmp 47 | result += chr(ord(string[i]) ^ (box[(box[a] + box[j]) % 256])) 48 | 49 | return keyc + base64.b64encode(result) 50 | 51 | if __name__ == '__main__': 52 | print "Please enter your string: " 53 | sys.stdout.flush() 54 | strings = raw_input() 55 | enc = authcode(strings, key.key) 56 | print "The cipher is: " + enc 57 | -------------------------------------------------------------------------------- /GCTF-eucalypt/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from flask import Flask 5 | from flask import request 6 | from flask import make_response 7 | from Crypto.Cipher import AES 8 | import json 9 | import os 10 | 11 | app = Flask(__name__) 12 | 13 | class Signal(): 14 | def __init__(self): 15 | self.aes_key = '???' 16 | assert len(self.aes_key) == 16 17 | 18 | def encode(self, obj): 19 | s = json.dumps(obj) 20 | iv = os.urandom(16) 21 | pad = (16 - (len(s) % 16)) 22 | s += chr(pad) * pad 23 | algo = AES.new(self.aes_key, AES.MODE_CBC, IV=iv) 24 | crypttext = algo.encrypt(s) 25 | c = (iv + crypttext).encode('hex') 26 | return c 27 | 28 | def decode(self, string): 29 | crypttext = string.decode('hex') 30 | if len(crypttext) < 16: 31 | return None 32 | iv, crypttext = crypttext[:16], crypttext[16:] 33 | algo = AES.new(self.aes_key, AES.MODE_CBC, IV=iv) 34 | plaintext = str(algo.decrypt(crypttext)) 35 | pad = ord(plaintext[-1]) 36 | if pad > 16: 37 | raise ValueError, "pad error - pad is %d" %(pad) 38 | expected = chr(pad) * pad 39 | piece = plaintext[-pad:] 40 | if piece != expected: 41 | raise ValueError, "padding is corrupted" 42 | try: 43 | obj = json.loads(plaintext[:-pad]) 44 | except: 45 | return None 46 | return obj 47 | 48 | @app.route('/') 49 | def index(): 50 | html = ''' 51 | Register
52 | GetFlag 53 | ''' 54 | return html 55 | 56 | @app.route('/register', methods=['GET', 'POST']) 57 | def register(): 58 | if request.method == 'GET': 59 | html = ''' 60 |
61 | 请输入用户名: 62 | 63 |
64 | ''' 65 | return html 66 | if request.method == 'POST': 67 | obj = {} 68 | obj['username'] = request.form['username'] 69 | if obj['username'] == "": 70 | return "bad username" 71 | if obj['username'] == 'admin': 72 | return "can't register admin" 73 | s = Signal() 74 | cookie = s.encode(obj) 75 | html = ''' 76 | 77 | ''' 78 | resp = make_response(html) 79 | resp.set_cookie('id', cookie) 80 | return resp 81 | 82 | @app.route('/getflag') 83 | def getflag(): 84 | cookie = request.cookies.get('id') 85 | s = Signal() 86 | obj = s.decode(cookie) 87 | if obj == None or "username" not in obj: 88 | html = "error cookie" 89 | else: 90 | if obj['username'] == 'admin': 91 | html = "flag" 92 | else: 93 | html = "Hi! %s, only admin can get flag" % obj['username'] 94 | return html 95 | 96 | if __name__ == '__main__': 97 | app.run(debug=False, port=8091, host="0.0.0.0", threaded=True) -------------------------------------------------------------------------------- /GCTF-wolf/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from flask import Flask 5 | from flask import request 6 | from flask import make_response 7 | from Crypto.Hash import SHA 8 | from Crypto.Cipher import AES 9 | import json 10 | import os 11 | import urllib 12 | import urlparse 13 | 14 | app = Flask(__name__) 15 | 16 | class Signal(): 17 | def __init__(self): 18 | self.aes_key = '??' 19 | self.mac_key = "??" 20 | assert len(self.aes_key) == 16 21 | assert len(self.mac_key) == 32 22 | 23 | def encode(self, s): 24 | iv = os.urandom(16) 25 | pad = (16 - (len(s) % 16)) 26 | s += chr(pad) * pad 27 | algo = AES.new(self.aes_key, AES.MODE_CBC, IV=iv) 28 | crypttext = algo.encrypt(s) 29 | return (iv + crypttext) 30 | 31 | def decode(self, string): 32 | if len(string) < 16: 33 | return ValueError, "bad string" 34 | iv, string = string[:16], string[16:] 35 | algo = AES.new(self.aes_key, AES.MODE_CBC, IV=iv) 36 | plaintext = str(algo.decrypt(string)) 37 | pad = ord(plaintext[-1]) 38 | if pad > 16: 39 | raise ValueError, "pad error - pad is %d" %(pad) 40 | expected = chr(pad) * pad 41 | piece = plaintext[-pad:] 42 | if piece != expected: 43 | raise ValueError, "padding is corrupted" 44 | raw = plaintext[:-pad] 45 | return raw 46 | 47 | def make(self, dct): 48 | tcd = urllib.urlencode(dct) 49 | h = SHA.new() 50 | h.update(self.mac_key) 51 | h.update(tcd) 52 | s = h.digest() 53 | coded = self.encode(tcd) 54 | return s.encode('hex') + "." + coded.encode('hex') 55 | 56 | def unmake(self, st): 57 | p = st.split(".") 58 | if len(p) != 2: 59 | return None 60 | 61 | s = self.decode(p[1].decode('hex')) 62 | if s == None: 63 | return None 64 | h = SHA.new() 65 | h.update(self.mac_key) 66 | h.update(s) 67 | f = h.hexdigest() 68 | print s 69 | if p[0] != f: 70 | return None 71 | 72 | kv = urlparse.parse_qsl(s) 73 | ret ={} 74 | for k, v in kv: 75 | ret[k] = v 76 | return ret 77 | 78 | @app.route('/') 79 | def index(): 80 | html = ''' 81 | Register
82 | GetFlag 83 | ''' 84 | return html 85 | 86 | @app.route('/register', methods=['GET', 'POST']) 87 | def register(): 88 | if request.method == 'GET': 89 | html = ''' 90 |
91 | 请输入用户名: 92 | 93 |
94 | ''' 95 | return html 96 | if request.method == 'POST': 97 | obj = {} 98 | obj['username'] = request.form['username'] 99 | if obj['username'] == "": 100 | return "bad username" 101 | if obj['username'] == 'admin': 102 | return "can't register admin" 103 | s = Signal() 104 | cookie = s.make(obj) 105 | html = ''' 106 | 107 | ''' 108 | resp = make_response(html) 109 | resp.set_cookie('id', cookie) 110 | return resp 111 | 112 | @app.route('/getflag') 113 | def getflag(): 114 | cookie = request.cookies.get('id') 115 | s = Signal() 116 | obj = s.unmake(cookie) 117 | if obj == None or "username" not in obj: 118 | html = "error cookie" 119 | else: 120 | if obj['username'] == 'admin': 121 | html = "flag" 122 | else: 123 | html = "Hi! %s, only admin can get flag" % obj['username'] 124 | return html 125 | 126 | if __name__ == '__main__': 127 | app.run(debug=False, port=8091, host="0.0.0.0", threaded=True) -------------------------------------------------------------------------------- /OTP/check_random.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from binascii import unhexlify 5 | from Crypto.Util.number import str2long 6 | from sha1 import SHA1 7 | import struct 8 | import sys 9 | 10 | L = 600 11 | 12 | def hx(v): 13 | return "{:0>8}".format(hex(v)[2:]) 14 | 15 | def main(random): 16 | h = struct.unpack("IIIII", random[L-40:L-20]) 17 | randhasher = random[L-40:L-20]+random[:44] 18 | sha1_hash = SHA1() 19 | for x in xrange(5): 20 | sha1_hash.hash_[x] = h[x] 21 | res = sha1_hash.sha1(randhasher, len(randhasher)) 22 | (v0, v1, v2, v3, v4) = struct.unpack(" 1: 35 | random = sys.argv[1] 36 | else: 37 | exit(); 38 | try: 39 | random = random.strip().decode('hex') 40 | assert len(random) >= 580 41 | except: 42 | print "error hex" 43 | outstr = main(random) 44 | if outstr in sys.argv[1]: 45 | print "the random can be predicted" 46 | else: 47 | print "the predict 20 byte number is: %s" %outstr -------------------------------------------------------------------------------- /OTP/hint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #ifndef FLAG 12 | #define FLAG "hitcon{N0_n33d_t0_rev0k3_pr1v4te_k3y}" 13 | #endif 14 | 15 | const char flag[] = FLAG; 16 | int type = 0; 17 | char *method[] = { 18 | "1. /dev/urandom", 19 | "2. openssl", 20 | "3. grypt", 21 | "4. gnutls" 22 | }; 23 | 24 | char* gen_key(size_t l) 25 | { 26 | char *key = (char*) malloc(l); 27 | if (!key) { 28 | puts("Error, plz contact admin"); 29 | exit(1); 30 | } 31 | 32 | if (type == 0) { 33 | FILE *fp = fopen("/dev/urandom", "r"); 34 | if (!fp) { 35 | puts("Error, plz contact admin"); 36 | exit(1); 37 | } 38 | fread(key, 1, l, fp); 39 | fclose(fp); 40 | } else if (type == 1) { 41 | RAND_bytes(key, l); 42 | } else if (type == 2) { 43 | gcry_randomize(key, l, GCRY_STRONG_RANDOM); 44 | } else if (type == 3) { 45 | gnutls_rnd(GNUTLS_RND_NONCE, key, l); 46 | } else { 47 | puts("Unsupport method."); 48 | exit(1); 49 | } 50 | 51 | return key; 52 | } 53 | 54 | void encrypt() 55 | { 56 | printf("PRNG method: %s\n", method[type]); 57 | 58 | puts("len?"); 59 | size_t len = read_int(); 60 | if (len <= 0 || len >= 0x10000) { 61 | puts("Too big!"); 62 | exit(0); 63 | } 64 | 65 | size_t out_len = len + strlen(flag); 66 | char *buf = (char*) malloc(out_len + 1); 67 | if (!buf) { 68 | puts("Error, plz contact admin"); 69 | exit(1); 70 | } 71 | bzero(buf, out_len + 1); 72 | puts("data?"); 73 | read(0, buf, len); 74 | memcpy(buf + len, flag, strlen(flag)); 75 | 76 | char *key = gen_key(out_len); 77 | 78 | for (int i = 0; i < out_len; i++) 79 | buf[i] ^= key[i]; 80 | puts(""); 81 | puts("encrypt content:"); 82 | for (int i = 0; i < out_len; i++) 83 | printf("%02x", buf[i] & 0xff); 84 | puts(""); 85 | 86 | free(key); 87 | free(buf); 88 | exit(0); 89 | } 90 | 91 | void prng() 92 | { 93 | for (int i = 0; i < sizeof(method)/sizeof(char*); i++) 94 | puts(method[i]); 95 | printf("> "); 96 | type = (read_int()-1) % 4; 97 | } 98 | 99 | int menu() 100 | { 101 | puts("====== OTP system ======"); 102 | puts("1. encrypt"); 103 | puts("2. change PRNG"); 104 | puts("3. exit"); 105 | printf("> "); 106 | return read_int(); 107 | } 108 | 109 | int read_int() 110 | { 111 | char buf[0x10]; 112 | fgets(buf, 0x10, stdin); 113 | return atoi(buf); 114 | } 115 | 116 | void motd() 117 | { 118 | puts("Welcome to OTP system."); 119 | puts("OTP system can help to encrypt your content with a random key."); 120 | puts("The flag will be hide in the encrypted file. :)"); 121 | } 122 | 123 | int main() 124 | { 125 | 126 | setvbuf(stdout, 0, 2, 0); 127 | setvbuf(stdin, 0, 2, 0); 128 | 129 | motd(); 130 | 131 | while(1) { 132 | switch (menu()) { 133 | case 1: 134 | encrypt(); 135 | break; 136 | case 2: 137 | prng(); 138 | break; 139 | case 3: 140 | puts("bye~"); 141 | exit(0); 142 | } 143 | } 144 | } 145 | 146 | -------------------------------------------------------------------------------- /OTP/hint_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | char* gen_key(size_t l) 10 | { 11 | char *key = (char*) malloc(l); 12 | if (!key) { 13 | puts("Error, plz contact admin"); 14 | exit(1); 15 | } 16 | 17 | gcry_randomize(key, l, GCRY_STRONG_RANDOM); 18 | 19 | return key; 20 | } 21 | 22 | void encrypt() 23 | { 24 | 25 | size_t out_len = 600; 26 | 27 | char *key = gen_key(out_len); 28 | 29 | for (int i = 0; i < out_len; i++) 30 | printf("%02x", key[i] & 0xff); 31 | puts(""); 32 | 33 | free(key); 34 | exit(0); 35 | } 36 | 37 | 38 | int main() 39 | { 40 | 41 | setvbuf(stdout, 0, 2, 0); 42 | setvbuf(stdin, 0, 2, 0); 43 | 44 | 45 | encrypt(); 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /OTP/sha1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | import ctypes 5 | import struct 6 | 7 | def ROTL32(x, r): 8 | try: 9 | a = (x << r) ^ (x >> (32 - r)) 10 | except: 11 | print type(x) 12 | print type(r) 13 | exit(-1) 14 | return a 15 | 16 | class SHA1(): 17 | def __init__(self): 18 | self.length_ = 0 19 | self.unprocessed_ = 0 20 | self.hash_ = [ 21 | 0x67452301, 22 | 0xefcdab89, 23 | 0x98badcfe, 24 | 0x10325476, 25 | 0xc3d2e1f0 26 | ] 27 | 28 | def sha1_process(self): 29 | wblock = [] 30 | for x in xrange(80): 31 | wblock.append(0) 32 | 33 | for x in xrange(16): 34 | wblock[x] = self.block[x] 35 | 36 | for x in xrange(16, 80): 37 | wblock[x] = ROTL32(wblock[x - 3] ^ wblock[x - 8] ^ wblock[x - 14] ^ wblock[x - 16], 1) & 0xFFFFFFFF 38 | 39 | a = self.hash_[0] 40 | b = self.hash_[1] 41 | c = self.hash_[2] 42 | d = self.hash_[3] 43 | e = self.hash_[4] 44 | 45 | for x in xrange(20): 46 | 47 | temp = ROTL32(a, 5) + (((c ^ d) & b) ^ d) + e + wblock[x] + 0x5A827999 48 | temp &= 0xFFFFFFFF 49 | e = d 50 | d = c 51 | c = ROTL32(b, 30) & 0xFFFFFFFF 52 | b = a 53 | a = temp 54 | 55 | for x in xrange(20, 40): 56 | temp = ROTL32(a, 5) + (b ^ c ^ d) + e + wblock[x] + 0x6ED9EBA1 57 | temp &= 0xFFFFFFFF 58 | e = d 59 | d = c 60 | c = ROTL32(b, 30) & 0xFFFFFFFF 61 | b = a 62 | a = temp 63 | 64 | for x in xrange(40, 60): 65 | temp = ROTL32(a, 5) + ((b & c) | (b & d) | (c & d)) + e + wblock[x] + 0x8F1BBCDC 66 | temp &= 0xFFFFFFFF 67 | e = d 68 | d = c 69 | c = ROTL32(b, 30) & 0xFFFFFFFF 70 | b = a 71 | a = temp 72 | 73 | for x in xrange(60, 80): 74 | temp = ROTL32(a, 5) + (b ^ c ^ d) + e + wblock[x] + 0xCA62C1D6 75 | temp &= 0xFFFFFFFF 76 | e = d 77 | d = c 78 | c = ROTL32(b, 30) & 0xFFFFFFFF 79 | b = a 80 | a = temp 81 | 82 | self.hash_[0] += a 83 | self.hash_[1] += b 84 | self.hash_[2] += c 85 | self.hash_[3] += d 86 | self.hash_[4] += e 87 | for x in xrange(5): 88 | self.hash_[x] &= 0xFFFFFFFF 89 | 90 | def str_to_block(self, x): 91 | self.block = [] 92 | for i in xrange(x, x + 64, 4): 93 | tmp = self.msg[i: i + 4] 94 | tmp = int(tmp.encode('hex') or '0', 16) 95 | self.block.append(tmp) 96 | 97 | def sha1(self, msg, length): 98 | self.msg = msg 99 | self.length_ = length 100 | self.msg += (64 - length % 64) * '\x00' 101 | self.str_to_block(0) 102 | self.sha1_process() 103 | return self.final() 104 | 105 | def final(self): 106 | for x in xrange(5): 107 | self.hash_[x] = ctypes.c_uint32(self.hash_[x]) 108 | result = "" 109 | for x in self.hash_: 110 | result += "{:0>8}".format(hex(x.value)[2:-1]) 111 | return result 112 | 113 | if __name__ == '__main__': 114 | hash_test = SHA1() 115 | msg = "a"*64 116 | print hash_test.sha1(msg, len(msg)) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CTF-Crypto-Library 2 | 3 | repetition Crypto -------------------------------------------------------------------------------- /RSA1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.cn-beijing.aliyuncs.com/hcamael/rsa:base 2 | MAINTAINER Docker Hcamael 3 | 4 | COPY rsa1.py /home/RSA/rsa1.py 5 | COPY flag.py /home/RSA/flag.py 6 | COPY flag /home/RSA/flag 7 | RUN chmod +x /home/RSA/rsa1.py 8 | 9 | USER rsa 10 | EXPOSE 7000 11 | CMD ["socat", "TCP4-LISTEN:7000,fork", "EXEC:\"python -u /home/RSA/rsa1.py\""] 12 | 13 | -------------------------------------------------------------------------------- /RSA1/README.md: -------------------------------------------------------------------------------- 1 | **author**: Hcamael 2 | 3 | > 题目名称: Crypto So Interesting 4 | 5 | > 分类: Crypto 6 | 7 | > 预估分值: 300 8 | 9 | > 描述: []~( ̄▽ ̄)~*
[crypto1.py](rsa1.py)
nc x.x.x.x xxxx 10 | -------------------------------------------------------------------------------- /RSA1/flag: -------------------------------------------------------------------------------- 1 | {"5c9597f3c8245907ea71a89d9d39d08e": "hctf{d8e8fca2dc0f896fd7cb4cb0031ba249}"} 2 | -------------------------------------------------------------------------------- /RSA1/flag.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import json 5 | 6 | def get_flag(token): 7 | with open('/home/RSA/flag') as f: 8 | flags = json.loads(f.read()) 9 | return flags[token] 10 | -------------------------------------------------------------------------------- /RSA1/flag.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/RSA1/flag.pyc -------------------------------------------------------------------------------- /RSA1/rsa1.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from flag import get_flag 5 | from hashlib import sha512 6 | from Crypto.Util.number import getPrime,bytes_to_long 7 | from libnum import invmod, gcd 8 | import random 9 | 10 | __author__ = 'Hcamael' 11 | 12 | def m_exit(n): 13 | print "==============Game Over!=================" 14 | exit(n) 15 | 16 | def cal_bit(num): 17 | num = int(num) 18 | l = len(bin(num)) 19 | return l-2 20 | 21 | def pi_b(x): 22 | bt = 536380958350616057242691418634880594502192106332317228051967064327642091297687630174183636288378234177476435270519631690543765125295554448698898712393467267006465045949611180821007306678935181142803069337672948471202242891010188677287454504933695082327796243976863378333980923047411230913909715527759877351702062345876337256220760223926254773346698839492268265110546383782370744599490250832085044856878026833181982756791595730336514399767134613980006467147592898197961789187070786602534602178082726728869941829230655559180178594489856595304902790182697751195581218334712892008282605180395912026326384913562290014629187579128041030500771670510157597682826798117937852656884106597180126028398398087318119586692935386069677459788971114075941533740462978961436933215446347246886948166247617422293043364968298176007659058279518552847235689217185712791081965260495815179909242072310545078116020998113413517429654328367707069941427368374644442366092232916196726067387582032505389946398237261580350780769275427857010543262176468343294217258086275244086292475394366278211528621216522312552812343261375050388129743012932727654986046774759567950981007877856194574274373776538888953502272879816420369255752871177234736347325263320696917012616273L 23 | return invmod(x, bt) 24 | 25 | def get_ed(p, q): 26 | k = cal_bit(q*p) 27 | phi_n = (p-1)*(q-1) 28 | r = random.randint(10, 99) 29 | while True: 30 | u = getPrime(k/4 - r) 31 | if gcd(u, phi_n) != 1: 32 | continue 33 | t = invmod(u, phi_n) 34 | e = pi_b(t) 35 | if gcd(e, phi_n) == 1: 36 | break 37 | d = invmod(e, phi_n) 38 | return (e, d) 39 | 40 | def verify(): 41 | print "Proof of Work" 42 | with open("/dev/urandom") as f: 43 | prefix = f.read(5) 44 | print "Prefix: %s" %prefix.encode('base64') 45 | try: 46 | suffix = raw_input() 47 | s = suffix.decode('base64') 48 | except: 49 | m_exit(-1) 50 | r = sha512(prefix + s).hexdigest() 51 | if "fffffff" not in r: 52 | m_exit(-1) 53 | 54 | def main(): 55 | verify() 56 | usage = """ 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 | print usage 85 | print "This is a RSA Decryption System" 86 | print "Please enter Your team token: " 87 | token = raw_input() 88 | try: 89 | flag = get_flag(token) 90 | assert len(flag) == 38 91 | except: 92 | print "Token error!" 93 | m_exit(-1) 94 | 95 | p=getPrime(2048) 96 | q=getPrime(2048) 97 | n = p * q 98 | e, d = get_ed(p, q) 99 | print "n: ", hex(n) 100 | print "e: ", hex(e) 101 | 102 | flag = bytes_to_long(flag) 103 | enc_flag = pow(flag, e, n) 104 | print "Your flag is: ", hex(enc_flag) 105 | 106 | 107 | if __name__ == '__main__': 108 | main() 109 | -------------------------------------------------------------------------------- /RSA1/rsa1_payload.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from hashlib import sha512 5 | from Crypto.Util.number import long_to_bytes, getPrime, bytes_to_long 6 | from libnum import invmod, gcd 7 | from pwn import process, context, remote 8 | import itertools 9 | import time 10 | import random 11 | 12 | fuzzing = "abcdefghijklmnopqrstuvwxyz0123456789QWERTYUIOPASDFGHJKLZXCVBNM" 13 | fuzz = itertools.permutations(fuzzing, 5) 14 | context.log_level = "debug" 15 | 16 | def cal_bit(num): 17 | num = int(num) 18 | l = len(bin(num)) 19 | return l-2 20 | 21 | def isqrt(n): 22 | x = n 23 | y = (x + 1) // 2 24 | while y < x: 25 | x = y 26 | y = (x + n // x) // 2 27 | if pow(x, 2) == n: 28 | return x 29 | else: 30 | return False 31 | 32 | def divide_pq(ed, n): 33 | # ed = e*d 34 | k = ed - 1 35 | while True: 36 | g = random.randint(3, n-2) 37 | t = k 38 | while True: 39 | if t % 2 != 0: 40 | break 41 | t /= 2 42 | x = pow(g, t, n) 43 | if x > 1 and gcd(x-1, n) > 1: 44 | p = gcd(x-1, n) 45 | return (p, n/p) 46 | 47 | def pi_b(x): 48 | bt = 536380958350616057242691418634880594502192106332317228051967064327642091297687630174183636288378234177476435270519631690543765125295554448698898712393467267006465045949611180821007306678935181142803069337672948471202242891010188677287454504933695082327796243976863378333980923047411230913909715527759877351702062345876337256220760223926254773346698839492268265110546383782370744599490250832085044856878026833181982756791595730336514399767134613980006467147592898197961789187070786602534602178082726728869941829230655559180178594489856595304902790182697751195581218334712892008282605180395912026326384913562290014629187579128041030500771670510157597682826798117937852656884106597180126028398398087318119586692935386069677459788971114075941533740462978961436933215446347246886948166247617422293043364968298176007659058279518552847235689217185712791081965260495815179909242072310545078116020998113413517429654328367707069941427368374644442366092232916196726067387582032505389946398237261580350780769275427857010543262176468343294217258086275244086292475394366278211528621216522312552812343261375050388129743012932727654986046774759567950981007877856194574274373776538888953502272879816420369255752871177234736347325263320696917012616273L 49 | return invmod(x, bt) 50 | 51 | def con_fra(a, b): 52 | r = [] 53 | while True: 54 | if a == 1: 55 | break 56 | tmp = a/b 57 | if tmp != 0: 58 | r.append(tmp) 59 | a, b = b, (a-tmp*b) 60 | return r 61 | 62 | def wiener_attack(e, n): 63 | cf = con_fra(e, n) 64 | for x in xrange(len(cf)): 65 | k, d = 0, 1 66 | while x >= 0: 67 | k, d = d, d*cf[x] + k 68 | x -= 1 69 | # print "k: %s\nd: %s\n" %(k, d) 70 | phi_n = (e*d - 1)/k 71 | B = n - phi_n + 1 72 | C = n 73 | dt = pow(B, 2) - 4*C # b^2 - 4*a*c 74 | if dt >= 0 and isqrt(dt) and (B+isqrt(dt)) % 2 == 0: 75 | print "phi_n: ", hex(phi_n) 76 | return phi_n 77 | print "wiener attack fail!" 78 | 79 | def sha512_proof(fuzz, prefix, verify): 80 | y = len(verify) 81 | while True: 82 | try: 83 | padd = "".join(fuzz.next()) 84 | except StopIteration: 85 | break 86 | r = sha512(prefix + padd).hexdigest() 87 | if verify in r: 88 | return padd 89 | 90 | def verify(r): 91 | r.readuntil("Prefix: ") 92 | prefix = r.readline() 93 | prefix = prefix.decode('base64') 94 | t1 = time.time() 95 | proof = sha512_proof(fuzz, prefix, "fffffff") 96 | print time.time() - t1 97 | r.send(proof.encode('base64')) 98 | 99 | def main(): 100 | r = remote("115.159.191.193", 12000) 101 | # r = process("rsa1.py") 102 | verify(r) 103 | r.readuntil("token: ") 104 | token = "81755de89626aba8db7de4c93e658b68wBJekMIo" 105 | r.sendline(token) 106 | 107 | r.readuntil("n: ") 108 | n = r.readline().strip() 109 | n = int(n[2:-1], 16) 110 | 111 | r.readuntil("e: ") 112 | e = r.readline().strip() 113 | e = int(e[2:-1], 16) 114 | 115 | r.readuntil("is: ") 116 | enc_flag = r.readline().strip() 117 | enc_flag = int(enc_flag[2:-1], 16) 118 | 119 | print "We know:" 120 | print "n: ", hex(n) 121 | print "e: ", hex(e) 122 | print "flag: ", hex(enc_flag) 123 | 124 | print "=======Start Attack======" 125 | t = pi_b(e) 126 | print "get t = ", hex(t) 127 | phi_n = wiener_attack(t, n) 128 | try: 129 | u = invmod(t, phi_n) 130 | except: 131 | return False 132 | print "get u = ", hex(u) 133 | qq, pp = divide_pq(u*t, n) 134 | print "get p = ", hex(pp) 135 | print "get q = ", hex(qq) 136 | d = invmod(e, (qq-1)*(pp-1)) 137 | print "get d = ", hex(d) 138 | flag = pow(enc_flag, d, n) 139 | print "get flag: ", long_to_bytes(flag) 140 | 141 | if __name__ == '__main__': 142 | main() -------------------------------------------------------------------------------- /RSA1/rsa_s.py: -------------------------------------------------------------------------------- 1 | from Crypto.Util.number import * 2 | from sympy.solvers import solve 3 | from sympy import Symbol 4 | import libnum 5 | 6 | def partial_quotiens(x, y): 7 | pq = [] 8 | while x != 1: 9 | pq.append(x / y) 10 | a = y 11 | b = x % y 12 | x = a 13 | y = b 14 | return pq 15 | 16 | def rational(pq): 17 | i = len(pq) - 1 18 | num = pq[i] 19 | denom = 1 20 | while i > 0: 21 | i -= 1 22 | a = (pq[i] * num) + denom 23 | b = num 24 | num = a 25 | denom = b 26 | return (num, denom) 27 | 28 | def convergents(pq): 29 | c = [] 30 | for i in range(1, len(pq)): 31 | c.append(rational(pq[0:i])) 32 | return c 33 | 34 | def phiN(e, d, k): 35 | return ((e * d) - 1) / k 36 | 37 | def wiener_attack(e, n): 38 | pq = partial_quotiens(e, n) 39 | c = convergents(pq) 40 | x = Symbol('x') 41 | print 'done' 42 | for (k, d) in c: 43 | if d != 196176397553781094149364022413702698618416570027142099596910222792686220199799634430113040703408219640551905602804050764120518037301734891772260502596755642106767631991390703026953707346708504142195119698789998222566587930259938572562702895638995035040020739921966671123993267592460124879940448923: 44 | continue 45 | if k != 0: 46 | y = n - phiN(e, d, k) + 1 47 | roots = solve(x**2 - y*x + n, x) 48 | if len(roots) == 2: 49 | p = roots[0] 50 | q = roots[1] 51 | if p * q == n: 52 | break 53 | return p, q 54 | 55 | bt = 536380958350616057242691418634880594502192106332317228051967064327642091297687630174183636288378234177476435270519631690543765125295554448698898712393467267006465045949611180821007306678935181142803069337672948471202242891010188677287454504933695082327796243976863378333980923047411230913909715527759877351702062345876337256220760223926254773346698839492268265110546383782370744599490250832085044856878026833181982756791595730336514399767134613980006467147592898197961789187070786602534602178082726728869941829230655559180178594489856595304902790182697751195581218334712892008282605180395912026326384913562290014629187579128041030500771670510157597682826798117937852656884106597180126028398398087318119586692935386069677459788971114075941533740462978961436933215446347246886948166247617422293043364968298176007659058279518552847235689217185712791081965260495815179909242072310545078116020998113413517429654328367707069941427368374644442366092232916196726067387582032505389946398237261580350780769275427857010543262176468343294217258086275244086292475394366278211528621216522312552812343261375050388129743012932727654986046774759567950981007877856194574274373776538888953502272879816420369255752871177234736347325263320696917012616273L 56 | 57 | e = 0x23f52cf5663b7c4725585b3aba7cccb1458937807da8fa5cefe5fec0b2a60ae4043bff95ed3e2b721901ca3db7a1ceff57fe26d37e9249737a65e3533ad8a2f86f5575165647981d44240d14040dca6f2450efcbb7e45ecbc1fab1f863fbdf4720b00291b423edafafae8df0aa8b76a7ee10d468102c25fe46c6064e4d874c3f9314937845663892f4343475179a55356af61b5a0e84f7a7e92e4c87168f6126289b781beb65762761bc94e1061936dc17232b603dee2e3f3d6a07dfa510f23d7b205b297ea2f874c595ee0a613fd74013befb163164fe916c5e83ee0add0039d858dd1dcbbde5c6c556eb88078d375ee6cce30047c5b453af90f9113615a0ab859d3ddf178acee80c6a16b5f5bd6d351ffcfba1ee2bae3b2596bd932fbc40b99206d2ae144b498cacca39c41e6f13d3df64e9993ede48fbad7f145a6afc7c3eca683ac025d11f7b5f1643784b487ff10357ab53549cd46a7c496effd5a8f2f28fbb9233287b5c4e0fb7b90a9ca503216faf6cba9233be8e5fc62dcaeae4b757437f6171dac83561d8dd0639515ced45ab3d56a8fd209b4ed1bdab9d863c1cfefe7daafa49095dd741085f39afa00fdf63eb7385ca1eb7c9c49f569d84c289bbecb23d0dd8e17766fa16ec317bae79e5c1277b6a3f291aa5e19dd6bcb4a66b796aeb664f14413bbbc3b6cdd827bd9b0cd284da1ad62822f5837ae555ad4f3009L 58 | 59 | n = 0x76fc639cc00be768d4c6ae1624b6ee8a94c07e3afa0da2bc34e483f235d496c08447b4285c93246cc9b4a952d219d9a47577644bc58facda642590ff37ad29a8f269d2ef07d436e8dbb9f610a4a64495eefbba07f7e5984d227476da17e8e522350a16d1aedb4135bca4d5f0343bca8c6f3fa2a3872e06113330153014bb62896e21abaed946d22dc7ac1259242b28f485fb31fc1de6c084a7f819e2881de21b1988a56f7590a47deb7bf872a2a05f6c6e314651ccfd0b1e048b5e9f693dc6b3a9c1cfd71a7ba6934767c98f4f2f241181c67e399e57c448b3a9bdcbb43d5344462c224d9c493e3f18453318a11c7cfd863fc1bae8fe95bf5c31460e213ea49f961cdee8aaa948c09023efbf602f74b7ff5ce50042f032dc6477f8bad33c490b1b9bf588a8fa580ba4ff274c76a339c065e459f5f88e273e80b0fd88f902cae331a91c6923636abe7446136e6a810aecc8c5ac10ce3c9c34f89ac2036193f17191839cade4df451b4a6f171b7ea4042ea7534bbbdffa6974cc64c8d59cdb04f76e6af011d3bb7f0c2cbfce1b13feaf54f8a0f7d32a2d11ab28e01385d6746d849140f71bffcc25fb20992d4a6bcbcf33e3b9e995a806839fa84b865200bd1c0b8f0466382c40323b834c77f822cc4583997fbe1770b1003c424a560889f8657cf2c7021aa59d71f4cc162b4bf7fe29e7a4d9dbf9f67efcc9a59025fc54ea1a9dL 60 | 61 | t = libnum.invmod(e, bt) 62 | 63 | print wiener_attack(t, n) -------------------------------------------------------------------------------- /RSA2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.cn-beijing.aliyuncs.com/hcamael/rsa:base 2 | MAINTAINER Docker Hcamael 3 | 4 | COPY rsa2.py /home/RSA/rsa2.py 5 | COPY flag.py /home/RSA/flag.py 6 | COPY flag /home/RSA/flag 7 | RUN chmod +x /home/RSA/rsa2.py 8 | 9 | USER rsa 10 | EXPOSE 7001 11 | CMD ["socat", "TCP4-LISTEN:7001,fork", "EXEC:\"python -u /home/RSA/rsa2.py\""] 12 | -------------------------------------------------------------------------------- /RSA2/README.md: -------------------------------------------------------------------------------- 1 | **author**: Hcamael 2 | 3 | > 题目名称: Crypto So Cool 4 | 5 | > 分类: Crypto 6 | 7 | > 预估分值: 350 8 | 9 | > 描述: - ( ゜- ゜)つロ
[crypto2.py](rsa2.py)
nc x.x.x.x xxxx 10 | -------------------------------------------------------------------------------- /RSA2/flag: -------------------------------------------------------------------------------- 1 | {"5c9597f3c8245907ea71a89d9d39d08e": "hctf{d8e8fca2dc0f896fd7cb4cb0031ba249}"} 2 | -------------------------------------------------------------------------------- /RSA2/flag.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import json 5 | 6 | def get_flag(token): 7 | with open('/home/RSA/flag') as f: 8 | flags = json.loads(f.read()) 9 | return flags[token] 10 | -------------------------------------------------------------------------------- /RSA2/flag.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/RSA2/flag.pyc -------------------------------------------------------------------------------- /RSA2/rsa2.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from Crypto.Util.number import getPrime, long_to_bytes, bytes_to_long, isPrime, size 5 | from Crypto.Cipher import DES 6 | from libnum import gcd, invmod 7 | from flag import get_flag 8 | from hashlib import sha512 9 | import signal 10 | import random 11 | 12 | __author__ = 'Hcamael' 13 | 14 | key = "abcdefg1" 15 | k = 2048 16 | e = 0x10001 17 | signal.alarm(40) 18 | 19 | def m_exit(n): 20 | print "==============Game Over!=================" 21 | exit(n) 22 | 23 | def get_bit(number, n_bit, dire): 24 | ''' 25 | dire: 26 | 1: left 27 | 0: right 28 | ''' 29 | 30 | if dire: 31 | sn = size(number) 32 | if sn % 8 != 0: 33 | sn += (8 - sn % 8) 34 | return number >> (sn-n_bit) 35 | else: 36 | return number & (pow(2, n_bit) - 1) 37 | 38 | def pi_b(x, m): 39 | ''' 40 | m: 41 | 1: encrypt 42 | 0: decrypt 43 | ''' 44 | enc = DES.new(key) 45 | if m: 46 | method = enc.encrypt 47 | else: 48 | method = enc.decrypt 49 | s = long_to_bytes(x) 50 | sp = [s[a:a+8] for a in xrange(0, len(s), 8)] 51 | r = "" 52 | for a in sp: 53 | r += method(a) 54 | return bytes_to_long(r) 55 | 56 | def gen_key(): 57 | while True: 58 | p = getPrime(k/2) 59 | if gcd(e, p-1) == 1: 60 | break 61 | q_t = getPrime(k/2) 62 | n_t = p * q_t 63 | t = get_bit(n_t, k/16, 1) 64 | y = get_bit(n_t, 5*k/8, 0) 65 | p4 = get_bit(p, 5*k/16, 1) 66 | u = pi_b(p4, 1) 67 | n = bytes_to_long(long_to_bytes(t) + long_to_bytes(u) + long_to_bytes(y)) 68 | q = n / p 69 | if q % 2 == 0: 70 | q += 1 71 | while True: 72 | if isPrime(q) and gcd(e, q-1) == 1: 73 | break 74 | m = getPrime(k/16) + 1 75 | q ^= m 76 | return (p, q, e) 77 | 78 | def verify(): 79 | print "Proof of Work" 80 | with open("/dev/urandom") as f: 81 | prefix = f.read(5) 82 | print "Prefix: %s" %prefix.encode('base64') 83 | try: 84 | suffix = raw_input() 85 | s = suffix.decode('base64') 86 | except: 87 | exit(-1) 88 | r = sha512(prefix + s).hexdigest() 89 | if "fffffff" not in r: 90 | exit(-1) 91 | 92 | def main(): 93 | verify() 94 | usage = """ 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 | print usage 123 | print "This is a RSA Decryption System" 124 | print "Please enter Your team token: " 125 | try: 126 | token = raw_input() 127 | flag = get_flag(token) 128 | assert len(flag) == 38 129 | except: 130 | print "Token error!" 131 | m_exit(-1) 132 | 133 | p, q, e = gen_key() 134 | n = p * q 135 | phi_n = (p-1)*(q-1) 136 | d = invmod(e, phi_n) 137 | while True: 138 | e2 = random.randint(0x1000, 0x10000) 139 | if gcd(e2, phi_n) == 1: 140 | break 141 | print "n: ", hex(n) 142 | print "e: ", hex(e) 143 | print "e2: ", hex(e2) 144 | flag = bytes_to_long(flag) 145 | enc_flag = pow(flag, e2, n) 146 | print "Your flag is: ", hex(enc_flag) 147 | print "============Start Games============" 148 | print "Please enter your cipher: " 149 | while True: 150 | try: 151 | s = raw_input() 152 | c = int(s) 153 | except: 154 | m_exit(-1) 155 | m = pow(c, d, n) 156 | print "Your Plaintext is: ", hex(m) 157 | time.sleep(1) 158 | 159 | if __name__ == '__main__': 160 | main() 161 | -------------------------------------------------------------------------------- /RSA2/rsa2_payload.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from Crypto.Util.number import size, long_to_bytes, bytes_to_long 5 | from Crypto.Cipher import DES 6 | from hashlib import sha512 7 | from pwn import process, context, remote 8 | import itertools 9 | import time 10 | 11 | fuzzing = "abcdefghijklmnopqrstuvwxyz0123456789QWERTYUIOPASDFGHJKLZXCVBNM" 12 | fuzz = itertools.permutations(fuzzing, 5) 13 | context.log_level = "debug" 14 | 15 | k = 2048 16 | key = "abcdefg1" 17 | 18 | def pi_b(x, m): 19 | ''' 20 | m: 21 | 1: encrypt 22 | 0: decrypt 23 | ''' 24 | enc = DES.new(key) 25 | if m: 26 | method = enc.encrypt 27 | else: 28 | method = enc.decrypt 29 | s = long_to_bytes(x) 30 | sp = [s[a:a+8] for a in xrange(0, len(s), 8)] 31 | r = "" 32 | for a in sp: 33 | r += method(a) 34 | return bytes_to_long(r) 35 | 36 | 37 | def get_bit(number, n_bit, dire): 38 | ''' 39 | dire: 40 | 1: left 41 | 0: right 42 | ''' 43 | 44 | if dire: 45 | sn = size(number) 46 | if sn % 8 != 0: 47 | sn += (8 - sn % 8) 48 | return number >> (sn-n_bit) 49 | else: 50 | return number & (pow(2, n_bit) - 1) 51 | 52 | def sha512_proof(fuzz, prefix, verify): 53 | y = len(verify) 54 | while True: 55 | try: 56 | padd = "".join(fuzz.next()) 57 | except StopIteration: 58 | break 59 | r = sha512(prefix + padd).hexdigest() 60 | if verify in r: 61 | return padd 62 | 63 | def verify(r): 64 | r.readuntil("Prefix: ") 65 | prefix = r.readline() 66 | prefix = prefix.decode('base64') 67 | t1 = time.time() 68 | proof = sha512_proof(fuzz, prefix, "fffffff") 69 | print time.time() - t1 70 | r.send(proof.encode('base64')) 71 | 72 | def main(): 73 | r = remote("115.159.191.193", 13000) 74 | # r = process("rsa2.py") 75 | verify(r) 76 | r.readuntil("token: ") 77 | token = "d58c9a2aca58a3f2faf17ec5e7deaec6ZHSBHK6e" 78 | r.sendline(token) 79 | 80 | # r.readuntil("p4: ") 81 | # p_4 = r.readline().strip() 82 | # p_4 = int(p_4[2:-1], 16) 83 | 84 | r.readuntil("n: ") 85 | n = r.readline().strip() 86 | n = int(n[2:-1], 16) 87 | e = 0x10001 88 | r.readuntil("e2: ") 89 | e2 = r.readline().strip() 90 | e2 = int(e2[2:], 16) 91 | print "n: ", hex(n) 92 | print "e: ", hex(e) 93 | print "e2: ", hex(e2) 94 | r.readuntil("flag is: ") 95 | flag = r.readline().strip() 96 | flag = int(flag[2:-1], 16) 97 | print "flag: ", hex(flag) 98 | print "=======start attack=====" 99 | n1 = get_bit(n, 3*k/8, 1) 100 | # print "n1: ", hex(n1) 101 | p4 = pi_b(get_bit(n1, 5*k/16, 0), 0) 102 | # if p_4 == p4: 103 | # return True 104 | # else: 105 | # return False 106 | print "p4: ", hex(p4) 107 | r.close() 108 | 109 | if __name__ == '__main__': 110 | # n = 0 111 | # for x in xrange(100): 112 | # if main(): 113 | # n += 1 114 | 115 | # print "n: {}%".format(n) 116 | main() -------------------------------------------------------------------------------- /RSA2/rsa2_payload.sage: -------------------------------------------------------------------------------- 1 | p4 = 0xf3a5f928e11c5901f9f4289e513f046748efb99d4f8e706e207a943e1d2c9df43feab38e20c2106d87167e5501ac41adfc4912732457103a4359e5b433da78f39ad6f206b8f170192aa0841feb501ce1 2 | n = 0x7e7007c7c85788b9b77cda64c9b3f5d2a795fe1b1f8d3f120288a30a168c3ea932c7574700ff0f596c5ad04a703756aedc66b9b9e44911d55f0a72a1cc1a569cee02a84499cdb091b8471a8e6cc0ebca583dfd6fb8d5fecf32ff67d2ddeaaaaf9c71a10009b4218fc57743675f283d22734ac7ade2ca240772d11b5783755378f7c30988f41d4a9d62561ea6e5f2f21d3d44e8689e781d3f61356123929457d17b07a1d04741bf970afb590cd820dd12cf88f68b0e896388f433fd2adf3354353c9c56abb0cfea223387e6d0b2df10e450c621ac153e47369f888fdc0b39c842a5ddc6a11339862ccdb4be97a81445205fb8f8bde9daaad5d0dc2ea5bd3b8c43 3 | 4 | pbits = 1024 5 | kbits = pbits - p4.nbits() 6 | print p4.nbits() 7 | p4 = p4 << kbits 8 | 9 | PR. = PolynomialRing(Zmod(n)) 10 | f = x + p4 11 | x0 = f.small_roots(X=2^kbits, beta=0.4)[0] 12 | print "x: %s" %hex(int(x0)) 13 | 14 | p = p4+x0 15 | print "p: ", hex(int(p)) 16 | assert n % p == 0 17 | q = n/int(p) 18 | 19 | print "q: ", hex(int(q)) -------------------------------------------------------------------------------- /RSA3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.cn-beijing.aliyuncs.com/hcamael/rsa:base 2 | MAINTAINER Docker Hcamael 3 | 4 | COPY rsa3.py /home/RSA/rsa3.py 5 | COPY flag.py /home/RSA/flag.py 6 | COPY flag /home/RSA/flag 7 | RUN chmod +x /home/RSA/rsa3.py 8 | 9 | USER rsa 10 | EXPOSE 7002 11 | CMD ["socat", "TCP4-LISTEN:7002,fork", "EXEC:\"python -u /home/RSA/rsa3.py\""] 12 | 13 | -------------------------------------------------------------------------------- /RSA3/README.md: -------------------------------------------------------------------------------- 1 | **author**: Hcamael 2 | 3 | > 题目名称: Crypto So Amazing 4 | 5 | > 分类: Crypto 6 | 7 | > 预估分值: 400 8 | 9 | > 描述: ∑^)/
[crypto1.py](rsa1.py)
nc x.x.x.x xxxx 10 | -------------------------------------------------------------------------------- /RSA3/flag: -------------------------------------------------------------------------------- 1 | {"5c9597f3c8245907ea71a89d9d39d08e": "hctf{d8e8fca2dc0f896fd7cb4cb0031ba249}"} 2 | -------------------------------------------------------------------------------- /RSA3/flag.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import json 5 | 6 | def get_flag(token): 7 | with open('/home/RSA/flag') as f: 8 | flags = json.loads(f.read()) 9 | return flags[token] 10 | -------------------------------------------------------------------------------- /RSA3/flag.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/RSA3/flag.pyc -------------------------------------------------------------------------------- /RSA3/rsa3.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from Crypto.Util.number import size, getPrime, long_to_bytes, bytes_to_long, isPrime, getRandomNBitInteger 5 | from libnum import invmod, gcd 6 | from flag import get_flag 7 | from hashlib import sha512 8 | import random 9 | import time 10 | import signal 11 | 12 | __author__ = 'Hcamael' 13 | 14 | k = 2048 15 | e = 0x10001 16 | o = 1024 17 | m = 256 18 | signal.alarm(40) 19 | 20 | 21 | def m_exit(n): 22 | print "==============Game Over!=================" 23 | exit(n) 24 | 25 | def verify(): 26 | print "Proof of Work" 27 | with open("/dev/urandom") as f: 28 | prefix = f.read(5) 29 | print "Prefix: %s" %prefix.encode('base64') 30 | try: 31 | suffix = raw_input() 32 | s = suffix.decode('base64') 33 | except: 34 | m_exit(-1) 35 | r = sha512(prefix + s).hexdigest() 36 | if "fffffff" not in r: 37 | m_exit(-1) 38 | 39 | def get_bit(number, n_bit, dire): 40 | ''' 41 | dire: 42 | 1: left 43 | 0: right 44 | ''' 45 | 46 | if dire: 47 | sn = size(number) 48 | if sn % 8 != 0: 49 | sn += (8 - sn % 8) 50 | return number >> (sn-n_bit) 51 | else: 52 | return number & (pow(2, n_bit) - 1) 53 | 54 | def int_add(x1, x2): 55 | return bytes_to_long(long_to_bytes(x1) + long_to_bytes(x2)) 56 | 57 | def H_hash(x): 58 | h = sha512(long_to_bytes(x)).hexdigest() 59 | return int(h, 16) 60 | 61 | def F_hash(x): 62 | h = sha512(long_to_bytes(x/4)).hexdigest() 63 | return int(h, 16) 64 | 65 | def pi_sit_x(sit, x): 66 | ''' 67 | default sit = 1024 68 | ''' 69 | xu = get_bit(x, sit/2, 1) 70 | xl = get_bit(x, sit/2, 0) 71 | yu = F_hash(H_hash(xu) ^ xl) ^ xu 72 | yl = H_hash(xu) ^ xl 73 | return int_add(yu, yl) 74 | 75 | def get_pkey(): 76 | print "DH key exchange system:" 77 | P = getPrime(m) 78 | print "P: ", hex(P) 79 | G = getRandomNBitInteger(m) 80 | a = getRandomNBitInteger(m/4) 81 | Ya = pow(G, a, P) 82 | print "Please enter you secret key: " 83 | try: 84 | b = raw_input() 85 | b = int(b) 86 | assert size(b) == m/4 87 | except: 88 | m_exit(-1) 89 | Yb = pow(G, b, P) 90 | K = pow(Yb, a, P) 91 | return (Ya, K) 92 | 93 | def GenPrimeWithOracle(spriv, L, e): 94 | ''' 95 | Generate p 96 | ''' 97 | T = L/2 + 64 98 | T1 = L - T 99 | PRF = random.Random() 100 | PRF.seed(spriv) 101 | while True: 102 | u = PRF.randint(2**(T-1), 2**T) 103 | l = getRandomNBitInteger(T1) 104 | p1 = int_add(u, l) 105 | if isPrime(p1): 106 | return p1 107 | 108 | def GetPrimes(spub, spriv): 109 | p1 = GenPrimeWithOracle(spriv, k/2, e) 110 | while True: 111 | s0 = getRandomNBitInteger(o - m - 1) 112 | s = int_add(s0, spub) 113 | t = pi_sit_x(o, s) 114 | r2 = getRandomNBitInteger(k-o) 115 | nc = int_add(t, r2) 116 | q1 = nc / p1 117 | if isPrime(q1): 118 | return (p1, q1) 119 | 120 | def main(): 121 | verify() 122 | usage = """ 123 | 01010111 01100101 01101100 01100011 01101111 01101101 124 | 01110100 01101111 00110010 00110000 00110001 00110110 125 | 01001000 01000011 01010100 01000110 01010010 01010011 01000001 126 | 01000100 01100101 01100011 01101111 01100100 01100101 127 | 01010011 01111001 01110011 01110100 01100101 01101101 128 | """ 129 | print usage 130 | print "This is a RSA Decryption System" 131 | print "Please enter Your team token: " 132 | try: 133 | token = raw_input() 134 | flag = get_flag(token) 135 | assert len(flag) == 38 136 | except: 137 | print "Token error!" 138 | m_exit(-1) 139 | 140 | spub, spriv = get_pkey() 141 | # Generation p, q 142 | p, q = GetPrimes(spub, spriv) 143 | n = p * q 144 | phi_n = (p-1)*(q-1) 145 | d = invmod(e, phi_n) 146 | while True: 147 | e2 = random.randint(0x1000, 0x10000) 148 | if gcd(e2, phi_n) == 1: 149 | break 150 | 151 | print "In this Game, Your public key:" 152 | print "n: ", hex(n) 153 | print "e: ", hex(e) 154 | print "e2: ", hex(e2) 155 | flag = bytes_to_long(flag) 156 | enc_flag = pow(flag, e2, n) 157 | print "Your flag is: ", hex(enc_flag) 158 | print "============Start Games============" 159 | print "Please enter your cipher: " 160 | while True: 161 | s = raw_input() 162 | try: 163 | c = int(s) 164 | except: 165 | m_exit(-1) 166 | m = pow(c, d, n) 167 | print "Your Plaintext is: ", hex(m) 168 | time.sleep(1) 169 | 170 | if __name__ == '__main__': 171 | main() 172 | -------------------------------------------------------------------------------- /RSA3/rsa3.sage: -------------------------------------------------------------------------------- 1 | from sage3 import get_p4 2 | 3 | n = 0xf7a8a487bc5c8127ac30cfbfc08e042580f359edce3db416b8a9abcb0e8dcac5404bb0eea3076966a78bb8e726e6fea79d305cc7c2cddb3dd2578a64b5591df1c9716878f35f1967398861cb368886b60c6d0c2984be3ead8dcdd80d68bb094805068b5d157c16d2b56cf0c3f06797b07bf3a7ab2a5099762958feaf72a212a63c74a4fb7da4092e6a91e72bf74ee961b995545891290c50cb28151b540efdedef9d4cc1c104758050c21dda8be8310fc7e005a08cedbcc8500fe0f9fdaa044e7cb07387060358add1d82521b5f8697b6a8ca2bd19a363bae7558e94404a1c4b82ee98878f9dff0e21030e020c698778aa645001f4c7726d3ac04720295975c9 4 | pbits = 1024 5 | 6 | g_p = get_p4() 7 | while True: 8 | p4 = g_p.next() 9 | # p4 = 0x81a722c9fc2b2ed061fdab737e3893506eae71ca6415fce14c0f9a45f8e2300711119fa0a5135a053e654fead010b96e987841e47db586a55e3d4494613aa0cc4e4ab59fc6a958b5 10 | kbits = pbits - 576 11 | p4 = p4 << kbits 12 | 13 | PR. = PolynomialRing(Zmod(n)) 14 | f = x + p4 15 | x0 = f.small_roots(X=2^kbits, beta=0.4) 16 | if len(x0) == 0: 17 | continue 18 | print "x: %s" %hex(int(x0[0])) 19 | 20 | p = p4+x0[0] 21 | print "p: ", hex(int(p)) 22 | assert n % p == 0 23 | q = n/int(p) 24 | 25 | print "q: ", hex(int(q)) 26 | print "p4: ", hex(p4) 27 | break -------------------------------------------------------------------------------- /RSA3/rsa3_payload.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from Crypto.Util.number import size, long_to_bytes, bytes_to_long, getRandomNBitInteger 5 | from hashlib import sha512 6 | from pwn import process, context, remote 7 | import itertools 8 | import random 9 | import time 10 | 11 | fuzzing = "abcdefghijklmnopqrstuvwxyz0123456789QWERTYUIOPASDFGHJKLZXCVBNM" 12 | fuzz = itertools.permutations(fuzzing, 5) 13 | context.log_level = "debug" 14 | 15 | k = 2048 16 | e = 0x10001 17 | o = 1024 18 | m = 256 19 | 20 | def get_bit(number, n_bit, dire): 21 | ''' 22 | dire: 23 | 1: left 24 | 0: right 25 | ''' 26 | 27 | if dire: 28 | sn = size(number) 29 | if sn % 8 != 0: 30 | sn += (8 - sn % 8) 31 | return number >> (sn-n_bit) 32 | else: 33 | return number & (pow(2, n_bit) - 1) 34 | 35 | def int_add(x1, x2): 36 | ''' 37 | bit plus 38 | ''' 39 | return bytes_to_long(long_to_bytes(x1) + long_to_bytes(x2)) 40 | 41 | def H_hash(x): 42 | h = sha512(long_to_bytes(x)).hexdigest() 43 | return int(h, 16) 44 | 45 | def F_hash(x): 46 | h = sha512(long_to_bytes(x/4)).hexdigest() 47 | return int(h, 16) 48 | 49 | def pi_sit_x1(sit, y): 50 | ''' 51 | inverse operation 52 | ''' 53 | yu = get_bit(y, sit/2, 1) 54 | yl = get_bit(y, sit/2, 0) 55 | xu = yu ^ H_hash(yl) 56 | xl = yl ^ H_hash(yu ^ F_hash(yl)) 57 | return int_add(xu, xl) 58 | 59 | def sha512_proof(fuzz, prefix, verify): 60 | y = len(verify) 61 | while True: 62 | try: 63 | padd = "".join(fuzz.next()) 64 | except StopIteration: 65 | break 66 | r = sha512(prefix + padd).hexdigest() 67 | if verify in r: 68 | return padd 69 | 70 | def verify(r): 71 | r.readuntil("Prefix: ") 72 | prefix = r.readline() 73 | prefix = prefix.decode('base64') 74 | t1 = time.time() 75 | proof = sha512_proof(fuzz, prefix, "fffffff") 76 | print time.time() - t1 77 | r.send(proof.encode('base64')) 78 | 79 | def main(): 80 | r = remote("120.27.4.96", 14000) 81 | # r = process("rsa3.py") 82 | verify(r) 83 | r.readuntil("token: ") 84 | token = "d58c9a2aca58a3f2faf17ec5e7deaec6ZHSBHK6e" 85 | r.sendline(token) 86 | r.readuntil("P: ") 87 | P = r.readline().strip() 88 | P = int(P[2:-1], 16) 89 | 90 | r.readuntil('key:') 91 | b = getRandomNBitInteger(m/4) 92 | r.sendline(str(b)) 93 | 94 | r.readuntil("n: ") 95 | n = r.readline().strip() 96 | n = int(n[2:-1], 16) 97 | e = 0x10001 98 | r.readuntil("e2: ") 99 | e2 = r.readline().strip() 100 | e2 = int(e2[2:], 16) 101 | r.readuntil("flag is: ") 102 | flag = r.readline().strip() 103 | flag = int(flag[2:-1], 16) 104 | r.close() 105 | print "n: ", hex(n) 106 | print "e: ", hex(e) 107 | print "e2: ", hex(e2) 108 | print "flag: ", hex(flag) 109 | print "=======start attack=====" 110 | t = get_bit(n, 1024, 1) 111 | print "t: ", hex(t) 112 | s = pi_sit_x1(o, t) 113 | print "s: ", hex(s) 114 | attack_spub = get_bit(s, m, 0) 115 | # if attack_spub == spub: 116 | # return True 117 | # else: 118 | # t += 1 119 | # s = pi_sit_x1(o, t) 120 | # attack_spub = get_bit(s, m, 0) 121 | # if attack_spub == spub: 122 | # return True 123 | # else: 124 | # raw_input() 125 | # return False 126 | attack_spriv = pow(attack_spub, b, P) 127 | print "spub: ", hex(attack_spub) 128 | print "spriv: ", hex(attack_spriv) 129 | 130 | if __name__ == '__main__': 131 | main() 132 | # n = 0 133 | # for x in xrange(100): 134 | # if main(): 135 | # n += 1 136 | 137 | # print "n: {}%".format(n) 138 | -------------------------------------------------------------------------------- /RSA3/sage3.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | spriv = 76515803399948578070392316249460231617205640228540294074078216016927174232385 4 | T = 512 + 64 5 | 6 | PRF = random.Random() 7 | PRF.seed(spriv) 8 | 9 | def get_p4(): 10 | while True: 11 | u = PRF.randint(2**(T-1), 2**T) 12 | yield u 13 | -------------------------------------------------------------------------------- /cf-RSA?/flag.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/cf-RSA?/flag.enc -------------------------------------------------------------------------------- /cf-RSA?/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MEEwDQYJKoZIhvcNAQEBBQADMAAwLQIoAsqpwJ3BBh5Qflt/Od3jRV/P4Seixpti 3 | HIP9nT0+qjqsQhR81xiMUwIBAw== 4 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /diy-tool/cbc-padding-oracle-attack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from optparse import OptionParser 5 | import requests 6 | import struct 7 | 8 | class POAttack(): 9 | """ 10 | 以GGCTF的一题为例写的Padding Oracle Attack 11 | By Hcamael 12 | """ 13 | def __init__(self, options): 14 | self.url = options.url 15 | self.length = options.length 16 | cookie = options.cookie.split("=") 17 | assert len(cookie) == 2 18 | self.c_name = cookie[0] 19 | c = cookie[1].decode('hex') 20 | if len(c) % self.length != 0 or len(c) == self.length: 21 | raise "cookie error!" 22 | self.sign = c[-self.length:].encode('hex') 23 | self.result = self.sign 24 | self.unenc = "" 25 | if options.plain: 26 | self.plain = options.plain 27 | self.pad_plain = (self.length - len(self.plain) % self.length) 28 | self.pad_iv = c[-self.length*2: -self.length] 29 | else: 30 | self.pad_plain = 0 31 | 32 | def attack(self, msg): 33 | self.a_str = msg 34 | pad = (self.length - len(self.a_str) % self.length) 35 | self.a_str += chr(pad) * pad 36 | assert len(self.a_str) % self.length == 0 37 | self.l_str = list(struct.unpack("16s"*(len(self.a_str)/self.length), self.a_str)) 38 | 39 | self.iv = "\x00" * self.length 40 | for x in xrange(len(self.l_str)): 41 | result = self.padding() 42 | self.unenc = result + self.unenc 43 | assert len(result) == len(self.l_str[-x-1]) == self.length 44 | tmp = "" 45 | for y in xrange(len(result)): 46 | tmp += chr(ord(result[y])^ord(self.l_str[-x-1][y])) 47 | self.sign = tmp.encode('hex') 48 | self.result = self.sign + self.result 49 | return (self.result, self.unenc.encode("hex")) 50 | 51 | def padding(self): 52 | tmp_iv = list(self.iv) 53 | result = list("\x00" * self.length) 54 | if not self.pad_plain: 55 | n = 0 56 | else: 57 | n = self.pad_plain 58 | for i in xrange(n): 59 | result[-i-1] = chr(n ^ ord(self.pad_iv[-i-1])) 60 | self.pad_plain = 0 61 | for x in xrange(n, self.length): 62 | if n != x: 63 | raise "Padding Error!" 64 | for i in xrange(x): 65 | tmp_iv[-i-1] = chr((x+1) ^ ord(result[-i-1])) 66 | for y in xrange(256): 67 | tmp_iv[-x-1] = chr(y) 68 | tmp = "".join(tmp_iv).encode('hex') 69 | cookie = {self.c_name: tmp + self.sign} 70 | try: 71 | req = requests.get(self.url, cookies=cookie, verify=False, allow_redirects=False) 72 | except: 73 | print result 74 | print self.result 75 | exit() 76 | if req.status_code != 500: 77 | result[-x-1] = chr(y^(x+1)) 78 | n += 1 79 | break 80 | return "".join(result) 81 | 82 | def add_parse(): 83 | parser = OptionParser() 84 | parser.add_option( 85 | "--url", 86 | dest="url", 87 | help="Please input the url") 88 | parser.add_option( 89 | "--l", 90 | dest="length", 91 | type="int", 92 | help="Please input the iv's bytes length") 93 | parser.add_option( 94 | "--cookie", 95 | dest="cookie", 96 | help="Please input the url's cookie") 97 | parser.add_option( 98 | "--s", 99 | dest="a_str", 100 | help="Please input you want to construct a string") 101 | parser.add_option( 102 | "--p", 103 | dest="plain", 104 | help="Please input if you know cookie's pliantext") 105 | return parser 106 | 107 | def main(): 108 | parser = add_parse() 109 | (options, args) = parser.parse_args() 110 | if not (options.url and options.length and options.cookie and options.a_str): 111 | parser.parse_args(['cbc-padding-oracle-attack.py', '-h']) 112 | exit(-1) 113 | 114 | cbca = POAttack(options) 115 | r, s = cbca.attack(options.a_str) 116 | print "+-------------------+" 117 | print "| Result |" 118 | print "+--------------------+" 119 | print "Your want string's cookie: " + r 120 | print "AES decrypt result: " + s 121 | 122 | if __name__ == '__main__': 123 | main() -------------------------------------------------------------------------------- /diy-tool/cbc-padding-oracle-attack2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from optparse import OptionParser 5 | import requests 6 | import struct 7 | 8 | class POAttack(): 9 | """ 10 | 以GGCTF的一题为例写的Padding Oracle Attack 11 | By Hcamael 12 | """ 13 | def __init__(self, options): 14 | self.url = options.url 15 | self.length = options.length 16 | cookie = options.cookie.split("=") 17 | assert len(cookie) == 2 18 | self.c_name = cookie[0] 19 | c = cookie[1].decode('hex') 20 | if len(c) % self.length != 0 or len(c) == self.length: 21 | raise "cookie error!" 22 | self.sign = c[-self.length:].encode('hex') 23 | self.result = self.sign 24 | self.unenc = "" 25 | if options.plain: 26 | self.plain = options.plain 27 | self.pad_plain = (self.length - len(self.plain) % self.length) 28 | self.pad_iv = c[-self.length*2: -self.length] 29 | else: 30 | self.pad_plain = 0 31 | 32 | def attack(self, msg): 33 | self.a_str = msg 34 | pad = (self.length - len(self.a_str) % self.length) 35 | self.a_str += chr(pad) * pad 36 | assert len(self.a_str) % self.length == 0 37 | self.l_str = list(struct.unpack("16s"*(len(self.a_str)/self.length), self.a_str)) 38 | 39 | self.iv = "\x00" * self.length 40 | for x in xrange(len(self.l_str)): 41 | print "+===================================================+" 42 | print "plaintext: %s" % self.l_str[-x-1].encode('hex') 43 | result = self.padding() 44 | self.unenc = result + self.unenc 45 | assert len(result) == len(self.l_str[-x-1]) == self.length 46 | tmp = "" 47 | for y in xrange(len(result)): 48 | tmp += chr(ord(result[y])^ord(self.l_str[-x-1][y])) 49 | self.sign = tmp.encode('hex') 50 | self.result = self.sign + self.result 51 | return (self.result, self.unenc.encode("hex")) 52 | 53 | def padding(self): 54 | tmp_iv = list(self.iv) 55 | result = list("\x00" * self.length) 56 | if not self.pad_plain: 57 | n = 0 58 | else: 59 | n = self.pad_plain 60 | for i in xrange(n): 61 | result[-i-1] = chr(n ^ ord(self.pad_iv[-i-1])) 62 | self.pad_plain = 0 63 | for x in xrange(n, self.length): 64 | if n != x: 65 | raise "Padding Error!" 66 | for i in xrange(x): 67 | tmp_iv[-i-1] = chr((x+1) ^ ord(result[-i-1])) 68 | for y in xrange(256): 69 | tmp_iv[-x-1] = chr(y) 70 | tmp = "".join(tmp_iv).encode('hex') 71 | cookie = {self.c_name: "d379b40e4da82e7d080d689d6fed5942671dde6f." + tmp + self.sign} 72 | try: 73 | req = requests.get(self.url, cookies=cookie, verify=False, allow_redirects=False) 74 | except: 75 | print result 76 | print self.result 77 | exit() 78 | if req.status_code != 500: 79 | result[-x-1] = chr(y^(x+1)) 80 | print "iv xor plaintext = %s" % "".join(result[-x-1:]).encode('hex') 81 | n += 1 82 | break 83 | return "".join(result) 84 | 85 | def add_parse(): 86 | parser = OptionParser() 87 | parser.add_option( 88 | "--url", 89 | dest="url", 90 | help="Please input the url") 91 | parser.add_option( 92 | "--l", 93 | dest="length", 94 | type="int", 95 | help="Please input the iv's bytes length") 96 | parser.add_option( 97 | "--cookie", 98 | dest="cookie", 99 | help="Please input the url's cookie") 100 | # parser.add_option( 101 | # "--s", 102 | # dest="a_str", 103 | # help="Please input you want to construct a string") 104 | parser.add_option( 105 | "--p", 106 | dest="plain", 107 | help="Please input if you know cookie's pliantext") 108 | return parser 109 | 110 | def main(): 111 | parser = add_parse() 112 | (options, args) = parser.parse_args() 113 | if not (options.url and options.length and options.cookie): 114 | parser.parse_args(['cbc-padding-oracle-attack.py', '-h']) 115 | exit(-1) 116 | options.a_str = "username=a\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x50&username=admin" 117 | cbca = POAttack(options) 118 | r, s = cbca.attack(options.a_str) 119 | print "+-------------------+" 120 | print "| Result |" 121 | print "+--------------------+" 122 | print "Your want string's cookie: " + r 123 | print "AES decrypt result: " + s 124 | 125 | if __name__ == '__main__': 126 | main() -------------------------------------------------------------------------------- /diy-tool/sha1-length-extend-attack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from optparse import OptionParser 5 | import struct 6 | import ctypes 7 | 8 | def ROTL32(x, r): 9 | x, r = int(x), int(r) 10 | return (x << r) ^ (x >> (32 - r)) 11 | 12 | class SHA1Attack(): 13 | """ 14 | SHA1 Length extend attack by Hcamael 15 | s = sha1(mac+m) 16 | if we know s, we can calculate sha1(mac+m+padding+msg) 17 | """ 18 | def __init__(self, options): 19 | self.hash_ = [0, 0, 0, 0, 0] 20 | for x in xrange(0, 40, 8): 21 | self.hash_[x/8] = int(options.signal[x:x+8], 16) 22 | self.length_ = len(options.extend) + ((options.macl + len(options.origin)) / 64 + 1) * 64 23 | print self.length_ 24 | self.str_to_block(options.extend) 25 | self.block = self.padding() 26 | 27 | def padding(self): 28 | message = [] 29 | for x in xrange(16): 30 | message.append(0) 31 | for x in xrange(16): 32 | tmp = struct.pack("I", self.block[x]) 33 | message[x] = int(tmp.encode('hex'), 16) 34 | 35 | index = (self.length_ & 63) >> 2 36 | shift = (self.length_ & 3) * 8 37 | message[index] &= ~(0xFFFFFFFF << shift) 38 | message[index] ^= 0x80 << shift 39 | index += 1 40 | 41 | if index > 14: 42 | while index < 16: 43 | message[index] = 0 44 | index += 1 45 | # 进行大小端转换 46 | for x in xrange(16): 47 | tmp = struct.pack("I", message[x]) 48 | message[x] = int(tmp.encode('hex'), 16) 49 | self.block = message 50 | self.sha1_process() 51 | index = 0 52 | 53 | while index < 14: 54 | message[index] = 0 55 | index += 1 56 | 57 | data_len = self.length_ << 3 58 | data_len = int(struct.pack("L", data_len).encode("hex"), 16) 59 | message[14] = data_len & 0x00000000FFFFFFFF 60 | message[15] = (data_len & 0xFFFFFFFF00000000) >> 32 61 | # 进行大小端转换 62 | for x in xrange(16): 63 | tmp = struct.pack("I", message[x]) 64 | message[x] = int(tmp.encode('hex'), 16) 65 | return message 66 | 67 | def str_to_block(self, msg): 68 | self.block = [] 69 | msg += (64 - self.length_%64) * '\x00' 70 | for i in xrange(0, 64, 4): 71 | tmp = msg[i: i + 4] 72 | tmp = int(tmp.encode('hex') or '0', 16) 73 | self.block.append(tmp) 74 | 75 | def calculate(self): 76 | self.sha1_process() 77 | for x in xrange(5): 78 | self.hash_[x] = ctypes.c_uint32(self.hash_[x]) 79 | result = "" 80 | for x in self.hash_: 81 | result += "{:0>8}".format(hex(x.value)[2:-1]) 82 | return result 83 | 84 | def sha1_process(self): 85 | wblock = [] 86 | for x in xrange(80): 87 | wblock.append(0) 88 | 89 | for x in xrange(16): 90 | wblock[x] = self.block[x] 91 | 92 | for x in xrange(16, 80): 93 | wblock[x] = ROTL32(wblock[x - 3] ^ wblock[x - 8] ^ wblock[x - 14] ^ wblock[x - 16], 1) & 0xFFFFFFFF 94 | 95 | a = self.hash_[0] 96 | b = self.hash_[1] 97 | c = self.hash_[2] 98 | d = self.hash_[3] 99 | e = self.hash_[4] 100 | 101 | for x in xrange(20): 102 | 103 | temp = ROTL32(a, 5) + (((c ^ d) & b) ^ d) + e + wblock[x] + 0x5A827999 104 | temp &= 0xFFFFFFFF 105 | e = d 106 | d = c 107 | c = ROTL32(b, 30) & 0xFFFFFFFF 108 | b = a 109 | a = temp 110 | 111 | for x in xrange(20, 40): 112 | temp = ROTL32(a, 5) + (b ^ c ^ d) + e + wblock[x] + 0x6ED9EBA1 113 | temp &= 0xFFFFFFFF 114 | e = d 115 | d = c 116 | c = ROTL32(b, 30) & 0xFFFFFFFF 117 | b = a 118 | a = temp 119 | 120 | for x in xrange(40, 60): 121 | temp = ROTL32(a, 5) + ((b & c) | (b & d) | (c & d)) + e + wblock[x] + 0x8F1BBCDC 122 | temp &= 0xFFFFFFFF 123 | e = d 124 | d = c 125 | c = ROTL32(b, 30) & 0xFFFFFFFF 126 | b = a 127 | a = temp 128 | 129 | for x in xrange(60, 80): 130 | temp = ROTL32(a, 5) + (b ^ c ^ d) + e + wblock[x] + 0xCA62C1D6 131 | temp &= 0xFFFFFFFF 132 | e = d 133 | d = c 134 | c = ROTL32(b, 30) & 0xFFFFFFFF 135 | b = a 136 | a = temp 137 | 138 | self.hash_[0] += a 139 | self.hash_[1] += b 140 | self.hash_[2] += c 141 | self.hash_[3] += d 142 | self.hash_[4] += e 143 | for x in xrange(5): 144 | self.hash_[x] &= 0xFFFFFFFF 145 | 146 | def add_parse(): 147 | parser = OptionParser() 148 | parser.add_option( 149 | "--macl", 150 | dest="macl", 151 | type="int", 152 | help="Please enter the length of mac") 153 | parser.add_option( 154 | "--o", 155 | dest="origin", 156 | help="sha1(mac+origin), Please enter the origin") 157 | parser.add_option( 158 | "--sign", 159 | dest="signal", 160 | help="signal=sha1(mac+origin), Please enter the signal") 161 | parser.add_option( 162 | "--e", 163 | dest="extend", 164 | help="Please enter the extend value") 165 | return parser 166 | 167 | def main(): 168 | parser = add_parse() 169 | (options, args) = parser.parse_args() 170 | if not (options.macl and options.origin and options.signal and options.extend): 171 | parser.parse_args(['sha1-length-extend-attack.py', '-h']) 172 | exit(-1) 173 | o_data_length = options.macl + len(options.origin) 174 | p = 64 - 8 - 1 - o_data_length 175 | n = 2 176 | while p < 0: 177 | p = 64 * n - 8 - 1 - o_data_length 178 | n += 1 179 | o_data_length *= 8 180 | o_data_length = "{:0>16}".format(hex(o_data_length)[2:]) 181 | data_l = "" 182 | for x in xrange(0, 16, 2): 183 | data_l += "\\x" + o_data_length[x:x+2] 184 | cal = SHA1Attack(options) 185 | result = cal.calculate() 186 | print "+---------------------------+" 187 | print "| Result |" 188 | print "+---------------------------+" 189 | print "Origin signal: " + options.signal 190 | print "New signal: " + result 191 | print "New msg: " + "(" + str(options.macl) + " bytes unknow MAC) + " + options.origin + "\\x80" + "\\x00" * p + data_l + options.extend 192 | 193 | if __name__ == '__main__': 194 | main() -------------------------------------------------------------------------------- /rabit/rabit.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python 2 | 3 | from Crypto.Random import random, atfork 4 | from Crypto.Util.number import bytes_to_long, long_to_bytes 5 | from hashlib import sha1 6 | 7 | import SocketServer,threading,os,time 8 | import signal 9 | 10 | from util import * 11 | from key import * 12 | 13 | PORT = 7763 14 | FLAG = "REDACTED" 15 | msg = """Welcome to the LSB oracle! N = {}\n""".format(N) 16 | 17 | def pad(s): 18 | assert(len(s) < N.bit_length() / 8) 19 | padded = bytes_to_long(s.ljust(N.bit_length()/8, padchar)) 20 | while decrypt(padded, p, q) == None: 21 | padded += 1 22 | return padded 23 | 24 | padded = pad(FLAG) 25 | enc_flag = encrypt(padded, N) 26 | 27 | assert long_to_bytes(padded)[:len(FLAG)] == FLAG 28 | assert decrypt(enc_flag, p, q) == padded 29 | assert decrypt(2, p, q) != None 30 | 31 | def proof_of_work(req): 32 | import string 33 | req.sendall("Before we begin, a quick proof of work:\n") 34 | prefix = "".join([random.choice(string.digits + string.letters) for i in range(10)]) 35 | req.sendall("Give me a string starting with {}, of length {}, such that its sha1 sum ends in ffffff\n".format(prefix, len(prefix)+5)) 36 | response = req.recv(len(prefix) + 5) 37 | if sha1(response).digest()[-3:] != "\xff"*3 or not response.startswith(prefix): 38 | req.sendall("Doesn't work, sorry.\n") 39 | exit() 40 | 41 | class incoming(SocketServer.BaseRequestHandler): 42 | def handle(self): 43 | atfork() 44 | req = self.request 45 | signal.alarm(60) 46 | 47 | def recvline(): 48 | buf = "" 49 | while not buf.endswith("\n"): 50 | buf += req.recv(1) 51 | return buf 52 | 53 | proof_of_work(req) 54 | 55 | signal.alarm(120) 56 | 57 | req.sendall(msg) 58 | 59 | req.sendall("Encrypted Flag: {}\n".format(enc_flag)) 60 | while True: 61 | req.sendall("Give a ciphertext: ") 62 | x = long(recvline()) 63 | m = decrypt(x, p, q) 64 | if m == None: 65 | m = 0 66 | req.sendall("lsb is {}\n".format(m % 2)) 67 | 68 | req.close() 69 | 70 | class ReusableTCPServer(SocketServer.ForkingMixIn, SocketServer.TCPServer): 71 | pass 72 | 73 | SocketServer.TCPServer.allow_reuse_address = True 74 | server = ReusableTCPServer(("0.0.0.0", PORT), incoming) 75 | 76 | print "Listening on port %d" % PORT 77 | server.serve_forever() 78 | -------------------------------------------------------------------------------- /rabit/rabit_8b98cc38ab1d0597ee51a30425d34d2e.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/rabit/rabit_8b98cc38ab1d0597ee51a30425d34d2e.tgz -------------------------------------------------------------------------------- /rabit/util.py: -------------------------------------------------------------------------------- 1 | from Crypto.Util.number import getPrime, getRandomRange, GCD 2 | 3 | def getBlumPrime(nbits): 4 | p = getPrime(nbits) 5 | while p % 4 != 3: 6 | p = getPrime(nbits) 7 | return p 8 | 9 | def genKey(nbits): 10 | p = getBlumPrime(nbits/2) 11 | q = getBlumPrime(nbits/2) 12 | N = p * q 13 | 14 | return ((p,q), N) 15 | 16 | def randQR(N): 17 | return pow(getRandomRange(1, N), 2, N) 18 | 19 | def encrypt(m, N): 20 | return pow(m, 2, N) 21 | 22 | def legendreSymbol(a, p): 23 | return pow(a, (p-1)/2, p) 24 | 25 | def decrypt(c, p, q): 26 | if GCD(c, p*q) != 1: 27 | return None 28 | if legendreSymbol(c, p) != 1: 29 | return None 30 | if legendreSymbol(c, q) != 1: 31 | return None 32 | return pow(c, ((p-1)*(q-1) + 4) / 8, p*q) 33 | -------------------------------------------------------------------------------- /re-Special-RSA/flag.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/re-Special-RSA/flag.enc -------------------------------------------------------------------------------- /re-Special-RSA/msg.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hcamael/ctf-library/d3b204ca8d3296275ffc706b95b0548870011ac3/re-Special-RSA/msg.enc -------------------------------------------------------------------------------- /re-Special-RSA/msg.txt: -------------------------------------------------------------------------------- 1 | Although two nodes are physically connected by a transmission medium such as cable or air, we need to remember that the data-link layer controls how the medium is used. However, in a internetwork such as the Internet we cannot make a datagram reach its destination using only IP addresses. As we will see in Chapter 13, the broadcast linklayer addresses in the most common LAN, Ethernet, are 48 bits, all 1s, that are presented as 12 hexadecimal digits separated by colons. 2 | -------------------------------------------------------------------------------- /re-Special-RSA/special_rsa.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | from key import k, random_r 3 | import msgpack 4 | 5 | N = 23927411014020695772934916764953661641310148480977056645255098192491740356525240675906285700516357578929940114553700976167969964364149615226568689224228028461686617293534115788779955597877965044570493457567420874741357186596425753667455266870402154552439899664446413632716747644854897551940777512522044907132864905644212655387223302410896871080751768224091760934209917984213585513510597619708797688705876805464880105797829380326559399723048092175492203894468752718008631464599810632513162129223356467602508095356584405555329096159917957389834381018137378015593755767450675441331998683799788355179363368220408879117131L 6 | 7 | def egcd(a, b): 8 | if a == 0: 9 | return (b, 0, 1) 10 | else: 11 | g, y, x = egcd(b % a, a) 12 | return (g, x - (b // a) * y, y) 13 | 14 | def modinv(a, m): 15 | g, x, y = egcd(a, m) 16 | assert g == 1 17 | return x % m 18 | 19 | def pad_even(x): 20 | return ('', '0')[len(x)%2] + x 21 | 22 | def encrypt(ms, k): 23 | out = [] 24 | for i in range(0, len(ms), 256): 25 | m = ms[i:i+256] 26 | m = int(m.encode('hex'), 16) 27 | r = random_r() 28 | r_s = pad_even(format(r, 'x')).decode('hex') 29 | assert m < N 30 | c = (pow(k, r, N) * m) % N 31 | c_s = pad_even(format(c, 'x')).decode('hex') 32 | out.append((r_s, c_s)) 33 | return msgpack.packb(out) 34 | 35 | def decrypt(c, k): 36 | out = '' 37 | for r_s, c_s in msgpack.unpackb(c): 38 | r = int(r_s.encode('hex'), 16) 39 | c = int(c_s.encode('hex'), 16) 40 | k_inv = modinv(k, N) 41 | out += pad_even(format(pow(k_inv, r, N) * c % N, 'x')).decode('hex') 42 | return out 43 | 44 | if __name__ == '__main__': 45 | if len(sys.argv) < 4 or sys.argv[1] not in ('enc', 'dec'): 46 | print 'usage: %s enc|dec input.file output.file' % sys.argv[0] 47 | sys.exit() 48 | 49 | with open(sys.argv[3], 'w') as f: 50 | if sys.argv[1] == 'enc': 51 | f.write(encrypt(open(sys.argv[2]).read(), k)) 52 | elif sys.argv[1] == 'dec': 53 | f.write(decrypt(open(sys.argv[2]).read(), k)) -------------------------------------------------------------------------------- /tonnerre/public_server_ea2e768e20e89fb1aafbbc547cdb4636.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python 2 | 3 | from Crypto.Random import random, atfork 4 | from Crypto.Hash import SHA256 5 | 6 | from database import import_permitted_users 7 | 8 | import SocketServer,threading,os,time 9 | 10 | msg = """Welcome to the Tonnerre Authentication System!\n""" 11 | flag = "REDACTED" 12 | 13 | N = 168875487862812718103814022843977235420637243601057780595044400667893046269140421123766817420546087076238158376401194506102667350322281734359552897112157094231977097740554793824701009850244904160300597684567190792283984299743604213533036681794114720417437224509607536413793425411636411563321303444740798477587L 14 | g = 9797766621314684873895700802803279209044463565243731922466831101232640732633100491228823617617764419367505179450247842283955649007454149170085442756585554871624752266571753841250508572690789992495054848L 15 | 16 | permitted_users = {} 17 | 18 | # This should import the fields from the data into the dictionary. 19 | # the dictionary is indexed by username, and the data it contains are tuples 20 | # of (salt, verifier) as numbers. note that the database stores these in hex. 21 | import_permitted_users(permitted_users) 22 | 23 | def H(P): 24 | h = SHA256.new() 25 | h.update(P) 26 | return h.hexdigest() 27 | 28 | def tostr(A): 29 | return hex(A)[2:].strip('L') 30 | 31 | class incoming(SocketServer.BaseRequestHandler): 32 | def handle(self): 33 | atfork() 34 | req = self.request 35 | req.sendall(msg) 36 | username = req.recv(512)[:-1] 37 | if username not in permitted_users: 38 | req.sendall('Sorry, not permitted.\n') 39 | req.close() 40 | return 41 | public_client = int(req.recv(512).strip('\n'), 16) % N 42 | c = (public_client * permitted_users[username][1]) % N 43 | if c in [N-g, N-1, 0, 1, g]: 44 | req.sendall('Sorry, not permitted.\n') 45 | req.close() 46 | return 47 | random_server = random.randint(2, N-3) 48 | public_server = pow(g, random_server, N) 49 | residue = (public_server + permitted_users[username][1]) % N 50 | req.sendall(tostr(permitted_users[username][0]) + '\n') 51 | req.sendall(tostr(residue) + '\n') 52 | 53 | session_secret = (public_client * permitted_users[username][1]) % N 54 | session_secret = pow(session_secret, random_server, N) 55 | session_key = H(tostr(session_secret)) 56 | 57 | proof = req.recv(512).strip('\n') 58 | 59 | if (proof != H(tostr(residue) + session_key)): 60 | req.sendall('Sorry, not permitted.\n') 61 | req.close() 62 | return 63 | 64 | our_verifier = H(tostr(public_client) + session_key) 65 | req.sendall(our_verifier + '\n') 66 | 67 | req.sendall('Congratulations! The flag is ' + flag + '\n') 68 | req.close() 69 | 70 | class ReusableTCPServer(SocketServer.ForkingMixIn, SocketServer.TCPServer): 71 | pass 72 | 73 | SocketServer.TCPServer.allow_reuse_address = True 74 | server = ReusableTCPServer(("0.0.0.0", 8561), incoming) 75 | server.timeout = 60 76 | server.serve_forever() 77 | --------------------------------------------------------------------------------