Inc0gnito CTF 2015 Write-Up | By RevDev

Forensic - 유출 추정 [150pt]


1. Ready to Solve
Problem
Alice는 자신의 컴퓨터에 공격자가 침입해서 중요한 zip 파일을 유출한 사실을 깨달았다.
급하게 도망치느라 공격자는 흔적을 완벽하게 지우지 못했다.
손상된 pcap 파일을 통해 어떤 파일이 유출되었는지를 분석해보자.
leakage_3c33219e8f72b7e29c50b3d16c5de63253ed2538.pcap 


Used Tools
Bless Hex Editor



2. Gathering Informations
Try with Wireshark




3. Solve

문제 자체에서 손상된 pcap파일을 주었다고 하였으므로 와이어샤크로 여는 것은 의미없다.
그렇다면 직접 헥스 에디터로 분석을 해주면 될 것이다. 가장 먼저 헥스 에디터로 주어진 파일을 열면 다음과 같을 것이다.

본인의 경우 우분투 환경에서 Bless Hex Editor를 사용했다. 물론 윈도우에서 HxD를 사용하였다 하더라도 문제 푸는데에는 전혀 지장이 없다. 툴이야 어떻게 되었던가 위의 문자열을 살펴보면 계속해서 key.zip이라는 이름의 파일이 거론되고 있다는 것을 알 수 있다. 그럼 zip파일이 위의 pcap파일 내에 존재하는지 알아보자. zip의 시그니쳐는 0x50, 0x4B, 0x03, 0x04, 즉 PK..이라는 문자열이 된다. 그 부분이 존재한다면, 우리는 pcap파일 내에 zip파일이 통째로 존재한다고 여겨도 무방할 것이다. 운이 좋게도 해당 문자열이 존재함을 알 수 있다.

따라서 우리는 위와 같이 zip파일을 특정해낼 수 있다. 이를 따로 빼내어 zip파일로 저장하자.

그리고 추출한 zip파일을 열면 key라는 파일을 얻을 수 있다.



4. Flag




Posted by RevDev
,

LeaveRet JFF3 Write-Up | By RevDev

Misc - sanity_check [10pt]


1. Ready to Solve
Problem
http://ctf.leaveret.kr/go/db0c6d1ce29a657b2963399813f4b009/


Used Tools
Firefox Developer Tools


WebPage Appearance




