tmxklab

UAC bypass(레지스트리 어뷰징) 분석 본문

Security/07 Malware Technique

UAC bypass(레지스트리 어뷰징) 분석

tmxk4221 2021. 1. 9. 15:10

0. 목차


1. 소개

1.1 UAC(User Account Control)

사용자 계정 컨트롤(User Account Control, UAC)은 윈도우 비스타 이상의 운영체제에서 제공하는 보안기능으로 권한이 없는 프로그램이나 악성코드가 바로 실행되지 않도록 사용자에게 실행 여부를 묻는 기능이다. 이를 통해 권한이 없는 프로그램의 자동 설치를 차단하고 시스템 설정을 실수로 변경하지 않도록 방지해준다. 예를 들어 악성코드가 C:\Windows 경로에 파일을 생성 및 쓰기 하려면 일반적인 경우 UAC 경고창이 나타나며 사용자에게 해당 작업 수행 여부를 확인하게 된다.

요약 : 시스템의 주요 자원을 변경하려고 시도하는 경우 사용자에게 해당 작업 수행 여부를 확인하는 기능 즉, UAC는 더 높은 권한을 필요로 할때에만 뜨는 메커니즘

추가 설명 1) - Administrator와 User

  • 윈도우에서 시스템 관리자(Administrartor)와 사용자(User)권한을 분리
  • 참고로, 처음 컴퓨터를 사고 계정을 생성하고 등록할 때 해당 계정은 관리자 그룹(Administrators)에 속하는데 동시에 사용자(User)그룹에도 속해 있음, 대신 표준 사용자 계정을 만들면 사용자(User)그룹에만 속해 있음
  • 윈도우에서는 로그온한 계정에 따라 적절한 보안 토큰을 주는데 관리자 계정일 경우 표준 사용자 계정이 받는 토큰과 비슷한 권한을 가진 보안 토큰, 관리자 토큰 2개를 받는다.

추가 설명 2) - Window Mandatory Integrity Level

  • Integrity 메커니즘은 커널의 SRM(보안 참조 모니터)에 기반한 아케텍쳐
  • SRM은 보안 접근 토큰에 존재하는 SID를 객체의 보안 디스크립터의 접근 권한과 비교해서 접근 제어를 강제한다.
  • Integrity Level(5단계)
    • System, High(관리자), Medium(일반 사용자), Low, Untrusted
  • 표준 사용자(User Group)로 로그온한 경우에는 표준 사용자 접근 토큰(Medium Integrity Level)을 받는다
  • 관리자 계정(Administrators Group)으로 로그온한 경우 표준 사용자 접근 토큰(Medium Integrity Level)과 관리자 접근 토큰(High Integrity Level) 2개를 받는다.

추가 설명 3) - 관리자 그룹에 속해있는데 UAC가 뜨는 이유

현재 계정이 표준 사용자 또는 관리자여도 응용 프로그램을 실행할 때는 Medium Integrity Level의 접근 토큰을 가지고 하게된다. (이유 : 애플리케이션 실행 시 explorer.exe의 자식 프로세스로 실행되는데 explorer.exe가 Medium레벨을 가지고 실행 중이기 때문) 하지만, 응용 프로그램 내부에 관리자 권한이 필요한 부분이 있는 경우 현재 접근 토큰이 Medium이기 때문에 High Integrity Level의 권한을 갖지 못하여 프로그램이 제대로 동작할 수 없다. 이러한 경우 보통 관리자 권한으로 프로그램을 실행할 수 있다.

만약, 현재 계정이 표준 사용자인 경우 관리자 권한으로 실행시키면 UAC가 나타나지만 관리자 접근 토큰을 받아 관리자 권한으로 실행시키기 위해 관리자의 비밀번호를 입력해야 한다. 하지만 현재 계정이 관리자라고 하더라도 관리자 권한으로 실행시키면 UAC가 뜨는 것을 볼 수 있다. 아까 위에서 설명했듯이 관리자 계정으로 로그온하더라도 explorer.exe가 Medium권한으로 실행되기 때문이다. 근데 비밀번호를 입력하지 않고 확인 버튼만 누르면 되는데 이것이 UAC의 핵심이다.

