Misc
md7
const fs = require ("fs" );const readline = require ("readline" );const md5 = require ("md5" );const rl = readline.createInterface ({ input : process.stdin , output : process.stdout }); function askQuestion (query ) { return new Promise (resolve => rl.question (query, resolve)); } function normalize (numStr ) { if (!/^\d+$/ .test (numStr)) { return null ; } return numStr.replace (/^0+/ , "" ) || "0" ; } console .log ("Welcome to our hashing factory " );console .log ("let's see how much trouble you can cause" );function generateHash (input ) { input = input .split ("" ) .reverse () .map (d => ((parseInt (d, 10 ) + 1 ) % 10 ).toString ()) .join ("" ); const prime1 = 31 ; const prime2 = 37 ; let hash = 0 ; let altHash = 0 ; for (let i = 0 ; i < input.length ; i++) { hash = hash * prime1 + input.charCodeAt (i); altHash = altHash * prime2 + input.charCodeAt (input.length - 1 - i); } const factor = Math .abs (hash - altHash) % 1000 + 1 ; const normalized = +input; const modulator = (hash % factor) + (altHash % factor); const balancer = Math .floor (modulator / factor) * factor; return normalized + balancer % 1 ; } (async () => { try { const used = new Set (); for (let i = 0 ; i < 100 ; i++) { const input1 = await askQuestion (`(${i + 1 } /100) Enter first number: ` ); const input2 = await askQuestion (`(${i + 1 } /100) Enter second number: ` ); const numStr1 = normalize (input1.trim ()); const numStr2 = normalize (input2.trim ()); if (numStr1 === null || numStr2 === null ) { console .log ("Only digits are allowed." ); process.exit (1 ); } if (numStr1 === numStr2) { console .log ("Nope" ); process.exit (1 ); } if (used.has (numStr1) || used.has (numStr2)) { console .log ("😈" ); process.exit (1 ); } used.add (numStr1); used.add (numStr2); const hash1 = generateHash (numStr1); const hash2 = generateHash (numStr2); if (md5 (hash1.toString ()) !== md5 (hash2.toString ())) { console .log (`⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⠟⠷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣾⠿⢫⡤⠀⣄⢈⠛⠷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⡶⠛⠋⢡⣾⡿⣿⡴⠁⠀⠀⣿⣾⣿⡁⠈⠛⠶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣦⣤⡀⠀⠀⠀⠀⢀⣤⡾⠟⠋⠐⠂⠸⠿⣿⣿⠿⠀⠩⠛⠀⠛⠻⣦⡅⠀⠀⠀⠀⠙⢧⡄⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠌⠙⠷⣦⣴⡾⠟⡡⠴⠂⠀⠀⠀⠀⠀⠀⠙⠦⠴⣤⣄⡀⠛⠶⣽⣮⡀⠀⠀⠀⠀⠀⠻⡄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣧⣰⢠⢞⡛⠉⠙⠋⠁⠀⠀⠀⠀⠀⠀⣀⡀⢄⡂⢰⡘⢿⢻⣤⢃⠄⡉⢻⡗⠀⠀⠀⠀⠀⢿⡀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⡇⣸⡇⠀⠀⠀⠀⠀⠀⠀⢀⡀⢾⣋⡝⣬⣟⣴⣫⣟⢾⣶⣿⣾⣤⣭⣿⠀⠀⠀⠀⠀⠘⣷⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣧⣿⡇⠀⠀⠀⠀⠀⠀⢠⣼⠏⣾⣿⣽⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⡀⡀⣽⣇⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣼⡧⠀⠀⠈⢀⣱⣘⣿⣿⣋⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣹⣿⣿⣿⣿⣤⠃⡜⢻⣟⣿⡇⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣯⣽⡗⣌⣺⠡⣘⣾⣿⣿⣿⣯⣞⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣹⣿⣿⣿⢧⣙⣔⣻⣿⣿⣿⡀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢈⣿⣿⣿⡹⢛⠶⣾⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡧⢌⠹⢹⣾⣿⢿⡇⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠿⣷⣌⢺⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠐⢪⡐⣣⣿⣿⣿⠇⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣿⡿⠀⠉⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢉⣦⣍⣝⣿⣿⠏⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⣿⠁⢰⠀⠁⢘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣩⠒⢢⢰⡘⣿⣿⡏⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣦⠟⠀⠀⠈⢩⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠱⠀⠈⠄⢂⣿⣿⣿⠁⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⡄⠀⠀⠀⠀⠀⠻⢿⣿⣿⣿⣿⡿⢟⣿⣿⣿⣿⢛⣿⣿⣿⡿⠉⠀⠀⠀⠀⢠⣸⣿⡏⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⡾⠟⠛⠛⠳⣶⣿⣟⢆⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⠱⣋⠔⡢⠑⣎⠣⣜⣶⠿⠃⠀⠀⠀⠀⠀⠠⠇⣿⠁⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣠⣤⠤⣤⣤⣼⠏⠀⠀⠀⠀⠀⠀⠙⠿⣿⣷⣄⠀⠀⠀⠀⠀⠈⠹⣿⡆⡑⠈⠄⠑⠨⢹⣥⣲⡶⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⢀⣠⡴⢾⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠈⢿⣾⣅⠀⢈⠡⢩⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⢀⣀⣴⣾⡟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣥⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⢣⠀⠀⠀⢀⠀⠀⠀⢢⣾⣿⣿⣶⡼⢣⣽⣿⣻⡿⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⣄⠀⠀⠀⠀⠀ ⣤⡾⠋⠉⠀⠀⠹⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣷⢦⣄⣀⣠⣤⣴⣶⣿⣿⠟⠉⠀⠀⠀⠀⢳⡀⠀⢸⠟⢿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⣄⠀⠀⠀ ⣿⠁⠀⠀⠀⠀⠈⠻⠦⠄⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣮⣭⣥⣶⣾⣿⠟⠁⠀⠀⠀⠀⠀⠀⠈⢷⣦⡀⢛⡾⣿⣿⣿⣿⢿⣭⡖⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢳⣄⠀ ⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣟⡛⡟⢿⢻⣟⣿⣿⠔⠂⠀⠀⠀⠀⠀⠀⠀⠀⠸⣷⣾⡐⣿⣿⣿⣼⡿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣆ ⣟⠀⠀⠀⠀⣠⡄⠀⠀⠀⠀⢻⡄⠀⠀⠀⠀⠀⢸⡯⢜⠩⢖⡩⡟⠙⢿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⢿⣷⣿⣿⡿⠟⠟⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡍ ⡇⠀⠀⠀⠀⣿⠇⠀⠀⠀⠀⢸⣇⠀⠀⠀⠀⠀⢸⣿⢎⡑⢮⣇⣇⠀⠀⢿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠩⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡜ ⡇⠀⠀⠀⠀⢿⡇⠀⠀⠀⠀⢼⣯⠀⠀⠀⠀⠀⠘⣿⢦⣱⣾⣿⠋⠀⠀⠀⠹⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⡼ ⡿⠀⣀⠀⠀⢺⣇⠀⠀⠀⠀⣸⣿⡀⠀⠀⠀⣀⣼⠟⠛⠉⠉⠀⠀⠀⠀⠀⢀⣼⣿⣶⡀⠀⠤⢀⡤⣤⣙⡴⣀⢤⣄⠲⠤⢄⡀⣀⡀⢀⣀⣀⡀⠄⡀⡀⢀⡀⢀⠀⡄⢤⡈⣵⡐ ⣷⣀⠈⡄⢈⠽⣿⡀⠆⢀⡤⢸⣿⣷⣠⣠⣼⠟⠁⠀⢀⣤⡤⣤⣤⣤⢶⣩⣾⣿⣿⠼⣇⠀⡆⢦⡔⢦⢭⡹⣬⢏⠶⣭⣛⢮⡝⣧⣾⡱⢮⣱⣙⢦⡵⣩⡶⣜⣬⡳⣎⣧⣝⡶⣽ ⠟⠷⠿⠛⠾⠿⡿⢷⣯⣬⣵⣷⣾⣿⣯⣿⣷⣠⣤⣼⣩⣴⣦⣭⣴⣽⣿⣿⣟⣩⢃⡾⢀⢣⠼⣦⢽⣚⡶⣽⣎⣿⣻⢶⣯⣟⣾⣳⢯⣟⣯⣷⣻⢮⣽⣷⣻⡽⣾⡽⣽⢾⡽⣞⣷` ); process.exit (1 ); } console .log ("Correct!" ); } console .log ("\ngg , get your flag\n" ); const flag = fs.readFileSync ("flag.txt" , "utf8" ); console .log (flag); } finally { rl.close (); } })();
generateHash()
函数对输入的处理是反转,每位数字加一模十,然后拼接回去
return normalized + balancer % 1;
balancer
是整数,所以不用管它,这里就只剩normalized
const normalized = +input;
这里是前导零 的一个利用
比如(1,19)
1 -> '2' -> +'2' -> 2 19 -> '91' -> '02' -> +'02' > 2
这样它们的字符串md5
就一样了,我们只要找到100
组各不一样的数字即可
from pwn import *from tqdm import trangedef transform (s: str ) -> str : s = s[::-1 ] res = "" for char in s: digit = int (char) new_digit = (digit + 1 ) % 10 res += str (new_digit) return res def reverse_transform (t: str ) -> str : res = "" for char in t: digit = int (char) original_digit = (digit - 1 + 10 ) % 10 res += str (original_digit) return res[::-1 ] def generate_pairs (): pairs = [] used_numbers = set () i = 1 while len (pairs) < 100 : s1 = str (i) t1 = transform(s1) t2 = "0" + t1 s2 = reverse_transform(t2) if s1 != s2 and s1 not in used_numbers and s2 not in used_numbers: if int (transform(s1)) == int (transform(s2)): pairs.append((s1, s2)) used_numbers.add(s1) used_numbers.add(s2) i += 1 return pairs solution_pairs = generate_pairs() conn = remote('numbers.p2.securinets.tn' , 7011 ) for i in trange(100 ): num1, num2 = solution_pairs[i] conn.sendlineafter(b"Enter first number: " , num1.encode()) conn.sendlineafter(b"Enter second number: " , num2.encode()) conn.recvline() print (conn.recvall().decode().strip())
Easy Jail
import randomimport stringseed = random.randint(0 , 2 **20 ) shift_rng = random.Random(seed) class ProtectedFlag : def __init__ (self, value ): self._value = value def __str__ (self ): return "variable protected, sryy" def __repr__ (self ): return "variable protected, sryy" def __getitem__ (self, index ): try : return self._value[index] except Exception: return "variable protected, sryy" flag = ProtectedFlag("flag{dummy_flag}" ) def shift_mapping (mapping ): def make_initial_mapping (): letters = list (string.ascii_lowercase) shuffled = letters[:] random.shuffle(shuffled) return dict (zip (letters, shuffled)) def main (): valid_chars = set (string.ascii_lowercase + "[]()~><*+" ) mapping = make_initial_mapping() print ("Welcome to the shifting jail! Enter text using only a-z, []()~><*+" ) try : while True : user_in = input ("> " ).strip() if len (user_in) > 150 : raise ValueError(f"Input exceeds 150 characters" ) if not all (c in valid_chars for c in user_in): print ("Invalid input. Only [a-z] and []()~><*+ are allowed." ) continue encoded = "" .join(mapping[c] if c in mapping else c for c in user_in) mapping = shift_mapping(mapping) try : result = eval (encoded, {"__builtins__" : None }, {"flag" : flag}) print (result) except Exception: print (encoded) except KeyboardInterrupt: print ("\nGoodbye!" ) if __name__ == "__main__" : main()
限制我们的输入为a-z []()~><*+"
,下划线、点都无法使用,但是它明确告诉了我们可以通过下标 读取flag
源码对小写字母做了映射 ,同时还有一个黑盒函数shift_mapping
,每输入一次都会被映射
先找找字母表有没有映射规律
yvgkwuqnfiodhltjapcbmezsrx zwhlxvrogjpeimukbqdcnfatsy yvgkwuqnfiodhltjapcbmezsrx zwhlxvrogjpeimukbqdcnfatsy aximywsphkqfjnvlcredogbutz byjnzxtqilrgkowmdsfephcvua aximywsphkqfjnvlcredogbutz byjnzxtqilrgkowmdsfephcvua czkoayurjmshlpxnetgfqidwvb byjnzxtqilrgkowmdsfephcvua aximywsphkqfjnvlcredogbutz byjnzxtqilrgkowmdsfephcvua aximywsphkqfjnvlcredogbutz zwhlxvrogjpeimukbqdcnfatsy aximywsphkqfjnvlcredogbutz byjnzxtqilrgkowmdsfephcvua czkoayurjmshlpxnetgfqidwvb dalpbzvskntimqyofuhgrjexwc ebmqcawtloujnrzpgvihskfyxd fcnrdbxumpvkosaqhwjitlgzye gdosecyvnqwlptbrixkjumhazf heptfdzworxmqucsjylkvnibag gdosecyvnqwlptbrixkjumhazf fcnrdbxumpvkosaqhwjitlgzye gdosecyvnqwlptbrixkjumhazf heptfdzworxmqucsjylkvnibag
发现每次都是上一次+1/-1
的偏移,那这样就好办了,会有26个 可能的字母表,'flag'
会被映射成26种 可能
同时在Python
中,可以利用空元组 构造数字,这里等号用不了,但可以取反 ,通过~(()>())
,可以构造出-1
通过加号连接可以构造出任意负数,再乘-1
可以构造任意正数
因为这里有150
的长度限制,所以需要正向遍历 +反向遍历 ,然后手动剃掉中间重复的字符即可
from pwn import *import stringdef caesar_shift_string (text, shift ): shifted_text = "" for char in text: shifted_ord = (ord (char) - ord ('a' ) + shift) % 26 + ord ('a' ) shifted_text += chr (shifted_ord) return shifted_text def generate_all_shifts (base_alphabet ): all_shifted_alphabets = [] for i in range (26 ): shifted_version = caesar_shift_string(base_alphabet, i) all_shifted_alphabets.append(shifted_version) return all_shifted_alphabets conn = remote("misc-b6c94dd8.p1.securinets.tn" , 7000 ) conn.sendlineafter(b"> " , f"{string.ascii_lowercase} " .encode()) conn.recvline() table = conn.recvline().strip().decode() tables = generate_all_shifts(table) for table in tables: t = dict (zip (table, string.ascii_lowercase)) map = ["" .join(t[i] for i in 'flag' )] def get_flag1 (): flag = '' for i in range (10 , 30 ): index = "[~(()>())*(~(()>())" + "+~(()>())" * i + ")]" count = 1 while count: for m in map : if len (m) + len (index) > 150 : return flag conn.sendline(f"{m} {index} " .encode()) conn.recvline() res = conn.recvline().strip().decode() if len (res) == 1 : flag += res count = 0 def get_flag2 (): flag = '' for i in range (30 ): index = "[~(()>())" + "+~(()>())" * i + "]" count = 1 while count: for m in map : if len (m) + len (index) > 150 : return flag conn.sendline(f"{m} {index} " .encode()) conn.recvline() res = conn.recvline().strip().decode() if len (res) == 1 : flag += res count = 0 flag1 = get_flag1() flag2 = get_flag2()[::-1 ] print ('Securinets{' + flag1 + flag2)