본문 바로가기
SeSAC/어플리케이션 보안 & 취약점 진단

[SeSAC 성동캠퍼스 1기] 어플리케이션 보안 & 취약점 진단 2일차

by zivvon 2023. 11. 15.
목차 접기

어플리케이션 보안 & 취약점 진단

[ Memory Architecture ]

- Descriptor Privilege Level- 코드가 실행되며 참조하고자 하는 메모리의 권한을 Multi Ring 형태로 디자인- 어플리케이션이 커널에 접근 시 API라는 것을 제공하여 시스템 보호- Ring Level~> Kernel Level (Ring 0)~> Application Level (Ring 3, Shell, Explorer.exe)

 

 

- Ring Level

~> H/W

~> Driver

~> Kernel

~> Shell

~> Application

~> OS = Shell + Kernel

 

스택 Stack

- FIFO 구조

- 높은 주소에서 낮은 주소로 진행

- 복귀 주소 (RET)

- 함수 파라미터 (Argument)

- 지역변수

- Dummy Code, Security Cookie

 

ex) c언어와 어셈블리로 보는 스택 구조

1. C언어
int my_socks(color_one, color_two, color_three);​

2. 어셈블리
push color_three
push color_two
push color_one
call my_socks​

 

✏️ 나를 위한 짚고 넘어가기 :) ㅋ....

[ 레지스터 ]

- ESP : 하나의 스택 프레임의 끝 지점 주소가 저장됨, PUSH/POP 명령어에 의해 값이 4씩 변함

- EBP : 하나의 스택 프레임의 시작 주소가 저장됨, 현재 스택 프레임 동안에는 절대로 값이 바뀌지 않다가 현재 스택 프레임이 소멸되면 이전 스택 프레임을 가리키게됨

 

[ 어셈블리 명령어 ]

- RET : CALL한 주소로 돌아감

 

Call By Value : '값'에 의한 호출

- 함수가 호출될 때 스택에 전달되는 변수 저장

- 전달되는 변수의 값을 복사하여 함수의 인자로 전달

- 인자로 받는 값을 복사하여 처리 => 안전, 원래 값 보존, 메모리 사용량 증가

 

Call By Reference : '참조'에 의한 호출

- 함수가 호출될 때 스택에 전달되는 변수의 포인터 저장

- 전달되는 변수가 가르키는 값을 참조

- 인자로 받은 값의 주소를 참조하기 때문에 직접 값에 영향을 줌

- 복사하지 않고 직접 참조 => 빠름, 원래 값 영향 받음

 

 


 

💡실습!

아래 소스코드로 만들어진 실행파일을 디버깅 해보자!
#include <stdio.h>
#include <windows.h>

int main() {
    SYSTEMTIME st;
    TCHAR lpstring[MAX_PATH] = "If Code!!";	// MAX_PATH는 어딘가에 정의되어있다고 한다.
    int iYeer = 2005;
    int iMonth = 0;
    int iDay = 32;
    GetLocalTime(&st);
    if(st.wYear == iYear) {
        if(st.wMonth == iMonth) {
            if(st.wDay == iDay) {
                printf("%s", lpString);
            }
        }
    }
    return 0;
}​

선언된 변수 값들이 2005년 0월 32일이기 때문에 "If Code!!"라는 출력문이 절대 나올 수 없는 코드이다.
따라서 우리는! "If Code!!"가 출력되게 OllyDBG에서 조작해보자 :)

' 디버거 물린 상태로 '
1. OllyDBG에서 디버깅 시작하고 JNZ OpCode에 도달할 때마다 CMP의 결과가 참이라는 의미로 Zero Flag값을 1로 바꾸면서 print() 함수 호출까지 F8 누르기
⚠️ 1 True 0 False

2. 어셈블리어 CMP문의 상수값을 7E7(2023), 0B(11), 0F(15) 현재 날짜로 바꿔주어 IF문이 True를 뱉을 수 있게 조작하기

3. 기계어 필드에서의 년, 월, 일 상수값을 현재 날짜로 바꿔주어 IF문이 True를 뱉을 수 있게 조작하기

4. 어셈블리어 명령어를 'JNZ(Jump if Not Zero)'에서 'JE(Jump if Equal)'로 바꿔주기

5. JNZ의 offset값을 기계어 필드에서 0으로 바꿔주기