프로그래밍을 하다 보면, 특히나 리눅스 환경에서 프로그래밍을 하다 보면 쉘 스크립트(Shell script)라는 단어를 들을 일이 있는데, 비슷한 단어인 쉘 코드(shell code)라는 단어와 햇갈릴 수 있습니다.

 

이 두 용어는 확실히 다른 단어로 혼용하시면 안됩니다.

 

간단하게 말하자면

 

쉘 스크립트쉘에서 사용되는 명령어를 나열한 실행가능한 텍스트파일이며,

쉘 코드쉘을 실행시키는 코드입니다.

 

실제 제가 사용하는 쉘 스크립트를 예를 들어 설명해보도록 하겠습니다.

 

리눅스 시스템에는 가장 범용적인 커멘드라인 쉘인 bash가 있습니다.

사용자는 이 bash 쉘에 명령어를 입력해서 무언가 하고싶은 동작들을 할 수 있습니다.

 

이 리눅스의 사용자인 저는, 리눅스 환경에서 알고리즘 문제를 풀려고, 문제별로 디렉토리와 소스코드 파일, 및 입력 테스트 케이스 파일들을 생성해서 잘 정리해 놓습니다.

 

그런데 매 문제를 만들 때 마다 디렉토리 구조를 만들고, 하는 것들이 항상 번거로워서 이를 자동화 하려고 합니다.

 

따라서 쉘 스크립트 파일 mk.sh 를 만들고, 이를 이용해서 디렉토리를 쉽게 만들려고 합니다.

 

아래에 첨부된 쉘 스크립트에 실행 권한을 준 뒤 다음 명령어를 입력하면 디렉토리가 생성됩니다.

 

./mk.sh dir main.cpp 3

위와 같이 인자를 주게 되면 다음과 같은 디렉토리 구조가 생성되게 됩니다.

> dir
-----> bin
-----> src
----------> main.cpp
-----> input1.txt
-----> input2.txt
-----> input3.txt

쉘 스크립트의 첫번째 인자는 문제 이름을 나타내는 디렉토리 명이며, 두번째 인자는 소스코드의 명입니다. 세번째 인자는 input.txt 파일의 개수가 됩니다.

 

mk.sh 쉘 스크립트의 내용은 다음과 같습니다.

#!/bin/bash

dir_path=$1
src_fname=$2
num_args=$#


if [ "$num_args" -ge 2 ]; then
    echo "mkdir -p `pwd`/$dir_path/src"
    mkdir -p `pwd`/$dir_path/src
    echo "touch `pwd`/$dir_path/src/$src_fname"
    if [ `echo $src_fname | cut -d"." -f2` == "cpp" ]; then
        echo -e "#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n\treturn 0;\n}\n" > `pwd`/$dir_path/src/$src_fname
    else
        touch `pwd`/$dir_path/src/$src_fname
    fi
    if [ "$num_args" -eq 3 ]; then
        num_input=$3
        
        i=1
        while [ $i -le $num_input ]
        do
            echo "touch `pwd`/$dir_path/input.$i.txt"
            touch `pwd`/$dir_path/input.$i.txt
            i=`expr $i + 1`
        done

    else
        echo "touch `pwd`/$dir_path/input.1.txt"
        touch `pwd`/$dir_path/input.1.txt    
    fi

else
    echo "Usage: $0 [directory path] [source file name with extension] (number of input file. optional)"
    echo "Supported file extension: cpp, py, asm"
    echo "사용법: $0 [디렉토리 경로] [확장자 포함 소스파일 이름] (입력 파일 개수. 옵션)"
    echo "지원하는 확장자: cpp, py, asm"
    

fi

 

위와 같이 쉘 스크립트를 텍스트 파일로 작성한 뒤, 실행을 하면 스크립트 안에 있는 내용들이 bash 쉘에서 순차적으로 실행되어 결과를 내게 됩니다.

 

이와 같이 쉘 스크립트쉘에서 동작하는 명령어들을 한꺼번에 텍스트 파일로 모아서, 여러번 사용가능하게 만들어 놓은 것이 쉘 스크립트입니다.

 

 

이와는 다르게 쉘 코드쉘을 실행시키는 코드입니다.

 

