실행부는 이전의 문제와 동일하다.
 

00007FF7C9A63000  AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5  .ØËË..ËÄ.¡Ò×ÒÖ¨¥  
00007FF7C9A63010  DC C7 AD A3 A1 98 4C 00 00 00 00 00 00 00 00 00  ÜÇ.£¡.L.........

비교함수의 덤프까지 가져왔다.
 
어셈블리 코드의 비교함수를 자세히 살펴보면

00007FF7C9A61000 | 48:894C24 08             | mov qword ptr ss:[rsp+8],rcx            |
00007FF7C9A61005 | 48:83EC 18               | sub rsp,18                              |
00007FF7C9A61009 | C70424 00000000          | mov dword ptr ss:[rsp],0                |
00007FF7C9A61010 | EB 08                    | jmp chall5.7FF7C9A6101A                 |
00007FF7C9A61012 | 8B0424                   | mov eax,dword ptr ss:[rsp]              |
00007FF7C9A61015 | FFC0                     | inc eax                                 |
00007FF7C9A61017 | 890424                   | mov dword ptr ss:[rsp],eax              |
00007FF7C9A6101A | 48:630424                | movsxd rax,dword ptr ss:[rsp]           |
00007FF7C9A6101E | 48:83F8 18               | cmp rax,18                              | 문자열 길이 0x18
00007FF7C9A61022 | 73 39                    | jae chall5.7FF7C9A6105D                 |
00007FF7C9A61024 | 48:630424                | movsxd rax,dword ptr ss:[rsp]           | 
00007FF7C9A61028 | 48:8B4C24 20             | mov rcx,qword ptr ss:[rsp+20]           | [rsp+20]:"asdfasdfasdf"
00007FF7C9A6102D | 0FB60401                 | movzx eax,byte ptr ds:[rcx+rax]         | eax에 입력된 현재 문자 저장(input[i])
00007FF7C9A61031 | 8B0C24                   | mov ecx,dword ptr ss:[rsp]              | ecx에 현재 인덱스 저장(i)
00007FF7C9A61034 | FFC1                     | inc ecx                                 | i++
00007FF7C9A61036 | 48:63C9                  | movsxd rcx,ecx                          | 
00007FF7C9A61039 | 48:8B5424 20             | mov rdx,qword ptr ss:[rsp+20]           | [rsp+20]:"asdfasdfasdf"
00007FF7C9A6103E | 0FB60C0A                 | movzx ecx,byte ptr ds:[rdx+rcx]         | ecx에 input[i+1]저장
00007FF7C9A61042 | 03C1                     | add eax,ecx                             | eax에 input[i] + input[i+1] 문자 저장
00007FF7C9A61044 | 48:630C24                | movsxd rcx,dword ptr ss:[rsp]           | rcx에 현재 인덱스 저장(i)
00007FF7C9A61048 | 48:8D15 B11F0000         | lea rdx,qword ptr ds:[7FF7C9A63000]     | 
00007FF7C9A6104F | 0FB60C0A                 | movzx ecx,byte ptr ds:[rdx+rcx]         | ecx에 저장된 암호문의 현재 인덱스값 저장
00007FF7C9A61053 | 3BC1                     | cmp eax,ecx                             | eax와 ecx비교
00007FF7C9A61055 | 74 04                    | je chall5.7FF7C9A6105B                  |
00007FF7C9A61057 | 33C0                     | xor eax,eax                             |
00007FF7C9A61059 | EB 07                    | jmp chall5.7FF7C9A61062                 |
00007FF7C9A6105B | EB B5                    | jmp chall5.7FF7C9A61012                 |
00007FF7C9A6105D | B8 01000000              | mov eax,1                               |
00007FF7C9A61062 | 48:83C4 18               | add rsp,18                              |
00007FF7C9A61066 | C3                       | ret                                     |

디버거를 따라가면서 확인해봤다.
input[i] + input[i+1] == str[i]가 되어야한다.
그렇다면 우리가 구해야 할 값은 input이고 str을 알고 있는데 i는 24까지 가며 덤프값을 통해 확인해봤을 때 str[24]는 00이다.
input[i] == str[i] - input[i+1]인데 최종 마지막에 들어가는 input[24]를 NULL로 생각하면서 한칸씩 내려오는 식으로 코드를 짜면 된다.

