Hot answers tagged

165

C and C++, contrary to most other languages, traditionally do not check for overflows. If the source code says to put 120 bytes in an 85-byte buffer, the CPU will happily do so. This is related to the fact that while C and C++ have a notion of array, this notion is compile-time only. At execution time, there are only pointers, so there is no runtime method ...


98

Memory isolation Your example wouldn't work on Windows 95, but it did work on DOS and Windows up to 3.11 (not Windows NT). The PC architecture, and the Microsoft series of operating systems, started with the Intel 8086 processor and an operating system (DOS) designed to run a single program at a time. You would run a program, and when you were finished ...


51

The main and almost unique reason why most software in the Linux ecosystem is written in C is Tradition. Developers see software written in C, libraries with a C-based API, and thus they use C, because that's convenient. Compilers are already there, and work well because the whole OS is written in C. None of this says that C is good for developing robust ...


36

Actually, "heartbleed" was not really a buffer overflow. To make things more "efficient", they put many smaller buffers into one big buffer. The big buffer contained data from various clients. The bug read bytes that it wasn't supposed to read, but it didn't actually read data outside that big buffer. A language that checked for buffer overflows wouldn't ...


25

Assuming buf's size is either controlled by n or larger than 16, the attacker could make n any number he wanted and use that to read an arbitrary amount of memory. memcpy and C in general do not throw exceptions or prevent this from happening. So long as you don't violate any sort of page protections or hit an invalid address, memcpy would continue ...


24

First, as others have mentioned, C/C++ is sometimes characterized as a glorified macro assembler: it is meant to be "close to the iron", as a language for system-level programming. So for instance, the language allows me to declare an array of zero length as a placeholder when, in fact, it may represent a variable-length section in a data packet or the ...


24

You can write secure code in C. Its just that the language is unsafe by default. The safety has to be tacked on manually with extra code (which of course can itself contain bugs). For that reason, C was never really the best choice for security-critical software. It was used anyway in FOSS because free compilers for it have historically been available on ...


21

String Termination Vulnerability Upon thinking about this more, using strncpy() is probably the most common way (that I can think of) that could create null termination errors. Since generally people think of the length of the buffer as not including \0. So you'll see something like the following: strncpy(a, "0123456789abcdef", sizeof(a)); Assuming ...


20

It is mostly untrue. Using a compiler of a different version than the one used for the "mainstream" binary, or using it with different compilation flags, may result in a few things ordered differently, but chances are that most of the code elements will appear in the same order. Insofar as it changes anything with regards to buffer overflow leveraging, ...


18

Your memory address 0xbffff880 is most likely non-executable, but only read/write. There are a couple of ways you can overcome this. If that is a stack address you can use -z execstack while compiling. This will essentially make the entire stack memory executable. For a more robust solution you can write the shellcode to call mprotect on the address ...


15

As the question is given in the headline, "Does compiling from sources .. protect from buffer overflow attacks?", the answer is in general no. However, here is a guess at what your friend might have been thinking of: Current versions of the GNU C Compiler (GCC) can optionally use the GCC Stack-Smashing Protector when invoked with the -fstack-protector ...


14

A good answer has already been given by sasha, but I want to look at this from another angle; specifically, what memcpy actually does (in terms of what code gets executed). Allowing for the possibility of minor bugs in this quick-and-dirty implementation, a trivial implementation of memcpy() that meets the C89/C99/POSIX function signature and contract might ...


13

The proper way is to use /dev/urandom, not /dev/random. There are very few cryptographic algorithm for which /dev/random is even theoretically better than /dev/urandom (this would be information-theoretic secure algorithms, not mundane things like AES or RSA). /dev/urandom produces randomness of cryptographic quality provided that it could get at some point ...


12

What happens here is that the foo() function uses a so-called old-style declaration, i.e. as things were done in C before the first normalization (aka "ANSI C" from 1989). In pre-ANSI C, a function bar() which takes two arguments of types int and char * would be defined that way: void bar() int i; char *p; { /* do some stuff */ } and it would ...


12

