Buffer Overflow

먼저 시작하기에 앞서 미리 알려드립니다!
내용이 요리조리로 통통 튀어다니면서 이상하고 틀린 부분도 있을 수 있습니다.

이번엔 시스템 해킹에서의 기본 중의 기본인 BOF를 정리하는걸로...

먼저 BOF는 말 그대로 Buffer (버퍼가) Overflow (넘치다)

버퍼가 넘친다는 말입니다.

프로그래머의 실수로 인해 버퍼가 할당받은 공간에 크기 제한을 하지 않고 값들을 집어넣어 할당받은 공간보다 더 값을 넣을 수 있는 취약점입니다.


쉽게 말해서 buf[10]이라는 배열을 만들었다면,

이 배열은 총 10개의 공간을 가지게 됩니다.

하지만 buf에 10개의 값을 넣는게 아닌 11개, 12개 혹은 그 이상의 값들을 크기를 확인하지 않고 마구잡이로 넣어서 BOF 취약점이 터지게 되는 것이죠 :D


먼저 BOF에 들어가기 앞서 스택 구조와 프롤로그 에필로그에 대해 알아보도록 하겠습니다.


Hello STACK!

네, 스택은 과연 무엇일까요?



이 블루스택 프로그램을 말하는 걸까요?

오...아쉽게도 아이콘은 비슷했지만 이 프로그램을 말하는 것은 아니였습니다.


음, 프로그래밍을 좀 해보셨다면 자료구조에서 스택을 분명히 들어보셨을겁니다.


  

스택은 선입후출 FILO(First In Last Out), 후입선출 LIFO(Last In First Out) 구조를 가지고 있으며, 쉽게 말해 접시와 같다고 흔히들 비교를 하십니다.



이렇게 처음에 쌓인 것이 나중에 나온다 해서 접시, 책 등등으로 쉽게 비교를 하시며 설명을 하십니다.


Open Program in GDB!

먼저 BOF 취약점이 존재하는 프로그램을 GDB에서 열어보았습니다.

아래는 그 프로그램의 코드입니다.


#include <stdio.h>

int main(int argc, char *argv[])
{
        char buf[10];
        scanf("%s", buf);

        return 0;
}



앗, 먼저 저희는 프롤로그와 에필로그에 대한 지식이 필요할 것 같습니다.

일단 여기서 뒤로 하고 프롤로그 에필로그에 대해 알아보도록 하겠습니다.


Stack Prologue&Epilogue

음...프롤로그 에필로그를 어디에서 들어봤을까요?
저는 보통 웹툰에서 들어본 것 같습니다...!

말 그대로 함수의 시작과 끝을 말해주는 녀석입니다.

Prologue

push ebp
mov ebp, esp

해당 함수가 시작된다는 것을 알려주는 녀석입니다.

Epilogue

leave
ret

이 leaveret을 풀어보게 되면 아래와 같아집니다.

leave

mov esp, ebp
pop ebp

ret

pop eip
jmp eip

말 그대로 leave에서는 프롤로그에서 push ebp 한 것을 스택에서 pop ebp로 스택에서 꺼내주는 과정입니다.

네, 그렇다면 프롤로그 에필로그를 이해했다면 아까 중간에 끊긴 것을 이어가도록 하겠습니다!

아까 보셨던 BOF 취약점이 존재하는 프로그램을 GDB에서 열은 것입니다.


먼저 프롤로그가 시작됩니다.



sub esp, 0x20은 스택을 사용하기 위해 공간을 확보하는 것입니다.


그 뒤에는 scanf가 실행되는데요.

위에 mov되는 것은 저희가 넘겨준 인자들입니다.



그렇다면 버퍼의 주소는 0xffffd6e6이겠네요.

그리고 실제로 버퍼 주소가 맞는 것을 확인할 수 있었습니다.



그렇다면 이번에는 크기를 제한하지 않고 버퍼보다 많은 값들을 넘겨줘보겠습니다.



띠용 eip가 주작이 되었습니다.


이제 여기서 알아야될 것은 SFP와 RET입니다!



위와 같이 생겨먹었습니다.

dummy는 gcc 2.9.6? 2.9.5? 음...아무튼 저 근처대의 버전에서 더미가 추가되었습니다.


SFP는 이전 함수의 EBP를 저장해두는 장소입니다.

해당 함수가 끝이 나서 함수를 빠져나와야되는데, 돌아갈 주소를 다시 찾아가기 위한 저장소(?)입니다.


RET은 SFP와 마찬가지로 이전 함수로 돌아가기 위한 주소를 가지고 있습니다.


아무튼, 위와 같은 구조를 가지고 있었기에, buf와 dummy를 넘기고 RET까지 도달하였기에 0x62626262으로 이동하게 된 것 입니다.

이러한 방법으로 RET을 의도적으로 원하는 주소로 이동시킬 수 있기 때문에

프로그램을 해커가 원하는 흐름으로 바꿀 수 있게 되는 것 입니다.


BOF는 해킹의 꽃이라고 볼 수도 있을 것 같습니다!

감사합니다.

'0x20 Security > 0x21 System' 카테고리의 다른 글

Format String Bug (FSB)  (0) 2016.12.01
Save Frame Pointer Overwrite (SFO)  (0) 2016.07.25
About LD_PRELOAD  (0) 2016.07.20
Use After Free (UAF)  (1) 2016.07.13
How main() is executed on linux  (2) 2016.07.04

그러타.

나는 미스터 로봇 시즌1을 다본 사람이다.

미스터 로봇 시즌1이 끝날때 마지막 부분에 아쉽게 끝내서 아쉬워하던 도중

어제 미스터 로봇 시즌 2가 나왔다는 소리를 들었다.


 

오.. 세상에 7월 13일에 나왔다니.


현재는 3화까지 나와있다.


아니 근데 여기서 왜 미스터 로봇이 롸이트업에 들어가있느냐~!?


바로 미스터 로봇에 숨겨진 이스터 에그가 있었다.



바로 이 장면에 나타나는 모니터에 있었다.



이 장면은 tool을 이용하여 랜섬웨어를 생성하는 장면이였는데.


수상한 아이피를 발견할 수 있었다.


192.251.68.254:80에 랜섬웨어가 배포되는 것처럼 느껴진다.


그리고 실제로 접속이 되는지 확인을 해보았다.



실제로 접속이 되고 헤더 중 Location을 발견할 수 있는데,

http://i254.bxjyb2jvda.net/에 리다이렉트가 되는 것을 발견할 수 있었다.



마지막으로는 http://i239.bxjyb2jvda.net 로 이동을 하게 된다.



실제로 접속해보면 이러한 페이지가 나타난다.

타이머로 시간이 가고 있고 요상한 페이지였다.



또로롱


그리고 web_analytics.js 라는 수상한 스크립트를 발견할 수 있었다.


web_analytics.js 코드는 아래와 같다.



/* analytics */

var AdobeTracking = new Object();

AdobeTracking.division = 'Cable';

AdobeTracking.businessUnit = 'USA Network';

AdobeTracking.contentGroup = 'Drama';

AdobeTracking.contentType = 'Home';

AdobeTracking.pageName = 'Mr. Robot : S2 Easter Egg Sites : Ransomware : Home';

AdobeTracking.showSite = 'Mr. Robot';

var q='PGRpdiBjbGFzcz0ib3ZlciI+PGRpdj4iSSBzaW5jZXJlbHkgYmVsaWV2ZSB0aGF0IGJhbmtpbmcgZXN0YWJsaXNobWVudHMgYXJlIG1vcmUgZGFuZ2Vyb3VzIHRoYW4gc3RhbmRpbmcgYXJtaWVzLCBhbmQgdGhhdCB0aGUgcHJpbmNpcGxlIG9mIHNwZW5kaW5nIG1vbmV5IHRvIGJlIHBhaWQgYnkgcG9zdGVyaXR5LCB1bmRlciB0aGUgbmFtZSBvZiBmdW5kaW5nLCBpcyBidXQgc3dpbmRsaW5nIGZ1dHVyaXR5IG9uIGEgbGFyZ2Ugc2NhbGUuIjwvZGl2PjxkaXYgY2xhc3M9ImF1dGhvciI+LSBUaG9tYXMgSmVmZmVyc29uPC9zcGFuPjwvZGl2PjwvZGl2Pg==';

AdobeTracking.showSiteFeatureII = 'Mr. Robot : S2 Easter Egg Sites : Ransomware';

function fire_beacon() { return window.atob(q); }

AdobeTracking.showSiteFeature = 'Mr. Robot : S2 Easter Egg Sites';

function fire_beacon_final(periods) { if ($('.over').length > 0) { AdobeTracking.pageName = 'Mr. Robot : S2 Easter Egg Sites : Ransomware : Countdown Ended'; _satellite.track('virtPageTrack'); }}

$(function () { var austDay = new Date(); austDay.setSeconds(austDay.getSeconds() + 86394 /*86394*/); $('#defaultCountdown').countdown({until: austDay,expiryText: fire_beacon(),onTick: fire_beacon_final, tickInterval: 1});});

_satellite.pageBottom();



뭐 그 뒤는 저 base64 인코딩된 문자열을 디코딩을 해보면.



라는 문자열을 발견하게 된다.


I sincerely believe that banking establishments are more dangerous than standing armies, and that the principle of spending money to be paid by posterity, under the name of funding, is but swindling futurity on a large scale.

- Thomas Jefferson


아마 나중에 나올 스토리와 연관이 있는 것 같다.

기대된다 ... !

'0x20 Security > 0x25 Write-Ups' 카테고리의 다른 글

