NOT4DOG
방명록 RSS 태그 글쓰기 관리자
 
[CTF] Dreamhack funjs 문제 Write-up
카테고리 없음 2022-01-11 22:27:23

반응형

문제) 입력 폼에 데이터를 입력하여 맞으면 플래그, 틀리면 NOP !을 출력하는 HTML 페이지입니다.
        main 함수를 분석하여 올바른 입력 값을 찾아보세요 !

        (해당 문제는 Dreamhack CTF Season 1 Round #4에 출제된 문제입니다.)

 

문제와 같이 index.html를 제공한다. index Page를 열어보니 입력창 하나가 보인다.

index.html 화면

문제는 이 입력창이 쉴새없이 이동한다는 점이다. 또한 Debugger의 동작도 제한하고 있어 

index.html의 html 코드를 확인해보았다.

 

<html>
    <head>
    <style>*{margin: 0;}</style>
    <script>
    var box;
    window.onload = init;
    function init() {
      box = document.getElementById("formbox");
      setInterval(moveBox,1000);
    }
    function moveBox() {
        box.posX = Math.random() * (window.innerWidth - 64); 
        box.posY = Math.random() * (document.documentElement.scrollHeight - 64); 
        box.style.marginLeft = box.posX + "px";
        box.style.marginTop  = box.posY + "px";
        debugger;
    }

    function text2img(text){
        var imglist = box.getElementsByTagName('img');
        while(imglist.length > 0) {imglist[0].remove();}
        var canvas = document.createElement("canvas");
        canvas.width = 620;
        canvas.height = 80;
        var ctx = canvas.getContext('2d');
        ctx.font = "30px Arial";
        var text = text;
        ctx.fillText(text,10,50);
        var img = document.createElement("img");
        img.src = canvas.toDataURL();
        box.append(img);
    };

    function main(){
        var _0x1046=['2XStRDS','1388249ruyIdZ','length','23461saqTxt','9966Ahatiq','1824773xMtSgK','1918853csBQfH','175TzWLTY','flag','getElementById','94hQzdTH','NOP\x20!','11sVVyAj','37594TRDRWW','charCodeAt','296569AQCpHt','fromCharCode','1aqTvAU'];
        var _0x376c = function(_0xed94a5, _0xba8f0f) {
            _0xed94a5 = _0xed94a5 - 0x175;
            var _0x1046bc = _0x1046[_0xed94a5];
            return _0x1046bc;
        };
        var _0x374fd6 = _0x376c;
        (function(_0x24638d, _0x413a92) {
            var _0x138062 = _0x376c;
            while (!![]) {
                try {
                    var _0x41a76b = -parseInt(_0x138062(0x17f)) + parseInt(_0x138062(0x180)) * -parseInt(_0x138062(0x179)) + -parseInt(_0x138062(0x181)) * -parseInt(_0x138062(0x17e)) + -parseInt(_0x138062(0x17b)) + -parseInt(_0x138062(0x177)) * -parseInt(_0x138062(0x17a)) + -parseInt(_0x138062(0x17d)) * -parseInt(_0x138062(0x186)) + -parseInt(_0x138062(0x175)) * -parseInt(_0x138062(0x184));
                    if (_0x41a76b === _0x413a92) break;
                    else _0x24638d['push'](_0x24638d['shift']());
                } catch (_0x114389) {
                    _0x24638d['push'](_0x24638d['shift']());
                }
            }
        }(_0x1046, 0xf3764));
        var flag = document[_0x374fd6(0x183)](_0x374fd6(0x182))['value'],
            _0x4949 = [0x20, 0x5e, 0x7b, 0xd2, 0x59, 0xb1, 0x34, 0x72, 0x1b, 0x69, 0x61, 0x3c, 0x11, 0x35, 0x65, 0x80, 0x9, 0x9d, 0x9, 0x3d, 0x22, 0x7b, 0x1, 0x9d, 0x59, 0xaa, 0x2, 0x6a, 0x53, 0xa7, 0xb, 0xcd, 0x25, 0xdf, 0x1, 0x9c],
            _0x42931 = [0x24, 0x16, 0x1, 0xb1, 0xd, 0x4d, 0x1, 0x13, 0x1c, 0x32, 0x1, 0xc, 0x20, 0x2, 0x1, 0xe1, 0x2d, 0x6c, 0x6, 0x59, 0x11, 0x17, 0x35, 0xfe, 0xa, 0x7a, 0x32, 0xe, 0x13, 0x6f, 0x5, 0xae, 0xc, 0x7a, 0x61, 0xe1],
            operator = [(_0x3a6862, _0x4b2b8f) => {
                return _0x3a6862 + _0x4b2b8f;
            }, (_0xa50264, _0x1fa25c) => {
                return _0xa50264 - _0x1fa25c;
            }, (_0x3d7732, _0x48e1e0) => {
                return _0x3d7732 * _0x48e1e0;
            }, (_0x32aa3b, _0x53e3ec) => {
                return _0x32aa3b ^ _0x53e3ec;
            }],
            getchar = String[_0x374fd6(0x178)];
        if (flag[_0x374fd6(0x17c)] != 0x24) {
            text2img(_0x374fd6(0x185));
            return;
        }
        for (var i = 0x0; i < flag[_0x374fd6(0x17c)]; i++) {
            if (flag[_0x374fd6(0x176)](i) == operator[i % operator[_0x374fd6(0x17c)]](_0x4949[i], _0x42931[i])) {} else {
                text2img(_0x374fd6(0x185));
                return;
            }
        }
        text2img(flag);
    }
    </script>
    </head>
    <body>
        <div id='formbox'>
            <h2>Find FLAG !</h2>
            <input type='flag' id='flag' value=''>
            <input type='button' value='submit' onclick='main()'>
        </div>
    </body>
</html>

 

html 코드에서 창의 이동과 Debugger의 감지를 담당하는 함수는

movebox() 임을 확인하고 해당 부분을 삭제하고 저장해 주었더니 더 이상 움직이지 않았다.

 

 function moveBox() {
        box.posX = Math.random() * (window.innerWidth - 64); 
        box.posY = Math.random() * (document.documentElement.scrollHeight - 64); 
        box.style.marginLeft = box.posX + "px";
        box.style.marginTop  = box.posY + "px";
        debugger;
    }
    // 이 부분 삭제

창이 더 이상 움직이지 않는다

 

이제 index.html를 자세히 분석하던 중 flag를 출력하는 for, if-else문을 발견했다.

 

        for (var i = 0x0; i < flag[_0x374fd6(0x17c)]; i++) {
            if (flag[_0x374fd6(0x176)](i) == operator[i % operator[_0x374fd6(0x17c)]](_0x4949[i], _0x42931[i])) {} else {
                text2img(_0x374fd6(0x185));
                return;
            }
        }

 

이 코드를 분석해보니 초기값 0부터 FLAG의 전체 길이 -1 까지 반복되고,

input의 문자열을 index 한 값과 원래 operator의 값, 두 값을 서로 비교하여 같지 않을경우,

NOP!를 출력하는 것을 확인할 수 있었다.

 

또한 _0x374fd6(0x17c)를 확인해보면 길이_0x374fd6(0x185)를 확인해보면 NOP! 임을 확인할 수 있다.

 

저 코드와 분석에서 얻은 정보들을 기반으로 크롬의 개발자도구 내

console 기능을 사용하면 쉽게 해결이 될 것으로 보인다.

 

우선 main 함수의 값들을 console에 load하고,

 

main 함수 load

 

전체 플래그 길이를 확인한 후 operator 값과 input을 같게 만드는 for문을 작성한 뒤 실행한다.

 

FLAG 획득

반응형


[CTF] Dreamhack rev-basic-4 문제 Write-up
CTF Write-up 2022-01-10 13:25:09

반응형

문제) Reversing Basic Challenge #4

          이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여

          correct 또는 wrong을 출력하는 프로그램이 주어집니다.

          해당 바이너리를 분석하여 correct를 출력하는 입력값을 알아내세요.

          획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.

          예시) 입력 값이 Apple_Banana일 경우 flag는 DH{Apple_Banana}

 