가령 Python으로 작성을 한다면 다음과 같은 코드가 쉘 코드가 되겠죠

import os

os.system("/bin/bash")

아니면 다음과 같은 방식으로도 생성할 수 있습니다.

쉘 코드 생성을 처음 공부할 때에는 많이 사용하는 방법 중 하나입니다.

 

다음과 같은 C언어 코드를 작성합니다.

#include <stdlib.h>
int main()
{
	char *str[2];
	str[0] = "/bin/bash";
	str[1] = 0;	
	execve(str[0], str, 0);
}

 

위 녀석을 컴파일하여 기계어로 만든 뒤, 독립적으로 실행되어도 쉘이 떨어지도록 정제를 합니다.

이 부분에 디테일한 부분은 생략하도록 하고, 좀더 내용을 보고싶으면 참고한 해커스쿨 쉘코드 강좌 링크를 눌러보세요.

 

오래된 자료라서 지금과는 많이 환경이 맞지 않는 부분이 있을 수는 있으나, 개념적인 부분은 도움이 많이 될 것입니다.

 

과정은 생략하고, 결과적으로는 

\xeb\x15\x31\xc0\x5b\x89\x43\x07\x89\x1e\x89\x46\x04\xb0\x0b\x31\xe4\x8d\x0e \x31\xd2\xcd\x80\xe8\xe6\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68

와 같은 기계어 코드를 얻을 수 있습니다.

 

이 기계어 코드가 CPU에서 실행되면, 쉘이 나타나게 되는 것이죠. 저러한 코드를 쉘 코드라고 부릅니다.

 

요 녀석은 일반적인 개발에서는 사용할 일이 거의 없는데, 해킹을 할 때에는 필수적인 녀석 중 하나입니다.

 

해커들이 보통 하는짓들이 프로그램의 취약점을 찾아내서, 의도치 않은 쉘을 띄우게 하는 것이기 때문이죠. 이 때, 쉘을 띄우게 하기 위해서 저 쉘코드를 주입한 뒤, 프로그램 카운터를 쉘코드의 시작 주소로 이동시켜서 쉘을 실행시킵니다.

 

아무쪼록 쉘코드와 쉘스크립트의 차이점에 대해 잘 이해가 되었기를 기원하며 이만 글을 줄입니다.

버프슈트 설치

 

웹 해킹을 입문/공부/실시 할 때 가장 많이 쓰이는 툴 중 하나가 웹 프록시(Web Proxy)입니다.

 

HTTP/HTTPS 웹 요청과 응답을 잠시 잡아두고, 그 패킷 내용을 확인해보거나 변조하기 용이하기 때문입니다.

 

 

이러한 웹 프록시는 종류가 다양한데, 그 중 많이 쓰이는 것 중 하나가 버프슈트(Burp suite)입니다.

 

https://portswigger.net/burp

 

Burp Suite Scanner | PortSwigger

PortSwigger offers Burp Suite for security testing & scanning. Choose from a wide range of security tools & identify the very latest vulnerabilities.

portswigger.net

공식 사이트를 방문해 보면, 버프슈트가 3가지 종류가 있는 것으로 나오는데, 딱 봐도 Enterprise와 Professional 버전에는 $표시와 금액이 표시 되어 있어서, 연간 사용료를 지급해야지 쓸 수 있는 버전임을 알 수 있습니다.

 

저희는 가난하기 때문에, 무료 버전인 Community 버전을 사용하도록 합니다.

 

Burp suite community version을 다운받아서 설치하도록 합니다.

 

그리고 실행을 해 보면 Java로 만든 듯한 GUI 환경이 펼쳐집니다.

 

아마 Disk based project는 버프슈트의 설정값들을 프로젝트별 디렉토리에 저장해놓고 두고두고 사용할 수 있는가 봅니다.

 

 Community는 Temporary Project만 사용가능하답니다. 따라서 하단의 Next를 누릅니다.

config 값들을 파일로 갖고있는 것은 Community 버전에도 가능한가봅니다. 기본 값으로 설정하고 우측 하단의 Start Burp를 눌러보겠습니다.

 

뭔가 기능이 많이보이는 GUI가 나타납니다. 일단 여기서는 Intercept 기능만 사용해 볼 것입니다.

 