str = 'AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5 DC C7 AD A3 A1 98 4C 00'
str = str.split(' ')
str.reverse()
res = ''
tmp = int(str[0], 16)

for i in range(0, 23): #0x18 == 24
    tmp = int(str[i + 1], 16) - tmp
    res += chr(tmp)


print(res[::-1])

 
사실 이번 문제를 4번문제와 동일하게 디컴파일된 함수를 그대로 파이썬 코드에 넣어서 풀었을 때 이상한 문자열이 출력됐었다. 왜냐하면 이번 문제는 문자열 하나 하나를 독립적으로 보는게 아닌 입력된 문자열에서 현재 인덱스와 다음 인덱스를 불러와서 계산을 하는 문제여서 역산이 필요한 문제였기 때문이다. 앞으로는 계산이 좀 더 필요할 것 같다.

'Security > Reversing' 카테고리의 다른 글

Dreamhack rev-basic-7  (0) 2022.06.21
Dreamhack rev-basic-6  (0) 2022.06.01
Dreamhack rev-basic-4  (0) 2022.05.25
Dreamhack rev-basic-3  (0) 2022.05.24
Dreamhack rev-basic-2  (0) 2022.05.23

프로그램을 실행하면 앞문제들과 동일하다.
 

메인함수도 동일
비교함수를 IDA로 바로 디컴파일 해보자.

__int64 __fastcall sub_7FF6A5671000(__int64 a1)
{
  int i; // [rsp+0h] [rbp-18h]

  for ( i = 0; (unsigned __int64)i < 0x1C; ++i )
  {
    if ( ((unsigned __int8)(16 * *(_BYTE *)(a1 + i)) | ((int)*(unsigned __int8 *)(a1 + i) >> 4)) != byte_7FF6A5673000[i] )
      return 0i64;
  }
  return 1i64;
}

 
3번문제와 동일하게 a1은 덤프를 통해 가져올 수 있다.

00007FF6A5673000  24 27 13 C6 C6 13 16 E6 47 F5 26 96 47 F5 46 27  $'.ÆÆ..æGõ&.GõF'  
00007FF6A5673010  13 26 26 C6 56 F5 C3 C3 F5 E3 E3 00 00 00 00 00  .&&ÆVõÃÃõãã.....

 
 
파이썬에 저 계산식 그대로 코드를 작성해보자.

str = '24 27 13 C6 C6 13 16 E6 47 F5 26 96 47 F5 46 27 13 26 26 C6 56 F5 C3 C3 F5 E3 E3'
str = tuple(str.split(" "))
res = ''


for i in range(len(str)):
    res += chr(16*(int(str[i], 16)) | int(str[i], 16)>>4)

print(res)

어딘가 문제가 생긴 것 같다.
어셈블리어 코드를 자세히 살펴봤더니 디컴파일이 잘못됐는건지 계산식에서 [and ecx,F0]라는 구문이 생략된 것 같다.
ecx에 계산결과를 계속 저장하고 있었으니 위 파이썬 코드에서 &0xF0를 추가하면 해결될 것 같다.
 

str = '24 27 13 C6 C6 13 16 E6 47 F5 26 96 47 F5 46 27 13 26 26 C6 56 F5 C3 C3 F5 E3 E3'
str = tuple(str.split(" "))
res = ''


for i in range(len(str)):
    res += chr(16*(int(str[i], 16)) & 0xF0 | int(str[i], 16)>>4)

print(res)

중간에 계산식 오류를 찾느라 어셈블리어와 디컴파일된 코드를 비교하며 하나하나 따라가다보니 어셈블리어 계산식이 살짝씩 눈에 들어오기 시작했다. 목표는 디컴파일 없이 어셈블리어만 보고 직접 계산식을 세워보는 건데 가능할지는 잘 모르겠다.

'Security > Reversing' 카테고리의 다른 글

Dreamhack rev-basic-6  (0) 2022.06.01
Dreamhack rev-basic-5  (0) 2022.05.28
Dreamhack rev-basic-3  (0) 2022.05.24
Dreamhack rev-basic-2  (0) 2022.05.23
Dreamhack rev-basic-1  (0) 2022.05.23

역시 실행부는 앞의 문제와 동일하다.
 

메인함수도 거의 동일하다.
7FF794AE1000함수로 들어가보자.