문제와 같이 chall4.exe 파일을 제공한다.

이전 rev-basic 문제들과 비슷하기에 ida를 이용해서 로직을 먼저 확인했다.

이번에도 동일하게 sub_140001000 함수에서 비교가 이루어지는것을 확인할 수 있다.

sub_140001000 함수에서 비교가 일어난다

이번에는 sub_140001000 함수의 Pseudo code를 확인하였다.

sub_140001000&amp;nbsp;Pseudo code

__int64 __fastcall sub_140001000(__int64 a1)
{
  int i; // [rsp+0h] [rbp-18h]

  for ( i = 0; (unsigned __int64)i < 0x1C; ++i )
  {
    if ( ((unsigned __int8)(16 * *(_BYTE *)(a1 + i)) | ((int)*(unsigned __int8 *)(a1 + i) >> 4)) != byte_140003000[i] )
      return 0i64;
  }
  return 1i64;
}

코드를 대략적으로 분석해보니 Left Shift, 자릿수 소거 등을 이용해서

최종적으로 hex값의 앞뒤가 바뀌는것을 확인할 수 있다.

만약 0010 1100 이 입력으로 들어가면 출력으로 1100 0010이 나온다.

이를 토대로 a1 배열값을 찾아 위 알고리즘에 맞게 변환해주면 FLAG를 얻을 수 있다.

 

