오랜만에 짬을 내서 문제를 계속해서 진행해보았다.

sub_20C의 가장 큰 블럭 중 하나를 분석했었는데 나머지 두 블럭도 추가적으로 분석하였다.
(1) 0x309 ~ 0x0310

이구간을 제외하면 이전글에서 분석했던 블럭과 크게 차이는 나지 않는다.
이구간에서 0xAD2에 저장된 값을 바꾸는데 내가 입력했던 문자열 8개를 레지스터에 계속 저장한다.
그 값을 0xAD2에 복사한다.
또 더하면서 carry flag가 set 되면 그 값을 r9 레지스터에 저장하는데 이 값은 나중에 사용된다.

(2) 0x32B ~ 0x3CB

이러한 코드가 계속해서 반복되고있다. 확인해보니 AVR reverse engineering (5) 에서 분석하였던 구간과 마찬가지로 
0xAE4 에서 값을 가져오고 이 값을 다른값과 and 연산을 한 후
sub_1E7의 인자값으로 이용한다
여기서 리턴된 값과 0x100을 더한 주소에 저장된 값을 불러온다.

이러한 과정을 AD2~ADB까지 모두 적용한뒤 0xAE4를 가지고 있는 레지스터는 1 증가 0x100를 가지는 레지스터에는 4씩 증가시키고
이를 총 8회 반복한다.


 (3)0x3D4 ~

이전 포스트에서 이 구간에서도 값을 변경했었던 것을 확인하였는데 

여기서 아까 언급하였던 r9 레지스터에 저장되었던 값이 Y+2 에 복사되었는데, 이 값을 Z+9 즉 0xADB 번지에 복사한다.


그 아래를 보면 Z (0xAD3 으로 초기화되어있음)에 r16레지스터 값을 저장하는게 있는데 r16과 r22는 각각 Z번지에 저장된 값으로 조건이 맞다면  rotate 연산과 shift연산을 수행한 후 or 연산한다.
따라서 shift와 rotate 연산 진입 조건을 만족시키지 않는다면 해당값은 변경이 없다.

비교대상값이 이 구간에서 변형이 없었다면 좋겠지만, 보장할 수 없기 때문에 이 구간에서 얼마나 변형되는지를 확인할 필요가 있었는데
(1)에서 구한 r8과 r9 레지스터의 저장된 값이 영향을 준다는 것을 확인하였다. 또 정말 운좋게도 우연히 입력했던 테스트 값이 비교 대상의 첫번째 바이트와 동일하였다.
첫번쨰 바이트는 (2)에서 r8 레지스터의 값(문자들의 합)이 xor 연산을 거듭하면서 변형된것이기 때문에 거꾸로 비교대상의 문자들의 총합을 유추 할 수 있었다.
해서 문자들의 총합을 유지하면서 값을 변경시켜봤을 때 계속 고정된 위치만 덮어씌워지는것을 확인하였다.

해서 변경된 바이트를 제외하고 브루트포싱으로 구할 수 있는지 확인해보고자 한다.

연산하는 코드를 위와 같이 c로 작성하였다.

작성한 코드로 기준문자와 비교하여 한문자씩 변화하였을 때 어떻게 영향을 주는지 확인하였다. 하지만 예상했던것과 다르게 결과가 나오는것을 확인하였다. 
아마 결과값 바이트 Y 와 결과를 만드는 바이트 X가 서로 같은 위치가 아니라 다른 위치이기 때문이라고 본다.

 
가장 윗줄은 처음에 입력된 바이트이고 화살표가 가리키는 것은 이 입력값이 어떤위치의 바이트라고 보면
그 밑에 있는 결과 값 중 노란색 원은 네번째 바이트에 의해서 만들어졌지만, 그 다음 줄의 결과값을 보면 두번째 줄의 초록색 원이 영향을 줬지만
그 초록색원은 첫번째 줄의 가장 왼쪽에 있는 초록색원에 의해서 생성된 값이다. 즉, 단계가 진행되면서 입력했던 네번째 바이트 뿐만아니라 다른 바이트에 의해서도 변할 수 있는 것이다.

따라서 그냥 연산으로 한문자씩 변화시켜가면서 구할 수는 없다는 것을 확인하였고 결국 역연산 코드를 짜야 되는 것으로 결론이 났다.

(3)에서 나오는 명령어들이 무엇을 수행하는지 코드를 보니 잘 몰랐는데 전체적인 기능은 레지스터를 대상으로 로테이트 명령어를 수행하는 녀석이었다.
그리고 첫번째 바이트가 (2)에서 첫번째 바이트를 바꾸는것을 확인하여 첫번째 바이트외에 다른 바이트가 연산에 포함되지 않았다고 판단하여
제일 첫번째 바이트가 동일하다면 역연산에 끝 바이트도 동일할 것이다.
역연산 끝에 나타나는 바이트는 입력한 문자를 모두 합한것이었기 때문에,  (3)에서 발생하는 스왑도 동일할 것이라 가정하였다. 

그래서, 비교대상 10 바이트 9A 7D 72 57 D5 78 49 E6 F2 02 는 9A 7D 72 75 EA 78 a4 E6 F2 02 가 된다고 생각하고 역연산 코드에 넣어보기로 했다.

중간에 반복횟수와 초기 입력값에 혼동이 있어 시간이 걸렸지만
.
.
.
.



비밀번호를 구했다!




성공적으로 로그인 되는것을 확인하였다. 그리고 리드미를 읽으니 플래그가 출력되었다 감동 ㅠㅠ
아쉽게도 비밀번호 문자열과 리드미가 읽는것과 어떤영향을 주는지 정확하게 파악하진 못했지만, 플래그를 얻었으니 여기서 마무리 지어야겠다.



끄읏

 

'reversing.kr' 카테고리의 다른 글

AVR reverse engineering (5) CustomShell  (0) 2018.08.06
reversing.kr CRC1  (0) 2018.02.07
AVR reverse engineering (4) CustomShell  (0) 2018.02.05
AVR reverse engineering (3) CustomShell  (0) 2018.02.05
AVR reverse engineering (2) AVR ATmega128  (0) 2018.01.30

+ Recent posts