[Pwnable.kr] input - 4 pt  (0) 2017.01.04
[Pwnable.kr] cmd2 - 9 pt  (0) 2016.10.05
[ReverseLab 스터디] [Abex's CM] Abex 1~5  (0) 2016.07.11
[Pwnable.kr] dragon - 75 pt  (0) 2016.06.25
[Codegate2016] Write ups  (372) 2016.03.18

LD_PRELOAD에 대해 ARABOZA

LOB 문제를 풀다 처음 알게 되어서 정리를 해봤습니다.

아, 환경마다 PRELOAD 환경 변수 이름이 다르더라구요.
뭐 사실상 AIX 빼고는 다 이름이 같습니다.

what is LD_PRELOAD ?

프로세스를 실행하는 중에 라이브러리를 로딩할 때,
이 LD_PRELOAD 환경변수가 설정되있으면 해당 변수에 지정된 라이브러리를 먼저 로딩을 하고,
이 중에 libc 함수명과 동일한 함수가 있다면 해당 함수를 먼저 호출을 해주게 됩니다.


where is LD_PRELOAD ?


LD_PRELOAD의 메모리 영역은 공유 라이브러리 영역에 존재해서 stack 영역보다 낮은 주소에 존재합니다. 


Let's compile shared library!

.so로 컴파일 하기 위해서는 아래와 같은 옵션을 넘겨주어야됩니다.


-Wall 옵션 : 모든 경고 메세지를 출력 (사실 상 안넘겨주어도 되는 옵션입니다.)
-fPIC 옵션 : Position-Independent Code의 약자이며 test.o파일을 동적라이브러리로 사용하도록 컴파일 하는 옵션이다.
-shared 옵션 : 공유 라이브러리를 만드는 옵션


$ gcc -Wall -fPIC -shared -o filename.so filesource.c


같이 공유 라이브러리를 컴파일 할 수 있습니다.


Modify LD_PRELOAD

초 간단합니다.

$ export LD_PRELOAD="./filename.so"


Fun it !

그렇다면 이 LD_PRELOAD를 이용하여 후킹을 해보도록 하겠습니다.


hostname 명령어는 말 그대로 호스트네임의 값을 출력해주는 명령어입니다.



gethostname를 만들면 되겠네요!



#include <stdlib.h>

#include <string.h>


int gethostname(char *name, size_t len)

{

    strncpy(name, "HOOKHOOK", len-1);

    name[len-1] = '\0';

    return 0;

}



$ gcc -shared -fPIC -o hook.so a.c


컴파일을 하신 뒤,



LD_PRELOAD에 직접 만든 라이브러리 경로를 넘겨주고!

실행을 하게 되면.



잘 된 것을 볼 수 있습니다!


하지만, 중요한 것은 LD_PRELOAD는 setuid가 걸려있으면 동작을 하지 않습니다.




'0x20 Security > 0x21 System' 카테고리의 다른 글

Save Frame Pointer Overwrite (SFO)  (0) 2016.07.25
Buffer Overflow (BOF)  (2) 2016.07.22
Use After Free (UAF)  (1) 2016.07.13
How main() is executed on linux  (2) 2016.07.04
System Hacking :: Memory Protection  (0) 2016.06.28

C# 7.0 New Features

C# 7.0 새로운 기능 소개

튜플 ( Tuples )

자, C# 7.0에서 새롭게 달라진 튜플들을 알아보도록 하겠습니다.

Before Code


struct infos{ public int age; public string school;}
public infos Getinfo(string name) { ... }
 
var yosi = Getinfo("Z1젼7rl발ㅈr");
Console.WriteLine($"age: {yosi.age}, school: {yosi.school}"); 


튜플 반환 타입 ( Tuple return types )

반환 타입이 2개 이상인 함수를 만들 수 있습니다.

after code


public (int age, string school) Getinfo(string name) 
    ... 
}
 
var yosi = GetLatLng("Z1젼7rl발ㅈr"); 
Console.WriteLine($"age: {yosi.age}, school: {yosi.school}");


인라인 튜플 ( Inline tuples )

역시 아래와 같이 하면 인라인도 가능합니다.


var yosi = new (int age, string school) { age = 0 , school = "Go" };


레코드 타입 ( Record types )

이전에는 프로퍼티 떡칠을 하였다면 7.0에서는 그 불편함을 없애주었습니다.

Before Code


public class Point
{
    public int X { get ; set ;}
    public int Y { get ; set ;}
}


After Code


public class Point (int X = 1, int Y = 2);


하지만 알아두어야할 점이 있습니다.

1. readonly 필드를 가진 get-only 속성으로 생성이 되어 immutable이 되어있습니다.
2. 이 record type은 상속이 됩니다.
3. record type은 IEquatable<> 인터페이스에도 상속이 가능합니다.
4. Tostring 메소드를 이용하여 레코드의 각 멤버와 값을 나열합니다. ex) "Point (X: 1 Y: 2)"

불멸 타입 ( Immutable Types )

값이 바뀌면 안되는 클래스에 대해 사용하는 키워드입니다.
그저 클래스 앞에 immutable 키워드를 넣어주면 됩니다.


public immutable class Point
{
    public Point(int x, int y)
    {
        x = x;
        Y = y;
    }

    public int X { get; }
    public int Y { get; }
}


위의 코드로 중간에 변조를 불가능하게 되어 처음부터 끝까지 이 값을 쓸 수 있게 된다.
이런 형식을 대비하여 유용한 문법이 생겼다.


var yosi0 = new Point(1, 3);
var yosi1 = yosi0 with { X = 9 };


기존 인스턴스로부터 값을 바꿔 새로운 인스턴스로 사용하는 것이다.

Non-Null 참조 타입 ( Non-null reference types )

일반적으로 값 형식은 null을 가질 수 없으며, 반드시 기본 값을 가지게 되어 있습니다.
하지만 6.0에서 Nullable<>형식이 생겨 데이터 타입 뒤에 ? 만 붙이면 null을 가질 수 있게 되었습니다.


int a; // non-nullable value type
int? b; // nullable value type
string c; // non-nullable value type
string? d; // nullable value type 


non-null 처리를 하려면 데이터 타입 뒤에 ! 를 붙이면 null이 불가능한 참조 변수를 만들 수 있습니다. 
이는 제네릭과 클래스에도 적용이 가능합니다.


int a; // non-nullable value type
int? b; // nullable value type
string! c; // non-nullable reference type 
string d; // nullable value type

// Dictionary non-nullable reference type
Dictionary<string, List<MyClass>>! myDict;   


지역 함수 ( Local Functions )

블록 내에 잠깐 처리를 위해 람다식을 사용했던 분들이라면 아래와 같은 불편함을 겪을 것이라 예상할 수 있습니다.

1. 제네릭 사용 불가능
2. ref 및 out 사용 불가능
3. 가변 인자 사용 불가능

이를 해결할 수 있는 지역 함수 기능을 제공하였습니다.
C# 7.0 에서는 람다식에서 못한 한계를 해결 할 수 있습니다!


public int Calculate(int someInput)
{
    int Factorial(int i)
    {
        if (i <= 1)
            return 1;
        return i * Factorial(i - 1);
    }
    var input = someInput + ... // Other calcs

    return Factorial(input);
}


그리고 마지막으로 제일 기대되고 제 생각으로는 개쩌는 기능입니다.

패턴매칭 ( Pattern Matching )

C# 7.0에서 나온 재미나고 사용을 하게 된다면 형태에 의한 분기가 편해질거라 예상됩니다.

is 메서드로 매칭이 가능합니다.

상수 매칭


if ( x is 1 )
{
    return 1;
}


형태 매칭


if ( x is T t )
{
    return 1;
}


x를 T로 캐스팅 한 것이 t에 들어가며 x가 T의 특정 타입일 때에 매치됩니다.

속성 매칭


if ( x is T {X is int, Y is int} )
{
    return 1;
}


재귀 매칭


if ( x is T ( var a 1 ) )
{
    return 1;
}


또한 switch 문에서도 패턴 매칭이 가능합니다.


class Geometry();
class Triangle(int Width, int Height, int Base) : Geometry;
class Rectangle(int Width, int Height) : Geometry;
class Square(int width) : Geometry;
 
Geometry g = new Square(5);
switch (g)
{
    case Triangle(int Width, int Height, int Base):
        WriteLine($"{Width} {Height} {Base}");
        break;
    case Rectangle(int Width, int Height):
        WriteLine($"{Width} {Height}");
        break;
    case Square(int Width):
        WriteLine($"{Width}");
        break;
    default:
        WriteLine("<other>");
        break;
}


switch 문을 각 상속된 클래스와 맞는지 비교하여 해당될 때에 해당 케이스 문을 실행할 수 있습니다.
이번 C# 7.0 정말 기대되네요.



'0x0a Programming > 0x0d C#' 카테고리의 다른 글

C# 6.0 New Features  (0) 2016.07.19

C# 6.0 New Features

C# 6.0 새로운 기능 10가지 소개
* 예전에 써둔 글 옮기는 중입니다!


1. 엘비스 연산자

엘비스 연산자는 ? 앞에 있는 객체가 NULL인지 아닌지를 체크해서 NULL이면 NULL을 리턴하고, 그렇지 않으면 ? 다음 속성이나 메서드를 실행합니다.
만약 인덱서 혹은 배열 요소등을 접근할 경우에는 ?[] 과 같이 표현이 가능합니다.

Before Code


var PageName = "Z1젼7rl발ㅈr";
if(UserName != NULL)
{
PageName = _Name;
}

var PageName = UserName != null ? _Name : "Z1젼7rl발ㅈr";


After Code


var PageName = UserName?._Name ?? "Z1젼7rl발ㅈr";



2. 문자열 보간

이 문자열 보간 기능을 사용하기 위해서는 $ 을 전체 서식 문자열 앞에 추가해야합니다.

Before Code


int x = 1,y=2;

string str = string.Format("{0}, {1}", x, y);



After Code


int x = 1,y=2;

string str = $"{x},{y}";



3. 딕셔너리(사전) 초기화

딕셔너리를 초기화하는 스타일과 사용하는 스타일이 약간의 차이가 있습니다.
6.0 으로 올라오면서 이러한 스타일을 통일시켰는데요.
※ 이 초기화 기능은 6.0으로 올라오면서 해시테이블, 인덱서를 지원하는 모든 객체에서 사용 가능합니다.

Before Code


var InfoMe = new Dictionary<string, string>()
{
{ "PageName", "Z1젼7rl발ㅈr"},
{ "AdminCnt", "3 Persons"}
};
string PN = InfoMe["PageName"];


After Code


var InfoMe = new Dictionary<string, string>()
{
["PageName"] = "Z1젼7rl발ㅈr",
["AdminCnt"] = "3 Persons"
};
string PN = InfoMe["PageName"];


4. nameof 연산자

C# 6.0의 name of 연산자는 타입, 메서드, 속성 등의 이름을 리턴하는 것으로 하드 코딩을 하지 않게 도움을 줍니다.

하드 코딩에 의한 타이핑 오류 방지에 도움이 됩니다.


Before Code


public Point Add(Point point)

{

if(point == null)

{

throw new ArgumentNullException("point");

}

}



After Code

public Point Add(Point point)

{

if(point == null)

{

throw new ArgumentNullException(nameof(point));

}

}


5. using static 문

지금까지는 클래스명,속성명으로 사용했습니다.

하지만 C# 6.0에서는 using static 클래스명을 작성하면 클래스명 없이 메서드를 직접 사용할 수 있게 됬습니다.


Before Code


namespace Z1젼7rl발ㅈr

{

    class Program

    {

        static void Main(string[] args)

        {


            Console.WriteLine("Z1젼7rl발ㅈr");


        }

    }

}



After Code


using static System.Console;


namespace Z1젼7rl발ㅈr

{

    class Program

    {

        static void Main(string[] args)

        {


            WriteLine("Z1젼7rl발ㅈr");


        }

    }

}



6. 예외 필터

이 기능은 Visual Basic, F#에서는 지원되고 있었지만 C#에는 지금까지 지원되지 않았던 기능입니다.

예외 필터란 catch 블럭이 예외를 catch하기 전에 필터링 할 수 있도록 허용하는 기능입니다.

C# 6.0 문법에서는 catch 문 뒤에 추가적인 when 조건문을 사용하면 됩니다.


Before Code


try
{
...
}
catch (ConfigurationException e)
{
}
finally
{
}


After Code


try
{
...
}
catch (ConfigurationException e) when (e.IsServere)
{
}
finally
{
}


7. catch 및 finally 블럭에 await

5.0 에서 await 기능을 도입했었지만 catch 및 finally 블럭에서 await 사용은 지원하지 않았다.
하지만 6.0으로 올라오면서 이를 기본적으로 지원하게 되었다.
비동기 짱짱 await


Code


try
{
service = new ServiceClient();
await service.Save(data);
}
catch (Exception ex)
{
await LoggingService.Log(ex);
}
finally
{
await service.Close();
}


8. 자동 프로퍼티 초기화

이전에는 프로퍼티를 자동 생성하는 방법에서 초기 값을 설정하는 방법은 생성자를 만들어서 이를 해당 값에 할당하였습니다.

하지만 6.0에서는 곧바로 자동 속성을 만들면서 = "값" 을 통해 생성자 구현 없이 값을 할당할 수 있게 되었습니다.


