Anonymous Memory Mapping (=AMM)


AMM은 Kerenl로부터 직접 메모리영역을 할당받는 기법으로, Heap을 거치지 않는다.

Heap영역 외의 공간에서부터 메모리를 할당받기 때문에 Heap에 메모리를 할당할 시 발생할 수 있는 Memory Fragmentation을 방지한다.

또, 커널에서 직접 할당해주는 메모리 공간이기에 zero filled 되어있다. 비록 Heap에 직접 접근하는 것보다 공간 할당에 있어서 더 느리다지만 memset으로 Heap을 초기화하는 오버헤드까지 고려하면 오히려 AMM이 더 빠를 수 있다.

할당 후 언제든지 할당공간의 크기를 재설정 할 수 있다는 것도 또 하나의 장점이다.

대게 이러한 특징들 때문에 대용량의 메모리 할당이 필요한 경우에 자주 쓰인다.


그런데 약간 문제가 있는 것이, BSD나 구버전의 Solaris(혹은 UNIX)기반 커널은 AMM을 지원하지 않는다.

이 러한경우 /dev/zero(swap영역으로 자주 쓰임, 가상파일)을 이용해서 Memory Mapping을 한다. 즉, AMM을 흉내라도 내보겠다는 것. 물론 /dev/zero의 file descriptor를 불러오는 것도 필요하고, 실제 AMM에 비해서 약간 느리기는 하다.

여기서는 두가지 기법 모두 기술하겠다.


[AMM]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define NULL 0
 
int main()
{
    const long szAlloc = sizeof("Hello Anonymous Memory Mapping!");
    char *ptr;
    int loop;
 
    ptr = mmap(NULL, szAlloc, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -10);
    if(ptr = MAP_FAILED)perror("mmap");
    ptr = "Hello Anonymous Memory Mapping!";
    printf("%s\t",ptr);
    return 0;
}
cs



[AMM /dev/zero]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define NULL 0
 
int main()
{
    const long szAlloc = sizeof("Hello Anonymous Memory Mapping!");
    char *ptr;
    int fd = -1, loop;
 
    if((fd = open("/dev/zero", O_RDWR, 0))<0)perror("open");
    ptr = mmap(NULL, szAlloc, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
    if(ptr = MAP_FAILED)perror("mmap");
    ptr = "Hello Anonymous Memory Mapping!";
    printf("%s\t",ptr);
    return 0;
}
cs


Posted by RevDev
,

-Simple SWF Fuzzer (Python, PyDbg)-



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# -*- coding: utf-8 -*-
from pydbg import *
from pydbg.defines import *
 
import utils
import random
import threading
import os
import shutil
import time
import ctypes
 
class file_fuzzer:
    def __init__(self, exe_path):
        self.targetfile        = "original_file"
        self.copyfile        = "mutated_file"
        self.ext            = 'swf'
        self.mutate_key        = {}
        self.mutate_count        = 5000
        self.exe_path        = "target_path"
        self.iteration        = 0
        self.crash             = None
        self.pid            = None
        self.in_accessv_handler    = False
        self.dbg            = None
        self.running        = False
        self.ready            = False
        self.eip            = None
 
    def fuzz(self):
        while 1:
            if not self.running:
                self.iteration += 1
                try:
                    shutil.copy(self.targetfile, self.copyfile)
                    self.mutate_file()
                except:
                    pass
                
                pydbg_thread = threading.Thread(target=self.start_debugger)
                pydbg_thread.setDaemon(0)
                pydbg_thread.start()
                
                while self.pid == None:
                    time.sleep(1)
                
                    monitor_thread = threading.Thread(target=self.monitor_debugger)
                    monitor_thread.setDaemon(0)
                    monitor_thread.start()
                
                else:
                    time.sleep(1)
 
    def start_debugger(self):
        print "\n[ * ] Starting Debugger for iteration : %d" % self.iteration
        self.running = True
        self.dbg = pydbg()
        
        self.dbg.set_callback(EXCEPTION_ACCESS_VIOLATION, self.check_accessv)
        
        pid = self.dbg.load(self.exe_path, self.copyfile)
        
        self.pid = self.dbg.pid
        self.dbg.run()
 
    def monitor_debugger(self):
        counter = 5
        print "[ * ] Monitor_thread for pid : %d" % self.pid
        
        while counter > 0:
            time.sleep(1)
            print  "Terminate Countdown : %d" % counter
            counter -=1
 
        if self.in_accessv_handler != True:
            time.sleep(1)
            self.dbg.terminate_process()
            self.pid        = None
            self.running    = False
        else:
            print "[ * ] The access violation handler is doing its business"
            
            while self.running:
                time.sleep(1)
 
    def check_accessv(self, dbg):
        print "\n[ * ] Handling an access violation!\n ",
        self.in_accessv_handler = True
        crash_bin = utils.crash_binning.crash_binning()
        self.crash = crash_bin.crash_synopsis()
 
        
        
        eipoff    = self.crash.find("EIP")
        eaxoff    = self.crash.find("EAX")
        self.eip    = self.crash[eipoff+5:eaxoff-3]
        eipname    = self.crash[eipoff+5:eaxoff+13]
        print "EIP = ",self.eip
        fd3 = open("D:\\fuzzing\\crashes.txt""a")
        fd3.write(self.eip)
        fd3.write("    iteration : %s    ext : %s\n" % (self.iteration,self.ext))
        
        
        crash_fd = open("D:\\fuzzing\\crashes\\crash-%s [ %d ].txt" % (eipname, self.iteration), "w+")
        crash_fd.write("=============== utils log ===============\n\n")
        crash_fd.write(self.crash)
        crash_fd.write("============ mutate_key log ============\n\n")
        crash_fd.write("%s " % self.mutate_key)
        crash_fd.write("\n\n END \n\n")
 
        
        shutil.copy(self.copyfile ,"D:\\fuzzing\\crashes\\crash-%s [ %d ].%s" % (eipname, self.iteration, self.ext))
        fd3.close()
        crash_fd.close()
        self.dbg.terminate_process()
        self.in_accessv_handler = False
        return DBG_EXCEPTION_NOT_HANDLED
 
    def mutate_file( self ):
        fd = open(self.copyfile, "rb")
        stream = fd.read()
        fd2 = open(self.copyfile, "wb")
        fd2.write(stream)
        stream_length = len(stream)
        attack_strs = [ "\x00""\x0d""\x0a""\xff"]
        
        for i in range(self.mutate_count):
            rand_offset = random.randint(0, stream_length - )
            self.mutate_key[rand_offset] = {hex(ord(stream[rand_offset:rand_offset+1] ) ) }
            attack_str = random.choice(attack_strs)
            fd2.seek(rand_offset)
            fd2.write(attack_str)
        fd.close()
        fd2.close()
        return
        
print "[ * ] Simple Fuzzer "
fuzzer = file_fuzzer(exe_path)
fuzzer.fuzz()
cs







Posted by RevDev
,


Codegate 2016 Junior Pre-Qual

-Revimal's WriteUp-





Codegate2016 Junior Pre-Qual WriteUp - Revimal.pdf


Posted by RevDev
,