728x90

1. 암호

암호 기본 개념

평문 Plaintext : 암호화되지 않은 메시지
암호문 Cypertext : 암호화된 메시지

암호화 Encryption : 평문을 암호문으로 만드는 것
복호화 Decryption : 암호문으로부터 평문을 복원하는 것

Key : 평문/암호문을 암호화/복호화시키는 암호 알고리즘에 필요한 핵심 가변정보 값

모듈러 연산 : 어떤 숫자를 다른 숫자로 나눈 나머지를 구하는 연산 ex) a ≡ b (mod n) : a와 b는 n으로 나눈 나머지가 같다
합동 : 어떤 숫자를 다른 숫자로 나눈 나머지가 같은 경우, 이를 합동이라고 함

인코딩 : 데이터를 코드화하고 압축하는 등 다른 형태로 변환하는 것

  • 인코딩은 암호화와 달리 데이터의 기밀성을 고려하지 않고 누구나 디코딩하여 원문을 구할 수 있다. 파일의 크기를 줄이거나 컴퓨터가 알아들을 수 있는 형식으로 변환하기 위해 사용한다.

Base64 : 8비트 이진 데이터(실행 파일, ZIP 파일 등)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식을 가리키는 개념.

  • 총 64개로 이루어지며, =은 끝을 알리는 코드로 사용.
  • 24비트 버퍼에 3바이트씩 집어넣고, 6비트식 끊어서 해당하는 문자로 변환

대칭키 암호 (=비밀키 암호)

암호화와 복호화에 같은 암호 키를 쓰는 알고리즘. (ex. DES, AES)

고대 치환 암호 : 평문을 이루는 각각의 문자를 다른 문자로 바꿔 정보를 숨기는 것
카이사르 암호(시저 암호) : 암호화하고자 하는 내용을 알파벳별로 일정한 거리만큼 밀어서 다른 알파벳으로 치환하는 암호 방식
비제네르 암호 : 여러 개의 수를 암호키로 사용하여 카이사르 암호보다 한 층 더 복잡한 다중 치환 암호

블록 암호 : 평문을 정해진 블록 단위로 암호화하는 알고리즘 (ex. AES, DES)
스트림 암호 : 이진 수열로 변환된 평문을 비트 단위로 암호화하는 알고리즘으로, 평문을 키와 배타적 논리합(XOR) 연산을 수행하여 암호문 생성.

비대칭키 암호 (=공개키 암호)

암호화와 복호화에 다른 암호 키를 쓰는 알고리즘으로, 전자서명에 사용됨 (ex. RSA, 타원곡선암호)

공개키 : 평문을 암호문으로 만드는 키로, 누구나 암호화 가능
비밀키(개인키) : 암호문을 복호화하는 키로, 키를 알고 있는 사람만 복호화 가능

일방향 함수 : 계산은 쉾지만 역을 구하는 것은 어려운 함수로, 대부분의 비대칭키 암호화 방식은 이것으로부터 구안
RSA 알고리즘 : 두 개의 큰 소수를 곱한 합성수는 소인수분해가 어렵다는 것을 기반으로 만들어진 암호 알고리즘

해시

데이터를 고정된 길이의 데이터로 매핑하는 함수로, N:1 일방향 함수 (ex. CRC, MD5, SHA1)

key : 매핑 전 데이터의 값(평문)
해시 값 Hash Value : 매핑 후 데이터의 값(암호문)
해시 테이블 Hash Table : 키와 데이터를 저장하는 자료구조
해싱 Hashing : 매핑하는 과정

해시 충돌 : 서로 다른 두 개의 입력값에 대해 동일한 해시 값을 출력하는 상황. 해시 충돌이 발생하지 않을수록 좋은 해시 함수.
눈사태 효과 : 입력 값의 일부만 변경되어도 해시 값이 매우 크게 변함

사용 예시 : 무결성 검증, 비밀번호 저장

스테가노그래피

데이터 은폐 기술 중 하나로, 데이터를 다른 데이터에 삽입해 그 데이터의 존재 자체를 숨기는 것. 오늘날 디지털 스테가노그래피는 이미지, 오디오 파일, 동영상 클립, 텍스트 파일 등 무해해 보이는 객체 안에 비밀 메시지를 감춰두는 방식으로 활용됨.

2, 네트워크 해킹

네트워크 해킹 개요

네트워크 해킹 : 네트워크 상에서 발생되는 해킹을 의미
보안의 기본 요소에 따라 기밀성, 무결성, 가용성의 침해를 받음

(기밀성) 스니핑 sniffing : 네트워크 흐름의 중간에서 도청, 감시 등의 공격을 하는 행위
(무결성) 스푸핑 Spoofing : 사용자가 원하는 행위를 속여 비정상적인 행동을 하는 행위
(가용성) Dos 공격 : 서비스 거부 공격을 수행하여 서버나 시스템이 동작하지 못하도록 공격하는 행위

네트워크 용어 정리