Before Code


public class Z1젼7rl발ㅈr
{
    public autos()
    {
        PageName = "Z1젼7rl발ㅈr";
    }

    public string PageName { get; set; }

}


After Code


public class autos
{

    public string PostName { get; } = "Z1젼7rl발ㅈr";

}


9. 읽기 전용 자동 프로퍼티

이전에는 자동 프로퍼티는 항상 get과 set을 함께 사용하였습니다.

하지만 6.0에서는 읽기 전용의 자동 프로퍼티를 쓸 수 있게 되었습니다..

즉 get만을 사용할 수 있게 됬습니다..

※ 값을 할당하지 않으면 컴파일러는 자동으로 default 값을 할당합니다. 


Before Code


public class Z1젼7rl발ㅈr
{

    public string PageName { get; set; }

}


After Code


After Code :

public class Z1젼7rl발ㅈr
{

    public string PageName { get; }

}


10. 식으로 구성된 메서드

Statement Block을 사용하는 대신 간단한 함수식을 사용할 수 있는데 이를 Expression-bodied member 표현이라고 합니다.

이는 기존의 람다식과 유사한 것으로 속성이나 메서드 body를 간략한 람다식처럼 표현합니다.


Code


public Point Move(int x, int y) => new Point(X+x, Y+y);


이상 C# 6.0 새로운 기능 소개 글이였습니다.


'0x0a Programming > 0x0d C#' 카테고리의 다른 글

C# 7.0 New Features  (1) 2016.07.20

친구가 포탈2를 선물해줬다.


신나는 기분으로 설치하고 있다.



포탈2는 멀티도 되므로 친구와 한판 땡길 예정이다.

사실 리뷰랄것도 별로 없다.


머리만 아플뿐.


물론 재미는 보장한다.

'0x01 Etc. > 0x05 Review' 카테고리의 다른 글

[Utils] Whale Browser  (0) 2016.12.02
[Utils] Vivaldi Browser  (0) 2016.08.12
[Utils] AireCam  (0) 2016.07.22
[Game] Life Is Strange 리뷰  (839) 2016.07.22
[Game] Youtubers Life 리뷰  (155) 2016.07.18

어저께 유투브를 둘러보다가 게임을 하는 것을 봤는데

재미있어보이더라.

그래서 구매를 했다!



나름대로 이 게임은 캐릭터의 특성을 정하고 유투브의 채널의 특성을 정하고 시작을 하게 되는데.

현재 0.7.13 버전으로서는 Game 채널밖에 열려있지 않다.



캐릭터의 특성을 고르는 부분이다.

아마도 특성을 고르면 그에 대한 캐릭터의 능력치가 조금 더 올라가는 것 같은 (?)



게임 채널을 고르는 부분이다.

현재로서는 위에서 말했듯이 게임 채널밖에 생성이 가능하지만,

후에 가면 다른 채널들도 할 수 있을 것 같지만.

Music 빼고는 그렇게 기대되지도 않는다.


게다가 캐릭터의 커스텀마이징을 할 수 있는데.

아쉽게도 수염의 색깔은 불가능했다.


그리고 버그가 잔잔하게 졸라게 많으면서 심하다.


1. 친구 프로필 보기


먼저 제일 중요한 친구 프로필 보기 부분이다.

친구 프로필 창이 병신이 되있어서 데이트도 못걸고 집에 초대도 못해서 합방도 못하고.

파티도 못간다...

누군가 불러줘야 갈 수 있다...


2. 방송하는 중에 모션 넣기


내가 유투브에서 하는 사람들을 보면 이렇게 되잇지 않았다.

물음표가 아닌 표정으로 나와서 그 표정에 맞게 넣으면 보너스 점수를 주는 형식이였는데..

이렇게 물음표로 나오는 버그(?) 비슷하게 나타난다.

더 이상한건 어쩌다가 제대로 잘 나온다.



3. 비디오 게임 만들기

이 부분은 현재 이미지가 없으므로 말로 설명하겠다.
비디오 만들기를 하다가 어쩌다가 창이 나가지면 무한으로 만들기 버튼만 눌려지는데.
이럴때 게임이 진행이 안된다.
아 쓔바...

그리고 그 외에도 잔버그가 엄청 많았다.
젠장.


괜히 샀다.



'0x01 Etc. > 0x05 Review' 카테고리의 다른 글

[Utils] Whale Browser  (0) 2016.12.02
[Utils] Vivaldi Browser  (0) 2016.08.12
[Utils] AireCam  (0) 2016.07.22
[Game] Life Is Strange 리뷰  (839) 2016.07.22
[Game] Portal2 리뷰  (0) 2016.07.18

요롤로룰루럴랄

일본어 공부를 하고 있다.

먼저 외우기가 급급하다.


히라가나



가타가나


20분 만에 히라가나 절반을 외우게 해준 최고의 영상이다.


공부하면서 참고하면 좋을 곳


http://m.blog.naver.com/piry777/100177126968

3년동안 열심히 모아온 돈을 이제 슬슬 풀어보려고 준비중이다.

바로 일본 여행을 생각하고 있는데

역시나 너무나 기대된다.

계획을 세우는 것이 너무 좋다.


교통편

먼저 일본을 가기 위해 교통편을 알아보았다.

일본을 가는 방법은 세 가지가 존재했다.
첫 번째, 비행기
두 번째, 배
세 번째, 텔레포트

마음 같아서는 세 번째로 텔레포트해서 돈을 줄이고 싶지만,
아쉽게도 나는 마법사가 아니였다.

그래서 비행기와 배 두개를 최대한 싸게 갈 수 있는 방법을 알아보았다.

비행기

먼저 비행기로 제일 싸게 갈 수 있는 방법을 알아보았다.

방법은 바로 저가항공사를 이용하는 것이다.
말 그대로 저렴하게 이용할 수 있는 항공사인데
당연히 장점과 단점이 존재하다.

장점은 당연히 매우 싸게 갈 수 있다는 것
단점은 식사나 부가 서비스를 통해 돈을 받아챙기고 일정을 잘 잡지않으면 비저가항공사와 비슷한 가격대로 올라갈 수도 있다는 점이다.

아마 저가항공사를 이용하는 사람들은 돈을 최대한 아끼려고 하는 사람들이기 때문에
아마도 비행기내에서 밥이나 로망을 챙기려는 사람들은 없을 것 같아보인다.

이제 저가항공사들에 대해 알아보도록 하였다.

이스트 항공

http://www.eastarjet.com/book/index.htm


이 항공사는 아래와 같은 항공권을 예매를 할 수 있다.


인천 -> 도쿄

인천 -> 오사카

인천 -> 오키나와

인천 -> 후쿠오카


피치항공

http://www.flypeach.com/pc/kr


이 항공사는 아래와 같은 항공권을 구매할 수 있다.


인천 -> 도쿄

인천 -> 오사카

인천 -> 오키나와


부산 -> 오사카


이 항공사는 저가항공사 중에 제일 매니아들에게 인기가 많은 항공사라고 한다.

가장 저렴한 금액으로 갈 수 있는 곳이라고 한다.


다만 부가 서비스는 따로 추가요금이 필요하다.


환불 불가 (항공사에 의해 취소되었을 경우는 제외)

탁송 수하물 유료

좌석 지정 유료 (창가나 넓은 자리나 문이랑 가까운 자리 등은 좌석지정제로만 사용가능)

예약 변경 유료

기내식 유료 (물도 포함)

담요 유료

기내 엔터테이먼트 없음


말 그대로 부분유료화


제주항공

http://www.jejuair.net/jejuair/main.jsp


이 항공사는 아래와 같은 항공권을 구매할 수 있다.


김포 -> 오사카


인천 -> 도쿄

인천 -> 오사카

인천 -> 나고야
인천 -> 후쿠오카

인천 -> 오키나와

인천 -> 삿포로


부산 -> 오사카

부산 -> 후쿠오카


안내 방송으로 영어, 한국어, 제주어가 나온다고 한다.


티웨이항공

https://www.twayair.com/main.do


이 항공사는 아래와 같은 항공권을 구매할 수 있다.


인천 -> 도쿄

인천 -> 사가

인천 -> 삿포로

인천 -> 오사카

인천 -> 오이타

인천 -> 오키나와

인천 -> 후쿠오카


대구 -> 도쿄

대구 -> 오사카

대구 -> 후쿠오카


이 항공사는 이벤트운임, 스마트운임, 정상운임이 존재하는데

풀어서 보면

이벤트운임 : 최저가운임

스마트운임 : 할인운임

정상운임 : 정상운임

이다.


이벤트운임을 차지하기 위해서는 한달정도 미리봐야 차지가 가능하다고 한다.


부산에어

http://www.airbusan.com


이 항공사는 아래와 같은 항공권을 구매할 수 있다.


부산 -> 오사카

부산 -> 도쿄

부산 -> 후쿠오카

부산 -> 삿포로


부산에서 출발하는 저가항공사이다.

체류기간이 7일 이내의 특가항공권 가격이 저렴하나, 7일 이상일 경우에는 가격이 올라간다.


진에어

http://www.jinair.com


이 항공사는 아래와 같은 항공권을 구매할 수 있다.


인천 -> 오사카

인천 -> 오키와나

인천 -> 도쿄

인천 -> 삿포로

인천 -> 후쿠오카


김해 -> 오사카

김해 -> 오키와나


두번째로 알아본 것은 배였다.
사실 배는 미리 친구들을 통해 어쩌다가 들어온 정보가 있는데
비행기 값으로 왕복을 할 수 있다고 들어와서 사실 엄청 기대를 했다.

코비

http://www.kobee.co.kr/


이 곳은 대마도와 후쿠오카밖에 안간다.


가격대도 5~12만원 정도를 생각을 해야된다.


고려훼리

http://www.koreaferry.co.kr


이곳도 역시 후쿠오카를 가는데

현재 알아보니 할인해서 54,000원이였다.

날짜에 따라 할인률이 바뀌는 것 같다.

제일 싼 가격이 45,000원이였다.

제일 비싼 가격은 75,000원.


다만 다른 선박과는 달리 운행시간이 많이 걸린다고 한다. (5시간 50분)


사실 와이파이만 잘 된다면 상관은 없어보인다.


그 대신에 선박 내부에 목욕탕과 노래방 시설도 있다고 한다.


일단 이렇게 교통편을 먼저 알아보았다.

내일 학교 다녀와서는 저렴한 숙소나 버스나 화폐 교환소나 할인티켓 같은 것을 알아봐야겠다.


Use After Free

오늘 다뤄볼 취약점은 Use After Free입니다.

말 그대로 사용한 후 메모리를 해제했을 때에 취약점을 발견할 수도 없을 수도 있을 수도 있습니다.

이 취약점은 근래에 브라우저 취약점에서 많이 발견되었습니다.


[CVE-2012-4792 IE Use-After-Free Analysis and Exploit]

- http://pgnsc.tistory.com/348


멋쟁이 sweetchip님의 BoB 프로젝트 도중에 그 당시에 문서로 남겨놓으셨습니다!


이러한 UAF 취약점은 스택 영역에서 이루어지는 취약점이 아닌 힙 영역에서 발생하는 취약점입니다.

What is Heap?

네, 그렇다면 heap은 무엇일까요


잘 빠지고 이쁜 엉덩이를 말하는 걸까요?
아쉽게도 이런 이쁜 엉덩이를 원하셨다면, 유감

