어셈블리 코드로서, gdb로 오픈 시 형태가 다를 수 있음.

 

#1.

global main

section .text
main:

mov ebx, eax    -------------- ebx에 eax의 주소값 복사         : *eax = 0xf7fbb808
mov ebx, 0xbffff098 -------- ebx에 0xbffff098 복사            : *ebx = 0xbffff098
mov dword [eax], 0x10 ---- eax의 주소값 안에 0x10 복사    : eax = 0x10 (0xf7fbb808 = 0x10)

mov ebx, dword [eax] ------ ebx에 eax의 주소값 안에 들어있는 값 복사 : *ebx = eax --> *ebx = 0x10
mov ebx, eax   -------------- ebx에 eax의 주소값 복사         :  ebx = 0xf7fbb808

 

#초기 주소값과 데이터

*eax = 0xf7fbb808

*ebx = 0x0

eax = 0xffffcd9c

ebx = Cannot access

 

mov

 - 데이터 복사 명령어

 - lea와의 차이 뒤에 기술.

 - mov ebx, eax ---> ebx = 0x7fbb808

 - mov ebx, [eax] --> ebx = 0xffffcd9c

 

 

#2.

global main

section .text
main:
mov eax, esp   ---------- eax에 esp의 주소값 복사                                         : *eax = 0xffffccfc
sub  esp, 8   ------------- esp의 주소에 8를 빼기연산                                      : *esp = 0xffffccf4 
mov [eax], dword 1 ----- eax의 주소 안에 0x1 데이터를 복사                           : eax = 0x1 ---> 0xffffccfc = 0x1
mov [eax-4], dword 2 --- eax의 주소에서 4를 뺀 주소 안(값)에 0x2 데이터를 복사 

                                                                                                       : [eax-4] = 0x2 ---> 0xffffccf8 = 0x2
sub [eax-4], dword 1 ---- eax의 주소에서 4를 뺀 주소 안에 0x1 데이터를 복사

                                                                                                       : [eax-4] = 0x1 ---> 0xffffccf8 = 0x1

 

#초기 주소값과 데이터

*eax = 0xf7fbb808

*esp = 0xffffccfc

eax = 0xffffcd9c

[eax-4] = 0x00000000

 

 

#3.

section .text
main: 
        mov     eax, 1 ------------ eax의 주소에 0x1 복사                                : *eax = 0x1, eax = {cannot access}
        mov     ebx, 4 ------------ ebx의 주소에 0x4 복사                               : *ebx = 0x4, ebx = {cannot access}

       mov    ecx, 7  ------------ ecx의 주소에 0x7 복사                                 : *ecx = 0x7, ecx = {cannot access} 
        lea     eax, [eax+ecx] ---- eax의 주소에 *eax+*ecx의 주소값                : *eax = 0x8, eax = {cannot access} 

        lea     ebx, [ebx*4] ------- ebx의 주소에 *ebx * 4 = 4*4 --> 0x10 복사 :  *ebx = 0x10, ebx = {cannot access}
        mov     eax, [eax+ecx] --- eax(*1=?), ecx(*7=?) --> 0x1과 0x7에는 메모리가 접근 불가.(힙으로 추정)

                                                                            에러 후 종료

        mov     eax ---------------- 

 

#초기 주소값과 데이터

(시작부터 복사해서 의미없음)

 

 

#4.

global main

section .text
main:
        mov     eax, 0x33 ------- eax의 주소에 0x33 복사          : *eax = 0x33
        mov     ebx, 0x55 ------- ebx의 주소에 0x55 복사         :  *ebx = 0x55
        mov     ecx, 0x42 -------- ecx의 주소에 0x42 복사        :  *ecx = 0x42

        and     eax, ebx  --------- eax의 주소와 ebx의 주소를 and연산 : *eax = 0x11
        or      eax, ecx ----------- eax의 주소와 ecx의 주소를 or연산 :  *eax = 0x53
        xor     eax, 0xac ---------- eax의 주소와 0xAC를 xor 연산 : *eax = 0xFF

 

+) and, or, xor 연산

1. and 연산 : 둘 모두 같아야 1

*eax = 0x33 = 0011 0011

*ebx = 0x55 = 0101 0101        and

-----------------------------------------

                    0001 0001  ----> 0x11

 

2. or 연산 : 둘 중 하나라도 1이면 1

*eax = 0x11 = 0001 0001

*ecx = 0x42 = 0100 0010          or

-----------------------------------------

                   0101 0011 ------> 0x53

 

