모빌리티보안

컴퓨터 과학

녕녕펀치 2024. 5. 17. 09:44

1. 진법

  • 임의의 숫자 혹은 문자를 사용하여 수를 표현하는 체계
  • n진법은 한 자리 수를 n가지(0~n-1)의 숫자 혹은 문자로 나타낼 수 있음
    • 10진법
      • 사람들이 자연스럽게 사용하고 있는 수 체계
    • 2진법
      • 컴퓨터는 2진법을 사용
      • 0과 1의 조합으로 이루어진 비트가 모여서 데이터를 표현
      • 2진수를 표현할 때는 보통 0b라는 접두어를 붙임
      • ex) 10진수 14 → 2진수 0b1110
    • 16진법
      • 2진수를진 좀 더 간편하고 효율적으로 표현하기 위해 쓰인 진법 중 하나
      • ex) 2진수 0b1100 → 16진수 0xC
      • 프로그램을 분석할 때 사용하는 디버깅 도구 같은 경우, 일반적으로 메모리의 위치를 나타내는 주소값을 16진수 형태로 출력
      • RGB 색상을 표현할 때도 16진수 형태로 표기

2. 비트와 바이트

  • 비트와 바이트는 컴퓨터의 데이터를 다루는 데 가장 기본이 되는 개념
  • 컴퓨터는 0과 1만으로 데이터를 표현하고 처리
  • 0과 1을 나타내는, 컴퓨터에서 사용하는 데이터의 최소 단위를 1비트라고 함
  • 8개의 비트로 구성된 더 큰 단위는 1바이트 → 메모리에 저장되는 최소 단위
  • 1바이트는 2의 8승 = 256 가지의 수를 표현할 수 있음
  • 10진수로 0~255, 2진수로 00000000~11111111, 16진수로 00~FF까지 나타냄

 

  • 최상위 비트(MSB)
    • 여러 개의 비트로 구성된 이진 데이터에서 가장 왼쪽에 있는 비트
    • 가장 왼쪽에 있는 비트가 숫자의 크기에 가장 큰 영향을 미침
  • 최하위 비트(LSB)
    • 여러개의 비트로 구성된 이진 데이터에서 가장 오른쪽에 있는 비트
    • 가장 오른쪽에 있는 비트는 숫자의 크기에 가장 작은 영향을 미침
  • 0b10010100( 10010100 )의 MSB는 1이고, LSB는 0

 

  • 부호 비트
    • 부호가 있는 데이터의 경우, MSB는 부호의 의미를 가지게 됨
    • MSB가 0이면 양수, 1이면 음수
    • 부호를 가지는 데이터는 Signed 데이터 또는 부호가 있는 데이터라고 함
    • 부호없이 양수만 나타내는 데이터는 unsigned 데이터 또는 부호가 없는 데이터라고 함

 

  • 바이트 오더링
    • 2바이트 이상의 데이터는 메모리에 연속적으로 저장됨
    • 이때 각 바이트가 메모리에 정렬되는 방식으 ㄹ바이트 오더링이라고 함
    • 바이트 오더링 방식
      • 빅 엔디안(Big Endian)
        • 큰 바이트부터 낮은 주소에 저장됨
      • 리틀 엔디안(Little Endian)
        • 작은 바이트부터 낮은 주소에 저장됨
    • 빅 엔디안, 리틀 엔디안을 설명할 때의 MSB, LSB는 앞서 배운대로 Significant Bit을 의미하는 것이 아니라 Significant Byte를 의미함
    • 바이트 오더링은 비트의 순서가 아니라 바이트의 순서를 고려하는 것으로, 바이트 내 비트의 순서는 동일하고 바이트의 순서만 달라짐.
      • 가장 왼쪽에 있는 바이트를 MSB
      • 가장 오른쪽에 있는 바이트를 LSB
  • 빅 엔디안
    • 가장 왼쪽에 있는(큰) 바이트부터 메모리의 낮은 주소에 저장됨
      • 네트워크 상에서 데이터를 전송할 때는 빅 엔디안 방식을 따름
      • 대표적으로 SPARC CPU에서 빅 엔디안을 사용함

Big Endian

  • 리틀 엔디안
    • 가장 오른쪽에 있는(작은) 바이트부터 메모리의 낮은 주소에 저장됨
      • 대표적으로 Intel의 x86, x86-64 CPU에서 리틀 엔디안을 사용
      • 대다수의 개인용 컴퓨터 및 서버 환경에서 x86-64 CPU 아키텍처를 사용하고 있는 만큼, 리틀 엔디안 방식을 잘 알고 있어야함