2. Gathering Informations
Source Code
/*
    patternLock.js v 0.4.2
    Author: Sudhanshu Yadav
    Copyright (c) 2013 Sudhanshu Yadav - ignitersworld.com , released under the MIT license.
    Demo on: ignitersworld.com/lab/patternLock.html
*/
;(function ($, window, document, undefined) {
    "use strict";

    var nullFunc = function () {},
        objectHolder = {};

    //internal functions
    function readyDom(iObj) {
...
...
...
function solve(check){
if(check.toString(13) == "75b8573") var flag=check.toString(12);
alert("Flag: "+flag);
}



3. Solve

이 문제는 전혀 깊게 생각할 필요가 없는 문제이다.
자바스크립트에서 toString함수가 무엇을 하는 함수인지만 알면 바로 풀 수 있다.
toString함수는 Object의 값을 문자열의 형태로 출력하는 함수로서, 인자로 정수가 들어갈 시 해당 정수에 해당하는 진법으로 값을 변형해서 출력하게 된다.

그럼, 답은 이미 나왔다. 다음 부분을 보자.

function solve(check){
if(check.toString(13) == "75b8573") var flag=check.toString(12);
alert("Flag: "+flag);
}

if(check.toString(13) == "75b8573") var flag=check.toString(12);라는 문이 보인다. 결국 13진수 75b8573을 12진수로 바꾼 것이 바로 플래그이다.
간단하게, 75b8573을 10진수로 바꾼 값을 solve(check)에서 check부분에 넣어주면 된다.

그렇다면 Console 창에 입력해야 할 코드는 다음과 같다.

var getauth = 35976814
solve(getauth)



4. Flag


Posted by RevDev
,

Pwnable.kr Write-Up | By RevDev

Toddler’s Bottle - collision [3pt]


1. Ready to Solve
Problem
Daddy told me about cool MD5 hash collision today.
I wanna do something like that too!
ssh col@pwnable.kr -p2222 (pw:guest)


Used Tools
GNU bash (version 4.3.11)



2. Gathering Informations
File List
col@ubuntu:~$ ls -al
total 32
drwxr-x---  4 root col  4096 Aug 20  2014 .
dr-xr-xr-x 48 root root 4096 Jul 12 05:20 ..
d---------  2 root root 4096 Jun 12  2014 .bash_history
-r-sr-x---  1 col2 col  7341 Jun 11  2014 col
-rw-r--r--  1 root root  555 Jun 12  2014 col.c
-r--r-----  1 col2 col2   52 Jun 11  2014 flag
dr-xr-xr-x  2 root root 4096 Aug 20  2014 .irssi


Source Code
#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
    int* ip = (int*)p;
    int i;
    int res=0;
    for(i=0; i<5; i++){
        res += ip[i];
    }
    return res;
}

int main(int argc, char* argv[]){
    if(argc<2){
        printf("usage : %s [passcode]\n", argv[0]);
        return 0;
    }
    if(strlen(argv[1]) != 20){
        printf("passcode length should be 20 bytes\n");
        return 0;
    }

    if(hashcode == check_password( argv[1] )){
        system("/bin/cat flag");
        return 0;
    }
    else
        printf("wrong passcode.\n");
    return 0;
}



3. Solve

이 문제는 Hash Collision의 기초 원리에 대해 이해하고 있냐에 대하여 묻는 문제이다.
argv[1]에 넣은 값이 check_password라는 함수를 거치면서 가공되고, 그 리턴 값이 0x21DD09EC가 되면 flag값이 나오는 듯 하다.

여기서 주목해야 할 부분은 총 세 부분, 크게는 두 부분이다.

가장 먼저, 문제의 입력 값 제한이다.

if(strlen(argv[1]) != 20){
    printf("passcode length should be 20 bytes\n");
    return 0;
}

이 문제에서는 입력 값을 char형으로 20Byte를 받고 있다는 것을 알 수 있다.

다음으로 살펴볼 곳은 연산부분이다.

unsigned long check_password(const char* p){
    int* ip = (int*)p;
    int i;
    int res=0;
    for(i=0; i<5; i++){
        res += ip[i];
    }
    return res;
}

이 부분을 보면 왜 입력 값을 char형 20Byte를 받는지 알 수 있다.
우선, int* ip = (int*)p;를 이용하여 문자열 배열을 강제로 정수 배열로 형변환을 하는 것에 주목하자, 만일 이 코드가 컴파일 된 환경에서의 int형 크기가 WORD형이라고 가정할 시, 아래의 for(i=0; i<5; i++);와 함께 쓰여, 총 20Byte를 가리키게 된다는 것을 알 수 있다.

그렇다면 대략적인 틀이 잡혔다. 총 20바이트의 문자열을 4바이트 단위로 끊어, 정수형으로 강제 형변환한 뒤, res라는 변수에 더하게 된다. 결국, 디버깅까지도 필요 없는, 단순 코드 분석 문제라는 것이다.

그럼 우리가 argv[1]에는 무엇을 넣어주어야 할까? 다시 코드로 돌아가서 다음 부분들을 살펴보자.

unsigned long hashcode = 0x21DD09EC;
if(hashcode == check_password( argv[1] ))

좋다, 이제 풀이를 위한 모든 재료가 모였다. 이제 적절하게 요리해보자. 간단하게 0x21DD09EC를 통째로 5로 나눈 뒤, 그 값을 반복해서 5번 입력해주되, 소수점 손실만 보정해주면 될 듯 하다. 자, 계산기를 꺼내 계산하자.

0x21DD09EC를 5로 나눈 몫 : 0x6C5CEC8
0x21DD09EC를 5로 나눈 나머지 : 0x4

이제 공격코드를 도출해낼 수 있다. 그 모습은 다음과 같다.

`python -c 'print "\xc8\xce\xc5\x06"*4+"\xcc\xce\xc5\x06"'`



4. Flag
col@ubuntu:~$ ./col `python -c 'print "\xc8\xce\xc5\x06"*4+"\xcc\xce\xc5\x06"'`
daddy! I just managed to create a hash collision :)
Posted by RevDev
,