시스템

  • 노드 : 인터넷에 연결된 시스템의 가장 기본적인 용어
  • 호스트 ; 컴퓨팅 기능이 있는 시스템. 양 끝단에 있는 송수신기를 뜻 (ex. PC)
  • 클라이언트 : 서비스를 요청하는 시스템 (호스트가 송신을 할 때)
  • 서버 : 서비스를 제공하는 시스템 (호스트가 수신을 할 때)

프로토콜 : 컴퓨터 간에 정보를 주고받을 때의 통신 방법에 대한 규칙이나 표준

게이트웨이 : 한 네트워크에서 다른 네트워크로 이동하기 위하여 거쳐야 하는 지점

  • 1계층 리피터(repeater)
  • 2계층 브리지(bridge)
  • 3계층 라우터(router)

프로토콜

기본 요소

  • 구문 Syntax : 전송하고자 하는 데이터의 형식(Format), 부호화(Coding), 신호 레벨(Signal Level) 등을 규정
  • 의미 Semantics : 두 기기 간의 효율적이고 정확한 정보 전송을 위한 협조 사항과 오류 관리를 위한 제어 정보를 규정
  • 시간 Timing : 두 기기 간의 통신 속도, 메시지의 순서 제어 등을 규정

OSI 7계층 (OSI 7 Layer)

국제 표준화기구 ISO에서 1984년에 네트워크 통신의 구조를 7계층으로 구분하여 각 계층 간 상호 작동하는 방식을 정의해놓은 것

송신자 측 : 원본 데이터를 상위 계층 → 하위 계층으로 전달하며 각 계층마다 헤더 추가

수신자 측 : 전달받은 데이터를 하위 계층 → 상위 계층으로 전달하며 원본 데이터 전달 받음

 

1계층 - 물리 계층 : 최하층 계층. 2진법의 바이너리 정보를 전기적, 물리적 신호로 수신자에게 정보 전달 (전송 단위 : Bit)

2계층 - 데이터 링크 계층 : 물리 계층에서 일어날 수 있는 오류들을 찾아내고 수정하여 하위 계층으로 데이터 전달 (전송 단위 : Frame)

3계층 -네트워크 계층 : 양 끝단의 사용자들의 IP를 확인하여 최적의 정보 전달이 가능한 루트를 찾는 라우팅을 진행 (전송 단위 : Packet)

4계층 -전송 계층 : 양 끝단의 사용자들이 신뢰성 있는 데이터를 주고받기 위해 프로토콜 정의, 하위 계층으로 데이터 전달 (전송 단위 : Segment)

5계층 -세션 계층 : 양 끝단의 사용자들의 통신을 관리하기 위한 방법을 정의하고 하위 계층으로 데이터 전달

6계층 -표현 계층 : 원본 데이터를 부호화, 변화, 암호화, 복호화, 압축 등을 진행하여 하위 계층으로 데이터 전달

7계층 -응용 계층 : 응용 소프트웨어에서 데이터를 생성하고 하위 계층으로 데이터 전달

 

패킷

네트워크에서 출발지와 목적지 간에 라우팅 되는 데이터 단위

네트워크 패킷은 사용자 데이터와 제어정보로 이루어지며, 사용자 데이터는 페이로드라고 함 (제어정보 : 페이로드를 전달하기 위한 정보)

 

구성요소

  • 헤더 : 소스 주소, 대상 주소, 프로토콜 및 패킷 번호 포함. 전송 중인 패킷 유형을 식별하는 데 도움이 됨.
  • 페이로드 : 패킷에 의해 전송되는 실제 데이털르 나타낸 것, 데이터라고도 함. 헤더 정보가 목적지에 도달할 때 제거됨.
  • 트레일러 : 패킷 트레일러의 내용은 각 네트워크 유형에 따라 다름. 비트와 CRC 포함.

Wireshark

네트워크 패킷을 캡쳐하고 분석하는 오픈 소스 패킷 분석 프로그램

강력하고 쉬운 사용법 때문에 해킹 뿐만 아니라 보안 취약점 분석, 보안 컨설팅, 개인정보 영향평가 등 여러 분야에서 폭넓게 사용됨 

728x90

문제 코드를 살펴보면 scanf("%s",A)에서 입력된 문자열을 변수 'A'에 저장하는데, 이때 길이에 대한 제한이 없다. 따라서 지정된 문자열 길이인 8을 넘기게 되면 변수 'B'의 메모리 영역에 덮어써지게 된다. 

이제 어셈블리 코드를 살펴보자.


   <+0>:     endbr64

 

// int main()

   <+4>:     push   rbp
   <+5>:     mov    rbp,rsp
   <+8>:     sub    rsp,0x20

 

//canary 저장
   <+12>:    mov    rax,QWORD PTR fs:0x28
   <+21>:    mov    QWORD PTR [rbp-0x8],rax

 

// eax 0으로 초기화
   <+25>:    xor    eax,eax

 

// 지역 변수 'A'  초기화, 입력을 받아 'A'에 저장
   <+27>:    mov    QWORD PTR [rbp-0x10],0x0
   <+35>:    lea    rax,[rbp-0x18]
   <+39>:    mov    rsi,rax
   <+42>:    lea    rdi,[rip+0xe0e]        # 0x2008
   <+49>:    mov    eax,0x0
   <+54>:    call   0x10d0 <__isoc99_scanf@plt> // scanf 함수 호출

 

