맨위로가기

셸코드

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

셸코드는 특정 CPU 아키텍처와 운영 체제에서 실행되도록 설계된, 기계어로 작성된 코드 조각이다. 공격자가 시스템 제어 권한을 획득하기 위해 버퍼 오버플로우와 같은 취약점을 악용하는 데 사용되며, 로컬과 원격 셸코드로 분류된다. 원격 셸코드는 리버스 셸, 바인드셸, 소켓 재사용 셸 등으로 구분되며, 다운로드 및 실행 셸코드와 스테이지드 셸코드, 에그헌트 셸코드, 오믈렛 셸코드 등의 변형이 존재한다. 셸코드는 침입 탐지 시스템을 우회하기 위해 인코딩될 수 있으며, 널 프리, 영숫자, 유니코드 등의 인코딩 기법이 사용된다. 셸코드 분석은 악성 코드를 탐지하기 위해 중요하며, 다양한 분석 도구와 기법이 활용된다.

더 읽어볼만한 페이지

  • 취약점 공격 - 보안 취약점
    보안 취약점은 시스템의 설계, 구현, 운영, 관리상 결함이나 약점으로, 위협에 의해 악용되어 시스템 보안 정책을 위반할 수 있는 요소이며, ISO 27005, IETF RFC 4949, NIST SP 800-30, ENISA 등 다양한 기관에서 정의하고 있다.
  • 취약점 공격 - 인터넷 보안
    인터넷 보안은 사이버 위협, 악성 소프트웨어, 서비스 거부 공격 등으로부터 정보와 시스템을 보호하기 위해 네트워크 계층 보안, 다단계 인증, 방화벽 등 다양한 기술과 방법을 포괄한다.
셸코드
개요
종류컴퓨터 프로그램
용도소프트웨어 취약점을 악용하는 데 사용되는 작은 코드 조각
상세 정보
기능셸을 시작하는 코드를 포함하는 경우가 많음
임의의 코드를 시스템에서 실행하는 데 사용될 수 있음
사용 목적취약점이 있는 시스템에서 권한 상승 또는 원격 코드 실행
특징일반적으로 기계어로 작성됨
특정 운영 체제 및 CPU 아키텍처에 종속적임
제한 사항크기가 제한될 수 있음
특정 문자 (예: 널 바이트)를 포함할 수 없음
개발 방법어셈블리어로 작성 후 컴파일
고급 프로그래밍 언어를 사용하여 생성
우회 기술알파벳 및 숫자만으로 구성된 셸코드 사용
암호화 또는 난독화 기술 적용
탐지 방법침입 탐지 시스템 (IDS) 사용
악성코드 분석 기술 활용
대응 방법소프트웨어 취약점 패치 적용
보안 강화 기술 적용 (예: 주소 공간 배치 무작위화 (ASLR), 데이터 실행 방지 (DEP))
관련 용어익스플로잇 (Exploit)
버퍼 오버플로 (Buffer Overflow)
리턴 투 리브 (Return-to-libc)

2. 셸코드의 종류

셸코드는 공격 대상 시스템을 제어하는 방식(로컬/원격)과 네트워크 연결 방식에 따라 분류된다.


  • 로컬 셸코드: 공격자가 이미 시스템에 제한적으로 접근 가능하지만, 더 높은 권한을 얻기 위해 사용한다.
  • 원격 셸코드: 공격자가 네트워크를 통해 다른 시스템을 공격할 때 사용한다.
  • 연결 방식에 따른 분류
  • 리버스 셸 (connect-back): 셸코드가 공격자에게 다시 연결한다.
  • 바인드셸 (bindshell): 셸코드가 피해 시스템의 특정 포트에 바인딩되어 공격자의 연결을 기다린다.
  • 바인드셸 랜덤 포트: 운영체제가 제공하는 임의 포트에서 수신 대기하는 특이한 형태이다.
  • 소켓 재사용 (socket-reuse): 기존 연결을 재사용하여 공격자와 통신하므로, 탐지가 더 어렵다.