우측 상단의 Alerts를 눌러보면, 

위와 같은 메시지가 떠있는 것을 알 수 있는데요, 프록시 서버가 로컬호스트 8080포트에서 시작되었음을 알 수 있습니다.

프록시 설정 - 인터넷 옵션

 

이제 그러면, 웹 브라우저에서 버프슈트를 잘 받아들이도록 설정을 해보도록 하겠습니다.

지금 하려는 설정은 프록시 설정인데, 이 프록시 설정은 크게 두가지 방법이 있습니다.

 

인터넷 옵션을 수정하는 방법과, 크롬 익스텐션을 이용하는 방법이 있습니다.

 

지금 보여드리는 방법은 인터넷 옵션을 수정하는 방법으로, 모든 웹 브라우저가 프록시 설정이 되게 됩니다.

크롬 익스텐션을 이용하는 방법은 크롬에서만 프록시가 설정되도록 할 수 있고 좀 더 디테일한 설정이 가능합니다.

 

일단은 인터넷 옵션 설정부터 보여드리겠습니다.

 

저는 크롬브라우저를 주로 사용하므로, 크롬 브라우저 기준으로 설명드리겠습니다.

크롬 브라우저 우측 상단의 점 3개 짜리 더 보기 아이콘을 누른 뒤, 설정으로 들어갑니다.

스크롤을 쭉 내려서 가장 아래로 간 뒤, 고급 을 누릅니다.

그리고 다시 가장 아래로 스크롤을 내린 뒤, "프록시 설정 열기"를 클릭합니다.

인터넷 속성 창이 뜨는데 하단의 LAN 설정을 누릅니다.

프록시 서버에 체크박스를 체크한 뒤, 주소와 포트를 위와 같이 127.0.0.1 / 8080으로 입력한 뒤 확인 버튼을 누릅니다.

 

그러면 웹 브라우저 설정은 준비가 되었습니다.

 

이제 웹 브라우저에서 아무 페이지로 요청을 보내보도록 하겠습니다. 아직 인증서 설정은 하지 않았으니, 가급적 http 평문 페이지로 이동 요청을 해 보겠습니다.

 

버프슈트 Intercept 항목에 주황색으로 Highlighting이 되면서 HTTP GET 요청 패킷이 잡혔습니다.

 

여기서 Forward를 누르면 해당 패킷이 지나갈 수 있게 놓아주며, Drop을 누르면 패킷을 보내지 않고 버리게 됩니다.

 

그리고 패킷 내용에 커서를 놓고 값을 변경할 수 도 있습니다.

 

Intercept is on 을 눌러서 intercept is off로 만들면 패킷들이 쭈르륵하고 자기 갈 길을 가도록 할 수 있습니다.

프록시 설정 - 크롬 익스텐션 SwitchyOmega

이제는 크롬 익스텐션 중 하나인 SwitchOmega를 이용해서 프록시를 설정해보도록 하겠습니다.

일단 아까 인터넷 설정에서 프록시 설정한 부분은 원래대로 되돌려 놓어야 합니다.

 

https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif

 

Proxy SwitchyOmega

Manage and switch between multiple proxies quickly & easily.

chrome.google.com

아래 링크로 이동하시면 Proxy SwitchyOmega 익스텐션을 확인할 수 있습니다.

저는 이미 설치를 해 놓았기 때문에, Chrome에서 삭제라고 우측 상단 버튼이 떠 있지만, 여러분들은 설치를 해주시면 됩니다.

 

그리고 Proxy 설정을 원하는 사이트로 이동합니다. 저 같은 경우에는 webhacking.kr로 이동했습니다.

그리고 우측 상단에 있는 SwitchyOmega 아이콘을 눌러서 순서대로 누르게 되면 webhacking.kr 도메인에서만 프록시가 설정되도록 할 수 있습니다.

 

그 외에도 다양한 기능들이 있는데 이것 저것 눌러보시고 가이드를 확인하면서 사용하시면 편리함을 느끼실 수 있을 겁니다. (저는 저 기능밖에 안씁니다)

 

Challenge 'Bitecode' give us a simple java class file. We can simply get java class file by compiling java source code file.