It is possible to have issues with printf(), by using as format string a user-provided argument, i.e. printf(arg) instead of printf("%s", arg). I have seen it done way too often. Since the caller did not push extra arguments, a string with some spurious % specifiers can be used to read whatever is on the stack, and with %n some values can be written to ...


12

A typcial example of non-trivial buffer handling is the parsing of binary files (or network packets) that can contain arbitrary-length strings. (Is there any ASN.1 parser that didn't have buffer overflows bugs at some time?) For example, consider the format of textual data chunks in PNG files: The keyword and text string are separated by a zero byte (...


12

If one goes back a few years before Windows, it was pretty much expected that any program running on a microcomputer would "own" the computer. If it wanted certain services to remain usable it would have to leave certain parts of the system alone, but otherwise there wasn't really any need to "protect" anything. Mainframe computers were sufficiently big ...


11

The statement, as you show it, is not vulnerable to anything. However, fprintf() is indeed an interpreter in its own right: what it takes as format string is not just a sequence of characters; it is source code for a specific language with directives beginning with a '%' sign. When you use your fprintf() function like that, sooner or later, some developer ...


11

There is plenty of malware out there that is written in .NET, but as a C# dev I can see why many malware authors avoid it: Easy to disassemble and reverse engineer. Easy for AV to detect use of certain classes and functions. Requires .NET on the box (older XP boxes might not have it, or might only have .NET 2.0) Harder to do anti-debug tricks in .NET than ...


11

On 32-bit x86 processors, with the ELF format in use on Linux systems, the function call convention states (page 3-12) that: A function that returns an integral or pointer value places its result in register %eax. In your program, the last element of main() is a call to strcpy(). That function returns a copy of its first argument, here a pointer to the ...


10

Send a mail to your sysadmin (you HAVE TO contact someone above you) or send it directly to the CIO, if you have to convince him, explain what you found and attach this part of the file named "a.c", that should suffice: * There are a number of commands that can be sent to the client: * * TSUNAMI <target> <secs> = A PUSH+...


10

In SSL/TLS, messages are sent as part of records. What should be expected is that the client first send a ClientHello message which itself is contained in one or several records. Record format is: record type: 1 byte (0x16 for "records contains some handshake message data") protocol version: 2 bytes (0x03 0x00 for SSL 3.0, 0x03 0x01 for TLS 1.0, and so on) ...


10

In order to make C code "safe", even against a malicious developer, then you have to fix the core issues of C, which have all been repeatedly exploited for arbitrary code execution (exactly what you want to avoid): Weak types. In C, you can take a bunch of bytes, and interpret them as a pointer, an integer, or whatever. All it takes is a cast. As long as ...


9

It depends on the rand() implementation... the standard (POSIX / Single Unix) gives a sample implementation but any system is free to have something better. You can see the sample code there. If that exact code is used, then the internal state is a 32-bit integer, and it suffices to get two successive 16-bit output values to recompute the internal state. ...


9

It is a race condition. You do the access(), then you do the open(). In the small time between the two calls, the file may have changed. Typically, the file is, say, /tmp/foo. Initially, the file is owned by some user (who is the bad guy of the story), and the target is some root-powered application. The application does the access(), sees that the file ...


9

At the time of MS-DOS, or in the graphical derivatives (up to and including Windows ME), there was no notion of "administrative rights". There are two distinct concepts here, that should be detailed. The first one is about what a process is allowed to do when it asks nicely. The second is what it can do if it is not nice at all. In MS-DOS, each process ...


8

"The process exiting on SEGV by itself is not a problem in this case": this is already a large assumption. Whatever the process was doing will not be finished; the caller gets an error code; if the process had created temporary files then those files do not get erased. Making sure that there really is no problem is tricky. Also, what creates the SEGV is the ...


8

[Does] compiling your own binary for an application (with specific compilation flags) instead of using the "mainstream binary" make it more difficult for an attacker to leverage buffer overflows? It depends on the operating system, the language the application is written in, and the compiler. First, the programming language must be a compiled language: C,...



Only top voted, non community-wiki answers of a minimum length are eligible