달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

※ 사전지식 


AVR Registers 

총 32개로 구성되어 있으며 R0 ~ R31 로 표기한다. 



AVR 메모리 참조 방식 

AVR은 독특하게도 X, Y, Z 라는 명칭(?)으로 메모리를 참조하는데 이는 각 아래와 같이 레지스터에 의존한다.

X : R27:R26 

Y : R29:R28

Z : R31:R30 




따라서 이런 연산을 하는 어셈블러들을 리버싱하는 동안에 수도 없이 볼 것이다. 



AVR 어셈블리어 

AVR Studio로 디버깅을 하면 친절하게 어셈 명령어 옆에 해당 명령어가 무엇을 하는지 나타낸다. 


추가로 AVR 어셈블리어도 앞에 위치하는 피 연산자(R30, R31)에 연산된 결과가 적용된다. 

즉, ADD R30, R24 -> R30 += R24 와 동일하다.

 

자주 보여졌던 어셈블리어에 대해서만 나열하도록 하겠다. 


RCALL - Relative Call to Subroutine

CPC- Compare with Carry 

CPI- Compare with Immediate

LDI - Load Immediate

LSR – Logical Shift Right

ST - Store Indirect From Register to data space using Index X

ST (STD) - Store Indirect From Register to data space using Index Y

ST (STD) - Store Indirect From Register to data space using Index Z

BRNE - Branch if Not Equal

BREQ - Branch if Equal

BST – Bit Store from Bit in Register to T Flag in SREG

BRCC - Branch if Carry Cleard 

BRTC – Branch if the T Flag is Cleared


사전지식 끝!



그럼 이제 문제풀이를 시작하도록 하겠다. 


이 문제는 사전지식에서 알 수 있듯이 AVR(Atmel AVR) 아키텍쳐 기반 애플리케이션을 리버싱하는 문제이다.

AVR는 임베디드 전용 아키텍쳐라고 하는데 이번 기회에 처음 접해보았다.  


해당 애플리케이션은 AVR Studio와 hapsim 을 이용하여 동적 디버깅을 하면 된다. 


간단히 프로그램들을 설명하자면 AVR Studio는 AVR 디버거이고

hapsim은 AVR 디버거로 분석하는 애플리케이션과 통신 할 수 있는 터미널 역할을 한다.  


AVR Studio를 이용하여 화면을 띄어보도록 하겠다. 




그리고 hapsim을 띄어보겠다. 



hapsim의 경우는 옵션에서 터미널 세팅의 시리얼 인터페이스를 USART1로 설정하면 알아서 통신한다. 

여기서 USART란 ATmel사에서 사용하는 직렬통신 방법이라고 한다. 


이 문제의 핵심(?)은 패스워드 처리 함수(비교함수 말고)에 대한 역연산으로 

이미 저장된 패스워드(비교대상)를 유추하는 것이다. 


이는 꼭 역연산을 하지 않고 브루트포싱을 해서 풀어도 시간이 오래 걸리지 않는다. 


나의 경우는 역함수를 구현하여 문제를 해결하였다. 

처음에 연산 순서를 역으로 배치하는 것 때문에 무지하게 애먹었다. 


논리상 문제가 없을 것이라고 판단했던 곳에서 문제가 발생하고 있었다. 

역시 내 머리는 너무 믿을게 못된다 -ㅅ-


anyway .. 


문제의 흐름을 간단히 살펴보도록 하겠다. 


이는 각 3단계의 반복문으로 구성되어 있으며 각 반복문에서 패스워드를 꼬아 다음 반복문에 전달하는 식으로 진행된다. 반복문에 전달하기 이전에 구성된 배열을 다시 재배치하는 작업도 진행한다. 


이는 아래와 같다(전체를 나타낸 것은 아님). 



위와 같은 재배치 과정이 끝나면 특정 연산과 함께 XOR를 진행하는데 XOR를 할 값을 구하기 위해 인덱스 값을 구하는 함수를 호출한다. 아래의 캡쳐에는 함수호출 부분이 빠져있다(일부로 뺀 것은 아님..)



패스워드를 변환하는 로직은 마지막 반복문을 빼고 이와 같은 순서를 가진다.

마지막 루프는 단순 ROTATE .. 



이를 쭈우욱 이해하고 역연산 함수를 짜면 패스워드가 나타난다 . 

이 패스워드를 이용해서 조금만 쉘을 가지고 놀면 답을 얻을 수 있다.

 

처음 작성했을 때 몇글자가 자꾸 깨져나와서 머리카락을 다 쥐어뽑을뻔 했는데 

결국 문제점을 찾아서 답을 얻을 수 있었다.


문제를 풀어서 마음이 한결 가벼워졌다. !!!!!ㅎ 


문제풀이 끝!




:
Posted by einai