// 입력 받은 값 출력
   <+59>:    lea    rax,[rbp-0x10]
   <+63>:    mov    rsi,rax
  <+66>:    lea    rdi,[rip+0xdf9]        # 0x200b
  <+73>:    mov    eax,0x0
  <+78>:    call   0x10b0 <printf@plt>

 

// strcmp를 통해 A와 "I.Sly"를 비교
  <+83>:    lea    rax,[rbp-0x10]
   <+87>:    lea    rsi,[rip+0xdf0]        # 0x2017
   <+94>:    mov    rdi,rax
   <+97>:    call   0x10c0 <strcmp@plt>

 

// 비교 결과에 따라 분기
   <+102>:   test   eax,eax
   <+104>:   jne    0x124d <main+132>

 

// 문자열이 "I.Sly"인 경우 "Good!" 메시지와 플래그 문자열을 출력
   <+106>:   lea    rdi,[rip+0xde3]        # 0x201d
   <+113>:   call   0x1090 <puts@plt>

   <+118>:   lea    rdi,[rip+0xde2]        # 0x2028
   <+125>:   call   0x1090 <puts@plt>

 

// 문자열이 "I.Sly"가 아닌 경우 다음 단계로 분기
   <+130>:   jmp    0x1264 <main+155>

 

// 입력 값이 비어 있지 않은 경우 "You're doing it right!" 메시지를 출력
   <+132>:   movzx  eax,BYTE PTR [rbp-0x10]
   <+136>:   movzx  eax,al
   <+139>:   test   eax,eax
  <+141>:   je     0x1264 <main+155>
   <+143>:   lea    rdi,[rip+0xdfb]        # 0x205a
   <+150>:   call   0x1090 <puts@plt>

 

// 함수가 정상적으로 종료되는지 확인하고 스택 프레임을 정리, 스택 보호 검사 후 함수에서 반환
   <+155>:   mov    eax,0x0
   <+160>:   mov    rdx,QWORD PTR [rbp-0x8]
   <+164>:   xor    rdx,QWORD PTR fs:0x28
  <+173>:   je     0x127d <main+180>
   <+175>:   call   0x10a0 <__stack_chk_fail@plt>
   <+180>:   leave
   <+181>:   ret

 

스택 프레임 구조를 그려보면 위와 같다. 

문자열 길이인 8을 넘기게 되면 B에 데이터가 덮어써진다는 점을 이용하여 I.Sly 앞에 A 8개을 붙여 입력해주었다. [check] 뒤에 출력된 결과를 보아 변수 B에 I.Sly가 저장된 것을 확인할 수 있다. 필요한 조건을 충족하여 flag가 출력된 것을 볼 수 있다. 

728x90

1. Pwnable

Pwnable(시스템 해킹)

  • 운영체제 또는 프로그램 취약점을 찾아 공격하고, 관리자의 권한 등을 얻어 시스템을 장악하거나 의도치 않은 행동을 하게 하는 것
  • 컴퓨터 프로그램의 행위를 조작하여 공격자가 원하는 행동을 실행하도록 하는 공격
  • 궁극적으로 관리자 권한 탈취가 공격의 목표

취약점 종류

  • Memory Corruption : Buffer Overflow, Out-Of-Boundary, Off-by-one, Format String Bug, Double Free/User-After-Free
  • Logical Bug : Command Injection, Race Condition, Path Traversal(경로 탐색)

해킹 과정

  • 취약점 발견 -> 공격 시나리오 작성 -> 필요 정보 수집 및 공격 -> 권한 탈취

Pwntools

  • 리눅스 환경에서 Exploit(공격)을 보다 편리하게 할 수 있게 여러가지 함수와 기능을 제공하는 파이썬 라이브러리
  • 주요 함수
    • remote, process, ssh : 통신할 때 사용
    • send, sendline, sendafter, sendlineafter : 데이터 송신
    • recv, recvline, recvuntill: 데이터 수신
    • p32 : 32비트 리틀 엔디안으로 패킹

Shellcode

  • 시스템의 특징 명령(shell)을 실행하는 작은 사이즈의 프로그램
  • 기계어로 작성되며, 메모리에 올리면 바로 실행됨
  • 주로 BOF, FSB 공격에 사용

2. Buffer Overflow

Buffer Overflow(=Buffer Overrun)

  • 메모리를 다루는 데에 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점
  • 지정된 버퍼를 벗어난 데이터를 다른 데이터로 덮어쓸 수 있음
  • Buffer : 지정된 크기의 메모리 공간
  • Stack Buffer Overflow : 스택에 위치한 버퍼에 할당된 것보다 많은 데이터를 쓸 때 발생, 함수의 return 주소를 조작하는 것이 일반적
  • Heap Buffer Overflow : 동적 메모리 할당 연결을 덮어써 프로그램의 함수 포인터 조작, 포인터가 가리키는 값을 조작하여 임의의 파일 또는 코드에 접근

3. Stack Frame

