패스트터틀

보안 취약점(19.5.29) 본문

Cyber Security(undergraduate)/security vulnerability

보안 취약점(19.5.29)

SudekY 2019. 5. 29. 17:07

Heap Tyeps

 

signature : 0xeeffeeff 를 만나면 heap라는걸 알수있음

Segment : 받아온 덩어리

 

Heapalloc(0x1000 = req_size) 

실제 allocsize = req_size + 8(information about heap = header)

 

HEAP영역에 대한 공부가 더 필요하다고 느낀다. 잘 이해가 안간다.

 

Low Fragmentation Heap

 

LFH of Allocation은 Heap안에서 메모리가 17번째번 할당되면 활성화되는것

 

0x100 = 256

+

8

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

264 

는 

Bucket표상 33번째에 해당하니 33번째를 쓴다.

(Bucket은 16384 보다 작은 사이즈만 허용)

 

해당 Bucket은 SegmentInfo '

 

(virutal alloc은 kernel에게 필요한만큼만 받아와야되서)

heap 많이 받아와서 쪼개서 씀

LFH heap은 0x100(256)짜리가 17번 생성되면(이론이 적용된것같음) 0x100짜리를 30개 받을수있는것들을 미리 생성함

(미리 쪼개버리자)

그리고 이제 0x100이 할당이 되면 여기다가 넣어버림 => 이러면 안쓰는공간이 최소화됨,또한 매우빠르게 연산가능

 

그리고 만약에 0x200을 할당을 받으면 이것도 또 17개가 되면은 또 크게 받아서 쓰이도록 되어있음

 