a1 배열의 값이 있는곳은 위에 sub_140001000 함수에서 확인할 수 있다.

byte_140003000[i] 에 있는 값을 참조하므로 Hex View에서 해당 위치를 조회해 보았다.

a1 배열의 Hex Value

그렇다면 a1 배열의 값은

{ 24 27 13 C6 C6 13 16 E6 47 F5 26 96 47 F5 46 27
13 26 26 C6 56 F5 C3 C3 F5 E3 E3 } 임을 확인할 수 있다.

 

나는 16진수값을 텍스트로 변환해주는 사이트를 이용했다.

물론 위 sub_140001000 알고리즘을 기반으로 c언어나 python을 사용해 작성해도 된다.

 

FLAG 획득

여기서 주의해야할 점은 위 알고리즘에 따라 (XXXX YYYY → YYYY XXXX)

a1 배열 16진수 값의 앞, 뒤를 서로 바꿔 변환해주어야 한다. 

이 점에 유의해서 변환하니 FLAG를 얻을 수 있었다.

반응형


[Tools] 무료 악성코드 제거 도구 MZK 소개 및 사용법
Tools 2022-01-07 22:38:50

반응형

 

MZK란 Malware Zero Kit 의 준말이며,  대한민국 보안 관련 인터넷 커뮤니티인 바이러스 제로 :

시큐리티 커뮤니티 카페 매니저 ViOLeT이 개발한 무설치 무료 악성코드 제거 도구이다.

프로그램은 설치 프로그램이 아닌 윈도우 배치 스크립트의 구성으로 이루어져있다.

프로그램의 장점으로는 100% 무료 프로그램이며, DB의 꾸준한 업데이트,

유료 프로그램 못지않은 바이러스 / 악성코드 탐지능력 등이 있다.

 

다만, 단점으로는 자동 업데이트 기능 미 지원, 스크립트 프로그램 기반 특성상 속도가 느린편이라는 점,

Prevent 기능이 없다는 점 정도로 꼽을 수 있다. (감염 시에만 바이러스 / 악성코드 탐지가능)

기능으로는 광고 프로그램 제거, 악성코드 제거, 악성 DNS 제거, 웹 브라우저 검사, 

캐시 청소, 시스템 변조 확인 기능이 있다.

 

개인적으로 MZK를 한달에 한번은 주기적으로 사용하는편이며,

사용할 때 마다 만족하는 프로그램 중 하나이다.

 

<설치 및 사용방법>

1. MZK 공식 홈페이지에 접속한다.

https://malzero.xyz/

 

Malware Zero - 무료 악성코드 제거 도구

악성코드 및 애드웨어 등 각종 유해 프로그램에 의한 고통에서 해방되기 위해 설치 없이 사용 가능한 무료 악성코드 제거 도구

malzero.xyz

 

2. 접속 후 '무료 내려받기' 버튼을 클릭해 프로그램을 다운로드 한다.

MZK Main Page

 

3. 다운로드한 파일의 압축을 풀어준다.

 

4. malzero 폴더에 들어가면, start.bat 이라는 배치파일을 권리자 권한으로 실행.

 

<실행 유의사항>

 

4-1. 압축 해제 대상 폴더 및 상위 폴더에 아래에 표시된 특수 문자가 삽입되어 있으면 실행되지 않음.

4-2. 실행 권한 없음 오류가 발생할 경우 Windows 파일 탐색기에서 실행 파일 선택 후 

        마우스 오른쪽 버튼을 클릭하여 표시되는 팝업 메뉴에서 "관리자 권한으로 실행" 항목 클릭

4-3. Windows의 PC 보호(SmartScreen) 기능으로 인해 실행되지 않을 경우
        PC 보호 창의 "추가 정보" 항목을 누른 후 "실행" 버튼 클릭

4-4. 사용자 계정 컨트롤(UAC) 비활성화 환경에서의 표준 사용자 계정 및 게스트 계정의 경우 실행 불가

        (관리자 권한이 필요하기 때문.)

4-5. 모든 백신 및 악성코드 관련 프로그램은 '안전모드'에서 진행하는것이 가장 바람직 함.

 

5. 실행 후 도구 초기화를 거치면 이런 메세지가 나온다.

읽어보고 '예'를 클릭하면 검사가 진행된다.

 

여기서 MZK 배경의 색깔이 파란색임을 확인할 수 있는데, 검사 도중 배경 색깔로 전체적인 상황을 확인할 수 있다.

  • 녹색 : 문제 없음
  • 황색 : 주의해야 할 항목 발견
  • 적색 : 악성코드(악성 프로그램) 또는 불필요한 항목 발견

검사 도중 탐지한 악성코드 / 바이러스의 삭제 여부를 알려주며, 당장 삭제가 어렵거나

