달력

4

« 2024/4 »

  • 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

'reverse.kr'에 해당되는 글 1

  1. 2017.07.24 [문제풀이] reversing.kr - WindowsKernel

이번 문제는 윈도우 커널과 관련있는 문제이다 .


윈도우 커널 쪽 분석은 시도한 적도 없고 굉장히 생소해서 신선한 경험을 해볼 수 있었다. 

이 문제는 키보드를 후킹하는 드라이버 파일을 분석하여 문제를 푸는 것이다. 문제를 푼 지금도 드라이버 동작 과정이나 커널 내부 동작 과정이 정확히는 그려지지 않고 아 이런식으로 동작하겠구나 정도로 겉핥기식 개념만 잡은 것 같다. 이 문제를 계기로 윈도우 커널쪽도 좀 더 공부해봐야 겠다.


그럼 문제풀이를 시작해보겠다. 



문제를 다운로드 받아서 풀면 위와 같이 3개의 파일로 구성되어 있다. 

아래는 ReadMe 파일인데 인증을 소문자로 해달라고 부탁하고 있다. 



일단 문제를 동작시켜 보았다. 맨 처음엔 비활성화 된 입력란이었지만 옆에 버튼을 누르면 활성화가 되면서 문자를 입력할 수 있게 변경된다. 문자열을 입력하고 Check를 클릭하면 내가 입력한 값이 맞았는지 틀렸는지 확인할 수 있다. 




우선 WindowsKernel.exe 파일은 SCM을 이용하여 드라이버를 로드시키고 있다. SCM을 이용하면 레지스트리 키가 생성되며 드라이버는 페이징되지 않는다. 아래 캡쳐는 로드되는 부분의  과정 중 일부이다. 



위 과정 중 StartService 함수를 만나면 아래와 같이 드라이버가 로드된다. 이는 Winker.sys 드라이버에 삽입된 디버깅 메시지이다. 



일단 WindowsKernel.exe 에서 DeviceIoControl 함수를 통해 디바이스 드라이버에 IRP 처리를 요청할 수 있다. 드라이버는 특정 IRP 요청에 맞춰 IRP를 처리할 수 있게 설계할 수 있다. 이는 드라이버 오브젝트의 MajorFunction을 수정하는 것으로 가능하다. DeviceIoControl 함수로 IRP 요청을 보낼 경우 IRP_MJ_DEVICE_CONTROL 에 설정된 함수에서 이를 처리하게 된다. 아래 캡쳐는 그 과정을 보여준다. 



위에서는 CREATE, CLOSE, DEVICE_CONTROL과 관련된 Major Function을 초기화해주고 있다. 실제 DEVICE_CONTROL 함수 쪽 내부를 따라 들어가면 몇몇 변수를 초기화해준다. 


그리고 이 문제를 풀기 위해 다른 중요한 개념은 DPC이다. 

원래는 여기에서 주저리 주저리 설명을 하려했는데 지저분하고 흐름을 끊어버리는 것 같아서 다음에 시간을 내서 별도로 작성하도록 하겠다. 



위에 있는 내용은 DPC 객체를 초기화하는 과정이다. EDI 레지스터에 KeInitalizeDpc 함수의 주소가 들어있다. 여기서 설정된 루틴이 이후에 해답을 찾을 때 매우매우 중요한 역할을 한다. 일단 이 부분에서는 초기화만 하고 지나간다. 



이후 흐름을 따라 내려가다보면 다시 한번 DPC 객체를 초기화하고 이를 큐에 삽입한다. 여기서 삽입된 DPC 루틴은 IDT의 키보드 관련 ISR을 후킹한다. 여기까지 왔으면 거의 다 푼거나 마찬가지다. 해당 루틴이 실행되고 나면 아래와 같이 IDT가 변경된다. 



해당 부분을 분석해보면 READ_PORT_UCHAR 함수를 이용하여 키보드가 입력할 때마다 값을 가져오고 이 값을 비교한다. 해당 함수를 통해 입력한 문자를 확인하면 보통 아스키코드 값이랑은 다르다. 어떤 의미인지 정확히는 모르겠지만 이 값을 이용하여 비교문을 잘 통과하면 답을 얻을 수 있다. 






:
Posted by einai