3. xor 연산 : 둘이 서로 (무조건)달라야 1

*eax    = 0x53 = 0101 0011

*0xAC = 10, 12= 1010 1100        xor

------------------------------------------

                      1111 1111 ----> 0xFF 

 

#5.

global main

section .text
main:
        mov     eax, 2 ------- eax의 주소에 2를 복사 eflags=0x246
        cmp     eax, 2 ------- eax의 주소와 2를 비교 eflags=0x246
        cmp     eax, 1 ------- eax의 주소와 1을 비교 eflags=0x202
        cmp     eax, 3 ------- eax의 주소와 3을 비교 eflags=0x297

        test    eax, eax ------ eax의 주소와 eax의 주소를 and연산 eflags=0x202 
        mov     eax, 0 ------- eax의 주소에 0 복사 eflags=0x202
        test    eax, eax ------ eax의 주소와 eax의 주소를 and 연산 eflags=0x246

 

+)

cmp : oper1 - oper2 ---> +,-,0 나올 수 있음.

 

EFLAGS Register

ex)202

0010 | 0000 | 0010 -----------> [IF]

OF DF IF TF | SF ZF 0 AF | 0 PF 1 CF

 

 

OF(Overflow Flag) : 연산의 결과 값이 Sign-bit(MSG)를 제외한 최대 허용 정수값보다 크거나,

                          최소 정수값보다 작으면 1이 된다. --> overflow check

 

DF(Direction Flag) : 문자열을 처리하는 명령(MOVS, CMPS, SCAS, LODS, STOPS)를 제어하는 플래그.

                          1이 되어 있으면 높은 주소에서 낮은 주소대로 처리, 0이면 낮은 주소에서

                          높은 주소로 처리한다. (assembly = STD : set(1), CLD : clear(0))

 

IF(Interrupt Flag) : 프로세스로부터 인터럽트가 발생하면 인터럽트 처리를 할 것인지 제어.

                       1이 되어 있으면 인터럽트 신호가 발생 시 인터럽트를 처리.

                       0인 경우는 인터럽트 신호 와도 반응안함.

 

TF(Trap Flag) : 디버깅 시 Single step mod 활성화 하였을 때 1이 된다.

                   명령 실행 시 TF를 세트하여 하나의 명령씩 프로그램을 수행 가능

 

SF(Sign Flag) : 최상위 bit의 결과와 같은 결과로 설정된다. Signed Integer로 사용되는 경우

                   SF가 0이면 양수, 1이면 음수를 나타낸다.

 

ZF(Zero Flag) : 산술 연산 결과가 0인 경우 1이 되고 아니면 리셋.

                    보통 값 비교에서 oper1 - oper2=0 (같음) 혹은 루프에서 1씩 차감하여

                    0이 되면 루프를 빠져나오게 하는 등의 방식으로 활용되는 플래그.

 

AF(Adjust Flag) : 산술연산 수행결과가 bit3 자리에 자리 올림이나 내림이 발생할 때 1이 됌.

                      10진법(BCD) 연산에 사용되는 플래그.

 

PF(Parity Flag) : 산술연산 수행결과가 하위 1Byte 중 1bit가 짝수면 1, 아니면 0이 된다.

 

CF(Carry Flag) : 산술연산 수행결과가 자리 올림이나 자리 내림이 발생할 때 1이 된다.

 

참고 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=no1rogue&logNo=30095428920 

 

즉, 3번째 줄 cmp     eax, 1 에서 eflags가 202가 나왔는데, 이는

0010 0000 0010 을 뜻하고, IF 하나만 세팅되었다는 것을 알 수 있다.

 

 

#6.

global main

section .text
main:
        mov     ecx, 0  ------------- ecx의 주소에 0 복사                      : *ecx = 0
        mov     eax, ecx ----------- eax의 주소에 ecx의 주소 복사          : *eax = 0
        inc     ecx ------------------ ecx의 주소에 1 증가                       : *ecx = 1
        cmp     ecx, 255 ----------- ecx의 주소에 255를 빼서 and연산     : *ecx - 255 != 0 ----> 1 != 255 [ZF = 0]
        jne     0x8048067 ---------- 같지 않으면 0x8048067로 점프       
        ret

 

 

#hint : /etc/xinetd.d에 백도어가 있다고 한다.

 

#/etc/xinetd.d 디렉터리에서 backdoor파일을 열었다.

 - xinetd.d : 오픈소스 슈퍼 서버 데몬 (인터넷 기반 연결을 관리한다.)

 - finger : 사용자 계정정보 명령어

  -> user : 파일을 실행할 사용자 권한

  -> server : 서비스 파일(동작)의 경로

 

