# [EN] How Is Your Math
###### tags: `Writeup` `Crypto` `English`
> [name=curious]
## Prior Knowledge
### Xor
- Boolean's xor
| $\oplus$ | True | False |
| --------- | ----- | ----- |
| **True** | False | True |
| **False** | True | False |
- Integer's xor
```
53 ^ 79 = 122
53 = (bin) 110101
^ 79 = (bin) 1001111
----------------------
122 = (bin) 1111010
```
- Character's xor
```
'e' ^ 'L' = (ASCII) 101 ^ 76 = 41 = ')'
```
- String's xor
```
'lHQL)#$' ^ 'Curious' = '/=#%FVW'
'l' 'H' 'Q' 'L' ')' '#' '$'
^ 'C' 'u' 'r' 'i' 'o' 'u' 's'
-------------------------------
'/' '=' '#' '%' 'F' 'V' 'W'
```
### AES CBC Mode
We don't need to know the details of the AES encryption process, we only need to know that by inputting a 16, 24, or 32-byte key and 16 bytes of plaintext into AES encryption, we can output a 16-byte ciphertext. Similarly, by inputting the same key and ciphertext, we can obtain the corresponding plaintext through AES decryption.
> To know the detailed AES encryption and decryption process, you can refer to the following resources::[Github](https://github.com/Curious-Lucifer/Crypto_Implementation)
Because basic AES can only handle 16 bytes of plaintext/ciphertext, different encryption modes are used with AES to handle encryption and decryption of non-16 byte data.
AES CBC Mode is an encryption mode that handles 16n bytes of data. When inputting a plaintext of length 16n bytes and an IV (Initialization Vector) of length 16 bytes, CBC mode first divides the plaintext into blocks of 16 bytes each, and then performs the following operation:
```
##################################################################
# AES CBC Mode (Encrypt) #
##################################################################
# #
# ----------- ----------- ----------- #
# | plain1 | | plain2 | | plain3 | #
# ----------- ----------- ----------- #
# ------ | | | #
# | IV | --> ⊕ *-------> ⊕ *-------> ⊕ #
# ------ | | | | | #
# ----------- | ----------- | ----------- #
# | | | | | | | | #
# | Encrypt | | | Encrypt | | | Encrypt | #
# | | | | | | | | #
# ----------- | ----------- | ----------- #
# | | | | | #
# ----------- | ----------- | ----------- #
# | cipher1 |---* | cipher2 |---* | cipher3 | #
# ----------- ----------- ----------- #
# #
##################################################################
```
To decrypt ciphertext of length 16*n bytes using AES CBC mode, input the ciphertext and a 16-byte IV, then divide the ciphertext into blocks and perform the following operation:
```
##################################################################
# AES CBC Mode (Decrypt) #
##################################################################
# #
# ----------- ----------- ----------- #
# | cipher1 |---* | cipher2 |---* | cipher3 | #
# ----------- | ----------- | ----------- #
# | | | | | #
# ----------- | ----------- | ----------- #
# | | | | | | | | #
# | Decrypt | | | Decrypt | | | Decrypt | #
# | | | | | | | | #
# ----------- | ----------- | ----------- #
# ------ | | | | | #
# | IV | --> ⊕ *-------> ⊕ *-------> ⊕ #
# ------ | | | #
# ----------- ----------- ----------- #
# | plain1 | | plain2 | | plain3 | #
# ----------- ----------- ----------- #
# #
##################################################################
```
---
## Train Of Thought
From server.py, it can be seen that both cipher and plain are 48 bytes long. Therefore, cipher can be divided into cipher1, cipher2, and cipher3, while plain can be divided into plain1, plain2, and plain3.
Assuming that cipher3 is decrypted by AES to obtain plain3', then plain3 = plain3' $\oplus$ cipher2. If you want to change plain3 to a specific value, you can either change plain3' or change cipher2.
To change plain3', you have to modify cipher3, but the changes brought about by changing cipher3 to plain3' are unpredictable. Therefore, the only way to change plain3 to a specific value is to change cipher2.
---
## Solution
Let $C_2$ = `cipher2`, $P_3'$ = `plain3'`, $P_3$ = `plain3`, $P_{3, new}$ = `new plain3`
If we know that $P_3 = C_2 \oplus P_3'$, and we change $C_2$ to $C_2 \oplus P_3 \oplus P_{3, new}$,
then
$$
\begin{align}
(C_2 \oplus P_3 \oplus P_{3, new}) \oplus P_3' &= (C_2 \oplus P_3') \oplus P_3 \oplus P_{3, new} \\
&= P_3 \oplus P_3 \oplus p_{3, new} \\
&= 0 \oplus P_{3, new} \\
&= P_{3, new}
\end{align}
$$
Solve Script :
```python
from pwn import *
r = remote('lotuxctf.com', 30000)
r.recvlines(22)
cipher = bytes.fromhex(r.recvline().strip().split(b': ')[1].decode())
ori_plain_block = bytes.fromhex(r.recvline().strip().split(b': ')[1].decode())
new_plain_block = bytes.fromhex(r.recvline().strip().split(b': ')[1].decode())
cipher = cipher[:16] + xor(cipher[16: 32], ori_plain_block, new_plain_block) + cipher[32:]
r.sendlineafter(b'> ', cipher.hex().encode())
r.interactive()
```
{%hackmd M1bgOPoiQbmM0JRHWaYA1g %}