출처 : https://namu.wiki/w/%EC%98%A4%EC%A6%88%EB%9E%9C%EB%93%9C


Heap은 프로그래머가 필요에 따라 메모리 공간이 동적 할당/소멸되는 영역입니다.

하지만 스택은 힙과는 달리 정적으로 할당이 되기 때문에 컴파일 시 미리 스택에 공간이 할당이 되어있습니다.


예를 들자면 아래와 같습니다.


0x08048510   <+0>: push   ebp

0x08048511   <+1>: mov    ebp, esp

0x08048513 <+3>: sub    esp, 0x120


위의 어셈 코드와 같이 0x120(288)만큼 할당하는 코드를 볼 수 있듯이 스택은 컴파일할 때에 할당되는 영역입니다.

하지만 힙은 런타임 시 할당되는 유용하게 사용되는 공간입니다.

이 영역은 시작과 동시에 메모리에 올라고 프로그램이 종료될때까지 남아있습니다.


이러한 힙 영역을 사용하기 위해서는 동적할당에 대해 알아두어야됩니다.


info malloc !

흔히 C언어로 코딩 좀 해봤다 싶으면 봤을 듯한 함수인 malloc입니다.

이 malloc 함수는 동적으로 메모리를 할당하는 함수로서 아래와 같이 생겨먹었습니다.


void* malloc(size_t size)


함수를 호출 시 할당하고자 하는 메모리의 크기를 인자에 전달하면 그 크기만큼 메모리를 할당하게 되고 그리고 그 할당한 메모리의 주소를 리턴하게 됩니다.

메모리에 할당에 실패하면 NULL을 리턴하게 됩니다.


Eh? return type is void* ??

ㅗㅜㅑ... 반환 타입이 void*네요.
왜 그럴까요?
이 malloc 함수는 그저 메모리를 할당해주는 함수이기 때문에 이 개발자라는 녀석이 어떤 데이터형으로 할당하는지 알 수 없습니다.
그렇기 때문에 void*로 반환하여 개발자가 입맛에 맞게 변환하여 사용할 수 있게 만들어뒀습니다.

Hell o malloc

malloc은 아래와 같이 생겨먹었습니다.

struct malloc_chunk {
  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */
  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */

  struct malloc_chunk* fd;         /* double links -- used only if free. */
  struct malloc_chunk* bk;

  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
};

INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */

INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */



할당을 하게 되면 이와 같은 구조를 가지고 있습니다.

prev_size 필드에는 free가 된 이전의 chunk의 사이즈를 가지고 있습니다.


size 필드에는 할당된 사이즈를 담고 있는데.

x86 아키텍처에서는 최소 4바이트 만큼의 공간이 필요합니다.

각 필드들은 8바이트 단위로 정렬이 되서 실제 크기는 더 커질 수 있습니다.


그리고 size 필드에는 3가지의 플래그가 있습니다.

P 플래그는 PREV_INUSE로 이전 chunk가 사용 여부를 나타내는 녀석입니다.

이 플래그가 지워져있으면 free chunk라는 의미가 됩니다.


N 플래그는 NON_MAIN_ARENA로 멀티 쓰레드로 돌아가는 프로그램에서 쓰레드마다 다른 힙 영역을 사용하는 경우

현재 chunk가 main 힙에 속하는지 여부를 나타냅니다.


M 플래그는 IS_MMAPPED로 해당 필드가 mmap()으로 할당된 것인지 아닌지를 나타냅니다.

mmap()으로 할당된 chunk는 malloc과는 다른 방식으로 메모리를 관리합니다.


#define PREV_INUSE       0x1

#define IS_MMAPPED       0x2

#define NON_MAIN_ARENA   0x4


#define SIZE_BITS        (PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA)

#define chunksize(p)     ((p)->size & ~(SIZE_BITS))


struct malloc_chunk* fd;         /* double links -- used only if free. */

struct malloc_chunk* bk;

struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */

struct malloc_chunk* bk_nextsize;

이 힙이 free될 때에 usable area영역에 fd와 bk가 생성이 되는데
fd는 forward pointer
bk는 backward pointer
를 의미하며 큰 chunk에서는 fd_nextsize와 bk_nextsize가 생성이 됩니다.

이는 더블 링크드 리스트의 prev, next와 비슷하다고 보시면 됩니다.

그럼 이정도로 설명을 하도록 하고 UAF로 넘어가보도록 하겠습니다.

Yeah Use After Free!

동적할당된 힙을 free하고 다시 재사용할 때에 취약점이 발견되는 것을 UAF라고 합니다.
아래의 코드는 UAF 취약점이 존재하는 코드입니다.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    void *one, *two;

    one = (char*) malloc(170);
    printf("[0] one : %s\n", (char*) one);

    printf("[1] input string in one : ");
    scanf("%s", (char*) one);

    printf("[2] one : %s\n", (char*) one);
    printf("one pointer : %p\n", (char*) one);
    free(one);

    two = (char*) malloc(170);
    printf("two pointer : %p\n", (char*) two);
    printf("[3] two : %s\n", (char*) two);
    return 0;
}

이 코드를 실행해보면 아래와 같은 결과를 볼 수 있습니다.


one에 입력한 내용이 two에도 출력이 되고 one 주소와 two의 주소가 같음을 볼 수 있습니다.

왜 이럴까요?


Why?

malloc의 caching 때문이다.


출처 : http://g.oswego.edu/dl/html/malloc.html


caching 기능의 Deferred Coalescing이 있는데.

free를 하더라도 chunk를 정리하는 것보다는 같은 사이즈로 요청을 받을 때에 병합또는 분할하는 시간을 절약하고자 재활용을 하게 해주는 것입니다.


출처 : 아는 동생의 중고거래 (무려 어제 있었던 일이다)


disas GDB


초록색 : one size
파란색 : 사용하지 않은 공간 사이즈

gdb로 보게 되면 이렇게 생겨져있습니다.
처음 할당된 부분이기 때문에 fd, bk가 있지 않습니다.

아직 힙에 아무 내용을 넣지 않았기때문에 깨끗합니다.


이제 값이 들어간 것을 볼 수 있습니다.


그리고 free한 뒤에 two를 malloc을 하게 됩니다.

free할 때에 재사용할 힙 공간이 처음에 사용한 0x804b008만 있기 때문에 자연스레 처음에 사용한 힙이 재사용되면서 전에 입력한 값이 출력이 되게 됩니다.



띵똥

Use After Free in sample program

아래는 문제의 코드입니다.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct q1w2e3r4{
    int id;
    char name[20];
    void (*clean) (void *);
} VULNED;

void cleanMem(void *mem){
    free(mem);
}

void hacksure(){
    system("/bin/sh");
}
    
int main(int argc, char *argv[]){
    void *vuln_tst;
    VULNED *vuln = malloc(170);

    fflush(stdin);
    printf("Enter your id number : ");
    scanf("%d",&vuln->id);
    fflush(stdin);
    printf("Enter your name : ");
    scanf("%s", vuln->name);
   
    vuln->clean = cleanMem;

    if(vuln->id > 400){
        printf("Your id is too big!\n");
        vuln->clean(vuln); 
    }                                   
 
    vuln_tst = malloc(170); 
    strcpy(vuln_tst,argv[1]); 
 
    free(vuln_tst);
    vuln->clean(vuln); 

    return 0;
}


문제의 코드이다.
이 코드의 출처는 멋지고 잘생기고 시스템 해킹 잘하는 cd80 문서에서 코드를 참조하였다.

직접 풀어보고 감을 익히는 게 좋을 것 같다.

$ gcc sample.c -o sample -z execstack -fno-stack-protector

컴파일을 하고 문제를 구경해보도록 합시다.


Scenario

먼저 사용을 하고 free를 해야 다시 할당을 할 때에 다시 그 공간을 사용하게 해야됩니다.

vuln의 id 값이 400보다 크면 id가 크다는 문자열을 띄워주면서 cleanMem을 실행하면서 vuln을 free를 해주게 됩니다.

그 다음에 vuln과 같은 크기로 vuln_tst을 할당하고 strcpy로 인자를 vuln_tst에 복사를 한 뒤에 vuln_tst를 free를 해주고 이미 free되있는 vuln을 호출하게 됩니다.


먼저 이에 대해서는 vuln과 vuln_tst은 같은 주소를 가르키고 있고, vuln_tst에 값을 크기 상관없이 조져버릴 수 있습니다.

그렇게 조져버린 메모리를 끝에서 호출을 하기 때문에 우리는 eip 주작질이 가능하게 됩니다.


Exploit

먼저 vuln의 clean이 어디에 위치해있는지를 알아봅니다.



그렇다면 clean은 24만큼 떨어진 곳에 있습니다.



이렇게 이후에 eip를 주작질을 할 수 있음을 볼 수 있습니다.


그 뒤로는 휘리릭 뾰로롱 하면 쉘이 따집니다.



넵, 안녕 !



길고 긴 글을 읽으시느라 수고하셨습니다.

감사합니다.






'0x20 Security > 0x21 System' 카테고리의 다른 글

Buffer Overflow (BOF)  (2) 2016.07.22
About LD_PRELOAD  (0) 2016.07.20
How main() is executed on linux  (2) 2016.07.04
System Hacking :: Memory Protection  (0) 2016.06.28
[SSA] 시스템 해킹 스터디 6주차  (349) 2015.11.09

Abex Crack Me 

리버싱을 공부해본 적이 있는 사람들이라면 한번은 꼭 봤을 듯한 크랙미 시리즈이다.
출처는 어디인지 모르지만 아마도 Abex라는 사람이 올린걸 유추할 수 있다.

Abex Crack Me 1

먼저 분석을 위해 이 프로그램이 어떻게 돌아가는 지를 확인해볼 필요가 있다.



나의 하드디스크를 CD-Rom으로 인식하게 만들어보란다.

하지만 당연히 내 하드디스크는 CD-Rom이 아니므로 저런 메세지는 당연하지만 ...



어셈 코드가 졸라 짧으므로 분석이 매우 쉽다.

GetDriveTypeA 함수는 지정한 disk가 어떤 형태의 저장소인지 판단을 하는 함수이다.

kernel32에 있는 함수이며, 함수가 실행되면 특정 정수 값을 리턴하는데 해당 값에 따라 디스크의 유형을 판단할 수 있다.


 상수

 값

 설명

 DRIVE_UNKNOWN

 0

 알 수 없음

 DRIVE_NO_ROOT_DIR

 1

 최상위 경로가 없음

 DRIVE_REMOVABLE

 2

 이동형 저장장치

 DRIVE_FIXED

 3

 고정형 저장장치

 DRIVE_REMOTE

 4

 네트워크 드라이브

 DRIVE_CDROM

 5

 DVD/CD-ROM 유형

 DRIVE_RAMDISK

 6

 램 디스크


그렇습니다.

아마 그렇다면 저 함수가 실행되고 eax 레지스터에는 3이 들어가있겠네요!



그리고 실제로 3이 들어간 것을 볼 수 있습니다.


하지만 저희는 CD-ROM으로 인식하게 해야되기 때문에 저 eax 값엔 원래는 6이 리턴이 되어야됩니다.


하지만 그 값들은 여기서 요상한 연산을 하고 eax랑 esi랑 비교를 하여 같을 경우에 CD-ROM으로 인식했다고 조져따 라고 메세지를 띄웁니다.