방화벽은 이러한 연결을 감지하여 공격을 막을 수 있지만, 소켓 재사용 셸코드와 같이 감지하기 어려운 경우도 있다.[5]

2. 1. 로컬 셸코드

로컬 셸코드는 공격자가 시스템에 제한적인 접근 권한만 가지고 있지만, 해당 시스템의 더 높은 권한을 가진 프로세스에서 버퍼 오버플로와 같은 취약점을 악용할 수 있을 때 사용된다.[1] 셸코드가 성공적으로 실행되면, 공격자는 대상 프로세스와 동일한 높은 권한으로 시스템에 접근할 수 있게 된다.[1]

로컬형 셸코드는 공격자가 해당 머신에 제한적인 접근 권한을 가졌을 때, 더 높은 권한 수준의 프로세스 취약점을 이용하는 것이다.[1] 성공하면 셸코드를 통해 공격자는 공격 대상 프로세스와 동등한 수준의 권한을 얻는다.[1] 로컬형 셸코드는 비교적 작성하기 쉬운데, 이 형식의 셸코드가 하는 일은 셸 실행 파일을 실행하는 것뿐이기 때문이다.[1]

2. 2. 원격 셸코드

원격 셸코드는 공격자가 근거리 네트워크, 인트라넷 또는 원격 네트워크의 다른 머신에서 실행 중인 취약한 프로세스를 공격하려는 경우에 사용된다. 셸코드가 성공적으로 실행되면 공격자는 네트워크를 통해 대상 머신에 접근할 수 있다. 원격 셸코드는 일반적으로 표준 TCP/IP 소켓 연결을 사용하여 공격자가 대상 머신에서 셸에 접근할 수 있도록 한다.[5]

원격 셸코드 연결 방식은 다음과 같이 분류할 수 있다.

  • 리버스 셸 (connect-back): 셸코드가 공격자의 머신에 다시 연결하기 때문에 '커넥트 백' 셸코드라고도 한다. 셸 코드 자체가 연결을 확립한다.[5]
  • 바인드셸 (bindshell): 공격자가 연결을 설정하는 경우이다. 셸코드가 희생자 머신의 특정 포트에 바인딩되기 때문에 '바인드셸'이라고 한다. 공격자가 대상 머신을 제어하기 위해 접속할 수 있는 특정 포트에 셸 코드가 바인드된다.[5]
  • 바인드셸 랜덤 포트: 바인딩 부분을 건너뛰고 운영 체제에서 제공하는 임의 포트에서 수신 대기하는 특이한 셸코드이다. 현재까지 사용 가능한 x86_64에 대한 가장 작은 안정적인 바인드셸 셸코드이다.[5]
  • 소켓 재사용 (socket-reuse): 익스플로잇이 셸코드가 실행되기 전에 닫히지 않는 취약한 프로세스에 대한 연결을 설정할 때 사용된다. 그러면 셸코드는 이 연결을 재사용하여 공격자와 통신할 수 있다. 소켓 재사용 셸코드는 셸코드가 재사용할 연결을 찾아야 하고 머신에 여러 연결이 열려 있을 수 있으므로 더 정교하다.[5]


방화벽은 커넥트 백 셸코드에 의해 만들어진 발신 연결과 바인드셸에 의해 만들어진 수신 연결을 감지하는 데 사용될 수 있다. 따라서 시스템이 취약하더라도 공격자가 셸코드에 의해 생성된 셸에 연결하는 것을 막아 공격자로부터 어느 정도 보호할 수 있다. 소켓 재사용 셸코드가 가끔 사용되는 한 가지 이유는 새로운 연결을 만들지 않기 때문에 감지하고 차단하기가 더 어렵기 때문이다.[5]

2. 3. 다운로드 및 실행 셸코드