Little Endian

  • 바이트 오더링 예시
    • 메모리에 저장된 값을 이용해 역연산을 수행하여 어떤 정답이 되는 값을 찾아내는 작업은 매우 흔함
    • 이때 메모리에 저장된 값이 어떤 엔디안으로 저장되어 있는지를 고려하지 않으면, 전혀 다른 데이터로 혼동하여 올바른 역연산 결과를 얻을 수 없게 됨

바이트 오더링 예시

위 사진은 문자열과 16진수 정수를 메모리에 저장하는 C 프로그램의 소스 코드

 

  • 문자열
    • str 변수 주소의 메모리를 1바이트씩 4바이트 출력한 결과
    • 문자열을 메모리에 저장할 때는 바이트 오더링을 고려하지 않음
    • 따라서, 문자열 "ABCD"는 리틀 엔디안 방식을 따르지 않고, 문자 순서 그대로 메모리에 저장됨

  • 문자열이 아닌 데이터 - 16진수 정수
    • num 변수 주소의 메모리를 1바이트씩 4바이트 출력한 결과
    • 문자열이 아닌 데이터는 리틀 엔디안 방식으로 저장됨
    • 따라서 16진수 0x41424344는 가장 오른쪽의 바이트부터 메모리의 낮은 주소에 저장된 것을 볼 수 있음
    • num 변수 값을 출력하면 메모리에 저장된 4바이트에서 높은 주소부터 읽어 와서 원래 값 그대로 출력됨


3. 비트 연산

  • 비트 연산
    • 2진수로 표현하여 비트 단위로 연산하는 것을 비트 연산이라고 함
    • 비트 단위로 논리 연산을 수행하거나, 비트를 특정 값만큼 이동하는 시프트(shift) 연산을 수행함
  • 논리 연산
    • 참 또는 거짓 값으로 연산을 수행하고 결과로 참(1, true) 또는 거짓(0, false)을 반환함

  • 비트 연산자
    • 비트 단위로 논리 연산을 수행함
    • 1은 참, 0은 거짓을 나타냄

  • 비트 연산자 OR (|)
    • 대응하는 비트 중 하나라도 1이면 1이 됨
    • 둘 다 1이 아닌 경우에만 0이 됨

  • 비트 연산자 AND(&) 
    • 대응하는 비트가 모두 1이어야 1이 되며, 하나라도 1이 아니면 0이 됨

  • 비트 연산자 XOR(^)
    • 대응하는 비트가 서로 다르면 1이 됨
    • 서로 같으면 0이 됨

  • 비트 연산자 NOT(~)
    • 0은 1이 되고, 1은 0이 됨

  • 시프트 연산자
    • 비트를 특정 값만큼 왼쪽 혹은 오른쪽으로 이동함
    • n만큼 시프트한 결과는 2의 n승으로 곱하거나 나눈 값과 같음

왼쪽 시프트 연산
오른쪽 시프트 연산
산술 시프트
논리 시프트
논리 시프트

  • 비트 연산 활용
    • And (&) 연산 활용한 비트 마스킹
      • 비트 마스킹 : 어떤 데이터가 존재할 때, 특정 위치의 비트만 표시하거나 가리는 연산
      • 0XABCD에 0X00FF를 AND 연산을 하면 0XCD만 남길 수 있음

  • AND (&) 연산과 시프트 연산을 활용하여 특정 비트/바이트 가져오기
- 하위 1 바이트만 가져오기
0x12345678 & 0x000000FF = 0x00000078 (0000 0000 0000 0000 0000 0000 0111 1000)
- 상위 1 바이트만 가져오기
0x12345678 >>> 24 = 0x00000012 (0000 0000 0000 0000 0000 0000 0001 0010)
0x12345678 >> 24 & 0x000000FF = 0x00000012 (0000 0000 0000 0000 0000 0000 0001 0010)
- 상위에서 두 번째 바이트 가져오기
0x12345678 >> 16 & 0x000000FF = 0x00000034 (0000 0000 0000 0000 0000 0000 0011 0100)
- 하위 1 바이트의 상위 4비트 가져오기
0x12345678 >> 4 & 0x0000000F = 0x00000007 (0000 0000 0000 0000 0000 0000 0000 0111)
  • XOR 연산을 활용한 비교와 암호화
    • XOR 연산은 비트 값이 같으면 0 반환 → 자기 자신과 XOR 연산하면 결과는 0
    • 어떤 값을 2번 XOR 하면 원래의 값과 동일해짐
      • x^y 결과가 z 라고 하면, z^y = x^y^y = x
      • y를 key로 설정하면 간단한 암호화, 복호화 가능
  • 시프트 연산을 활용한 곱셈, 나눗셈
    • 2의 n승을 곱하거나 나눈 결과와 동일함
    • 시프트 연산을 사용하면 비트 레벨에서 연산을 하므로 더 효율적이고 속도가 빠름

