외로운 Nova의 작업실

Programm Hacking Challenge - 1(악성 코드 심기) 본문

Computer App Penetesting/System Vulnerability

Programm Hacking Challenge - 1(악성 코드 심기)

Nova_ 2022. 8. 24. 23:16

안녕하세요. 해킹 첫번째 도전으로 제가 어셈블리어로 만든 ArraySum 프로그램에 항상 마지막 값이 +3이 되는 악성 코드를 심어 결과값이 바뀌게 도전을 하려고합니다. ArraySum 프로그램의 코드는 아래와 같습니다.

;this program prompts the user for three integers
;store them it an array, calculates the su of the array, and display the sum


;-----------------INCLUDE-------------------------
;
include 	c:\assembly\irvine32.inc
includelib  c:\assembly\irvine32.lib
includelib  c:\assembly\kernel32.lib
includelib  c:\assembly\user32.lib
;-----------------------------------------------


.data
INTEGER_COUNT = 3
str1 BYTE "Enter a signed integer : ", 0
str2 BYTE "The sum of the integers is: ", 0
intArray DWORD INTEGER_COUNT DUP(?)

   

.code
main PROC

    call Clrscr
    mov esi, OFFSET intArray
    mov ecx, INTEGER_COUNT
    call PromptForIntegers
    call ArraySum
    call WaitMsg
    call DisplaySum

exit
main ENDP

;--------------------------------------------------------------------------
PromptForIntegers PROC USES ecx edx esi
;
;prompt the user for three 32-bit integers
;store them in array
;Receive : ESI points to an array of doubleword integers, ecx = array size
;Retruns : nothing
;calls : ReadInt, WriteString
;--------------------------------------------------------------------------
    mov edx, OFFSET str1
L1: call WriteString
    call ReadInt
    call Crlf
    mov [esi], eax
    add esi, TYPE DWORD
    loop L1
    ret
PromptForIntegers ENDP

;-------------------------------------------------------------------------
ArraySum PROC USES esi ecx
;
;Calculate the sum of an array of 32-bit Integers
;Receive : ESI points to an array, ecx - array size
;Returns : eax = sum of the array elements
;-----------------------------------------------------------------------
    mov eax, 0
L1: add eax, [esi]
    add esi, TYPE DWORD
    loop L1
    ret
ArraySum ENDP

;-----------------------------------------------------------------------
DisplaySum PROC USES edx
;
;Display the sum on the screen
;Receive : eax = the sum
;Returns : nothing
;Calls : WriteString,  WriteInt
;------------------------------------------------------------------------
    mov edx, OFFSET str2
    call WriteString
    call WriteInt
    call Crlf
    ret
DisplaySum ENDP

END MAIN

일단, 악성코드를 심는 방법부터 알아야겠습니다. 지금은 모르지만 방법을 알게된다면, 이어서 포스팅을 진행하겠습니다.

 

8/26 - 악성 코드의 종류에는 바이러스라는 게있습니다. 바이러스는 자신의 코드를 다른 파일에 옮기고 또 자신을 복제하여 다른 파일에 옮기는 그런 악성 코드를 지칭합니다. 위 도전은 컴퓨터 바이러스에대한 지식이 필요한 것 같다는 생각이 들었습니다. 하지만 아직 어셈블리어를 끝내지않아 이해하는데 부족한 지식이 있는 것을 확인했습니다. 해당 어셈블리 공부를 모두 끝마치고 해당 도전을 이어가보도록 하겠습니다. 

 

<2022-12-22>

어셈블리어를 끝내고 리버싱을 배우는 단계에서 코드인젝션을 배웠기에 해당 첼린지를 해보려고합니다. 일단 먼저 리버싱을 해줍니다.

 

- reversing

 

첫 시작의 코드를 보게되면 call 명령어로 해당 arraysum에 있는 함수를 부르게됩니다. 이때, 제가 쓴 코드에도 제가 만든 함수가 총 4개가 있는데 이와 매치가 되는 듯합니다. 

CPU Disasm
Address   Hex dump          Command                                  Comments
0040100F  |.  E8 16000000   CALL 0040102A                            ; [arraysum.0040102A
00401014  |.  E8 33000000   CALL 0040104C                            ; [arraysum.0040104C
00401019  |.  E8 DC0B0000   CALL 00401BFA                            ; [arraysum.00401BFA
0040101E  |.  E8 3A000000   CALL 0040105D                            ; [arraysum.0040105D

 

즉, 0040102A함수는 PromptForIntegers 함수와 매치되고 0040104C 함수는 ArraySum 함수와 매치되며 00401BFA함수는 WaitMsg 함수와 매치되고 0040105D함수는 DisplaySum 함수와 매치되는 듯합니다. 이유는 그다음에는 exitprocess가 있기때문입니다. 실제 0040104C 함수 즉, ArraySum함수를 보게되면 loop문으로 EAX값에 ESI주소에 있는(우리가 입력한 값)들이 저장되는 것처럼 보입니다. bp를 걸고 확인해보겠습니다.

실제 ESI 레지스터에 있는 00404037 주소의 메모리에 보게되면 0C로 10진수 12가 있습니다. 즉 제가 입력한 값들이 들어가 있고 EAX에 계속 누적됩니다. 3번째까지 누적되면 다시 RETN되고 다음함수를 실행합니다.

 

- CRACK

코드 인젝션으로 EAX의 값을 3번다 누적한다음 마지막에 +3을 해주는 코드를 넣어주려고합니다. 그렇게되면

3번 누적이 끝나는 시점인, 0040105A에 JMP 문을 넣어줘야합니다. 다만 JMP문은 5바이트로 여기에 넣게되면 0040105E에서도 1바이트가 필요하므로 명령어가 00401062까지 날라갑니다. 날라갈때 DisplaySum 함수의 시작점인 0040105D까지 날라갑니다. 복잡해지므로 다른 방법을 생각해봅시다.

 

DisplaySum 구문에서 EAX값을 표시해주기전에 코드를 injection하는 코드를 삽입해보겠습니다. JMP문을 삽입할 만한 적당한 코드가 있는지 보았더니

딱 5바이트짜리 코드가 보입니다. 이 코드를 기점으로 code injection을 실행하겠습니다. 이제, 아무것도 없는 코드 부분을 확인해보겠습니다.

0040229E 주소의 코드 저장소를 이용해서 인젝션을 실행하겠습니다. 아까 기준점으로 돌아가서 JMP 0040229E를 넣어줍니다.

이제 0040229E 주소로가서 기준점에 있었던 MOV EDX, OFFSET 0040401A를 넣어주고 인젝션 코드인 ADD EAX, 3과 다시 되돌아갈 JMP 00401063을 넣어줍니다.

이제 저장을하고 실행시켜보겠습니다.

하지만 저장하려했더니 이 경고가나옵니다.. 무슨 경고인지는 잘모르겠습니다. dump를 떠봣지만 dump도 실행이 안됩니다. 다만, 변경된 코드로 ollydbg에서 실행하면 +3이 된 값이 결과로 나옵니다. 프로그램을 저장하는 방법에 대해서 알게되면 또다시 포스팅하겠습니다.

Comments