Stack Frame 레지스터 : 스택 오버플로우와 관련된 x86(32bit) 레지스터

  • 범용 레지스터 : EAX, EBX, ECX, EDX
  • 스택 포인터 레지스터 : 실제 메모리상의 주소를 참조할 때 SS(Stack Segmaent) 레지스터와 함께 사용
    • ESP : 현재 스택 영역에서 가장 하위 주소를 저장
    • EBP : 스택 세그먼트에서 현재 호출되어 사용되는 함수의 시작 주소 값 지정
  • 명령어 포인터 레지스터 : EIP 또는 PC, 유효주소를 계산하는데 필요한 주소 저장
  • 상태 레지스터 : EFLAGS, x86 프로레서의 상태를 저장하기 위해 사용
  • 세그먼트 레지스터 : 각 세그먼트의 위치를 가리킴, 물리 주소 변환에 사용
    • 코드 세그먼트 (CS) : 실행 가능한 명령어 코드가 존재하는 세그먼트의 시작 주소
    • 스택 세그먼트 (SS) : 스택이 존재하는 세그먼트의 시작 주소
    • 데이터 세그먼트 (DS) : 사용되는 데이터가 존재하는 세그먼트의 시작 주소
    • ES, FS, GS : 추가 세그먼트의 시작주소로, FS는 통상 스레드 관리용도로 사용

Stack Frame

  • 스택의 데이터 : 높은 주소에서 낮은 주소로
  • 데이터 작성 : 낮은 주소에서 높은 주소로
  • Buffer Overflow : 프로세스가 데이터를 버퍼에 저장할 때 프로그래머가 지정한 곳 바깥에 저장하는 것

728x90

int_reversing

  • pwndbg

    pwndbg를 실행하고 info func명령을 통해서 함수 목록을 확인했다.

    disassemble main 명령을 통해서 main 함수의 어셈블리 코드를 확인했다.

코드를 살펴보면

  1. <+78>cmp DWORD PTR [rbp-0xc],eax : eax 값과 rbp-0xc 값을 비교합니다.
  2. <+65>mov eax, 0x0, <+70>call 0x10b0 <__isoc99_scanf@plt> : 해당 부분에서 scanf 함수를 호출하고 eax가 인자로 사용된 것을 보아 우리가 찾는 값이 rbp-0xc 에 저장되어 있는 것을 알 수 있다.
  3. <+27> mov QWORD PTR [rbp-0xc], 0x146 : 이 부분에서 우리가 찾는 값이 0x146인 것을 확인할 수 있다. 0x146은 10진수로 326이다.

 

  • IDA

    IDA에서 int_reversing 파일을 실행시키고 F5 단축키를 통해 decomplie을 해준다.

    그러면 위와 같이 원본 코드를 알 수 있다. 찾는 정수가 326인 것을 알 수 있다.

    파일을 실행해서 확인해보면 맞는 것을 확인할 수 있다.

 

string_reversing

  • pwndbg


pwndbg를 실행하고 info func 명령을 통해서 함수 목록을 확인했다.


disassemble main 명령을 통해서 main 함수의 어셈블리 코드를 확인했다.

코드를 살펴보면

  1. <+117>call 0x10c0 <strcmp@plt> : 이 부분에서 rsi와 rdi 값을 비교하는 것을 알 수 있다. 그 값은 각각 rbp-0x40과 rbp-0x20에서 불러져 온 것을 확인했다.
  2. scanf 가 호출되어 있는 부분에서 사용된 인자를 확인해보면 rbp-0x20이다. 해당 값은 사용자 입력값인 것을 알 수 있고, 이제 찾는 값은 rbp-0x40에 저장된 것을 알 수 있다.
  3. <+47> 줄을 보면 rax 값이 rbp-0x40에 전달된 것을 알수 있고, 그 위에 rax와 rbx 찾는 값이 저장된 것을 볼 수 있다.


찾은 값을 hex을 char으로 변환해보았다. 순서가 이상한것을 확인하고 little endian으로 정렬됐다는 것을 알 수 있었다.


이것을 다시 정렬해보면 우리가 찾는 문자열이 "Hacked_By_ISly” 인 것을 알 수 있다.


파일을 실행하여 해당 문자열을 입력하면 맞는 것을 확인할 수 있다.

 

  • IDA

    IDA에서 string_reversing 파일을 실행시키고 F5 단축키를 통해 decomplie을 해준다.

    그러면 위와 같이 원본 코드를 알 수 있다. 찾는 문자열이 "Hacked_By_ISly”인 것을 알 수 있다.
728x90

1. Reversing

Reversing : 물건이나 기계장치 혹은 시스템 등의 구조, 기능, 동작 등을 분석하여 그 원리를 이해하며 단점을 보완하고 새로운 아이디어를 추가하는 작업

정적 분석 방법 (Static Analysis) : 파일을 실행하지 않고 겉모습을 관찰하여 분석하는 방법
동적 분석 방법 (Dynamic Analysis) : 파일을 직접 실행시켜 분석하고 디버깅 통해 코드 흐름과 메모리 상태 등을 자세히 살펴보는 방법