고로 저는 다 필요없이 비교 부분에 서로 같은 것을 비교하게 조져버렸습니다.



ㅅㄱ



Abex Crack Me 2



먼저 이 문제는 흔하디 흔한 키젠 문제인 것 같습니다.

분명히 이름을 통해 시리얼키가 생성이 되고 그 생성된 키와 체크하는 것이라고 예상을 할 수 있겠습니다.


디버깅 ㄱㄱ



이 부분에서 eax에 리턴 값이 들어가고 그 ax 끼리 test 연산을 하고 시리얼이 틀렷는지 맞는지 확인을 하므로

vbaVarTstEq가 서로 비교하는 함수라는 것을 알 수 있습니다.


그렇게 내부로 들어가보면.



실제로 비교하는 것을 알 수 있었습니다.



차곡차곡 쌓인 것을 볼 수 있습니다.



00000008

0018F40C

00298784  UNICODE "CCD9C6C9"

0018F3C4


00000008

0018F40C

0029886C  UNICODE "123456789"

0018F3C4



CCD9C6C9과 제가 입력한 값을 비교합니다.



ㅅㄱ링딩동


그리고 시리얼 생성하는 부분을 분석을 하고 키젠을 만들어봤다.


def keygen(name):

key = ''

for i in range(4):

key += chr(ord(name[i])+0x64).encode("hex")

return key.upper()


Abex Crack Me 3




실행을 해보면 이러하다.

아마도 그렇다면 예상 시나리오는.

키 파일이라는 걸 생성해서 그 키 파일에서 내용을 읽고 체크하는 문제일까 하고 생각을 해보았다.


뭐 이런 생각은 디버깅을 하고 난 뒤면 꼼짝 못해~!



뭐 코드도 짧으니 금방 분석이 가능하시겠다.

메세지 박스를 띄우고 abex.l2c를 읽기모드로 연다.

하지만 당연히 eax에는 이 파일이 없기때문에 FFFFFFFF을 리턴하고 저 eax 비교에서 분기되서 파일을 찾을 수 업써!! 라고 메세지를 띄우게 된다.

고로 프로그램이 있는 경로에 저 파일을 생성해주자.



ㅇㅋ


그렇다면 파일을 찾았기 때문에.

아마 파일 찾는 분기에서는 걸리지 않을 것이다.


그 다음은 파일의 사이즈를 리턴하여 그 사이즈가 12가 아닐 경우에는 틀린 키 파일이라면서 찡찡거리게 된다.

고로 사이즈를 0x12(18)로 맞추고 실행을 해주면 풀릴 것 이다.



Abex Crack Me 4



그렇다.

이 문제는 버튼이 비활성화가 되있다...


고로 디버깅 ㄱ



현재 날짜들을 구해와서 mul, add연산을 통해 시리얼이 완성된다.



이렇게 eax에 시리얼이 들어있는 것을 볼 수 있다.


이게 시리얼인지 확인하는 방법은 vbacmp 함수를 확인하면 된다.



입력한 값과 시리얼을 비교하는 것을 볼 수 있다.


그리고 같을 경우 가입이 활성화된다.


Abex Crack Me 5



L2C-57816784-ABEX가 시리얼이다. 

끝.


'0x20 Security > 0x25 Write-Ups' 카테고리의 다른 글

[Pwnable.kr] cmd2 - 9 pt  (0) 2016.10.05
Mr.Robot Season2 Easter Egg  (0) 2016.07.21
[Pwnable.kr] dragon - 75 pt  (0) 2016.06.25
[Codegate2016] Write ups  (372) 2016.03.18
[Pwnable.kr] cmd1 - 1 pt  (0) 2015.10.07


세인트루이스워싱턴대학 연구팀에서 뇌를 해킹하여 원격 조작을 할 수 있게 한 메뚜기를 이용해서 폭발물을 찾아내는 시험을 하고 있다고 한다.

메뚜기의 뛰어난 후각을 이용하여 폭발물 탐지에 응용한다는 것인데...

덜덜하다...


예전에 바퀴벌레의 뇌에 전류를 보내서 원격조작하는 것을 보고 덜덜했는데...



'0x01 Etc. > 0x03 IT News' 카테고리의 다른 글

증강현실 게임 Pokemon Go  (279) 2016.07.09


상황

음 역시나 시간이 조금 애매해서 최대한 단축시켰다.
그리고 원하는 시간대를 얻어낼 수 있었다.
그래서 오늘은 시도를 해보았다.
원본 영상에서 부분만 잘라내서 비교를 해보기로 했다.

비교하기



네, 잘 되는 것을 볼 수 있었습니다.
매우 뿌듯하네요!

이제 제가 원하는 데로

잔뜩 있는 영상들을 비교해서 중복된 걸 제거하려고 하는데

서버 용량이 50GB라 다 안들어가서 유감.


그리고 미야노는 귀여워요.



'0xe0 Project > 0xe2 CoMpOvie' 카테고리의 다른 글

[CoMpOvie] 0x3 Report(2)  (0) 2016.07.10
[CoMpOvie] 0x2 Report(1)  (0) 2016.07.09
[CoMpOvie] 0x1 Report(0)  (0) 2016.07.09
[CoMpOvie] 0x0 Start  (155) 2016.07.08


상황

음...일단 틀은 완성이 됬다고 기뻐하던 중...


그렇다...

영상 프레임이 커지면서 시간이 너무 심각하게 오래걸린다는 점이였다...

아니...1시간 24분이나...

사실은 이때 테스트용으로 돌려놓고 오버워치하고 오면 되겠지~

하고 시간을 확인하려고 했으나...

경과된 시간을 보고 경악을 하고 말핬다...

차라리 이렇게 걸릴빠엔 직접 스스로 영상 30개 대조해도 이것보단 빠르겠다 싶어서 

이 프로젝트의 목적이 없어지고 말아버렸다...

그래서 최대한 시간을 단축시킬 수 있는 방법을 생각해봤다.


생각

음...생각을 해봤다.
프레임은 크고
이 프레임을 쪼게고 쪼게고 한번에 해버리면 어떨까 싶었다.
그렇게 병렬처리를 해버렸다!

효과

아래의 사진은 개선하기 전의 실행 결과이다.
총 걸린 시간은 5076초...정도...


그렇게 개선을 하고 난 뒤의 실행결과이다.

총 걸린 시간은 259초 정도.

그렇다고 빨리 된것도 아니기에 조금 더 개선을 해볼까하고 생각도 해보고 있다.



효과는 괜찮았던 것 같다.


영상


역시 시간 개선이 조금 더 필요해보인다.


'0xe0 Project > 0xe2 CoMpOvie' 카테고리의 다른 글

[CoMpOvie] 0x4 Report(3)  (2) 2016.07.10
[CoMpOvie] 0x2 Report(1)  (0) 2016.07.09
[CoMpOvie] 0x1 Report(0)  (0) 2016.07.09
[CoMpOvie] 0x0 Start  (155) 2016.07.08


상황

서로 크기가 다른 프레임들을 어떻게 비교를 해야 효율적일까 생각을 하기 시작했다.
이래저래 이것저것 생각을 해본 결과
결국엔 노가다!를 선택했다.
일단 돌아가게 만든 뒤에 나중에 시간이 괜찮은 날(학교)에 효율적인 방법을 생각해봐야겠다.

그래서 현재 상황은?


2분 정도...?

뭐 그럭저럭 시간이 많이 들어가진 않는다.

아마 그래도 프레임이 1000단위로 넘어가면 5분 10분 걸릴 수도 있는 상황이라 조금 위험하긴하다만,

그래서 생각한 것이 하나 있긴한데 이건 아직 시도하지 않아서 시도해보고 효율적이라면 이 방법으로 해야겠다.



아니 세상에...

'0xe0 Project > 0xe2 CoMpOvie' 카테고리의 다른 글

[CoMpOvie] 0x4 Report(3)  (2) 2016.07.10
[CoMpOvie] 0x3 Report(2)  (0) 2016.07.10
[CoMpOvie] 0x1 Report(0)  (0) 2016.07.09
[CoMpOvie] 0x0 Start  (155) 2016.07.08


이 포켓몬 고는 증강현실(AR) 기반 모바일 게임인데.

GPS 기능을 활용하여 그 지역에 맞는 포켓몬을 수집하게 하는데


사실 나오기 전부터 엄청 기대했지만,

현재 하루만에 앱스토어 1위를 달리고 있다고 한다.


주변에 포켓몬이 나타나면 진동으로 알려주고,

기존과 똑같이 포켓몬 볼로 포켓몬을 잡을 수 있다.




몬스터볼은 포켓스탑이라는 곳에서 얻을 수 있고,

랜드마크 같은 곳에 가면 희귀한 몬스터를 얻을 수 있다고 한다.


하지만 아직 한국은 정식 출시가 되지 않아서 플레이가 불가능한다고 하는데요.

꼭 플레이를 해보고 싶으신 분은 해외 계정을 만드신 뒤에 설치를 하여 플레이를 하시면 될 것 같습니다.



'0x01 Etc. > 0x03 IT News' 카테고리의 다른 글

메뚜기의 뇌를 해킹하여 폭탄찾기  (0) 2016.07.10

프로젝트 구상을 하다 자기 전에 웹툰을 본 뒤에 베도에 갔더니 우연히 발견한 'DJ 카일 하우스'라는 웹툰을 발견하였다.

딱히 DJ에 크게 관심도 있는 것도 아니라 1화만 보고 나오려고 했는데

그림체가 나의 취향을 저격하는 것이 아닌가...!

게다가 스토리도 그렇게 막장으로 나가는 것도 아니라 괜찮았다.

하지만 아쉬운 부분은 과거편의 끝을 정확히 맺어줬으면 좋았을 것 같기도...

게다가 이 작가분 영어를 잘하시는 것 같더라.

보다가 중간에 갑자기 영문으로 나와서 해석하면서 봤더니 알고보니 정신차려보니 초반에 봤던 ... 7화였다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

그리고 보다가 C++ 이 나왔는데

얼마나 반가우던지 ㅋㅋㅋㅋㅋ



아마 작가분도 컴퓨터를 다뤄본 적이 있는 걸까?


근데 아마 깊게 하신 분은 아닌 것 같다...

아들과 C++을 한다니..

얼마나 마조히스트 가정인가...


아무튼 정말 재미있게 봤다.


정말 열심히 하시는 것 같아서 나도 열심히해야겠구나 싶기도 함.

그 분보다는 어리니까


상황

일단 구상을 하기 시작했다.
영상을 서로 비교하는 방법이 뭐가 있을까 곰곰히 생각해봤다.
대략 2가지의 방법이 생각이 났는데.
음향 스펙트럼을 비교해서 비슷하면 같은 영상이라고 판단하는 것
영상의 프레임들을 쪼게서 그 이미지들을 서로 비교하는 것

이 2가지의 방법이 생각났지만.
음향 스펙트럼은 영상의 특성상 우연히 같은 음향을 뿜을 수 있기 때문에 일단 패스하고 프레임들을 쪼게기로 결정했다.

필요한 패키지들 찾아나서기

일단 파이썬에서 영상 프로세싱이 가능한 패키지를 찾아봤다.

음...역시... openCV를 쓰기로 했다.


How to install OpenCV for Python in Ubuntu 14.04

그냥 명령어 하나만 집어넣으면 된다.

$ sudo apt-get install libopencv-dev


와, 엄청 많이 설치하는 것을 볼 수 있습니다.



