'GRAY HAT PYTHON'

 

Chapter 3. Windows Debugger

   3.1. Debugger (ERROR_FILE_NOT_FOUND)

   3.2. Debugger (ERROR_ACCESS_DENIED)

   3.3. Get CPU register status

   3.4. Debug event handler

   3.5. Break Points


* 본 문서는 'Gray Hat Python' 책의 내용을 살펴보며 개인적으로 정리하고 싶은 내용들을 기록한 페이지입니다. 

  Phtyon3 기준으로 예제는 변경되었습니다. 잘못된 내용이 있거나 추가가 필요한 사항이 있다면 언제든지 알려주시기 바랍니다.


3.1 Debugger (ERROR_FILE_NOT_FOUND)


Python3에서 p56의 예제 화일을 수행하였더니 kernel32.GetLastError() 부분에서 0x2 에러가 발생합니다.

Windll에서 발생한 에러이므로 아래 MS 홈페이지를 참조해보니 ERROR_FILE_NOT_FOUND입니다.

혹시 path_to_exe에 잘못된 스트링이 전달되었는지 출력을 해보았으나 특히 점은 코드상에서 보이지 않습니다.


https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx


my_test.py (page 56)

import my_debugger

debugger.load("c:\\Windows\\System32\\calc.exe")
debugger = my_debugger.debugger()

[*] Error : 0x00000002 c:\Windows\System32\calc.exe.

ERROR_FILE_NOT_FOUND
2 (0x2)

The system cannot find the file specified.


우선은 아래처럼 string을 unicode로 변환을 곧바로 하는 방법이 있습니다.


my_test_modify.py


import my_debugger

debugger.load(b"c:\\Windows\\System32\\calc.exe")
debugger = my_debugger.debugger()



혹은 debugger.load부분이 아닌 my_debugger.py를 수정할 수 있습니다.

ascii-strings만 받는 CreateProcessA 가 아닌 CreateProcessW를 사용하는 방법입니다.


my_debugger.py


...

    if kernel32.CreateProcessW(path_to_exe,
                                   None,
                                   None,
                                   None,
                                   None,
                                   creation_flags,
                                   None,
                                   None,
                                   byref(startupinfo),
                                   byref(process_information)):
            print ("[*] We have successfully launched the process!")
            print ("[*] PID: %d " % process_information.dwProcessId)

...


Then if you use Python 3.x you should use not CreateProcessA but CreateProcessW function because all string in Python 3.x is in unicode (in WinAPI all functions ends with 'A' accept asci-strings, ends with 'W' accept unicode-strings)



3.2 Debugger (ERROR_ACCESS_DENIED)


위 에러를 수정하고 나서 p60의 예제를 수행해보니 이번에는 debugger.attach() 함수내의 DebugActiveProcess(pid)에서 0x5번 에러가 발생합니다.


my_test.py (p60)


import my_debugger


debugger = my_debugger.debugger()

debugger.attach(int(pid))pid = input("Enter the PID of the process to attach to: ")


debugger.run()

debugger.detach()


Enter the PID of the process to attach to: 9476
[*] Unable to attach to the process.
[*] Error : 0x00000005
There was an error


ERROR_ACCESS_DENIED
5 (0x5)
Access is denied.



구글링으로 찾아보니 64비트용 프로그램은 수행할 수 없다는 정보가 있습니다.


http://stackoverflow.com/questions/20807108/pythondebugger-from-gray-hat-python

그래서 windows 10의 Task Manager에서 (32bit) 표시가 있는 process를 시도 해보니 정상적으로 attach가 진행됩니다.



3.3 Get CPU register status


C에서는 { } 를 이용하여 scope를 정하지만 Python에서는 indent를 가지고 code code와 structure를 구분합니다.

P66에 잘못 프린트된 indent로 인해 무한 루프에 빠지는 부분이 있어 수정이 필요합니다.


    def enumerate_threads(self):
        thread_entry = THREADENTRY32()
        thread_list = []
        snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid)
       
        if snapshot is not None :
            thread_entry.dwSize = sizeof(thread_entry)
            success = kernel32.Thread32First(snapshot, byref(thread_entry))
            print ("[*] Snapshot check %d" % success)
           
            while success:
                if thread_entry.th32OwnerProcessID == self.pid :
                    thread_list.append(thread_entry.th32ThreadID)
                success = kernel32.Thread32Next(snapshot, byref(thread_entry))   
                print ("[*] Snapshot check %d" % success)


            kernel32.CloseHandle(snapshot)

            print ("[*] Snapshot handle closed")

            return thread_list

        else: 

            return False


[*] Getting Thread Context success
[*] Dumping registers for thread ID: 0x000029e8
[*] EIP : 0x772e8f00
[*] ESP : 0x0077fff0
[*] EBP : 0x00000000
[*] EAX : 0x77319d20
[*] EBX : 0x00000000
[*] ECX : 0x00000000
[*] EDX : 0x00000000
[*] End DUMP
[*] Finished debugging. Exiting...


앞서 범용 CPU register에서 살펴 보았지만 다시 한번 복습하는 의미에서

EIP : Instruction Pointer

ESP : Stack Pointer

EBP : Base Pointer

EAX : Accumulator register

EBX : 추가적인 register

ECX : Count register

EDX : Data register





반응형

'Security&Encryption > Black Hat' 카테고리의 다른 글

CPU registers and dis-assemble of Python  (0) 2016.06.29
Pydev on Eclipse  (0) 2016.06.28
Trojan using Git hub  (0) 2016.03.30
ICMP Decoding with Python  (0) 2016.03.16

+ Recent posts