2. ASCII

ASCII : 미국 국립 표준 협회(ANSI)에서 표준화한 정보교환용 7비트 부호체계

파이썬 아스키코드 변환

  • ord() : 문자 -> 아스키코드 값
  • chr() : 아스키코드 값 -> 문자

3. Byte Order

엔디안 (Endianness) : 1차원 공간에 여러 개의 연속된 대상을 배열하는 방법

빅 엔디안(Big-endian) : 최상위 바이트(MSB)부터 차례로 저장
리틀 엔디안(Little-endian) : 최하위 바이트(LSB)부터 차례로 저장

예시 빅 엔디안 리틀 엔디안
0x12345678 0x12 / 0x34 / 0x56 / 0x78 0x78 / 0x56 / 0x34 / 0x12

4. Memory Structure

Memory : 프로그램의 실행을 위해 컴퓨터의 운영체제에서 할당하는 공간

  • RAM (주기억장치, 메모리) : 사용 중인 프로그램이나 데이터가 저장되는 휘발성 메모리
  • ROM : 시스템 소프트웨어를 기억하는 비휘발성 메모리

메모리 공간 분류

(1) Stack 영역

  • 함수 호출과 함께 할당, 호출 완료시 소멸, 지역변수와 매개변수 저장
  • 스택 프레임 : 스택 영역에 저장되는 함수 호출 정보
  • Push (데이터 저장), Pop (데이터 인출)
  • 동작방식 : 후입선출(LIFO)

(2) heap 영역

  • 실행중에 동적으로 할당
  • 스택 세그먼트와 반대 방향으로 자람(충돌 방지)

(3) data 영역

  • 프로그램의 전역변수와 정적변수가 저장되는 영역
  • 프로그램 시작과 함께 할당, 종료 시 소멸

(4) code 영역 = text 영역

  • 실행할 프로그램의 코드가 저장되는 영역
  • CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리

5. Instruction Cycle

Instruction Cycle : 기계 코드가 실행되는 한 번의 과정

  1. Fecth : 다음 실행할 명령어를 읽어옴
  2. Decode : 읽어온 명령어 해석
  3. Execute : 해석한 명령어 실행

1,2,3의 과정을 반복

6. Computer Structure

CPU(중앙처리장치) : 프로그램을 실행하고 입력된 데이터를 처리
Memory(주기억장치) : 실행 중인 프로그램(=프로세스)와 프로그램 실행에 필요한 데이터를 일시적으로 저장
Disk(보조기억장치) : 프로그램과 데이터를 영구적으로 저장
프로그램 : 컴퓨터를 실행시키기 위해 차례대로 작성된 명령어 모음
프로세스 : 정적 프로그램이 메모리에 올라와서 실행 가능해진 상태

 

레지스터 : CPU에서 명령어를 실행하는 동안 필요한 정보를 저장하는 기억 장소, 중앙처리장치 종류에 따라 개수와 크기가 다름
목적에 따른 레지스터 분류

  • 범용 레지스터(General Register): 주 용도는 있으나, 그 외의 용도로도 자유롭게 사용할 수 있는 레지스터. x64에는 rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp, r8-r15가 있다.
  • 세그먼트 레지스터(Segment Register): 과거에는 메모리 세그먼테이션이나, 가용 메모리 공간의 확장을 위해 사용했으나, 현재는 주로 메모리 보호를 위해 사용되는 레지스터이다. x64에는 cs, ss, ds, es, fs, gs가 있다.
  • 플래그 레지스터(Flag Register): CPU의 상태를 저장하는 레지스터
  • 명령어 포인터 레지스터(Instruction Pointer Register, IP): CPU가 실행해야할 코드를 가리키는 레지스터. x64에서는 rip가 있다.

7. Assembly Language

  Intel AT&T
레지스트리 표현 eax %eax
상수 표현 h(16진수), b(2진수), o(6진수) ex)80h $숫자 ex) $0x80
operands 위치 <instr><dest><src> <instr><scr><dest>
메모리 주소 참조 [eax] (%eax)
레지스터+offset 위치 [eax+숫자] 숫자(%eax)

 

Intel Syntax : <명령어> <피연산자1><피연산자2> ;주석

ex) mov eax, 5

  • 데이터 이동 : mov, lea
  • 스택 조작 : push, pop
  • 연산 : inc, dec, add, sub
  • 흐름 제어 : jmp, cmp, je, jne
  • 프로시저 : call, ret

8. How to Reverse Engineering?

Debugger : 디버거 툴은 Breakpoint(중단점)을 잡고, 그때의 레지스터 값을 관찰하며 소프트웨어를 분석하는데 사용

  • OllyDbg(Win GUI, x86) 
  • gdb, pwndbg(Linux CLI)

x/print 명령어 : 프로그램 실행 시 메모리를 검사할 때 사용

-  형식 : (gdb) x/옵션 기준점 (기준점 : 메모리 주소 or 레지스터) 

728x90

1. OWASP TOP 10

OWASP TOP 10 : OWASP에서 발표하는 가장 중요한 웹 애플리케이션 보안 위협 목록