뭐 여차저차 설치가 된 것을 볼 수 있습니다.

여기서 에러가 나타나시는 분들은 제대로 설치가 안됬거나 numpy가 설치가 되지 않아서 일겁니다.

일단 OpenCV는 설치가 끝났습니다.


이제 2번째는 이미지 프로세싱이 가능해야되서 이미지 프로세싱이 가능한 패키지를 찾았습니다.

모두 파이썬 한 두번 해봤다면 들어봤을 듯한 패키지입니다.


PIL(Python Imaging Library)를 설치하기로 했습니다.


PIL 설치는 아래와 같은 명령어를 집어넣으면 가능합니다.


$ sudo apt-get install python-PIL


이렇게 일단 필요한 패키지 준비는 여기서 끝났습니다.


이미지는 어떻게 비교를 해야될까?

이에 대한 고민을 많이 했습니다.

openCV로 이미지 비교를 할까 했지만 일단 킾해놓기로 하고.
OpenCV for python ORB, SIFT - http://m.blog.naver.com/samsjang/220657424078

이미지를 흑백으로 만들고 거기서 픽셀들을 비교하는 것으로 했다.

뭐 이런것도 있더라...

http://www.phash.org/


그래서 현재 상황은?



뭐 그럭저럭 틀이 잡혀가고 있다.

이제 문제는 서로 프레임이 다르기때문에 어떻게 비교를 해야 효율적일까 생각을 해봐야겠다.

'0xe0 Project > 0xe2 CoMpOvie' 카테고리의 다른 글

[CoMpOvie] 0x4 Report(3)  (2) 2016.07.10
[CoMpOvie] 0x3 Report(2)  (0) 2016.07.10
[CoMpOvie] 0x2 Report(1)  (0) 2016.07.09
[CoMpOvie] 0x0 Start  (155) 2016.07.08


주요 기능

영상들끼리 비교를 통해 유사한 영상인지 아닌지를 판별


개발하게 된 이유

아, 이 프로젝트를 시작한 이유는 내가 여러 영상들을 자주 받는데...

영상이 100여개가 넘어가다보니 받은지 안받은지 기억이 안나더라...

그래서 아 그냥 만들어야지 하고 시작해봄.


프로젝트 이름이 CoMpOvie 인 이유

사실 이름 정하는게 진짜 고민되고 그랫는데...
영상들끼리 비교하기 때문에 비교인 Comparison를 적고 영상끼리 비교기 때문에 Movie를 넣어야됬음..!
Comparison을 다 적기에는 너무 길어지기 때문에 comp 까지 적고 대문자로 무비를 강조했음.


개발 언어

아무래도 서버에서 주로 작업을 하게 될 것 같아서 파이썬으로 채택했음.
Python 2.7.11

개발 환경

Windows7, Ubuntu


주저리 주저리

사실 상 이걸 뭐 프로젝트라고 말하기는 부끄럽지만 심심해서 뭐라도 만들어보기위해 시작함.


'0xe0 Project > 0xe2 CoMpOvie' 카테고리의 다른 글

[CoMpOvie] 0x4 Report(3)  (2) 2016.07.10
[CoMpOvie] 0x3 Report(2)  (0) 2016.07.10
[CoMpOvie] 0x2 Report(1)  (0) 2016.07.09
[CoMpOvie] 0x1 Report(0)  (0) 2016.07.09

main()는 리눅스에서 어떻게 실행이 될까?



시작하기에 앞서 리눅스에서의 실행파일이 무엇인지 알아본 뒤에 main 실행이 어떻게 되는지 깊숙히 파고들 예정입니다.
먼저 리눅스에서의 실행파일이 무엇인지 알아본 뒤에 실행 포맷 구조를 알아 본 뒤에 main에 대해 들어갈 예정입니다.
아마 내용이 축구공처럼 통통 튀기고 이리저리 갈 것 같으니 언제든지 이상한 부분은 댓글로 지적해주시면 감사하겠습니다.


What is ELF?



그래서 ELF는 무엇일까요?

게임 또는 애니메이션이나 소설에 나오는 엘프를 말하는 걸까요?

네, 하지만 여러분들이 생각하는 그런 엘프는 아니라 유감,


그렇다면 ELF에 대해 알아봅시다!

1999년 86open 프로젝트에 x86기반 유닉스 계열 시스템들의 표준 바이너리 파일 형식입니다.

ELF (Executable and Linkable Format)은 실행파일, 목적파일, 공유 라이브러리 그리고 코어 덤프를 위한 표준 파일 형식인데요.


음 그냥 간단히 윈도우에서의 .exe 파일과 비슷하다고 보시면 될 것 같습니다. 


ELF 포맷 구조를 보도록 하겠습니다.



그림판으로 그려서 못생긴 기분이 들지만...


대략 이렇게 생겨먹었습니다.

ELF파일은 ELF 헤더가 맨 앞에 위치하며, 프로그램 헤더 테이블과 섹션 헤더 테이블은 그 뒤에 위치합니다.


그렇다면 이제 elf 파일 형식을 직접 봐보도록 하겠습니다.



ELF Header View



ELF 파일 형식을 보기 위해서는 readelf 명령어를 이용합니다.

readelf 명령어 옵션에 대해 알아보고 싶으신 분은 아래의 링크를 참조바랍니다.

readelf - https://sourceware.org/binutils/docs/binutils/readelf.html


저희는 ELF Header를 보려고 하는 중이기 때문에

아래와 같은 옵션으로 넘겨줍니다.


-h

--file-header

Displays the information contained in the ELF header at the start of the file. 


$ readelf -h ./hello



ELF 헤더는 다음과 같은 구조를 가지고 있습니다.


#define EI_NIDENT 16


typedef struct {

        unsigned char   e_ident[EI_NIDENT];  // Magic number and other info

        Elf32_Half      e_type;  // Object file type

        Elf32_Half      e_machine;  // Architecture

        Elf32_Word      e_version;  // Object file version

        Elf32_Addr      e_entry;  // Entry point virtual address 

        Elf32_Off       e_phoff;  // Program header table file offset

        Elf32_Off       e_shoff;  // Section headr table file offset 

        Elf32_Word      e_flags;  // Processor-specific flags

        Elf32_Half      e_ehsize;  // ELF header size in bytes

        Elf32_Half      e_phentsize;  // Program header table entry size

        Elf32_Half      e_phnum;  // Program header entry count

        Elf32_Half      e_shentsize;  // Section header table entry size

        Elf32_Half      e_shnum;  // Sectino header table entry count 

        Elf32_Half      e_shstrndx;  // Sectino header string table index

} Elf32_Ehdr; // x86


typedef struct {

        unsigned char   e_ident[EI_NIDENT];  // Magic number and other info

        Elf64_Half      e_type;  // Object file type

        Elf64_Half      e_machine;  // Architecture

        Elf64_Word      e_version;  // Object file version

        Elf64_Addr      e_entry;  // Entry point virtual address 

        Elf64_Off       e_phoff;  // Program header table file offset

        Elf64_Off       e_shoff;  // Section headr table file offset 

        Elf64_Word      e_flags;  // Processor-specific flags

        Elf64_Half      e_ehsize;  // ELF header size in bytes

        Elf64_Half      e_phentsize;  // Program header table entry size

        Elf64_Half      e_phnum;  // Program header entry count

        Elf64_Half      e_shentsize;  // Section header table entry size

        Elf64_Half      e_shnum;  // Sectino header table entry count 

        Elf64_Half      e_shstrndx;  // Sectino header string table index

} Elf64_Ehdr;  // x86_64


참고 : http://www.sco.com/developers/gabi/2003-12-17/ch4.eheader.html


Program Header table



프로그램 헤더 테이블은 ELF헤더의 e_phoff로 지정된 오프셋에서 시작하고 e_phentsize와 e_phnum으로 정해진 크기를 갖는 테이블입니다.

프로그램 헤더 테이블의 전체 크기는 e_phnum * e_phentsize byte 입니다.


지금 현재는 프로그램 헤더 테이블을 보려는 중이니 아래와 같은 옵션으로 넘겨줍니다.


-l

--program-headers

--segments

Displays the information contained in the file's segment headers, if it has any. 


$ readelf -l ./hello



프로그램 헤더는 다음과 같은 구조를 갖고 있습니다.


typedef struct {

Elf32_Word p_type;  // Segment type 

Elf32_Off p_offset;  // Segment file offset 

Elf32_Addr p_vaddr;  // Segment virtual address 

Elf32_Addr p_paddr;  // Segment physical address

Elf32_Word p_filesz;  // Segment size in file 

Elf32_Word p_memsz;  // Segment size in memory

Elf32_Word p_flags;  // Segment flags 

Elf32_Word p_align;  // Segment alignment 

} Elf32_Phdr;  // x86


typedef struct {

Elf64_Word p_type;  // Segment type 

Elf64_Word p_flags;  // Segment flags 

Elf64_Off p_offset;  // Segment file offset 

Elf64_Addr p_vaddr;  // Segment virtual address 

Elf64_Addr p_paddr;  // Segment physical address

Elf64_Xword p_filesz;  // Segment size in file 

Elf64_Xword p_memsz;  // Segment size in memory

Elf64_Xword p_align;  // Segment alignment 

} Elf64_Phdr;  // x86_64


세그 먼트 타입에는 다음과 같이 있습니다.


PT_NULL 0

PT_LOAD 1

PT_DYNAMIC                 2

PT_INTERP 3

PT_NOTE 4

PT_SHLIB 5

PT_PHDR 6

PT_TLS 7

PT_LOOS 0x60000000

PT_HIOS 0x6fffffff

PT_LOPROC         0x70000000

PT_HIPROC         0x7fffffff


참고 : http://www.sco.com/developers/gabi/latest/ch5.pheader.html



Section header table



이 곳은 Section&Segment 오프셋이나 크기, 타입 등의 정보를 담고 있는 테이블입니다.

이 테이블은 오브젝트 파일 같이 relocation 가능한 ELF 오브젝트에는 반드시 있어야되는 녀석입니다.


지금 현재는 Section header table을 보려는 중이니 아래와 같은 옵션을 넘겨줍니다.


-S

--sections

--section-headers

Displays the information contained in the file's section headers, if it has any. 


$ readelf -S ./hello



섹션 헤더는 다음과 같은 구조를 갖고 있습니다.


typedef struct {

    uint32_t   sh_name;  // Section name

    uint32_t   sh_type;  // Section Type

    uint32_t   sh_flags;  // Section Flag

    Elf32_Addr sh_addr;  // Section virtual address 

    Elf32_Off  sh_offset;  // Section offset

    uint32_t   sh_size;  // section size

    uint32_t   sh_link;  // section index link

    uint32_t   sh_info;  // extra information

    uint32_t   sh_addralign;  // section alignment constraints

    uint32_t   sh_entsize;  // hold a table of fixed-sized

} Elf32_Shdr;  // x86


typedef struct {

    uint32_t   sh_name;  // Section name

    uint32_t   sh_type;  // Section Type

    uint64_t   sh_flags;  // Section Flag

    Elf64_Addr sh_addr;  // Section virtual address 

    Elf64_Off  sh_offset;  // Section offset

    uint64_t   sh_size;  // section size

    uint32_t   sh_link;  // section index link

    uint32_t   sh_info;  // extra information

    uint64_t   sh_addralign;  // section alignment constraints

    uint64_t   sh_entsize;  // hold a table of fixed-sized

} Elf64_Shdr;  // x86_64