혹시라도 삭제된 파일의 복원이 필요할 경우 모든 탐지 항목들은 시스템 드라이브 루트에 생성되는

Quarantine_MZ 폴더에 격리(이동 조치 및 실행 불가 처리)되므로 오진이 발생하더라도 

파일의 복원이 가능하다. 오진 없이 처리되었다면 생성된 격리 폴더를 삭제해 마무리하면 된다.

 

또한 감지되지 않거나, 제거가 불가능한 악성코드의 경우 1번의 공식 홈페이지에서 분석을 요청하여

추후 DB 업데이트에 힘을 보탤 수 있다.

반응형


[Tools] 패킷 분석 프로그램 Wireshark 설치 및 사용법
Tools 2022-01-03 18:15:18

반응형

Wireshark네트워크 패킷을 캡처하고 분석하는 오픈소스 도구이다.

패킷분석 관련 GUI 프로그램 중 가운데 제일 간단하고 또 강력한 도구라고 생각한다.

보안 컨설팅, 취약점 분석, 보안 공격등에 폭 넓게 사용되는 도구 중 하나이다.

오늘은 Wireshark를 설치하고 간단한 사용법에 대해 작성하고자 한다.

 

1. 우선 Wireshark 다운로드 페이지에 접속한다.

https://www.wireshark.org/download.html

 

Wireshark · Download

Download Wireshark The current stable release of Wireshark is 3.6.1. It supersedes all previous releases.

www.wireshark.org

 

2. 페이지에 접속하여 본인 플랫폼에 맞는 설치파일을 다운로드 받는다.

   (설치 중 설정값은 기본값으로 유지하고 진행한다)

필자는 Windows 기반 64bit를 선택했다.

 

3. Wireshark 설치 도중 나오는 Npcap 설치또한 반드시 진행해주어야 한다. 

    (취약점 스캔과 네트워크 검색을 위한 무료 오픈소스 툴이다.

     네트워크 관리자는 Npcap을 사용해 시스템에서 실행 중인 디바이스를 파악하고

     사용 가능한 호스트 및 이러한 호스트가 제공하는 서비스를 검색하고 열린 포트를 찾고 보안 위험을 탐지한다.)

Npcap 설치 화면

 

4. 설치가 완료된 후 Wireshark를 실행하면 기본 화면이 나오고 캡쳐할 인터페이스

   필터 옵션을 선택할 수 있다.

   필터 옵션 : capture filter : 특정 패킷만 캡처 하고자 할 때 사용

                       display filter : 일단 모든 패킷을 받고 그 중에서 원하는 패킷만 확인하고자 할 때 사용

인터페이스의 종류와 개수는 사용자마다 다르다.

5. 간단한 테스트를 위해 이더넷으로 캡처를 진행하였다.

     이더넷으로 주고받는 패킷의 대한 정보가 실시간으로 업데이트 되어 캡처된다.

이더넷 Capture 화면

파란색 부분은 No. : 패킷을 수집한 순서, Time : 패킷이 캡처된 시간, Source : 패킷을 보낸 주소
                           Destination : 패킷이 도착한 주소, Protocol : 프로토콜 정보, Length : 패킷 길이, Info : 패킷 정보

 

빨간색 부분은 원하는 필터링 식으로 적용해서 Display 할 수 있다.

예를 들어 eth.addr == [MAC Address] → 출발지나 목적지 MAC 주소로 검색
                  ip.addr == [IP Address] 출발지나 목적지 IP주소로 검색
                  tcp.port == [Port Number] TCP 출발지나 목적지 포트 번호로 검색
                  ip.src != [IP Address] 출발지 IP주소가 해당 IP주소가 아닌것 검색
                  eth.dst == [MAC Address] 목적지 MAC주소 검색 이런식으로 다양한 필터링이 가능하다.

 

6. 간단한 테스트를 위해 구글의 Public DNS인 8.8.8.8로 ping test를 진행했다.

8.8.8.8 ping test

7. ping의 동작여부를 확인하기 위해 5번에서 설명했던 필터링에 icmp를 입력한다.

    (icmp란 TCP/IP에서 IP 패킷을 처리할 때 발생되는 문제를 알려주는 프로토콜이다.

    ping 명령어는 icmp 프로토콜에서 작동한다.)

패킷의 교환 확인

이 처럼 내 Host IP와 8.8.8.8 간의 패킷 교환을 확인할 수 있다. 

 

8. 단순한 확인뿐만 아니라 TCP Stream, HTTP Stream, Hex Value, Export Objects 기능 등을 활용해

   데이터 분석, 이미지 등 파일 추출 등의 작업이 가능하다.

   이로 인해 네트워크 관련 CTF 문제 풀이 시에는 필수인 툴 중 하나이다.

TCP Stream

 

반응형