4. 인코딩, 디코딩

  • 인코딩
    • 데이터를 특정한 형식으로 변환하는 것
    • 데이터의 크기를 줄이거나, 컴퓨터가 이해하기 쉽게 변환할 때 사용
  • 디코딩
    • 인코딩된 데이터를 원래의 값으로 되돌리는 것
  • 인코딩은 암호화와 유사하지만, 암호화는 데이터의 기밀성을 목적으로 비밀키가 있어야 원문을 복구할 수 있지만, 인코딩은 누구나 표준화된 방식을 사용해서 디코딩하여 원문을 구할 수 있음
  • 아스키 코드
    • 정보 교환을 위한 미국 표준 코드
  • 유니코드
    • 영어 뿐만 아니라, 전세계 모든 언어의 문자에 고유한 번호를 부여하는 국제 표준 코드
    • 유니코드 안에 아스키 코드가 포함된다고 볼 수 있음
  • URL 인코딩 (퍼센트 인코딩)
    • 웹 브라우저로부터 받은 URL 문자열을 유효한 형식으로 변환하는 것
    • %기호 뒤에 해 문자의 아스키 코드 16진수 값을 붙여 나타냄
      • URL에 공백이 포함되는 경우 + 기호 혹은 %20으로 변환됨 (%20 : URL 인코딩 결과)
  • base64 인코딩
    • 이진 데이터를 아스키 문자로 구성된 텍스트로 변환하는 인코딩 방식
    • 총 64개의 아스키 문자가 인코딩에 사용되기 떄문에 64진법(Base 64)라는 의미에서 이름 붙여짐
    • base64 인코딩 방식
      • 원본 이진 데이터를 비트 나열로 표현하고, 이를 6비트씩 끊어서 묶음. 만약 비트의 개수가 6의 배수가 아닐 경우, 0을 뒤에 추가하여 6의 배수로 만듦
      • 각 6 비트 묶음을 수로 변환한 뒤, base64 테이블에서 해당하는 문자를 찾아 이로 치환함
      • 이렇게 치환 과정을 거친 뒤, 글자 수가 4의 배수가 되도록 문자 '='를 반복해 뒤에 추가함
        • 이를 패딩(Padding)이라고 함

5. 운영체제 (OS)

  • 운영체제
    • 응용 프로그램의 동작을 수행하고, 응용 프로그램에게 시스템 자원을 할당하는 등의 복잡합 관리 작업을 하는 것은 운영체제라는 소프트웨어에 의해 이루어짐
    • 기능
      • 실행 중인 프로그램, 즉 프로세스에 CPU를 번갈아 할당해야 하는데, 이때 어떤 프로세스에 CPU를 할당할지 결정함 (CPU 스케줄링)
      • 메모리공간을 각 프로세스에 분배하고 사용하는 과정을 관리함
      • 컴퓨터가 입출력 장치와 정보를 주고 받는 과정을 관리함
  • 커널과 셸
    • 커널
      • 운영체제의 핵심 기능인 하드웨어 관리를 실제로 수행하는 프로그램
      • 소프트웨어와 하드웨어 간의 커뮤니케이션을 관리하며, 시스템이 부팅될 때 메모리에 올라가서 꺼질 때까지 실행됨
      • 사용자와 운영체제의 커널 사이에서 사용자가 운영체제에 명령을 내릴 수 있도록 인터페이스 역할을 함 
    • 사용자가 셸에 명령을 입력하면, 셸이 명령어를 해석하여 커널에 요청함
    • 커널은 명령을 수행하며 하드웨어를 조작하고, 수행 결과를 셸에 전송함
    • 셸은 이 결과를 해석하여 사용자에게 출력해줌
    • 즉, 셸은 명령어를 해석하는 역할을 하여 사용자와 운영체재가 소통할 수 있도록 함
    • 셸을 획득하면 명령어를 통해 원하는 작업을 수행하고 시스템을 제어할 수 있게 됨
    • 일반적으로 셸을 획득하는 것을 시스템 해킹의 성공으로 여김