OWASP TOP 10 (2024)

  1. 부적절한 자격 증명 사용(Improper Credential Usage)
  2. 불충분한 공급망 보안(Inadequate Supply Chain Security)
  3. 보안에 취약한 인증 및 권한 부여(Insecure Authentication/Authorization)
  4. 부족한 입력/출력 검증(Insufficient Input/Output Validation)
  5. 안전하지 않은 통신(Insecure Communication)
  6. 불충분한 개인 정보 보호 제어(Inadequate Privacy Controls)
  7. 부족한 바이너리 보호(Insufficient Binary Protections)
  8. 잘못된 보안 구성(Security Misconfiguration)
  9. 안전하지 않은 데이터 저장소(Insecure Data Storage)
  10. 불충분한 암호화(Insufficient Cryptography)

2. SQL Injection

SQL Injection

악의적인 사용자가 웹 응용 프로그램의 입력 매개 변수를 통해 SQL 쿼리를 삽입하여 데이터베이스 시스템을 공격하는 기술

SQL 문법

  • 데이터 정의 언어 (DDL) : CREATE, ALTER,DROP
  • 데이터 조작어 (DML) : DB에 있는 데이터를 검색, 삽입, 수정, 삭제하는 데 사용 (=쿼리)
    • SELECT : 데이터 조회
    • INSERT : 데이터 삽입
    • UPDATE : 데이터 수정
    • DELETE : 데이터 삭제
  • 데이터 제어 언어 (DCL) : GRANT,REVOKE
  • 트랜잭션 제어 언어 (TCL) : COMMIT,ROLLBACK

논리연산

SQL문의 WHERE 절을 항상 참으로 만드는 공격을 수행하는데 이용
기본적으로 논리 연산이 여러 개가 나열되면 NOT-AND-OR 순서로 계산

SQL Injection 종류

  • Error based SQL Injection : 논리적 에러를 이용하는 공격. 논리 연산을 이용하는 것이 일반적이며 인증 우회가 목적.
  • UNION based SQL Injection : 여러 SQL문을 합쳐 실행할 수 있는 UNION을 이용하는 공격. 데이터 노출이 목적.
  • Blind SQL Injection : 데이터베이스 메시지가 공격자에게 보이지 않는 경우에 사용하는 공격. 데이터베이스 서버의 응답을 통해 데이터베이스에 대한 정보를 추측.
  • Boolean based SQL Injection : 쿼리가 참일 때와 거짓일 때의 서버 반응으로 데이터를 얻어내는 공격.
  • Time based SQL Injection : 쿼리의 참과 거짓을 판별할 수 없는 경우 사용하는 공격. 시간 지연시키는 쿼리를 주입하여 응답 시간 차로 참과 거짓 여부 판별.

방어 방법

  • 입력값 검증 : /,-,'," 등의 의도하지 않은 입력을 검증
  • Prepared statement 사용 : 쿼리를 사전에 컴파일하고 입력 변수 값만 삽입하는 방법. 사용자 입력이 매개변수로 전달되므로, 입력 값이 직접 SQL 쿼리에 삽입되지 않음.

3. File Upload Vulnerability

File Upload Vulnerability

파일 업로드 취약점 : 악성 스크립트를 업로드하여 원격 코드를 실행할 수 있는 취약점

공격 목적

  1. 웹 서버를 통해 DB 정보 획득 : DB에 직접 접근할 수 없기 때문에 서버에 먼저 접근
  2. 근접 네트워크 침투 : 내부 포탈 서버, 로그 서버 등 내부 시스템을 대상으로 포트포워딩, 터널링 기법 등을 통해 네트워크에 침투

공격 원리

  1. 확장자 제한 및 파일 접근/실행 권한이 있는지 확인
  2. 파일 접근/실행이 가능하고 확장자 제한만 있는 취약한 웹 사이트의 경우 Proxy 툴을 이용한 파일 타입 변조하거나 Null 이용하여 확장자를 숨김

방어 방법

  • 시큐어 코딩을 통한 확장자 검증
  • 화이트리스트(허용 리스트) 허용으로 확장자 검증
  • 시스템 보안 레벨 상승
  • 서버를 분리해 관리하거나, 실행 권한 삭제
  • 지속적인 모니터링

4. XXS

XSS(Cross Site Scripting)

클라이언트 사이드 취약점. 특정 계정의 세션 정보를 탈취하고 해당 계정으로 임의의 기능 수행 가능.
공격자는 웹 리소스에 악성 스크립트를 삽입하여 이용자 웹 브라우저에서 해당 스크립트 실행 가능.

Java Script

웹 문서의 동작을 정의.
웹 브라우저의 저장된 세션 및 쿠키를 JS로 이용자와의 상호 작용 없이 조회하거나 변경할 수 있음.
다양한 동작을 정의할 수 있기 때문에 XSS 공격에 주로 사용.