'''다운로드 및 실행'''은 대상 시스템에서 특정 멀웨어를 다운로드하고 실행하는 원격 셸코드의 한 유형이다. 이 셸코드는 셸을 생성하지 않고, 네트워크에서 특정 실행 파일을 다운로드하여 디스크에 저장하고 실행하도록 컴퓨터에 지시한다. 오늘날에는 피해자가 악성 웹 페이지를 방문하여 다운로드 및 실행 셸코드를 실행, 피해자의 컴퓨터에 소프트웨어를 설치하는 드라이브 바이 다운로드 공격에 일반적으로 사용된다.[6][7] 이 셸코드의 변형은 동적 로딩을 통해 라이브러리를 다운로드하고 로드하기도 한다. 이 기술은 코드가 작고, 대상 시스템에서 새로운 프로세스를 생성할 필요가 없으며, 대상 프로세스를 정리하는 코드가 필요 없다는 장점이 있다. 이는 프로세스에 로드된 라이브러리에서 수행할 수 있기 때문이다.

공격자는 대상 시스템에 특정 멀웨어를 설치하려는 경우가 많은데, 이때 '''다운로드 실행형''' 셸코드가 자주 사용된다. 이 셸코드는 셸을 실행하지 않고, 해당 머신에 네트워크를 통해 특정 실행 파일을 다운로드하여 디스크에 저장하고 실행한다. 이를 드라이브 바이 다운로드 공격이라고 부른다.

2. 4. 스테이지드 셸코드 (Staged Shellcode)

공격 대상 시스템의 메모리 제약 등으로 인해 한 번에 큰 셸코드를 실행하기 어려울 때, 단계적으로 실행하는 방법이 사용될 수 있다. 먼저 작은 크기의 셸코드(1단계)가 실행된다. 이 코드는 더 큰 셸코드(2단계)를 프로세스의 메모리에 다운로드하여 실행한다.

2. 5. 에그헌트 셸코드 (Egg-hunt Shellcode)

이는 공격자가 더 큰 셸코드를 프로세스에 주입할 수 있지만, 프로세스 내 어디에 위치하게 될지 알 수 없을 때 사용되는 또 다른 형태의 '스테이지' 셸코드이다. 작은 '에그헌트' 셸코드는 예측 가능한 위치에 프로세스에 주입되어 실행된다. 이 코드는 프로세스의 주소 공간에서 더 큰 셸코드('에그')를 검색하여 실행한다.[8]

2. 6. 오믈렛 셸코드 (Omelette Shellcode)

이 유형의 셸코드는 ''에그 헌트(egg-hunt)'' 셸코드와 유사하지만 여러 개의 작은 데이터 블록(''에그'')을 찾아 이를 하나의 더 큰 블록(''오믈렛'')으로 재결합하여 실행한다. 이는 공격자가 프로세스에 소수의 작은 데이터 블록만 주입할 수 있을 때 사용된다.[9]

3. 셸코드 실행 전략

취약점 공격은 일반적으로 프로그램 카운터를 조작하기 전이나 동시에 대상 프로세스에 셸코드를 주입한다. 프로그램 카운터는 셸코드를 가리키도록 조정된 후 실행되어 작업을 수행한다. 셸코드 주입은 취약한 프로세스에 네트워크를 통해 전송된 데이터에 셸코드를 저장하거나, 취약한 프로세스에서 읽는 파일에 셸코드를 제공하거나, 로컬 익스플로잇의 경우 명령줄 또는 환경 변수를 통해 수행된다.[1]

4. 셸코드 인코딩

셸코드는 침입 탐지 시스템의 탐지를 피하고 대상 시스템의 제약 조건을 우회하기 위해 다양한 방식으로 인코딩된다. 대부분의 프로세스는 주입될 수 있는 데이터를 필터링하거나 제한하므로, 셸코드는 이러한 제약을 고려하여 작성해야 한다. 예를 들어 코드를 작게 만들거나, 널(null) 바이트가 없도록 하거나, 영숫자를 사용해야 할 수 있다.

이러한 제약을 우회하기 위한 일반적인 방법은 다음과 같다.


  • 셸코드 크기를 줄이기 위한 설계 및 구현 최적화.
  • 셸코드에서 사용되는 바이트 범위의 제한을 우회하기 위한 구현 수정.
  • 자기 수정 코드를 사용하여 실행 전에 자체 코드의 여러 바이트를 수정, 일반적으로 프로세스에 주입할 수 없는 바이트를 다시 생성.