비록 관리자 계정이 관리자 권한을 갖더라도 평소에는 축소된 표준 사용자 권한을 가지고 있다가 관리자 권한으로 프로그램을 실행할 때에는 사용자의 확인을 받고 실행하는 것이다.

1.2 UAC Bypass

위에서 설명했듯이 관리자 계정을 가지고 있더라도 관리자 권한이 필요한 프로그램을 실행하는 경우에는 UAC가 뜨게 되는데, 악성코드를 설치하거나 악의적인 작업을 하기 위해 레지스트리 수정같이 관리자 권한이 필요한 경우가 많다. 따라서 악의적인 작업을 진행하기 위해서는 Medium권한으로는 한계가 존재하며 UAC를 우회하는 작업이 필요하다. UAC 우회는 Medum 무결성 레벨에서 High 무결성 레벨의 권한을 획득하는 과정이며 사용자가 인지하지 못하도록 UAC 확인 창 없이 High 무결성 레벨을 얻는 것을 목표로 한다.

UAC Bypass의 전제 조건으로 먼저 사용자가 관리자 계정여야 하며 UAC 옵션이 디폴트 옵션("Notify me only when programs try to make changes to my computer)으로 선택한 경우에만 통한다. UAC의 가장 강한 옵션인 "Always Notify"로 설정된 경우에는 제대로 동작하지 않는 기법들이 많다.

(물론 대부분 사용자는 관리자 계정을 사용하고 UAC도 디폴트 옵션이므로 대부분 통함)

이번에 분석하는 UAC Bypass기법은 일반적으로 사용하는 기법으로 레지스트리에 특정 키를 생성해 우회하는 것이다. (레지스트리 어뷰징)

레지스트리의 HKCU(HKEY_CURRENT_USER)HKCR(HKEY_CLASSES_ROOT)은 서로 링크되어 있어 HKCU값을 변경하면 HKCR값도 변경된다. HKCR은 관리자 권한이 필요하지만 HKCU는 일반 사용자 권한으로 수정이 가능한 레지스트리 영역이다. 따라서 높은 권한으로 실행되는 HKCU값을 조작해 권한이 상승된 임의의 명령어를 실행시킬 수 있다.

특정 Windows 소프트웨어는 실행 시 레지스트리 키의 값에 따라 동작이 변경되는데 위의 HKCU값을 조작하는 점을 이용하여 권한이 높은 정상 시스템 파일의 레지스트리를 수정하여 임의의 명령어나 파일 실행이 가능하게 된다.

예를 들어 C:\Windows\System32 내부에 위치한 fodhelper.exe는 Microsoft가 신뢰하는 파일로 자동으로 권한이 상승이 되어 실행된다. 이 때 fodhelper.exe는 실행 시 HKCU:\Software\Classes\ms-settings\shell\open\command 키의 기본 값에 저장된 명령도 실행하게 된다. 만약 command에 저장되 키 값을 특정 프로그램 경로로 설정한 뒤 다시 fodhelper.exe를 실행하게 되면 자동으로 권한이 상승되어 UAC가 뜨지 않고 High Integriti Level로 실행하게 될 것이다.

eventvwr.exe, fodhelper.exe, ComputerDefaults.exe은 다음과 같이 레지스트리를 변경하면 UAC를 우회하여 높은 권한으로 특정 프로그램을 실행시킬 수 있다.

  • HKEY_CURRENT_USER\Software\Classes\ms-settings\shell\open\command (기본값) 키에 실행 명령어 (예, cmd.exe) 등록
  • HKEY_CURRENT_USER\Software\Classes\ms-settings\shell\open\command DelegateExecute 키에 공백으로 등록


2. UAC 우회 악성코드 유형 분석

2.1 분석환경

NameTags
OSWindows 10(x64)
Debugging ToolIDA Prox64dbg
etcProcessExplorer


3. 분석

3.1 정적 분석

1) TOKEN_ELEVATION_TYPE 확인 및 분기