XSS 종류

  • Stored XSS : 악성 스크립트가 서버에 저장되고 서버의 응답에 담겨오는 XSS. 서버의 데이터베이스 또는 파일 등의 형태로 저장된 악성 스크립트를 조회할 때 발생.
  • Reflected XSS : XSS에 사용되는 악성 스크립트가 URL에 삽입되고 서버의 응답에 담겨오는 XSS. 서버가 악성 스크립트가 담긴 요청을 출력할 때 발생.
  • DOM 기반 XSS : XSS에 사용되는 악성 스크립트가 URL Fragment에 삽입되는 XSS

방어 기법

  • 입력 값 제한
  • 입력 값 치환 : 태그 문자(<,>) 등 위험한 문자 입력 시 문자 참조로 필터링하고, 서버에서 브라우저로 전송 시 문자 인코딩
  • 스크립트 영역에 출력 자제

5. CSRF

CSRF (Cross-Site Request Forgery)

사이트 간 요청 위조. 공격자가 공격 대상 브라우저에 다른 웹 사이트로 HTTP 요청을 보내 서버에 대한 공격을 함.
취약한 웹 사이트에서 이미 인증을 완료한 공격 대상이 전혀 인지하지 못한 상황에서 요청을 보냄
웹 사이트에서 요청을 인증하는 절차상의 약점을 악용하여 서버 측 정보를 수정하고 사용자 계정을 장악함.

HTTP Request Method

  • GET method : 클라이언트에서 서버로 어떠한 리소스로부터 정보를 요청하기 위해 사용되는 메소드. 대표적으로 URL에 Parameter를 붙여 전송.
  • POST method : 리소스를 생성/업데이트하기 위해 서버에 데이터를 보내는데 사용되는 메소드. GET과 달리 전송할 데이터를 HTTP 메시지 body 부분에 담아서 서버로 전송.

공격기법

  • GET 요청 기반 CSRF 공격 : 공격자가 악의적인 링크에 접속하도록 유도하는 것
  • POST 요청 기반 CSRF 공격 : 공격자가 피해자의 브라우저를 통해 악의적인 폼을 자동으로 제출하도록 하는 것
  • 히든 폼 기법 : 악의적인 웹 페이지에 웹 애플리케이션에 대한 요청을 생성하는 히든 폼을 포함하는 것

방어 기법

  • CSRF 토큰
  • CORS(Cross-Origin Request Sharing) 사용
  • HTTP 요청과 함께 제출된 Origin이나, Referer 헤더의 값을 확인하고 예측값이 포함되어 있지 확인
728x90

Sever-Client

웹 서버에 있는 리소스를 클라이언트가 받아 보려면, 클라이언트는 웹에게 특정 리소스를 지정하여 제공해달라고 요청해야 함. 이때, 서버는 해당 요청을 이해하고 대응되는 동작을 통해 클라이언트에게 리소스 반환함.

Cookie

  • 클라이언트의 정보 기록과 상태 정보를 표현하는 용도로 사용
    • 정보 기록 : 웹 서버는 각 클라이언트의 팝업 옵션을 기억하기 위해 사용
    • 상태 정보 : 웹 서버는 클라이언트를 식별할 수 있는 값을 저장하여 사용
  • HTTP
    • 하나의 Request와 Response의 쌍이 독립적으로 구성되어 통신
      • connectionless 속성 : 하나의 요청에 하나의 응답을 한 후 네트워크 연결을 끝맺는 것
      • stateless 속성 : 네트워크가 연결이 끝맺을 때 상태를 유지하지 않는 것
    • 위와 같은 속성 때문에 HTTP 요청마다 사용자 인증을 해야되는데, 상태를 유지하기 위해서 cookie가 탄생함
  • Cookie 가 있는 통신
    • 클라이언트는 서버에 요청을 보낼 때마다 쿠키를 포함하고, 서버는 해당 쿠키를 통해 클라이언트를 식별함
    • 하지만, 서버가 별다른 검증 없이 쿠키를 통해 이용자의 인증 정보를 식별한다면 쿠키 변조를 통해 공격자가 타 이용자를 사칭해 정보 탈취가 가능함.

Session

  • 세션은 일정 기간동안 같은 사용자(클라이언트)로부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술
  • 쿠키에 인증 상태를 저장하지만, 클라이언트가 인증 정보를 변조할 수 없도록 하기 위해 사용
  • 인증 정보를 서버에 저장하고 해당 데이터에 접근할 수 있는 키 (랜덤 문자)를 만들어 클라이언트에 전달하는 방식
    • 브라우저 -> 해당 키를 쿠키에 저장하고 이후 HTTP 요청을 보냄
    • 서버 -> 요청에 포함된 키에 해당하는 데이터를 가져와 인증 상태를 확인

개발자 도구 (F12)

  • 요소 검사 버튼 : 웹 페이지의 각 요소에 마우스를 갖다대고 클릭하면 해당 코드를 쉽게 찾을 수 있음
  • 디바이스 툴바 버튼 : 현재 브라우저의 화면 비율 및 User-Agent를 원하는 값으로 변경 가능
  • Elements : 페이지를 구성하는 HTML 검사
  • Console : 자바 스크립트를 실행하고 결과 확인
  • Sources : HTML, CSS, JS 등 페이지를 구성하는 리소스 확인 및 디버깅
  • Network : 서버와 오가는 데이터 확인
  • Application : 쿠키를 포함한 웹 어플리케이션과 관련된 데이터 확인

