- Check
풀이 과제 하면서 라업 몇 개 더 참고했었는데 그중에서 좀 흥미로웠던 문제가 하나 있다.
CRC를 조작할 예정이다.

스터디 시간에 썼던 만두를 재탕할 예정이다.
CRC 4 bytes가 만들어지는 원리는 다음과 같다.
CRC32 코드를 사용하여 chunk type+data로 검사한다. (chunk length는 제외)
내가 만들 문제는 chunk length+chunk type+data로 CRC 코드를 만들어줄거다.

해당 청크들 CRC를 모두 바꿔줄 것이다.
- 파이썬 크립토 코드가 맞는지 확인
```python from zlib import crc32
data = open(“mandu.png”, ‘rb’).read() index = 12 # IHDR chunk가 시작되는 인덱스
chunk = bytearray(data[index:index+17]) # IHDR 시작부터 CRC 전까지의 범위
print(hex(crc32(chunk)))
위 파이썬 코드의 결과이다.

hxd에 있는 CRC와 동일하다. 맞게 잘 짠 거 같다.
이제 각 인덱스를 알아야 한다.
| chunk | length 시작하는 index | CRC index |
|-------|-----------------------|-----------|
| IHDR | 8 | 29 |
| IDAT | 33 | 8233 |
| IDAT | 8237 | 16437 |
| IDAT | 16441 | 24641 |
| IEND | 24645 | 27627 |
오프셋 말고 인덱스를 이용해서 코드를 다시 짰다.
```python
from zlib import crc32
data = open("mandu.png", 'rb').read()
index = [8, 33, 8237, 16441, 24645] # length부터 시작하는 index
endindex = [29, 8233, 16437, 24641, 27627]
for i in range(5):
chunk = bytearray(data[index[i]:endindex[i]]) # size
print(hex(crc32(chunk)))
출력된 값은 위와 같다. 이제 HxD를 이용하여 값을 수정하고 저장하면 문제 파일 완성이다.

아니 근데 너무 잘 열린다. CRC를 바꿨는데 왜 파일이 잘 열리는걸까
1-1.
RACTF 2020에 나온 CRC 문제를 비슷하게 제작해보기로 했다…
문제 알고리즘은 IHDR 청크의 weight와 height를 맞춰야 하는 문제이다. CRC를 통해 weight, height를 추측하고 png를 바꿔준다.
문제 파일은 간단하게 IHDR 청크의 weight, height를 00 00 00 00으로 바꾸고 저장하면 된다.

이 문제를 풀어보자면..

weight와 height가 0이다. 이 값을 알아내기 위해 CRC를 이용해야 한다. 해당 이미지의 CRC는 58 A0 C4 3C 이다. 파이썬 코드로 어떤 값을 crc32로 돌렸을 때 58 A0 C4 3C가 되는 값을 찾아야 한다.
from zlib import crc32
data = open("size.png", 'rb').read()
index = 12 # IHDR chunk가 시작되는 인덱스
IHDR = bytearray(data[index:index+17]) # IHDR 시작부터 CRC 전까지의 범위
width_index = 7 # width 부분의 세 번째 바이트 인덱스
height_index = 11 # height 부분의 세 번째 바이트 인덱스
for x in range(1, 2000):
height = bytearray(x.to_bytes(2, 'big')) # to_bytes(length, byteorder, *, signed=False)
for y in range(1, 2000):
width = bytearray(y.to_bytes(2, 'big'))
for i in range(len(height)):
IHDR[height_index - i] = height[-i - 1]
for i in range(len(width)):
IHDR[width_index - i] = width[-i - 1]
if hex(crc32(IHDR)) == '0x58a0c43c': # crc 값
print("width: 0x{}, height: 0x{}".format(width.hex(), height.hex()))
for i in range(len(width)):
IHDR[width_index - i] = bytearray(b'\x00')[0]
파이썬 코드를 돌려주면 위 값이 나오는데 이걸

이 부분에 입력해주면

원래의 이미지가 나온다.
- 자바는 꼭 대문자를..

대충 이미지 하나 만들어줬다

해당 이미지를 TweakPNG로 열면 chunk 구조를 볼 수 있다.
gAMA랑 IDAT를 소문자로 바꿔보자.

이러면 문제 파일이 만들어진다.

저장하고 이미지 파일을 열면 만들었던 이미지가 정상적으로 나온다.