[ uac.exe - main() ]

  • OpenProcessToken() : 현재 프로세스의 토큰 핸들을 획득 → TokenHandle
  • GetTokenInformation() : 권한상승 형태에 대한 정보(Access Token)를 얻음
    • Access Token은 계정과 그룹의 SID, 계정의 관련된 정보를 얻는다.
  • CreateWellKnownSid() : 관리자 그룹의 SID값을 생성
  • GetTokenInformation() : 연결된 토큰의 핸들을 얻는다.
  • CheckTokenMembership() : 원래의 토큰이 관리자의 SID를 포함하고 있는지 여부를 확인한다. → 관리자 그룹에 속하는지 확인하는 함수 , 성공할 경우 0이 아닌 값 반환

정리) 권한상승의 형태와 관리자 권한으로 수행되었는지 확인하는 로직

  • TokenInformation(TOKEN_ELEVATION_TYPE)값에 따라 분기
    • TokenElevationTypeLimited(0x3) : uac()를 호출
    • TokenElevationTypeFull(0x2) : 지정된 레지스트리 키 값을 제거하고 메시지박스와 cmd창을 띄운다.

+) TOKEN_ELEVATION_TYPE

  • TokenElevationTypeDefault : 연결된 토큰이 없음, 기본 사용자이거나 UAC기능이 off된 상태
  • TokenElevationTypeFull : 상승된 토큰, 권한 상승되었음
  • TokenElevationTypeLimited : 제한된 토큰, 필터된 토큰에 의해 제한된 권한으로 수행되었음

2) 레지스트리 키 생성 및 ComputerDefaults.exe 실행

[ uac.exe - main() ]

  • GetModuleFileNameA() : 실행되는 경로의 위치 즉, "uac.exe"의 경로를 구해 Filename변수에 저장
  • HKEY_CURRENT_USER 밑에 하위 키를 생성, 즉, HKEY_CURRENT_USER키 밑에 "Software\\Classes\\ms-settings\\shell\\open\\command"키를 생성

  • RegSetValueExA() : 위에서 생성한 키에 2개의 값을 세팅
    • 0 ↔ FileName / data type : REG_SZ(0x1)
    • "DelegateExecute" ↔ 0 / data type : REG_SZ(0x1)
  • CreateProcessA() : command에 저장된 문자열을 명령행 인수로 받아 새로운 프로세스를 실행
  • lpApplicationName변수가 널 값이므로 command문자열의 첫 번째 토큰은 cmd 즉, cmd를 실행시켜 ComputerDefaults.exe를 실행

3.2 동적 분석

(디버깅 껐다 켰다해서 pid값이랑 주소 값다를 수 있음)

현재 x64dbg에 uac.exe를 올렸을 때 전부다 integrity level은 medium상태이다.

1) TOKEN_ELEVATION_TYPE 확인 및 분기

  • CheckTokenMembership()을 수행한 후 flag(ebx)값이 1로 세팅되어 있음
  • 현재 계정이 관리자 그룹에 포함된 것을 확인
  • TokenInformation[rbp-0x11]에 따라 분기, 현재 TokenElevationTypeLimited(0x3)으로 세팅되어 있으므로 uac()를 호출

