Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

According to an article I just read, the functions printf and strcpy are considered security vulnerabilities due to Buffer overflows. I understand how strcpy is vulnerable, but could someone possibly explain how/if printf is really vulnerable, or I am just understanding it wrong.

Here is the article: https://www.digitalbond.com/blog/2012/09/06/100000-vulnerabilities/#more-11658

The specific snippet is :

The vendor had mechanically searched the source code and found some 50,000-odd uses of buffer-overflow-capable C library functions such as “strcpy()” and “printf().”

Thanks!

share|improve this question
2  
If you are interested in this topics I suggest you to read Hacking: The Art of Exploitation by Jon Erickson. Chapter three contains a working exploit using the format string vulnerability of printf. –  Bakuriu Oct 9 '13 at 20:07
    
Sure I understand the format string vulnerabilities, from what I've read at least. However, I was under the impression that the function itself was somehow exploitable (even if it was used as intended). –  DarkMantis Oct 9 '13 at 20:58
2  
Seen another way, C/C++ itself is a buffer overflow vulnerability. All that direct toying with memory... –  LateralFractal Oct 10 '13 at 2:05

4 Answers 4

up vote 9 down vote accepted

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 memory (%n means: "the next argument is an int *; go write there the number of characters emitted so far).

However, I find it more plausible that the article you quote contains a simple typographical mistake, and really means sprintf(), not printf().

(I could also argue that apart from gets(), there is no inherently vulnerable C function; only functions which need to be used with care. The so-called "safe" replacements like snprintf() don't actually solve the problem; they hide it by replacing a buffer overflow with a silent truncation, which is less noisy but not necessarily better.)

share|improve this answer
1  
I've even seen argued (with some merit) that gets is not inherently vulnerable either. For example, if a program calls gets to read back data that it wrote, it may be guaranteed that the data fits in the buffer. For a file this is not robust but may be correct; for a self-pipe it could even be robust. –  Gilles Oct 9 '13 at 18:37
    
Slightly off-topic, but I do not agree at all with your comment regarding snprintf: it is difficult to use sprintf in a secure manner (and practically impossible if you use a %s format specifier), but snprintf, when used correctly, is safe: when snprintf truncates the input, because its size exceeds the buffer, it is not silent but tells you by giving a return value equal to the buffer size. –  AardvarkSoup Oct 10 '13 at 11:10

In addition to the answer by @Tom, I would also like to guide you to the OWASP code review guidelines, where some issues on using printf() are highlighted and this answer to a similar question on cs.stackexchange website.

share|improve this answer

Some printf directives (ie; %n) have side effects to addresses found on the stack, so print directives can be dangerous, even if the explicit output is implemented correctly.

share|improve this answer

Here is an example that shows how this overflow can help you. Imagine you don't have access to the private members (pwd for example) so printf will help you see the content of this variable

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

struct SecureLogin{
    SecureLogin(const char * login_)
    {
        strcpy(login,login_);
        strcpy(pwd,"ijk");//the user does not see this part of the source code as it is in a DLL
    }
    char login[8];
private:
    char pwd[8];

};


int main() {
    // your code goes here
    SecureLogin log("abc");
    printf("Pwd = %s\n",(&log.login[0])+8);//bcz you know the size of login is 8 bits
    return 0;
}

Output:

Pwd = ijk

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.