[cmp rax,18]를 보아 문자열의 길이가 0x18 = 24임을 알 수 있다.
rev-basic-2문제와 유사해 보이지만 덤프를 따라가보면

아스키 변환한 값이 이상한 것을 보니 헥스 코드를 사용하는 것 같다. 
 
어셈블리어 해석을 할 수 있어야 되는데 어색하니 IDA를 통해 비교함수부분을 디컴파일 해보면
 

조건식이 나온다. a1에 헥스코드가 들어가고 이를 파이썬을 통해 역산식으로 대입해보면

str = '49 60 67 74 63 67 42 66 80 78 69 69 7B 99 6D 88 68 94 9F 8D 4D A5 9D 45'
str = tuple(str.split(" "))
res = ''

for i in range(24):
    res += chr((int(str[i],16) - (2*i)) ^ i)

print(res)
위의 코드 실행 결과

어떠한 문자열이 나온다. 이를 chall3.exe에 입력하면

이제 어셈블리어를 해석해야되는 수준까지 왔다. 아직 어셈블리어가 익숙하지 않기 때문에 스터디 기간동안 어셈블리어를 공부해야될 필요성을 느끼게됐다

'Security > Reversing' 카테고리의 다른 글

Dreamhack rev-basic-5  (0) 2022.05.28
Dreamhack rev-basic-4  (0) 2022.05.25
Dreamhack rev-basic-2  (0) 2022.05.23
Dreamhack rev-basic-1  (0) 2022.05.23
Dreamhack rev-basic-0  (0) 2022.05.23

0번과 1번문제와 또또 같다.
 

실행부도 똑같다.
 

입력: asdfasdfasdf

비교함수가 이전 문제와는 다르다.
문자와 직접 비교하는게 아니라 어딘가에 저장된 문자와 비교하는것 같다. 
[cmp rax,12]는 문자를 0x12번 반복하며 검사한다는 것을 알 수 있다.
실제 문자열 비교문은

cmp dword ptr ds:[rcx+rax*4],edx

이다.
 
이를 덤프에서 따라가면

그 주소에 문자가 저장되어 있다.
 

아직 튜토리얼느낌으로 그냥 디버거를 따라가기만 하면 풀 수 있는 것 같다.

'Security > Reversing' 카테고리의 다른 글

Dreamhack rev-basic-5  (0) 2022.05.28
Dreamhack rev-basic-4  (0) 2022.05.25
Dreamhack rev-basic-3  (0) 2022.05.24
Dreamhack rev-basic-1  (0) 2022.05.23
Dreamhack rev-basic-0  (0) 2022.05.23

드림핵의 rev-basic-1 문제다.

rev-basic-0문제와 기본 입출력은 같다.
 

0번문제와 조건문도 같다.
 

문자열 비교함수에 들어가보니 문자열 통째로 비교한 0번문제와는 달리 한글자씩 비교한다.
 

아직까진 너무 쉽다

'Security > Reversing' 카테고리의 다른 글

Dreamhack rev-basic-5  (0) 2022.05.28
Dreamhack rev-basic-4  (0) 2022.05.25
Dreamhack rev-basic-3  (0) 2022.05.24
Dreamhack rev-basic-2  (0) 2022.05.23
Dreamhack rev-basic-0  (0) 2022.05.23

이번에 동아리에서 워게임 스터디를 진행하게 되었다. 그래서 드림핵의 리버싱 문제를 Level1부터 차근차근 풀어보려고 한다.
그 중 rev-basic-0이라는 문제다

문제의 파일을 실행하면 나오는 화면이다. 아무렇게나 막 입력을 하면

"Wrong"이 출력된다. 어느 부분에 조건문이 있을거라고 생각되기 때문에 디버거로 확인해보자.

Correct또는 Wrong을 출력시키는 조건문이 있다.
test eax,eax를 보아 바로 위의 함수에서 문자열을 비교하는것 같다.

비교함수를 보니 "Compar3_the_str1ng"이 답인것같다.

 

'Security > Reversing' 카테고리의 다른 글

Dreamhack rev-basic-5  (0) 2022.05.28
Dreamhack rev-basic-4  (0) 2022.05.25
Dreamhack rev-basic-3  (0) 2022.05.24
Dreamhack rev-basic-2  (0) 2022.05.23
Dreamhack rev-basic-1  (0) 2022.05.23

+ Recent posts