On the other hand, we can simply get java source code file by decompiling java class file.

 

I can find online java decompiler site. [http://www.javadecompilers.com/]

 

There are several versions of decompiler. I tried all of them, but only second one "CFR" was working.

 

 

I got the java source code like above.

Full decompiled java source code is below.

 

/*
 * Decompiled with CFR 0.139.
 * 
 * Could not load the following classes:
 *  \u0000java.lang.System
 */
import \u0000java.lang.System;
import java.io.PrintStream;

/*
 * Class file version 45.0 predates 45.3 (Java 1.0), recompilation may lose compatibility!
 */
public class BiteCode {
    private static /* synthetic */ int a;

    /*
     * Unable to fully structure code
     */
    public static void main(String[] var0) {
        block83 : {
            block67 : {
                block82 : {
                    block77 : {
                        block81 : {
                            block54 : {
                                block80 : {
                                    block79 : {
                                        block57 : {
                                            block78 : {
                                                block74 : {
                                                    block76 : {
                                                        block75 : {
                                                            block60 : {
                                                                block73 : {
                                                                    block62 : {
                                                                        block72 : {
                                                                            block56 : {
                                                                                block71 : {
                                                                                    block64 : {
                                                                                        block70 : {
                                                                                            block69 : {
                                                                                                block68 : {
                                                                                                    block66 : {
                                                                                                        block65 : {
                                                                                                            block63 : {
                                                                                                                block61 : {
                                                                                                                    block55 : {
                                                                                                                        block59 : {
                                                                                                                            block58 : {
                                                                                                                                var1_1 = var0.length;
                                                                                                                                var2_2 = BiteCode.a;
                                                                                                                                if (var1_1 - 1 != 0) {
                                                                                                                                    (System)null;
                                                                                                                                    java.lang.System.out.println("Nah");
                                                                                                                                    return;
                                                                                                                                }
                                                                                                                                var3_3 = var0[0].toCharArray();
                                                                                                                                var4_4 = var3_3.length;
                                                                                                                                if ((var4_4 ^ 927739485 ^ 927739457) != 0) {
                                                                                                                                    (System)null;
                                                                                                                                    java.lang.System.out.println("Nah");
                                                                                                                                    return;
lbl15: // 1 sources:
                                                                                                                                    do {
                                                                                                                                        switch (var2_2) {
                                                                                                                                            default: 
                                                                                                                                        }
                                                                                                                                        java.lang.System.out.println("Yeah");
                                                                                                                                        return;
                                                                                                                                        break;
                                                                                                                                    } while (true);
                                                                                                                                }
                                                                                                                                v0 = var3_3;
                                                                                                                                if ((v0[0] ^ 189074585) - 189074673 != 0) lbl-1000: // 3 sources:
                                                                                                                                {
                                                                                                                                    do {
                                                                                                                                        if (var2_2 == 0) {
                                                                                                                                            (System)null;
                                                                                                                                            java.lang.System.out.println("Nah");
                                                                                                                                            return;
                                                                                                                                        }
                                                                                                                                        break block54;
                                                                                                                                        break;
                                                                                                                                    } while (true);
                                                                                                                                }
                                                                                                                                if ((v0[1] ^ -227215135) - -227215214 != 0) lbl-1000: // 2 sources:
                                                                                                                                {
                                                                                                                                    do {
                                                                                                                                        if (var2_2 == 0) {
                                                                                                                                            (System)null;
                                                                                                                                            java.lang.System.out.println("Nah");
                                                                                                                                            return;
                                                                                                                                        }
                                                                                                                                        break block55;
                                                                                                                                        break;
                                                                                                                                    } while (true);
                                                                                                                                }
                                                                                                                                if ((v0[2] ^ 19240864) - 19240899 == 0) break block58;
                                                                                                                                if (var2_2 != 0) ** GOTO lbl-1000
                                                                                                                                (System)null;
                                                                                                                                java.lang.System.out.println("Nah");
                                                                                                                                return;
                                                                                                                            }
                                                                                                                            if ((v0[3] ^ 245881291) - 245881279 == 0) break block59;
                                                                                                                            if (var2_2 == 0) {
                                                                                                                                (System)null;
                                                                                                                                java.lang.System.out.println("Nah");
                                                                                                                                return;
                                                                                                                            }
                                                                                                                            break block60;
                                                                                                                        }
                                                                                                                        if ((v0[4] ^ 233391094) - 233390992 == 0) break block61;
                                                                                                                    }
lbl54: // 2 sources:
                                                                                                                    while (var2_2 == 0) {
                                                                                                                        (System)null;
                                                                                                                        java.lang.System.out.println("Nah");
                                                                                                                        return;
                                                                                                                    }
                                                                                                                    break block62;
                                                                                                                }
                                                                                                                if ((v0[5] ^ 56978353) - 56978378 == 0) break block63;
lbl62: // 2 sources:
                                                                                                                while (var2_2 == 0) {
                                                                                                                    (System)null;
                                                                                                                    java.lang.System.out.println("Nah");
                                                                                                                    return;
                                                                                                                }
                                                                                                                break block64;
                                                                                                            }
                                                                                                            if ((v0[6] ^ -213838484) - -213838565 != 0) lbl-1000: // 4 sources:
                                                                                                            {
                                                                                                                do {
                                                                                                                    if (var2_2 == 0) {
                                                                                                                        (System)null;
                                                                                                                        java.lang.System.out.println("Nah");
                                                                                                                        return;
                                                                                                                    }
                                                                                                                    break block56;
                                                                                                                    break;
                                                                                                                } while (true);
                                                                                                            }
                                                                                                            if ((v0[7] ^ -231671677) - -231671605 == 0) break block65;
lbl78: // 3 sources:
                                                                                                            do {
                                                                                                                if (var2_2 != 0) ** GOTO lbl-1000
                                                                                                                (System)null;
                                                                                                                java.lang.System.out.println("Nah");
                                                                                                                return;
                                                                                                                break;
                                                                                                            } while (true);
                                                                                                        }
                                                                                                        if ((v0[8] ^ -132473862) - -132473910 == 0) break block66;
                                                                                                        if (var2_2 == 0) {
                                                                                                            (System)null;
                                                                                                            java.lang.System.out.println("Nah");
                                                                                                            return;
                                                                                                        }
                                                                                                        break block67;
                                                                                                    }
                                                                                                    if ((v0[9] ^ 143449065) - 143449053 == 0) break block68;
lbl94: // 2 sources:
                                                                                                    while (var2_2 == 0) {
                                                                                                        (System)null;
                                                                                                        java.lang.System.out.println("Nah");
                                                                                                        return;
                                                                                                    }
                                                                                                    break block56;
                                                                                                }
                                                                                                if ((v0[10] ^ 108102484) - 108102411 == 0) break block69;
                                                                                                do {
                                                                                                    if (var2_2 != 0) ** GOTO lbl-1000
                                                                                                    (System)null;
                                                                                                    java.lang.System.out.println("Nah");
                                                                                                    return;
                                                                                                    break;
                                                                                                } while (true);
                                                                                            }
                                                                                            if ((v0[11] ^ 71123188) - 71123073 == 0) break block70;
                                                                                            if (var2_2 != 0) ** GOTO lbl62
                                                                                            (System)null;
                                                                                            java.lang.System.out.println("Nah");
                                                                                            return;
                                                                                        }
                                                                                        if ((v0[12] ^ 146096006) - 146096089 == 0) break block71;
                                                                                    }
                                                                                    if (var2_2 != 0) ** GOTO lbl94
                                                                                    (System)null;
                                                                                    java.lang.System.out.println("Nah");
                                                                                    return;
                                                                                }
                                                                                if ((v0[13] ^ -173487738) - -173487628 == 0) break block72;
                                                                            }
                                                                            if (var2_2 != 0) ** GOTO lbl54
                                                                            (System)null;
                                                                            java.lang.System.out.println("Nah");
                                                                            return;
                                                                        }
                                                                        if ((v0[14] ^ -116507045) - -116507132 == 0) break block73;
                                                                    }
                                                                    if (var2_2 == 0) {
                                                                        (System)null;
                                                                        java.lang.System.out.println("Nah");
                                                                        return;
                                                                    }
                                                                    break block74;
                                                                }
                                                                if ((v0[15] ^ -68013365) - -68013319 == 0) break block75;
                                                            }
lbl143: // 2 sources:
                                                            do {
                                                                if (var2_2 == 0) {
                                                                    (System)null;
                                                                    java.lang.System.out.println("Nah");
                                                                    return;
                                                                }
                                                                break block57;
                                                                break;
                                                            } while (true);
                                                        }
                                                        if ((v0[16] ^ 171414622) - 171414529 != 0) {
                                                            do {
                                                                if (var2_2 != 0) ** continue;
                                                                (System)null;
                                                                java.lang.System.out.println("Nah");
                                                                return;
                                                                break;
                                                            } while (true);
                                                        }
                                                        if ((v0[17] ^ 94412444) - 94412524 == 0) break block76;
lbl159: // 2 sources:
                                                        while (var2_2 == 0) {
                                                            (System)null;
                                                            java.lang.System.out.println("Nah");
                                                            return;
                                                        }
                                                        break block77;
                                                    }
                                                    if ((v0[18] ^ 197453081) - 197453163 == 0) break block78;
                                                }
                                                ** while (var2_2 != 0)
lbl169: // 1 sources:
                                                (System)null;
                                                java.lang.System.out.println("Nah");
                                                return;
                                            }
                                            if ((v0[19] ^ -50622153) - -50622201 == 0) break block79;
                                        }
                                        if (var2_2 != 0) ** GOTO lbl159
                                        (System)null;
                                        java.lang.System.out.println("Nah");
                                        return;
                                    }
                                    if ((v0[20] ^ 190140381) - 190140290 == 0) break block80;
                                    if (var2_2 != 0) ** GOTO lbl78
                                    (System)null;
                                    java.lang.System.out.println("Nah");
                                    return;
                                }
                                if ((v0[21] ^ 77383944) - 77383996 == 0) break block81;
                            }
                            ** while (var2_2 != 0)
lbl192: // 1 sources:
                            (System)null;
                            java.lang.System.out.println("Nah");
                            return;
                        }
                        if ((v0[22] ^ -41590082) - -41590047 == 0) break block82;
                    }
                    ** while (var2_2 != 0)
lbl200: // 1 sources:
                    (System)null;
                    java.lang.System.out.println("Nah");
                    return;
                }
                if ((v0[23] ^ 61204303) - 61204283 != 0) lbl-1000: // 2 sources:
                {
                    do {
                        if (var2_2 != 0) ** continue;
                        (System)null;
                        java.lang.System.out.println("Nah");
                        return;
                        break;
                    } while (true);
                }
                if ((v0[24] ^ -24637751) - -24637791 != 0) {
                    if (var2_2 != 0) ** continue;
                    (System)null;
                    java.lang.System.out.println("Nah");
                    return;
                }
                if ((v0[25] ^ 61697107) - 61697122 != 0) {
                    if (var2_2 != 0) ** continue;
                    (System)null;
                    java.lang.System.out.println("Nah");
                    return;
                }
                if ((v0[26] ^ 267894989) - 267895017 == 0) break block83;
            }
            while (var2_2 != 0) {
            }
            (System)null;
            java.lang.System.out.println("Nah");
            return;
        }
        ** while ((v0[27] ^ -13480562) - -13480461 == 0)
lbl234: // 1 sources:
        ** while (var2_2 != 0)
lbl235: // 1 sources:
        (System)null;
        java.lang.System.out.println("Nah");
    }
}

Analyzing overall source code with peek, the java program get a single main function argument input called 'var0'

 

We can simply guess, printing "Nah" means invalid input.

The number of argument (var1_1) should be 1,

The length of first argument (var4_4) should be 927739485 ^ 927739456 => 28

 

With similar pattern, the first character of argument (v0[0]) shoudl be 189074585 ^ 189074673

The second character of argument (v0[1]) should be -227215135 ^ -227215214

 

Proceeding this work, we can easily find not only the header of flag "hsctf{", but also the rest part of the flag.

 

You can do it manualy one by one, or write a python script to extract the source code line contains the pattern like "v0[index] ^ A - B != 0" and evaluate the each letter on flag.

But I did with hand one by one.

+ Recent posts