1. 문제
1) mitigation 확인
- 문제 이름대로 32비트 MIPS 바이너리 파일이다.
2) 문제 확인
- qemu로 확인할라 했는데 이상하게 mips만 안됨, 실행시키면 세그먼테이션 폴트 발생
3) 코드흐름 파악
undefined4 main(void){
char input_24;
int input_length;
int flag1;
char cStack49;
int flag2;
uint flag3;
int flag4;
char input [28];
memset(input,0,0x1a);
printf(0xdf0);
__isoc99_scanf(0xdfc,input);
input_length = strlen(input);
if (input_length == 0x19) {
flag1 = 0;
while (flag1 < 6) {
flag2 = 0x18;
while (input_24 = input[24], -1 < flag2) {
if (flag2 == 0) {
input[0] = cStack49;
}
else {
if (flag2 == 0x18) {
input[24] = input[23];
cStack49 = input_24;
}
else {
input[flag2] = *(char *)((int)&flag4 + flag2 + 3);
}
}
flag2 = flag2 + -1;
}
flag1 = flag1 + 1;
}
flag3 = 0;
while ((int)flag3 < 0x19) {
if ((*(uint *)(data + flag3 * 4) ^ flag3 ^ (int)input[flag3]) != *(uint *)(comp + flag3 * 4))
{
puts(0xe10);
return 0;
}
flag3 = flag3 + 1;
}
flag4 = 0;
while (flag4 < 0x19) {
_IO_putc((int)(char)*(undefined4 *)(comp + flag4 * 4),_stdout);
flag4 = flag4 + 1;
}
puts(0xe1c);
}
else {
puts(0xe00);
}
return 0;
}
- 먼저, scanf()로 input값을 받는데 0x19만큼의 길이가 되어야한다.
- 그 다음 밑에 3개의 while루프가 도는데 다음 접근 방법에서 보기 쉽게 변형해보자
[ 전역변수 data ]
- 0x72, 0x9, 0x4, .... 4byte단위씩 끊어져서 값이 저장되어 있다.
(0x72, 0x9, 0x4, 0x10, 0x49, 0x19, 0x3A, 0x1C, 0x34, 0x3B, 0x26, 0x2A, 0x15, 0x30, 0x52, 0x1B, 0xD, 0xC, 0x12, 0x38, 0x49, 0x4, 0x2, 0x69, 0x4B)
[ 전역변수 comp ]
- 여기도 동일하게 0x43, 0x6f, 0x6e, ... 4byte씩 끊어서 저장되어 있음
(0x43, 0x6F, 0x6E, 0x67, 0x72, 0x61, 0x74, 0x7A, 0x5F, 0x59, 0x6F, 0x75, 0x5F, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x5F, 0x46, 0x6C, 0x61, 0x67, 0x21, 0x21)
2. 접근 방법
[ 첫 번째 while루프 ]
- 크게 6번 while루프가 돌고 2번째 while문에서는 input길이만큼 돈다.
- flag2가 0x18인 경우 input[0x18] = input[0x17]
- flag2가 0x0인 경우 input[0x0] = input[0x18]
- 이외인 경우 input[flag2] = *(&stack40 + flag2 + 3)
- 근데 디버깅을 못해서 stack40이 정확히 어디 위치에 있는지를 모르겠다.;;
[ 두 번째 while루프 ]
(data + i * 4) ^ i ^ input[i] != (comp + flag3 * 4)
- 다시 고치면
data[i * 4] ^ i ^ input[i] != comp[i * 4]
- 위와 같이 비교하고 같지 않으면 리턴된다.
- 따라서, 두 항의 값이 참이 되도록 찾아야 할 것 같다.
[ 세 번째 while루프 ]
- comp 값을 출력해준다.
그럼 이제 data[i * 4] ^ i ^ input[i] != comp[i * 4]
여기에서 모르는 값은 input값이다. 좌항에 input값만 남겨두려면 우항에 동일하게 data[i * 4] ^ i ^
을 넘겨주면 될 것이다.
그럼 다시 바꾸면
input[i] != comp[i * 4] ^ data[i * 4] ^ i
일케 된다. 그럼 파이썬 코드 짜서 한 번 돌려보자
3. 문제 풀이
data = [0x72, 0x9, 0x4, 0x10, 0x49, 0x19, 0x3A, 0x1C, 0x34, 0x3B, 0x26, 0x2A, 0x15, 0x30, 0x52, 0x1B, 0xD, 0xC, 0x12, 0x38, 0x49, 0x4, 0x2, 0x69, 0x4B]
comp = [0x43, 0x6F, 0x6E, 0x67, 0x72, 0x61, 0x74, 0x7A, 0x5F, 0x59, 0x6F, 0x75, 0x5F, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x5F, 0x46, 0x6C, 0x61, 0x67, 0x21, 0x21]
new_list = []
for idx in range(len(data)):
new_list.append(chr(comp[idx] ^ data[idx] ^ idx))
print("".join(new_list))
flag값이 순서대로 나오지는 않는다. "Hack"문자열 앞에 6byte는 원래 뒤에 와야되는데 앞으로 온걸 보니깐 아까 첫 번째 while문의 역할이 rotation돌리는 것 같다.
Uploaded by Notion2Tistory v1.1.0