URI(URL)

  • URI (Uniform Resource Identifier)
    : 인터넷에서 특정 리소스를 나타내는 유일한 주소. URL(Uniform Resource Locator)과 URN(Uniform Resource Name)의 두 가지 형태로 나뉨.
  • URL (Uniform Resource Locator)
    : 인터넷 상의 특정 리소스의 위치를 지정하는 URI의 하위 집합. 일반적으로 프로토콜(예: HTTP, HTTPS), 호스트(웹 사이트의 도메인 이름), 리소스의 경로 및 파일 이름 등의 구성 요소로 구성. 
    ex) "https://www.example.com/page.html" ->  HTTPS 프로토콜을 사용하여 "www.example.com" 호스트에 위치한 "page.html"이라는 파일

포트

  • 호스트 내에서 실행되고 있는 프로세스를 구분짓기 위한 16비트의 논리적 할당
  • 0~65536개의 개수 가짐
  • IP주소는 컴퓨터를 찾을 때 필요한 주소, 포트는 컴퓨터 안에서 프로그램을 찾을 때 사용
  • 포트 번호
    • 0번 ~ 1023번 : well-known port (ex. 80 : HTTP / 443 : HTTPS)
    • 1024번 ~ 49151번 : registered port
    • 49152번 ~ 65535번 : dynamic port (동적 포트)

PHP

  • Hypertext Preprocessor : C언어를 기반으로 만들어진 서버 측에서 실행되는 서버 사이드 스크립트 언어

Burp Suite

  • 웹 응용 프로그램의 보안 테스트 도구
  • 웹 애플리케이션, 모바일 서비스 등을 대상으로 요청에 대한 클라이언트를 대신하여 중간에 만날 수 있는 모든 환경 작업을 수행하기 위한 프록시 서버 기능을 가짐
728x90

Level 0

  •  SSH(Secure Shell) : 원격지 호스트 컴퓨터에 접속하기 위해 사용되는 인터넷 프로토콜
  •  접속 명령어 
ssh [USER]@[HOSTNAME] -p [PORT]

명령어와 문제에 나온 패스워드를 입력하여 서버에 접속했다.


Level 0 → Level 1

readme 파일 안에 패스워드가 있다.

  • ls : 현재 디렉토리의 내용 나열
  • cd : 디렉토리 변경
  • cat : 파일 내용 표시
  • file : 파일의 유형 확인
  • du : 디스크 사용량 보고
  • find :  파일 및 디렉토리 검색

홈 디렉토리 안에 readme 파일이 있고, 해당 파일을 열어 패스워드를 확인할 수 있다.


Level 1 → Level 2

'-'라는 이름을 가진 파일 안에 패스워드가 있다. 

`cat -`으로 입력하면 옵션으로 인식되기 때문에 `-`로 시작하는 이름을 가진 파일은 단순하게 cat만 사용하여 열 수 없다.

`cat < -`(리다이렉션) 또는 `cat ./-` (파일경로입력) 와 같은 방식으로 열 수 있다.


Level 2 → Level 3

'spaces in this filename' 파일 안에 패스워드가 있다.

명령줄 인터프리터는 각 공백을 인수 구분자로 인식하기 때문에 공백이 포함된 파일명은 따옴표 `' '` 안에 입력하거나 공백 앞에 `\`을 입력해야 올바르게 인식된다.


Level 3 → Level 4

inhere 디렉토리의 숨겨진 파일 안에 패스워드가 있다.

`-a` 옵션을 이용하여 숨겨진 파일과 디렉토리를 모두 표시하면, 숨겨진 '.hidden' 파일을 확인할 수 있다.

숨겨진 파일과 디렉토리는 이름이 `.`으로 시작한다.


Level 4 → Level 5

inhere 디렉토리에서 사람이 읽을 수 있는 파일에 패스워드가 있다.

inhere 디렉토리에 있는 모든 파일 (`*`)의 정보를 `file` 명령어를 이용해서 확인해보면 '-file07'이 아스키코드로 되어 있다는 걸 확인할 수 있다. 


Level 5 → Level 6

inhere 디렉토리 안 '사람이 읽을 수 있고, 크기가 1033 바이트에, 실행이 불가능한' 파일 안에 패스워드가 있다.

`find` 명령어의 `size` 옵션을 사용하여 1033바이트의 크기를 가진 파일이 './maybehere07/.file2' 하나인 것을 확인할 수 있다. 

`file` 명령어를 통해 해당 파일의 정보를 확인해보면 아스키코드로 되어있어 사람이 읽을 수 있다는 조건을 만족한다.

`ls -l` 명령어를 통해 해당 파일의 파일 권한을 확인해보면 '-rw-r-----'로 실행할 수 없다는 조건을 만족한다. 

따라서 './maybehere07/.file2' 파일이 모든 조건을 만족하고, 해당 파일을 읽어보면 패스워드를 확인할 수 있다. 

+ Recent posts