참고 : http://linux.die.net/man/5/elf


ps. 오 세상에... 여기까지 귀찮게 다 작성했더니 마지막에 섹션 헤더에 대해 구글링을 하다가 엄청난 자료를 발견하였다. 무려 한글로 된 ... 고로 첨부합니다.


ELF File Format.doc


이렇게 리눅스에 ELF 포맷에 대해 알아보았습니다.

그렇다면 이제 어떻게 main을 불러오는지 알아보도록 하겠습니다!

오 할렐루야 이제야...



I want go to main() !



먼저 바이너리의 엔트리 포인트를 먼저 보도록 하겠습니다.



Entry point address는 0x8048320 이라고 합니다.

이제 이 주소에 뭐가 있는지 디버깅을 하면서 찬찬히 들어가보도록 하겠습니다.



Entry point address는 _start함수의 주소였습니다.

그렇다면 프로그램이 실행되면 _start 함수가 먼저 실행이 되겠네요.

_start 함수가 실행되면 스택 프레임은 아래와 같습니다.


Stack Top

0x804841d

 ...

esi

ecx

0x8048440

0x80484b0

edx

esp

eax


현재 이렇게 스택 프레임이 생겨먹었습니다.

여기서 그렇다면 궁금증이 몇가지가 생기셨을꺼라 생각됩니다.

뭐 저만 생긴 걸 수도 있지만요.


  1. 스택에 push된 저 값들은 무엇인가요?
  2. _start에서 0x8048310을 호출하는데 뭐지?



스택에 push된 저 값들은 무엇인가요?



먼저 스택에 push된 값들은 아래와 같습니다.

0x80484b0, 0x8048440, 0x804841d


0x804841d : main() 함수의 주소

0x8048440 : __libc_csu_init() 함수 주소

0x80484b0 : ??


들이라는 것을 알 수 있었습니다.



_start에서 0x8048310를 호출하는데 뭐지??



음 뭐 사실 뭐하는 녀석인지는 옆에 함수 명이 보이기 때문에 크게 생각하실 것은 없습니다.

0x0804833c <_start+28>: call   0x8048310 <__libc_start_main@plt>

__libc_start_main@plt 를 호출합니다.


plt를 호출하는 이유는 __libc_start_main를 처음 호출하는 것이라 바로 호출하지 않고 plt에서 got를 다이나믹 링킹하고 호출을 합니다.


아니 그러면 __libc_start_main은 뭘까요?

깊숙히 들어가보도록 하겠습니다.


  1. __libc_start_main은 뭔가요?


__libc_start_main은 뭔가요?



음...

현재 이 흐름은 libc의 손에 달려있습니다...!

__libc_start_main함수는 libc.so.6 안에 있거든요!



glibc 소스 코드에서 __libc_start_main를 발견할 수 있습니다.

코드는 아래와 같습니다!


int __cdecl __libc_start_main(int (__cdecl *main)(int, char **, char **), 

int argc, 

char **ubp_av, void (*init)(void), 

void (*fini)(void), 

void (*rtld_fini)(void), 

void *stack_end)



__libc_csu_init 호출



_init 호출



호로록



이 부분에선 gmon 프로파일링 시스템 초기화가 필요하다면 gmon_start를 호출하여 초기화합니다.




그 뒤에 다시 __libc_start_main으로 돌아오고 저희가 만든 main을 호출하게 됩니다.



이상입니다.


뭔가 덤성덤성 뛰어넘은 부분이 많지만 ...

도움이 되었으면 좋겠습니다!


길고 긴 글을 읽어주셔서 감사합니다.







'0x20 Security > 0x21 System' 카테고리의 다른 글

About LD_PRELOAD  (0) 2016.07.20
Use After Free (UAF)  (1) 2016.07.13
System Hacking :: Memory Protection  (0) 2016.06.28
[SSA] 시스템 해킹 스터디 6주차  (349) 2015.11.09
[SSA] 시스템 해킹 스터디 5주차  (155) 2015.11.05

0. Open the Google Chrome browser, type the following and press Enter


chrome://flags/#disable-direct-write


1. To enable or disable, just click on the link (Enable || Disable)


2. Click on Disable.


3. End

0. Start - Control Panel



1. Change keyboards or other input methods



2. Keyboards and Languages - Change keyboards



3. Add 


4. Korean - keyboard - Microsoft IME check - OK



5. Default input language - Korean (korea) - Microsoft IME - OK


6. END


2~3일 전에 구매한 메신저 백이 어제 왔다.

백팩을 메고 다니면 등에 땀이 장난아니라서 옆으로 매고 다니는게 나을 것 같아서 구매하려고 1달전 부터 찾아보고 있었는데

가격이 매우 저렴한 메신저 백이 있어서 구매해봤다.

3만 9천원에 구매를 했는데

가방 줄이 튼튼했으면 좋겠다.




  • 성명


한글 : 문승현

한자 : 文昇炫

영문 : Seunghyun Moon


  • Etc.

생일 : 1998.11.20
나이 : 만 18세(981120)
E-Mail : mhubeen@gmail.com
혈액형 : RH -O
페이스북 : fb.com/hubeener
트위터 : @mhubeen
거주지역 : 충청남도 서산시


    소유 자격증

  1. ITQ 한글
  2. ITQ 파워포인트
  3. 정보처리기능사
  4. 화학분석기능사

    활동

  1. RNH 프로그래밍 팀 운영 (2013.07.13~2015.05.03)
  2. SW로 말해요 스플래시 참여(2015.03.21)
  3. 충청남도 장학생 선발(2015.06.25)
  4. SecurityPlus SecurityPlus Students Academy(SSA) 대표 (2016.01.04~)
  5. Hacking Camp 14th Speaker (2016.08.27~2016.08.28)


    대회

  1. 정보올림피아드 프로그래밍 부문 은상 (13.05.25)
  2. 제 1회 대한민국 SW융합 해카톤 대회 본선 (15.05.29~05.05.31)
  3. YISF 2015 예선 27위 (15.8.9) [CTF 첫 참가]
  4. 제 10회 중고생정보보호올림피아드 본선 참가 (15.10.16)
  5. 화이트햇 콘테스트 2015 청소년 부 Hackman팀 본선 (15.10.21)
  6. Codegate Junior 2016 Final Round (2016.05.02)
  7. 제 1회 전국 청소년 화이트 해킹 공모전 (16.09.24)
  8. 제 11회 중고생정보보호올림피아드 본선 참가 (16.10.21)


    학교

  1. 석림초등학교 전학 (05.04~07.??)
  2. 예천초등학교 졸업(07.??~11.03)
  3. 서산중학교 졸업(11.04~14.03)
  4. 운산공업고등학교 졸업예정 (14.04~17.03)
  5. 공주대학교 재학예정 (17.03.02~??)


Memory Protection Techniques

writen by hubeen




Linux 환경에서의 메모리 보호 기법에 대해 작성하려고 합니다.

/*이 글은 틀린 정보가 있을 수도 있으며 글의 맥락이 축구공처럼 뻥뻥 돌아다닐 수도 있습니다.*/


일단 메모리 보호라는 개념을 알아보도록 하겠습니다.



네, 그렇습니다.

운영체제에서 실행되고 있는 프로세스에게 메모리를 할당을 해주게 되는데.

할당되지 않은 영역의 메모리에 접근을 하는 것을 막기 위해 있는 것이 메모리 보호 기법의 주된 목적입니다.


이러한 메모리 보호 기법들은 짱짱한 분들이 해커들의 공격을 막기 위해 열심히 노력을 해서 완성이 된 녀석들입니다. 




1. ASLR (Address Space Layout Randomization)



이 ASLR은 2001년 즈음에 Linux PaX 프로젝트에서 처음으로 "ASLR" 개념을 설계하고 2002년부터 커널 스택 무작위 배치를 구현을 하였다고 합니다.

