├── .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 |
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 |
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 |
--------------------------------------------------------------------------------