0x100일경우 0x2000만큼 받음(

 

다시한번 정리하면 heap이 virtual alloc에서 받아오는거를 segments 그리고 sub-sugments로 나누고

그러면 sub-subments는 어떻게 크기를 결정하냐면 0x400, 0x800, 0x,1000 ~~~ 0x40000

 

이러한 표가있는데 

 

Buckets(0x100,0x200....) - Size of UserBlocks(0x400,0x800...)

0x2000 - 8(info) /(나누기) 0x100 + 8(info) = 30버켓

근데 0x100을 계속 무한대로 받아오면은  0x2000 17번주고 그다음에 0x4000을 8번주고 한다. 0x8000 bytes 8번받아옴

 

Bucket -> segments -> activesubsegment -> usersub -> aggregateExchg -> FreeEntryOffset = 0x2

Offset은 0x2 x(곱하기) 8 = 16 = 0x10bytes  (그다음번이 어디냐고 알려주는거)

(single linked list처럼)

이런식으로 따지면 복잡도(엔트로피?) 가 1로 굉장히 단순해져서 빨라진다는것임

Last Free First Use 라는 특성 ( window 7까지만 )

 

이렇게 해서 쭈우구~~~~~~~~~~~~~~~~ 40000까지 채우면 다 채워버리면

Virtual alloc에서 새롭게 받아옴 그리고나서부터는

 

0x100000, 0x200000, 0x400000,0x800000, 0xfd00000 ( windows 7 )

 

HeapManager는 브라우저나 프로그램마다 다 다르다.

 

해킹할때 이런게 필요하다는것도 알면좋지만 내가 만든 프로그램이 어떻게 메모리가 할당이 되고있구나 라는것을 알면은 좋음. 

 

# Virtual Alloc 으로 받아지는 메모리 영역은 항상 0000으로 끝난다.

 

 

 

 

18개를 만든순간 frontend가 활성화가 되고 Localdate-0번째-seg정보-32번째를 보니

활성화가 되었으나 아무것도 안채워진 상태에서 데이터를 더 채워보면(100개정도)

 

1.txt
0.02MB
2.txt
0.00MB

 

이렇게 해서 LFH offset 만큼 subsegment에서 더하면 다음 free공간이라는것을 알수있음

어떤 특정 버켓의 LFH가 활성화가 되면 해당사이즈에 해당하는것은 LFH만 쓴다.(LFH아닌영역이 free가되어도)

Last Free first use는 맨마지막에 해당하는것만 딱 하나만 하고 나머지는 기존 활성화된 subsegment를 함

 

 

defualt heap

 

 

기본적으로보면 printf나 이런것들을 쓰면 여기다가 쓰기때문에 기본적으로 채워져있는걸알수있따.

 

LFH는 기본적으로 깨끗하다.

 


        0045af98: 00060 . 00038 [101] - busy (2e)
        0045afd0: 00038 . 01008 [101] - busy (1000)
        0045bfd8: 01008 . 01008 [100]                 ---------여기서부터 데이터가 들어감
        0045cfe0: 01008 . 00020 [111] - busy (1d)

 

데이터 집어넣고

 

0045af98: 00060 . 00038 [101] - busy (2e)             
        0045afd0: 00038 . 01008 [101] - busy (1000)        
        0045bfd8: 01008 . 00108 [101] - busy (100)       ---------여기서부터 데이터가 들어감  
     ㅁ   0045c0e0: 00108 . 00108 [101] - busy (100)
     ㅁ   0045c1e8: 00108 . 00108 [101] - busy (100)  
     ㅁ   0045c2f0: 00108 . 00108 [101] - busy (100)
     ㅁ   0045c3f8: 00108 . 00108 [101] - busy (100)
     ㅁ   0045c500: 00108 . 00108 [101] - busy (100)
     ㅁ   0045c608: 00108 . 00108 [101] - busy (100)
           0045c710: 00108 . 00030 [100]
     ㅁ   0045c740: 00030 . 00108 [101] - busy (100)
     ㅁ   0045c848: 00108 . 00108 [101] - busy (100)
     ㅁ   0045c950: 00108 . 00108 [101] - busy (100)
     ㅁ   0045ca58: 00108 . 00108 [101] - busy (100)
     ㅁ   0045cb60: 00108 . 00108 [101] - busy (100)
     ㅁ   0045cc68: 00108 . 00108 [101] - busy (100)
     ㅁ   0045cd70: 00108 . 00108 [101] - busy (100)
     ㅁ   0045ce78: 00108 . 00058 [101] - busy (4c)
     ㅁ   0045ced0: 00058 . 00110 [101] - busy (100)
     ㅁ   0045cfe0: 00110 . 00108 [101] - busy (100)
     ㅁ   0045d0e8: 00108 . 00108 [101] - busy (100)

 

17개가 생성되고 

 

여기다가 하나더 만들면

 

다시 하나 더만들면 30개의 LFH데이터가 생김

 0045cfe0: 00110 . 00108 [101] - busy (100)
        0045d0e8: 00108 . 00108 [101] - busy (100)
        0045d1f0: 00108 . 02000 [101] - busy (1ff8) Internal 

        LFH data region at 0045d1f8 (subsegment 00457bd8):
            0045d208: 00108 - busy (100)
            0045d310: 00108 - free
            0045d418: 00108 - free
            0045d520: 00108 - free
            0045d628: 00108 - free
            0045d730: 00108 - free
            0045d838: 00108 - free
            0045d940: 00108 - free
            0045da48: 00108 - free
            0045db50: 00108 - free
            0045dc58: 00108 - free
            0045dd60: 00108 - free
            0045de68: 00108 - free
            0045df70: 00108 - free
            0045e078: 00108 - free
            0045e180: 00108 - free
            0045e288: 00108 - free
            0045e390: 00108 - free
            0045e498: 00108 - free
            0045e5a0: 00108 - free
            0045e6a8: 00108 - free
            0045e7b0: 00108 - free
            0045e8b8: 00108 - free
            0045e9c0: 00108 - free
            0045eac8: 00108 - free
            0045ebd0: 00108 - free
            0045ecd8: 00108 - free
            0045ede0: 00108 - free
            0045eee8: 00108 - free
            0045eff0: 00108 - free

 

 

그리고 여기다가 100개정두를 더 집어넣으면

 

 

            00460498: 00108 - busy (100)
            004605a0: 00108 - busy (100)
            004606a8: 00108 - busy (100)
            004607b0: 00108 - busy (100)
            004608b8: 00108 - busy (100)
            004609c0: 00108 - busy (100)
            00460ac8: 00108 - busy (100)
            00460bd0: 00108 - busy (100)
            00460cd8: 00108 - busy (100)
            00460de0: 00108 - busy (100)
            00460ee8: 00108 - busy (100)
            00460ff0: 00108 - busy (100)

        004611f0: 02000 . 00180 [100]
        00461370: 00180 . 02000 [101] - busy (1ff8) Internal 

        LFH data region at 00461378 (subsegment 00457c18):
            00461388: 00108 - busy (100)
            00461490: 00108 - busy (100)
            00461598: 00108 - busy (100)
            004616a0: 00108 - busy (100)
            004617a8: 00108 - busy (100)
            004618b0: 00108 - busy (100)
            004619b8: 00108 - busy (100)
            00461ac0: 00108 - busy (100)
            00461bc8: 00108 - busy (100)
            00461cd0: 00108 - busy (100)
            00461dd8: 00108 - busy (100)
            00461ee0: 00108 - busy (100)
            00461fe8: 00108 - busy (100)
            004620f0: 00108 - busy (100)
            004621f8: 00108 - busy (100)
            00462300: 00108 - busy (100)
            00462408: 00108 - busy (100)
            00462510: 00108 - busy (100)
            00462618: 00108 - busy (100)
            00462720: 00108 - busy (100)
            00462828: 00108 - busy (100)
            00462930: 00108 - busy (100)
            00462a38: 00108 - busy (100)
            00462b40: 00108 - free
            00462c48: 00108 - free
            00462d50: 00108 - free
            00462e58: 00108 - free
            00462f60: 00108 - free
            00463068: 00108 - free
            00463170: 00108 - free

 

쭈욱생성이된다.~~

넣고 뺏고 하는거는 기본적으로 global heap하고 똑같다.

 

객체 분석

 

classes(분류) - object(분류에 해당하는 예시)

 

class B1{

}

B1 *b1 = new B1();

void func <-> virutal void func() == virtual을 사용하면 func의 주소가 들어감

[ virtual void func() ] ==  [void *func = func()] 포인트가 들어가기 때문에

(포인터값을 포함하기때문에, 포인터가 같이 데이터입력되기때문에)

 

 

void main(){
    Foo *f = new Foo();
    f->foo();
}

==

IN ASSEMBLY

mov ecx, <addr. of the foo object>

call 0x4040404 == call func // addr of the foo's func() // 이런식으로 된다고보면됨

Struct Bar{
    void *function_pointer;
    unsigned int bar;
};

void main(){
    Bar *b = new Bar();
    b->func();
}

==

IN ASSEMBLY(x86)

mov ecx, <addr. of the foo object>

mov eax, [ecx+4];

call eax;  // Indirect call 주소를 가져와서 eax넣는 과정을 거침 , 객체에서 이주소를 가져옴

 

call 0x4040404 == call func // addr of the foo's func() // 이런식으로 된다고보면됨

 

 

오브젝트의 할당 b1

 

malloc과 new는 = heapalloc을 -> default heap을쓴다.

free , delete는 -> heapfree을 <- Default Heap에서

 

B1 *b = new B1()

B1 *b = (B1*)HeapAlloc();

 

이렇게 똑같다는것인데 이것은 LFH에 할당이 된다.

그러면 왜 malloc으로 안쓰고 new b1이런식으로 쓰느냐라고 묻는다면

b->uint_in_b1 = 0; <<<<<<<< 이 기능을 쓸려면 생성자를 써야만 사용가능하다.

 

class B1{

    unsigned int uint_int_b1;

 

    B1(){

       b1 = 0x41414141;

    }

    ~B1(){

      }

}

 

free(b) 라고 안하고 delete b; 라고 하는이유는 delete b 는 b->~B1(); 하고 free(b)해주는 역할을 동시에함

그렇기때문에 이런식으로 쓴다는 부분이다.

 

여하튼 new b를 하면 heapalloc(sizeof(b1)) 하고 같다라는 얘기이다.

 

 

 

allocheap 8사이즈 확인해보면 가능

 

 

배열을짜면 이런식으로 들어가있다는것을 알수있음

 

여기를 보면 20보다 작은것들도 들어가있는것도 확인가능한데

 

여기 서브세그먼트를 들어가서 

 

머라고 했는데 잘모르겠음 버킷이 이렇게 되어서 확인해보니 도표를 보니 저렇게 되었다고함

 

java의 경우에는

 

VM(Virutal Machine)이 있어서 java a.class 라고한다면 

vm a.class(bytecodes) -> x86으로 파싱해서 변한다고 함

new A() 이 사이즈가 20이라고 칠때

VM이 -> 0x20 을 처리하기위한 버켓이 반드시 있음

 

LFH도 병행해서 사용하게된다. 자바에 관련된 것들은 Custom heap manager 그밖 c처리는 LFH Heap Manager가 처리한다.

 

https://github.com/jaeseolee/IS571-ACSP-Fall-2018/tree/master/lec04

 

jaeseolee/IS571-ACSP-Fall-2018

Contribute to jaeseolee/IS571-ACSP-Fall-2018 development by creating an account on GitHub.

github.com

 

8+8(헤더) = 16

 

17째에 LFH가 활성화되고 18번째부터 LFH에 들어감

 

다중상속

 

다중상속을 받으면 HEAP 에서 합쳐진다고 보면됨

virutal을 썻던이유는 오버라이드 기능을 쓸수있기때문이다.

int foo()

     {

    return 0;

     }

int main(){
     foo();           -> call foo

     return 0;

  }

 

virtual을 하지 않으면 f1을 호출할때 해당 클래스껏만 사용가능하고 밑에 오버라이드도 안됨

mov eax, [ecx];

move eax,  [eax]

call eax;       <-- 이게 상수값이기때문에 포인터로는 상속을 변경할수있기때문에 virtual을 쓴다.

 

Triple Inheritance

 

 

순서대로 b1 b2 b3 d 로 되어있는것은 형변환을 위해 table이 존재한다.

(casting 을위해서)

 

Up cast는 안전하다

Down cast는 작게 메모리 할당했는데 더많은 엑세스를 하니 위험하다.

 

Custom Heap Manager

 

윈도우는 자체 Heap이 있다.

근데 S/W는 따로 Heap을 만들어서 쓰기도함

왜냐면 플랫폼 통합(Linux,window,mac에서도 배포하고싶어서) 또는 최적화, 보안기능을 넣고싶어서

 

Flash Player

 

content created하는것, 4억개시스템에서 사용되다가 이제 사장될위기에 처함

flash는 dll아니면 activeX기능으로 동작함, offices도 flashdll chrome은 untrusted 권한으로 flash.dll을줌

Youtube swithches HTML5 video 이후로 줄어들고있다.

크롬에서 플래쉬를못쓰게 하는거는 보안상 그리고 느리고 전력사용이 많아서 모바일에 불리

(0day : 하나도 공개되지 않는, 1day : 공개는되었음 근데 모든 사용자가 패치를 하거나 보완한것은 아님)

 

p-zero 팀이라는곳에서 2015년에 300개이상의 취약점을 공개하면서 flash를 버리자라고함

 

Custom Heap Manager for Flash

 

GCAlloc GCLargeAlloc VirtualAlloc LargeAlloc FixedAlloc

 

GCBlock은 Userblock이랑 똑같음 GcHeap은 7b0 보다 큰얘들 관리 하는얘들 무조건 16M로 나눠서 할당

해서~~~ 문서참고해주세용^^

 

Chrome

 

왜 굳이 구글은 크롬브라우저를 만들었을까? 근데 결국은 크롬이 이겼음...

근데 사파리는 계속 올라가는게 앱등이들이 올려주는것이다.그리고 정책상 WebKit을 애플사꺼만 쓰게 해놓음

사실상 엔진은 전부다 chrome(naver,samsung internet등등)

 

크롬은 매우 안전한데 이유로서는 개발프로세스를 굉장히 잘만들었기때문에

크롬은 4가지로 버젼을 관리한다. canary(까나리젓갈 생각나는) 버젼 개발자들이 취약점을 공개해서 서로 고칠수있고 하는 약간 위키백과같은것들을 하는 버젼이고 이것들에서 조금더 나아간것이 dev버젼을 만들고 그리고 안정화시키고 그리고 beta버젼을 만들고 취약점을 마지막으로 찾고 마지막에 가서 stable버젼으로 공개

 

공개된것을 컴파일할려면 엉청난 cpu개수로도 엉청나게 걸릴만큼 오래걸린다. 그만큼 웹브라우저이상의 거대한 프로젝트라는것이다.

 

문서참고^^ 

 

Object Tracking in Flash

 

TAGED POINT = A라는 객체가 할당이 되면 (LFH힙을 보면 0 또는 8이다. Virtual 0000 이런식)

끝에 3비트는 TAg 정보를 같이 주는 포인트를 같이 추가한것

이렇게 하면 찾기가 힘들다고함 (심볼값을 찾기가)

flash는 3비트 크롬은 1비트.

 

 

'Cyber Security(undergraduate) > security vulnerability' 카테고리의 다른 글

보안취약점(19.5.29)  (0) 2019.05.30
보안취약점 (19.5.28)  (0) 2019.05.28
Comments