침입 탐지 시스템은 네트워크를 통해 전송되는 단순한 셸코드의 시그니처를 탐지할 수 있다. 따라서, 셸코드는 탐지를 피하기 위해 종종 인코딩되거나, 자체 해독되거나, 다형성으로 만들어진다.

4. 1. 퍼센트 인코딩

웹 브라우저를 대상으로 하는 공격에서 셸코드는 주로 퍼센트 인코딩, 이스케이프 시퀀스 인코딩 uXXXX영어 또는 HTML 엔티티 인코딩을 사용하여 자바스크립트 문자열로 인코딩된다.[10] 이러한 인코딩 방식은 셸코드를 URL에 포함시키기 위해 사용된다. 또한, 일부 공격은 IDS에 의한 탐지를 피하기 위해 인코딩된 셸코드 문자열을 추가적으로 난독화하기도 한다.

예를 들어, IA-32 아키텍처에서 두 개의 NOP (무연산) 명령어는 다음과 같이 여러 방식으로 인코딩될 수 있다.

인코딩된 이중 NOP
퍼센트 인코딩unescape("%u9090")
유니코드 리터럴"\u9090"
HTML/XML 엔티티"邐" 또는 "邐"


4. 2. 널 프리 셸코드 (Null-free Shellcode)

대부분의 셸코드는 널 문자를 사용하지 않고 작성되는데, 이는 널 종료 문자열을 통해 대상 프로세스에 삽입되기 때문이다. 널 종료 문자열을 복사할 때, 처음 널 문자까지만 복사되고 셸코드의 이후 바이트는 처리되지 않는다. 따라서 널 문자를 포함하는 셸코드가 삽입되면 셸코드의 일부만 삽입되어 정상적으로 실행될 수 없다.

널 문자를 포함하는 셸코드에서 널 프리 셸코드를 생성하기 위해서는, 0을 포함하는 기계어 명령을 널이 없으면서 동일한 효과를 가지는 명령어로 대체한다. 예를 들어, IA-32 아키텍처에서 다음 명령어는:

:B8 01000000 MOV EAX,1 // 레지스터 EAX를 0x00000001로 설정

이는 리터럴의 일부로 0을 포함하며(10x00000001로 확장됨), 다음 명령어로 대체할 수 있다:

:33C0 XOR EAX,EAX // 레지스터 EAX를 0x00000000로 설정

:40 INC EAX // EAX를 0x00000001로 증가

위 명령어들은 동일한 효과를 가지면서 인코딩에 더 적은 바이트를 사용하고 널이 없다.

4. 3. 영숫자/인쇄 가능 셸코드

대상 시스템이 영숫자 또는 인쇄 가능한 문자만 허용하는 경우에 사용되는 셸코드이다. 이러한 제약 조건을 우회하기 위해 자기 수정 코드와 같은 기술이 사용된다.

영숫자 셸코드는 0–9, A–Z, a–z와 같은 영숫자 ASCII 또는 유니코드 문자로 구성되거나 실행 시 자체적으로 어셈블되는 셸코드이다.[11][12] 이러한 유형의 인코딩은 작동하는 기계어 코드를 텍스트처럼 보이도록 숨기기 위해 해커에 의해 만들어졌다. 이는 코드의 탐지를 피하고 문자열에서 영숫자가 아닌 문자를 제거하는 필터를 통과할 수 있도록 하는 데 유용할 수 있다.