2) 레지스트리 키 생성 및 ComputerDefaults.exe 실행

  • 현재 실행되고 있는 "uac.exe"파일의 경로를 가져온다.

  • HKEY_CURRENT_USER\SOFTWARE\Classes\ms-settings\shell\open\command 위치에 데이터가 저장된다. → "uac.exe"파일 경로

  • HKEY_CURRENT_USER\SOFTWARE\Classes\ms-settings\shell\open\command 위치에 DelegateExecute값이 쓰여진다.

  • CreateProcessA()를 호출할 때 명령행 인자 값으로 "cmd /c ComputerDefaults.exe"를 받는다.

  • message box와 cmd창이 실행된다. 실제로 "ComputerDefaults.exe"가 실행되면서 레지스트리 값에 지정된 "uac.exe"를 실행시키고 "ComputerDefaults.exe"의 Integrity가 High이므로 message box와 cmd창을 실행하게 되는 것이다.

  • 최종적으로 cmd.exe는 UAC창이 뜨지 않고 관리자 권한으로 실행하게 된다.


4. 정리

4.1 몰랐던 내용

이번에는 단순히 레지스트리 값을 변경시켜 UAC Bypass 및 권한상승을 일으키는 실습을 진행해보았다. UAC Bypass 유형에는 COM객체를 이용하거나 DLL Hijaking, 등등 여러가지 종류가 존재한다. 악성코드에서 흔히 UAC Bypass하는 기법이 나오므로 이후에 다른 유형들도 공부해봐야겠다.

추가로 윈도우 보안 요소들에 대한 내용과 레지스트리에 관한 내용, 액세스 토큰 등 모르는 내용이 너무 많아서 따로 정리해야할 필요성을 느꼈다.

4.2 레지스트리 관련 API 함수 정리

1) RegOpenKeyExA()

→ 지정된 레지스트리 키를 여는 함수(키 이름 대소문자 구분안함)

→ 성공하면 반환 값은 ERROR_SUCCESS

  • hKey : 오픈할 레지스트리 키의 핸들, 기본적으로 정의되어 있는 키의 핸들을 사용
    • HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_LOCAL_MACHINE, 등등...
  • lpSubKey : 레지스트리 하위 키 이름
  • ulOptions : 키를 열때 적용할 옵션(0 또는 REG_OPTION_OPEN_LINK)
  • samDesired : 엑세스 권한 지정
    • KEY_ALL_ACCESS(0xF003F)
  • phkResult : 오픈된 키에 대한 핸들을 받는 포인터

2) RegCreateKeyA()

→ 지정된 레지스트리 키를 만드는 함수

  • hKey : 레지스트리 키에 대한 핸들
  • lpSubKey : 만들 키의 이름, hKey 변수로 식별되는 키의 하위키
  • phkResult : 생성된 키에 대한 핸들을 받는 변수에 대한 포인터

3) RegSetValueExA()

→ 지정된 키에 data 및 type을 설정

  • hKey : 레지스트리 키에 대한 핸들
  • lpValueName : 설정할 값의 이름
  • Reserved : 예약되어 있는 변수이며 0이여야 한다.
  • dwType : lpData가 가리키는 데이터 type
    • REG_SZ(0x1) : 널로 끝나는 문자열
  • lpData : 저장할 데이터
  • cbData : 저장할 데이터 사이즈(byte)

4) RegDeleteKeyA()

→ 하위 키와 해당 값을 삭제하는 함수

  • hkey : 레지스트리 키에 대한 핸들
  • lpSubKey : 삭제하는 서브 키의 이름을 나타내는 문자열의 주소를 지정, 0(NULL)을 지정할 수 없음

5) RegCloseKey()

→ 지정된 레지스트리 키에 대한 핸들을 닫는 함수

  • hKey : 닫을 키에 대한 핸들


5. 참고자료

5.1 UAC 및 UAC bypass 관련

5.2 Window Access Token

5.3 UAC bypass 관련 오픈 소스


'Security > 07 Malware Technique' 카테고리의 다른 글

악성코드 지속메커니즘  (0) 2021.04.18
파일리스(Fileless)기법 설명  (0) 2021.01.16
Reflective DLL Injection  (4) 2021.01.07
Dropper 3-4(Thread Injection)  (0) 2020.12.30
Dropper 3-3(PE Injection)  (0) 2020.12.29
Comments