#backdoor파일 생성 후 컴파일

 - level5의 권한으로 실행할 때, 패스워드를 알아야 되므로

   패스워드를 출력하는 실행 파일을 server 경로에 "backdoor" 이름으로 만든다.

 

#finger 서비스 실행

 - finger @localhost

  -> @localhost로 현재 접속한 계정의 정보를 출력하면

      server의 서비스파일이 실행되면서 level5의 패스워드를 출력한다.

'[P]wnable&[R]eversing > [P]HackerSchool(FTZ)' 카테고리의 다른 글

HackerSchool level-3  (0) 2021.05.09
HackerSchool level-2  (0) 2021.05.09
HackerSchool level-1  (0) 2021.05.09

#hint : 프로그램 코드가 주어지고, 이를 분석하여 level4의 권한을 열어야 한다.

 - if( argc!=2){...}

  -> 인자값이 2가 아니면 printf 두줄을 출력한다.

  

 - strcpy( cmd, "dig @" );

  -> cmd에 "dig @"를 복사

  -> dig : DNS 정보 확인 명령어

 

 - strcat( cmd, argv[1] );

  -> 입력한 문자열 (argv[1])을 이어붙임

 

 - strcat( cmd, " version.bind chaos txt");

  -> " version.bind chaos txt"를 cmd에 이어붙임

 

 tip) strcpy : 문자열 복사

      strcat : 문자열 이어붙이기

 

 - system( cmd );

  -> cmd 문자열 실행

 

: "dig @(입력한 문자열) version.bind chaos txt"

 hint1 : 동시에 여러 명령어를 사용하려면?

  -> ";" 기호를 사용한다.

 hint2 : 문자열 형태로 명령어를 전달하려면?

  -> " " 로 감싸주어야 한다.

 

 즉, 입력한 문자열 부분에서 첫 번째 입력값은 dig 명령어의

 파라미터로 들어가게 되므로,

"(dig파라미터);(실행명령어) #(뒷부분 주석처리)"

" ;my-pass #"를 입력하여야 한다.

 

#autodig 파일찾고 이동.

 

#autodig " ;my-pass #"

 실제 실행 코드 : dig @ ;my-pass # version.bind chaos txt

'[P]wnable&[R]eversing > [P]HackerSchool(FTZ)' 카테고리의 다른 글

HackerSchool level-4  (0) 2021.05.09
HackerSchool level-2  (0) 2021.05.09
HackerSchool level-1  (0) 2021.05.09

#hint : 텍스트 파일 편집 중 쉘 명령 실행

 

#find : level3 setuid 권한을 가진 파일찾기

 

#vi로 열어보니 파일이 깨지므로, 경로를 이동해서 실행(=VIM)

 - 빈 파일이 나온다.

 

#:!my-pass

 - 텍스트 파일 안에서 외부 쉘 명령어를 실행하려면 esc를 눌러 명령모드로 진입한 다음,

   ":!명령어"를 입력을 하면 실행이 된다.

 

#flag

 - 파일이 level3의 권한으로 setuid가 걸려 있어서, level3의 권한으로 명령이 실행되어

   비밀번호가 출력되었다.

'[P]wnable&[R]eversing > [P]HackerSchool(FTZ)' 카테고리의 다른 글

HackerSchool level-4  (0) 2021.05.09
HackerSchool level-3  (0) 2021.05.09
HackerSchool level-1  (0) 2021.05.09

#level1 password : level1

 

#hint : level2권한으로 setuid가 걸린 파일을 찾아 야 한다.

#find 명령어 활용.

-user [username]

->유저이름

-perm -[perm number]

-> 권한 정보 (setuid4000이다.)

- 2>/dev/null

-> 표준에러 ‘2’/dev/null로 보내서 화면에

출력되지 않게 함.

 

#/bin/ExecuteMe 실행

- password를 알아야 level2로 넘어갈 수 있는데,

my-pass가 잠겨있다.

- /bin/bash를 입력하여 level2의 권한으로

쉘을 하나 실행.

 

#id, my-pass

- id를 입력하여 권한이 level2인지 확인하고

my-pass로 비밀번호를 확인한다.

'[P]wnable&[R]eversing > [P]HackerSchool(FTZ)' 카테고리의 다른 글

HackerSchool level-4  (0) 2021.05.09
HackerSchool level-3  (0) 2021.05.09
HackerSchool level-2  (0) 2021.05.09

+ Recent posts