이와 유사한 유형의 인코딩은 '인쇄 가능한 코드'라고 하며 모든 제어 문자 (0–9, A–Z, a–z, !@#%^&*() 등)를 사용한다. 이와 유사하게 제한된 변형은 ECHO 명령에 의해 허용되지 않는 문자를 포함하지 않는 'ECHO 가능한 코드'이다. 일반적인 영어 텍스트처럼 보이는 셸코드를 생성하는 것이 가능하다.[13]

영숫자 또는 인쇄 가능한 코드를 작성하려면 코드가 실행될 기계의 명령 집합 아키텍처에 대한 충분한 이해가 필요하다. 여러 기기에서 실행 가능한 영숫자 코드를 작성하는 것이 가능하며,[14] 다중 아키텍처 실행 파일 코드를 구성할 수 있다.

특정 상황에서는 대상 프로세스가 주입된 셸코드에서 인쇄 가능 문자 또는 영숫자 문자가 아닌 모든 바이트를 필터링한다. 이러한 상황에서는 셸코드를 작성하는 데 사용할 수 있는 명령어 범위가 매우 제한된다. 이러한 문제에 대한 해결책은 Rix가 Phrack 57[11]에 게시했으며, 여기에서 그는 모든 코드를 영숫자 코드로 변환하는 것이 가능하다는 것을 보여주었다.

종종 사용되는 기술은 자기 수정 코드를 생성하는 것인데, 이를 통해 코드는 일반적으로 허용되는 범위를 벗어난 바이트를 포함하도록 자체 바이트를 수정할 수 있으므로 사용할 수 있는 명령어의 범위를 확장할 수 있다. 이 트릭을 사용하여 처음에는 허용된 범위 내의 바이트만 사용하는 자체 수정 디코더를 생성할 수 있다. 셸코드의 메인 코드는 또한 허용된 범위 내의 바이트만 사용하여 인코딩된다. 출력 셸코드가 실행되면 디코더는 자체 코드를 수정하여 제대로 작동하는 데 필요한 모든 명령을 사용할 수 있게 한 다음 원래 셸코드를 디코딩한다. 셸코드를 디코딩한 후 디코더는 제어 권한을 셸코드로 이전하여 정상적으로 실행할 수 있도록 한다. 일반적인 영어 텍스트처럼 보이는 임의로 복잡한 셸코드를 생성하는 것이 가능하다.[13]

어떤 상황에서는, 인쇄 가능한 문자(제어 문자 제외)나 영숫자만 주입할 수 있는 경우가 있다. 그러한 상황에서는 셸코드를 작성하는 데 사용할 수 있는 명령 종류가 크게 제한된다. 이를 위한 기술은 Phrack 57호에서 Rix가 발표했으며,[19], 이에 따르면 임의의 코드를 영숫자만의 코드로 변환할 수 있다. 자주 사용되는 기술은 자기 수정 코드로, 디코더 부분은 제한된 코드만으로 동작하도록 작성해야 한다. 셸코드 본체도 예를 들어 영숫자만의 코드로 부호화해두고, 디코더가 이를 주입 후에 수정하고, 그 후 실행한다.

4. 4. 유니코드 셸코드

현대 프로그램은 텍스트의 국제화를 위해 유니코드 문자열을 사용한다. 이러한 프로그램들은 종종 들어오는 ASCII 문자열을 처리하기 전에 유니코드로 변환한다. UTF-16으로 인코딩된 유니코드 문자열은 각 문자를 인코딩하는 데 2바이트를 사용한다(일부 특수 문자의 경우 4바이트). ASCII(일반적으로 Latin-1) 문자열이 UTF-16으로 변환될 때, 원래 문자열의 각 바이트 뒤에 0바이트가 삽입된다. Obscou는 Phrack 61[12][20]에서 이러한 변환 후에도 성공적으로 실행될 수 있는 셸코드를 작성하는 것이 가능함을 증명했다. 동일한 원리에 기반하여, 소규모의 자체 수정 디코더가 원본 셸코드를 디코딩하는 방식을 사용하여, 모든 셸코드를 영숫자 UTF-16-proof 셸코드로 자동 인코딩할 수 있는 프로그램이 존재한다.

5. 플랫폼 종속성

셸코드는 기계어로 작성되기 때문에 CPU, 운영 체제 및 서비스 팩의 특정 조합, 즉 플랫폼을 대상으로 만들어진다.[15][16][17] 하지만 하나의 셸코드가 여러 플랫폼에서 작동하는 경우도 있다.

이는 다양한 플랫폼을 대상으로 하는 여러 버전의 셸코드를 생성하고, 코드가 실행되는 플랫폼에 맞는 올바른 버전으로 분기되는 헤더를 생성하여 달성된다. 코드가 실행되면, 다른 플랫폼에 따라 다르게 동작하며, 실행 중인 플랫폼에 맞는 셸코드 부분을 실행한다.

6. 셸코드 분석

셸코드는 직접 실행될 수 없다. 셸코드가 수행하려는 작업을 분석하려면 다른 프로세스에 로드해야 한다. 일반적인 분석 기법 중 하나는 셸코드를 바이트 버퍼로 포함하는 작은 C 프로그램을 작성한 다음 함수 포인터 또는 인라인 어셈블러를 사용하여 실행을 셸코드로 전송하는 것이다. 또 다른 기술은 shellcode_2_exe와 같은 온라인 도구를 사용하여 셸코드를 미리 만들어진 실행 파일 껍데기에 포함시킨 다음 표준 디버거에서 분석하는 것이다. iDefense sclog 프로젝트와 같이 특화된 셸코드 분석 도구도 존재하며, 이 도구는 2005년에 Malcode Analyst Pack의 일부로 처음 출시되었다.[1] Sclog는 외부 셸코드 파일을 로드하고 API 로깅 프레임워크 내에서 실행하도록 설계되었다.[1] 에뮬레이션 기반 셸코드 분석 도구도 존재하는데, 예를 들어 크로스 플랫폼 libemu 패키지의 일부인 sctest|sctest영어 응용 프로그램이 있다.[1] libemu 라이브러리를 기반으로 구축된 또 다른 에뮬레이션 기반 셸코드 분석 도구인 scdbg|scdbg영어는 기본적인 디버그 셸과 통합 보고 기능을 포함한다.[1]

참조

[1] 서적 Sockets, Shellcode, Porting, & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals https://books.google[...] Elsevier Science & Technology Books 2005-04-12
[2] 서적 The shellcoder's handbook: discovering and exploiting security holes Wiley 2007
[3] 서적 Buffer overflow attacks: detect, exploit, prevent Syngress 2005
[4] 웹사이트 Tiny Execve sh - Assembly Language - Linux/x86 https://github.com/g[...] 2021-02-01
[5] 웹사이트 Shellcode/Socket-reuse http://www.blackhatl[...] 2013-06-06
[6] 웹사이트 Download and LoadLibrary shellcode released http://skypher.com/i[...] 2010-01-11
[7] 웹사이트 Download and LoadLibrary shellcode for x86 Windows http://code.google.c[...] 2010-01-11
[8] 웹사이트 Safely Searching Process Virtual Address Space http://www.hick.org/[...] nologin 2004-03-09
[9] 웹사이트 w32 SEH omelet shellcode http://skypher.com/w[...] Skypher.com 2009-03-16
[10] 웹사이트 JavaScript large number of unescape patterns detected http://www.iss.net/s[...]
[11] 간행물 Writing ia32 alphanumeric shellcodes http://www.phrack.or[...] Phrack Inc. 2001-08-11
[12] 간행물 Building IA32 'Unicode-Proof' Shellcodes http://www.phrack.or[...] Phrack Inc. 2003-08-13
[13] conference English Shellcode http://www.cs.jhu.ed[...] 2009-11
[14] 웹사이트 Multi-architecture (x86) and 64-bit alphanumeric shellcode explained http://www.blackhatl[...] Blackhat Academy
[15] 웹사이트 Architecture Spanning Shellcode http://www.phrack.or[...] Phrack Inc. 2001-08-11
[16] 웹사이트 OSX - Multi arch shellcode. https://seclists.org[...] 2005-11-13
[17] conference Platform-Independent Programs https://softsec.kais[...] Carnegie Mellon University 2010-10-08
[18] 문서 Sockets, Shellcode, Porting, & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals.
[19] 웹사이트 Writing ia32 alphanumeric shellcodes http://www.phrack.or[...] Phrack 2001-11-08
[20] 웹사이트 Building IA32 'Unicode-Proof' Shellcodes http://www.phrack.or[...] Phrack 2003-08-13
[21] 웹사이트 Architecture Spanning Shellcode http://www.phrack.or[...] Phrack 2001-08-11



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com