# Shaktictf 2022 Crypto Writeups
### Challenge Title: Eazy_peaZy
### Challenge Description :
Who knew encryption could be so simple?
### Difficulty Level
Beginner
### Points
50
### Flag format
shaktictf{...}
### Author
Rees
### Writeup
This is the combination of base64 and shifting
```python!
from base64 import b64decode
x = 'ZFlSXGVaVGVXbFRjamFlIVAiZFBkZmEkY1BWUmtqampqampQWFQlJCNlYyYnWCVlYyYlbg=='
x = b64decode(x)
flag = ''
for i in x:
flag = flag + chr(i +15)
```
#### flag
`shaktictf{crypt0_1s_sup3r_eazyyyyyy_gc432tr56g4tr54}`
## Challenge Title: secRetS And seCReTs
### Challenge Description :
I think Sun Tzu forgot that greater the number of primes used, stronger would be the encryption.
### Author
Rees
### Difficulty Level
Easy
### Points
100
### Flag format
shaktictf{...}
### Writeup
The challenge uses crt and rsa to encrypt the flag. From the final assert statement provided in the source code it can be seen that the secret (which is given) when divided by an unknown value x, would give us the modulus that we require to perfrom RSA decryption.
From the first assert statement we can infer that x can be retrieved by performing the chinese remainder theorem on the array n and c given using the crt function in the sympy module.
from sympy.ntheory.modular import crt
x=crt(n,c)[0]
```
#x=175393906935410597646312735251121734825355066308014883020996453700680562811773639892091486800372429659125492317788178170078374593410001133290406346042424977949257610021473876645919378922293673885436422442069899845701280009009220968827934275876545186933778202134359447023530167415550308017091921680916413562203
```
Once x is retrieved, N can be found as secret//x
N=secret//x
```
#N=24527876714777610556168704102334063247745307067942987179946992203143782911214218738693269763284353107444558551004104842495208613554362680493609315262323088218069305109094883023250460622553819850578030167910933028392613333549556209547555445147475324578694902644739395420556980677634640744378713609298141891560253460328397733071122264628468706243972435551492706426936176969047044900758569383152320313902601091822535952698142154712130550473808314533625099780507036524949344974327532792045713711551245809959038345909568860198589805752319051021759477458800632328558389734253607892450861044270982742648526813361769154927281
```
From the hint we can understand the number of primes used to set our private key was less. So, on using sympy's factorint function we can see that n factorises into a squared prime.
```python
from sympy import factorint
factorint(N)
```
```
#{156613782007770984536049055700840395037085682399926189984796410929143868636172989598027406051641994725886674336805075334390044528511942285958708618671006005927130990180083143883853840126990685118290412751594654157367930730824790742241421921147161987915110899307344903473712967071752529319870067482601269289159: 2}
#p=156613782007770984536049055700840395037085682399926189984796410929143868636172989598027406051641994725886674336805075334390044528511942285958708618671006005927130990180083143883853840126990685118290412751594654157367930730824790742241421921147161987915110899307344903473712967071752529319870067482601269289159
```
We can now calculate Euler's totient as p*(p-1) as N=p^2
```python
phi=p*(p-1)
```
```
#phi=24527876714777610556168704102334063247745307067942987179946992203143782911214218738693269763284353107444558551004104842495208613554362680493609315262323088218069305109094883023250460622553819850578030167910933028392613333549556209547555445147475324578694902644739395420556980677634640744378713609298141891560096846546389962086586215572767865848935349869092780236951380558117901032122396393554292907850959097096649278361337079377740505945296372247666391161836030519022213984147449648161859871424255124840747933157974206041221875021494260279518055537653470340643278834946262988977148077199230213328656745879167885638122
```
Using the inverse function we can calculate the private key d as inverse of e and euler's totient.
```python=
from Crypto.Util.number import inverse
d=inverse(e,phi)
```
```
#d=12976716501083114741505370666039473503350367456044481659067428485582257120108192415379278003301316436431713057341125275856941395818704200997221657812999197976488350337178187574426098557544724288250790240810164958625769902713944221640331262486815263578087009771595420257518229260351036796463724872594022823840933182176525919029375831248830129737097141858965988207513545296422203983807312665421181897156053905025132679686629545955176412753730886597545459522931179123030612104190678878354458814439067976007495812844445727544246548859732219763976525316341284726507536308407339008755430600740481089868997899657725988353611
```
pt_int can then be calculated by using `(ct^d)%N`
```python!
pt_int=pow(ct,d,N)
#pt_int= mpz(1058749935816526928514932347698586539511633166445946912656393573071070805207400525111857343067141631643689341)
```
The flag can then be obtained on converting the pt_int value to bytes and decoding.
```python
from Crypto.Util.number import long_to_bytes
flag=long_to_bytes(pt_int).decode()
```
#### flag
`shaktictf{w0w_you_kn0w_h0w_RSA_&_CRT_w0rks_!}`
## cAex0r
### Challenge Description :
I tried to develop a new generator but I am not sure how it is working.
### Difficulty Level
Easy
### Author
[b4b7gr00t](https://twitter.com/Paavani21)
### Points
100
### Flag format
shaktictf{...}
### Writeup
This challenge is the combination of Ceaser cipher and xor. The number of letters to be shifted is given as a random number, and the key is also a random string with lenght `3` for xor.
The idea is to use a `Known Plaintext attack`.
You have cass function, which does Ceaser cipher encryption and ciphertext.
Use the flag format `shaktictf{`.
Brute for the `stride` value within the range of 1 to 27.
xor `cass(b'sha',brute value)` and `ct[:3]` to get the key. xor that key with ciphertext. check whether `shaktictf{` is in `cass(pt,brute value)`.
```python=
from itertools import product
from pwn import xor
ct = open("ciphertext.txt","rb").read()
def cass (text,stride):
u_alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
l_alpha="abcdefghijklmnopqrstuvwxyz"
enc_text = ""
for i in text:
if i>=65 and i<= 90:
enc_text += u_alpha[(u_alpha.find(chr(i)) + stride)%26]
elif i>=97 and i<= 122:
enc_text += l_alpha[(l_alpha.find(chr(i)) + stride)%26]
else:
enc_text += chr(i)
return enc_text.encode()
for i in range(1,27):
key = xor(cass(b'sha', i),ct[:3])
pt = xor(ct,key)
if b'shaktictf{' in cass(pt,-i):
print(cass(pt,-i).decode())
```
#### Flag
`shaktictf{welCom3_t0_cRyptOo_WoRLD_77846b12bfd9b91ebce67b236aa4}`
## Challenge Title: d0uble_cbc
### Challenge Description :
My uncle has been working as a schoolteacher. One fine day, he decides to give chocolates to all his students. He brought a different types of chocolates. But two students are asking for the same kind of chocolate. All chocolates of that kind are completed except one. So, he decided to change the chocolate wrapper and give the same chocolate that he has.Can you help him to find that same chocolate wrapper?
### Difficulty Level
Medium
### Author
[b4b7gr00t](https://twitter.com/Paavani21)
### Points
200
### Flag format
shaktictf{...}
### Writeup
1. This chall is combination of two iv detection in cbc mode and cbc mac vulnerability with non zero IV.
2. Find iv using the oracle provided and use that iv as input for cbc mac oracle.
3. iv detection can done by encrypting the `pt='\x00'*32` , decrypt `ct = b"\x00"*16+bytes.fromhex(ct)[:16]` , decrypt the result again to get iv.
```python=
from pwn import *
from os import urandom
host,port = '65.2.136.80',31351
io = remote(host,port)
io.recvuntil(b'4.exit')
io.sendline('1')
io.recvuntil(b'format\n')
pt = '\x00'*32
io.sendline(pt.encode().hex())
io.recvline()
ct = io.recvline()
ct = ct[25:-1].decode()
# host,port = '0.0.0.0',4304
io = remote(host,port)
io.recvuntil(b'4.exit')
io.sendline('2')
io.recvuntil(b'decrypt')
io.sendline(ct)
io.recvline()
pt = io.recvline()[28:-1]
ct = b"\x00"*16+bytes.fromhex(ct)[:16]
io = remote(host,port)
io.recvuntil(b'4.exit')
io.sendline('2')
io.recvuntil(b'decrypt')
io.sendline(ct.hex())
io.recvline()
iv_dec = (bytes.fromhex(io.recvline()[28:-1].decode())[16:]).hex()
```
5. Now pass that iv to the sign function. It will return the tag as ct[16:].
```python=
io.recvuntil(b'4.exit')
io.sendline('3')
io.recvuntil(b'further')
io.sendline(iv_dec)
io.recvuntil(b'messages\n')
io.sendline('0')
io.recvline()
msg1 = urandom(16).hex()
io.recvline()
io.sendline(msg1)
io.recvline()
io.recvline()
tag1 = (io.recvline().decode())[:-1]
```
6. sign funtion is returning the last 16 bytes from `ct`.
7. sign(sign(block0) xor block1) gives the same sign value. (So, simply append the ciphertext of the previous block)
#### Flag
`shaktictf{double_cheese_double_mac_yummyyyy_4120686170707920636263206d6f6465}`
### r33d3m_rand0m
### Challenge Description :
You know, everything is fair in CTFs and competition.
### Author
[b4b7gr00t](https://twitter.com/Paavani21)
### Difficulty Level
Hard
### Points
300
### Flag format
shaktictf{...}
#### Writeup
This is a simple `Random faults attack` which works with RSA decryption and signature verification with CRT. A signature can be built using CRTof Sp, Sq, Sr. Sp, Sq, and Sr are signatures of hash function with p,q, and r, respectively.
```py=
p,q,r = getPrime(256),getPrime(256),getPrime(256)
n = p*q*r
e = 65537
phi = (p-1)*(q-1)*(r-1)
d = inverse(e,phi)
ct = pow(bytes_to_long(flag),e,n)
h =int(sha256(flag).hexdigest(),16)
dp = d%(p-1)
dq = d%(q-1)
dr = d%(r-1)
sp = pow(h,dp,p)
sq = pow(h,dq,q)
sr = pow(h,dr,r)
s = (((sp*q*r*(inverse(q*r,p)))%n) + (sq*p*r*(inverse(p*r,q)) %(n)) + ((sr*p*q*(inverse((p*q),r)))%n))%n
```
`s` is the signature.
Now, it is easy to find p,q,r,when the attacker has the full knowledge of `h`.
If the signature is valid, i.e., `s^e mod N = h`, the attacker has a chance to manipulate `Sp, Sq and Sr` values. If you compute the signature using changed `Sp, Sq, and Sr` values, the verification fails. Now give faults Sp value, i.e., add some value to `Sp ( Sp+3 )` for first signature verification and don’t change `Sq and Sr`. Calculate `gcd(S^e - h,n)`, which is equal to the `product of q and r`. In the same way, input `Sp, modified_Sq, Sr`, and get the `product of p and r`. Next, find the `product of p and q`.
```python=
sp1 = sp+2 #create faults value one each time
sq1 = sq+2 #create faults value
sr1 = sr+2
io = remote(host,port)
io.recvuntil(b'provided\n')
n = int(io.recvline()[4:-1])
e = int(io.recvline()[4:-1])
h = int(io.recvline()[4:-1])
io.recvuntil(b'values\n')
io.sendline('2')
io.recvuntil(b'sp value: ')
io.sendline(str(sp1))
io.recvuntil(b'sq value: ')
io.sendline(str(sq))
io.recvuntil(b'sr value: ')
io.sendline(str(sr))
qr = GCD((s**e)-h , n )
```
```python=
pr = GCD((s**e)-h , n)
pq = GCD((s**e)-h , n)
p = GCD(pq,pr)
q = GCD(pq,qr)
r = GCD(pr,qr)
```
find `pq` and `pr` in the same way.
Now find the `gcd(pq,pr),gcd(pq,qr) and gcd(pr,qr)` to get `p`,`q` and `r` values respectively.
```python=
phi = (p-1)*(q-1)*(r-1)
d = inverse(e,phi)
pt = long_to_bytes(pow(ct,d,n))
print(pt)
```
#### flag
`shaktictf{rand0m_cr4z7_p3rs0n_aLw4ys_tries_cr7pt0_a7de4873ca0f9f697f1d2c09004f33dc1ad98b64}`