( https://en.wikipedia.org/wiki/Address_space_layout_randomization )


이 녀석은 말 그대로 주소 공간을 랜덤한다. 입니다.


흔히 Buffer Overflow 공격으로부터 보호하기 위해 Stack, Heap, Libc, 프로세스 주소 공간을 포함하는 데이터 영역 위치들을 랜덤하게 변경하여 메모리의 특정 악용 함수 주소를 랜덤하게 하여 공격을 방지를 할 수 있게 하는 녀석입니다.


실제로 이 ASLR이 작동을 하는지 눈으로 확인을 하도록 하겠습니다.


cat /proc/self/maps 명령을 입력을 하여 직접 확인해보도록 하세요! 



앙 바뀐띄~


이 ASLR이 적용이 되있는지 안되있는지 확인하는 방법은 아래와 같습니다.


cat /proc/sys/kernel/randomize_va_space 


0 : No randomization. Everything is static.

1 : Conservative randomization. Shared libraries, stack, mmap(), VDSO and heap are randomized.

2 : Full randomization. In addition to elements listed in the previous point, memory managed through brk() is also randomized.


그렇다면 이 ASLR을 해제를 해보도록 하겠습니다.


echo 0 > /proc/sys/kernel/randomize_va_space


보시는 것과 같이 주소 값이 바뀌지 않는 것을 볼 수 있습니다.


#include <stdio.h>

#include <stdlib.h>


int main()

{

char *heap = NULL;


heap = (char*) malloc(50);


printf("[Heap Address] : %p\n", heap);


return 0;

}


간단한 코드로 주소를 출력을 해보도록 하겠습니다.

gcc -o a a.c



왼쪽은 ASLR을 끈 상태이며 오른쪽은 ASLR이 적용되있는 상황입니다.


보시는 것과 같이 ASLR이 적용되있지 않을 때에는 힙의 주소 값이 일정하지만 ASLR이 켜져있을 경우에는 주소 값이 랜덤하게 바뀌는 것을 볼 수 있습니다.




2. DEP (Data Execution Prevention)



DEP라는 녀석에 대해 알아보도록 하겠습니다.



네, 그렇습니다!

흔히 Overflow로 인해 메모리 영역에 훼손이 발생하더라도, Data 영역에서 실행(Execution)을 방지함으로써 공격을 방어하는 기법입니다.


고로 해커가 Buffer Overflow 공격으로 ret을 스택영역에 놓은 쉘코드 주소로 변경했을 때에 DEP가 적용이 안되있는 경우에는 그대로 쉘코드가 실행이 되어 쉘을 딸 수 있겠지만, DEP가 적용이 되어있다면 실행 권한이 없으므로 쉘코드가 실행되지 않고 종료가 됩니다.


아래는 포스트 할 때 사용한 예제 코드 입니다.


#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <unistd.h>


pid_t getpid(void);

pid_t getppid(void);


/*

        The Lord of the BOF : The Fellowship of the BOF

        - gremlin

        - simple BOF

*/


int main(int argc, char *argv[])

{

    char buffer[256];

    pid_t pid;

    char cmd[25];

    if(argc <2){

        printf("argv error\n");

        exit(0);

    }

    strcpy(buffer, argv[1]);

    printf("%s\n", buffer);


    if ((pid=fork()) == -1){

        printf("fork failed\n");

    }

    else if(pid != 0){

        printf("getpid : %ld\n", getpid());

        sprintf(cmd, "cat /proc/%d/maps", getpid());

        system(cmd);

    }


}


이 예제 코드는 간단한 bof 취약점이 존재하는 프로그램입니다.

코드가 익숙하시다고요?

넵, 맞습니다.

LOB gate 문제 코드거든요!


그렇다면 컴파일을 하고 보게 되면?



보시는 것과 같이 rw-p 로 스택에 실행 권한이 없는 것을 볼 수 있습니다.


그리고 DEP 해제를 하고 보도록 하겠습니다.


gcc 컴파일을 하실 때에 dep를 해제를 하시려면 -z execstack 옵션을 넘겨주시면 됩니다.


DEP 해제 : gcc -z execstack a.c -o a



역시 보시는 것과 같이 rwxp로 스택에 실행권한이 있는 것을 볼 수 있습니다. 

이렇게 바이너리에 DEP가 걸려 있지 않는다면 bof를 통해 ret을 쉘코드가 있는 스택 주소로 변조하면 쉘코드가 잘 실행이 되겠죠?




3. ASCII-Armor



다음으로는 ASCII_Armor 보호 기법에 대해 알아보도록 하겠습니다.

이 녀석은 뭘 하는 녀석일까요?


이름 그대로 "아스키 철갑옷" 이름 값하는 녀석입니다.

라이브러리를 공유 라이브러리 영역에 올리지 않고 텍스트 영역의 16MB 아래의 주소에 할당하는 녀석입니다.


이 ASCII-Armor가 적용이 되게 되면 라이브러리 영역 주소의 최상위 1byte가 \x00으로 됩니다.



보시는 것과 같이 최상위 1byte가 \x00 으로 되잇는 것을 볼 수 있습니다.


이렇게 \x00 은 NULL로 인식이 되고 RTL같은 체이닝 공격을 할 수 없게 되어 익스플로잇을 하지 못하게 만드는 녀석입니다.




4. SSP (Stack Smashing Protector)



마지막으로 SSP입니다.

이 Stack Smashing Protector 는 gcc 4.1버전 부터 지원하는 Buffer Overflow 방어 기법입니다.

4.1 버전 이상인 gcc에서 아래와 같은 코드를 컴파일 한 뒤에 BOF를 발생시켜보겠습니다.


#include <stdio.h>

#include <string.h>


int main(int argc, char *argv[]){

        char buffer[5];


        strcpy(buffer, "0123456789abcdef");

        return 0;

}


컴파일 하고 실행을 하게 되면 다음과 같이 *** stack smashing detected ***: ./b terminated 라는 문자열이 나타나는 것을 볼 수 있습니다.



gdb로 까보도록 해보겠습니다.



초록색 박스 안에서는 카나리 값을 스택에 저장하는 부분이며,

주황색 박스 안에서는 카나리 값이 변조되었는지 안되있는지 체크하는 루틴입니다.



esp+0x1c에 카나리가 들어간다고 합니다.


그렇다면 아마도 0x450b8200이 카나리 값이겠네요 (웃음)



어이쿠 카나리 값을 "5"로 덮어버리고 말았어요!


이 부분에서 카나리 값이 없어지고 카나리 체크하는 루틴에서 걸려서 보호를 하게 됩니다.


이 카나리는 버퍼와 sfp의 사이에 숨어있어요!


buf[5] | dummy[?] | canary[4] | sfp[4] | ret[4]


이 SSP를 해제하는 옵션은 아래와 같아요.


SSP 해제 : gcc b.c -o b -fno-stack-protector




길고 멍청한 글을 읽어주셔서 감사합니다.





'0x20 Security > 0x21 System' 카테고리의 다른 글

Use After Free (UAF)  (1) 2016.07.13
How main() is executed on linux  (2) 2016.07.04
[SSA] 시스템 해킹 스터디 6주차  (349) 2015.11.09
[SSA] 시스템 해킹 스터디 5주차  (155) 2015.11.05
[SSA] 시스템 해킹 스터디 4주차  (31) 2015.11.05

The about Technique of Anti Debugging_2.pdf

※ Anti-Debugging 문서 작성 시작. 

- 04:46 March 25, 2016 

[+] Anti-Debugging 기법 소개표&TEB&PEB 구조체 추가 
- 05:38 March 25, 2016 

[+] 기법들에 대한 샘플 코드와 우회 방법을 작성 
- 05:57 March 31, 2016 

The about Technique of Anti Debugging_2.pdf 
SHA256: 9cdd6e72a070a4fcf1f2d100067c5f165f4c75eca62b669726c7f9355370747c 

ps. 오타&틀린 부분 지적 감사히 받겠습니다. 
이미 널리고 널린 내용이지만 작성해보았습니다 !





'0xe0 Project > 0xe1 DOC' 카테고리의 다른 글

Pintool로 문제 풀기  (54) 2016.08.29


코드게이트_2016_Write_Up_문승현.pdf




Hello, 

i sense that didn't written in Writeup

hmm... but have name in the file name

it's okay 

maybe lol..

'0x20 Security > 0x25 Write-Ups' 카테고리의 다른 글

[ReverseLab 스터디] [Abex's CM] Abex 1~5  (0) 2016.07.11
[Pwnable.kr] dragon - 75 pt  (0) 2016.06.25
[Pwnable.kr] cmd1 - 1 pt  (0) 2015.10.07
[Pwnable.kr] lotto - 2 pt  (0) 2015.10.07
[Pwnable.kr] blackjack - 1 pt  (0) 2015.10.06



사실 강의가 진행이 안된 이유는 이미지로 쓸 그림을 그려달라고 닥달을 해서 작품이 나올 때까지 기다리고 있었다.



1. 함수

오늘은 함수에 대해서 알아보도록 하겠습니다.

함수는 흔히 수학에서 들어보셨을 겁니다.

그 수학에서 배운 함수와 현재 우리가 배울 함수와 비슷합니다.

x 값을 넣으면 y의 값이 정해지는 것처럼 함수에 인자를 집어넣으면 함수는 결과 값을 되돌려줍니다. 




1-1. 사용한다 나는 함수를

그렇다.


지금까지 Go로 작성한 프로그램에서는 하나의 함수만을 사용해왔습니다.


바로 그 함수는 메인 함수입니다.


아래는 함수 선언 방법입니다.




아, Go 언어에서는 함수를 선언할 때 위치 제약이 없습니다.

c, c++에서는 호출할 때 해당 함수의 선언이 앞에 있어야만 호출할 수 있었습니다.

다만 Go언어에서는 함수 선언이 어디에 있든 상관없이 함수를 호출할 수 있습니다. 


아래는 입력 값을 받고 그 값들을 더한 값을 출력하는 예제입니다.

하지만 코드가 길어진다면 보기가 난해해질 수 있습니다.

이럴 때에 보기 좋게 함수를 사용합니다!



그러면 덧셈 함수를 만들어보도록 하겠습니다.



이 프로그램은 숫자를 입력 받고 두 수를 더한 값을 출력합니다.


함수는 func 키워드로 시작해 이어서 함수의 이름이 나온다.

함수의 인자는 이름 타임, 이름 타입, ... 같은 식으로 선언합니다.

그 뒤에는 리턴 값의 타입을 지정합니다.



1-2. 2개 이상의 값 반환

Go에서는 한 함수에서 여러 값을 반환할 수 있습니다.


여러 값을 반환해주려면 몇 가지를 변경해주어야합니다.

먼저 반환 형이 , 기준으로 여러 개의 값을 담도록 수정해야합니다.






1-3. 이 함수를 따돌릴겁니다. (지연)

Go에서는 특현한 defer 키워드가 있습니다.

이 키워드는 해당 함수를 끝으로 옮깁니다.



defer 키워드를 second 함수에 적용하였습니다.


그렇다면 이 코드의 작동은 아래의 코드와 같이 작동합니다.



처음의 코드를 실행한 결과는 당연히 아래와 같이 출력됩니다.




이 키워드는 자원을 해제해야 할 때 자주 사용합니다.

예를 들면 파일을 열고 저장을 하는 상황에 끝에서는 파일을 닫아줘야합니다.


이럴 때에 defer 키워드를 사용하여 편하게 사용할 수 있습니다.

 


이렇게 오랜만에 Go 강좌 함수에 대해 알아보았습니다.

사실 재귀, 함수 안의 함수 만들기도 작성할까 했지만...


하여튼 길고 긴 글을 읽어주셔서 감사합니다 ^^!


다음 강좌에서는 포인터를 다뤄보도록 하겠습니다.



1. 배열


오늘은 배열에 대해 알아보도록 하겠습니다.

아, 저번 강좌에서 이번에는 배열에 다뤄본다고 말씀드렸는데.

생각해보니 배열만 하는 것보단 슬라이스, 맵까지 다루는 것이 좋아보여 더 추가하였습니다.



1-1. 사용한다 나는 배열을


배열이란, 변수를 모아 놓은 집합이라고 말할 수 있습니다.

Go언어에서는 배열의 길이가 고정되어있습니다.


음... 예를 들자면 우리 반 학생들의 성적을 변수에 담는다고 가정하면 아래와 같은 변수를 선언해야 됩니다.


딱 보기만 해도 비효율적이고, 반에 학생이 50명이 있다면 하나하나 변수를 50번 선언해야 하며 사용자에게 학생들의 점수를 알려주려 할 때에 

변수에 접근하여 값을 얻어올 때도 상당히 불편함을 겪을 수 있습니다.


여기서 우리는 배열을 사용하면 이 문제점들을 한번에 잡을 수 있습니다!


상당히 편해지고 접근도 편해졌습니다.

아, 배열에 접근 할 때는 인덱스로 접근을 하게 됩니다.

이 인덱스는 항상 0부터 시작합니다.


아래는 학생의 점수 배열에 인덱스로 각 배열 요소에 접근하여 그 값을 출력하는 예제입니다.



아까처럼 변수를 일일히 선언하는 것보다 배열 하나를 사용하는 것이 더 편하며,

변수를 일일히 접근하는 것보다 배열에 인덱스를 이용하여 접근하는 것이 더 편하다는 것을 알 수 있습니다.


아래는 배열의 선언 방법입니다.



데이터 타입 앞에 대괄호를 여러 번 사용하면 다차원 배열을 생성할 수 있습니다.

아래와 같이 다차원 배열을 만들 수 있습니다.




2. 슬라이스


슬라이스는 배열과 비슷하지만, 길이가 고정되있지 않는 녀석입니다.

크기가 동적으로 늘어납니다.


또한 배열과 다른 타입입니다.

배열은 제네릭 타입이지만 슬라이스는 참조 타입입니다.



2-1. 사용한다 슬라이스를 나는


아래는 슬라이스를 선언하는 방법입니다.



슬라이스는 배열과 달리 크기를 정하지 않습니다.


아래에는 슬라이스를 선언하여 값을 초기화하는 예제입니다.



아래에는 이 초기화한 값에 다른 값을 슬라이스에 추가하는 예제입니다.



다음 아래에는 슬라이스에 접근하여 값을 가져오는 방법들입니다.




3. 맵


맵이란 사전과 비슷합니다.

Love 라는 단어에 "사랑"이라는 뜻이 있듯이 맵에는 Key, Value가 있습니다.


이러한 맵을 Go언어에서는 기본 자료형으로 지원합니다.

이 맵은 슬라이스와 마찬가지로 참조 타입입니다. 



3-1. 맵을 사용한다 나는


아래는 맵을 선언하는 방법입니다.



아래에는 맵을 선언하여 Key 와 Value를 초기화하는 예제입니다.



이제 이 맵을 이용하여 출력하고 데이터를 삭제하는 예제입니다.




다음 강좌에서는 함수에 대해 알아보도록 하겠습니다.

+ Recent posts