Hot answers tagged

170

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 ...


101

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 ...


95

A bit of a weird one, but: it's a denial-of-service risk, or potential information disclosure. Because C's preprocessor will cheerfully include any file specified in an #include directive, somebody can #include "../../../../../../../../../../dev/zero" and the preprocessor will try to read to the end of /dev/zero (good luck). Similarly, especially if you ...


57

Note that there is some amount of circular reasoning involved: Security issues are frequently linked to C and C++. But how much of that is due to inherent weaknesses of these languages, and how much of it is because those are simply the languages most of the computer infrastructure is written in? C is intended to be "one step up from assembler". There is no ...


50

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 ...


50

So let me preface this with "I'm not implying you're a child" Often when I teach kids about CIS and they hear what I do for a living, the first question is "How do I hack?" I'll tell you the same thing I tell them. Hacking isn't a thing you learn as much as it is the result of years of experience in a series of topics that relate to security. Often you'...


40

Compiler bombs C is a very powerful language, and some of the terrible things you can do with it would shock you. For example, you can create a 16 byte C program that takes 27 minutes to compile, and when it finally finishes, it compiles to a 16 Gigabyte executable file. And that's only using 16 bytes. When you factor in the preprocessor and larger source ...


37

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 ...


28

@AndréBorie is correct. Compilers and the corresponding configuration will not be well vetted for security issues, so generally speaking you should not compile untrusted code. The risk is that a buffer overflow or some type of library execution vulnerability is exploited, and the attacker gains access to the (hopefully non-root!) user account that ran the ...


28

A call to fopen is not in itself a TOCTOU vulnerability. By definition, TOCTOU involves two operations: a “check” and a “use”. A common example of TOCTOU vulnerability is checking access permissions with access before opening a file. It's a bug (race condition) because the permissions might change between checking and opening, and it's usually a ...


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 ...


25

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 ...


25

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 ...


22

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 you ...


22

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 that ...


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, ...


20

I see multiple problems with your shellcode. First of all let's debug your code. I compiled the C code containing your shellcode, run it with gdb and step until the first system call (int 0x80) [----------------------------------registers-----------------------------------] EAX: 0x5655700b --> 0xde3050f7 EBX: 0x5655550c (<main+35>: mov eax,0x0) ...


18

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 ...


17

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 ...


15

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 ...


14

Yes, it's dangerous: but as people have said it's possible to do. I'm the author and maintainer of the online compilers at https://gcc.godbolt.org/, and I've found it pretty workable to make it safe using a combination of: The whole site runs on a VM instance with little permissions to do anything. The networking is severely limited with only port 80 ...


13

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 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. ...


12

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 ...


12

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) ...


12

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 ...


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 ...


12

You would not want to be running the compiler as root, though I have seen this happen for "ease and convenience" reasons. It would be all too easy for an attacker to include something like: #include "../../../../etc/passwd" #include "../../../../etc/shadow" and get the contents of these files back as part of the compiler error message. Also compilers are ...


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 ...


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