Slashdot Mirror


Various *nix OSes Open To Format String Attacks

Numerous readers have pointed, as this unnamed correspondent does, to this CNET article: "There is an article on cnet claiming that both unix and linux systems contain security flaws, called 'format string' vulnerabilities, which allow hackers the ability to trick systems through command manipulation and subsequently run unauthorized applications."

28 of 208 comments (clear)

  1. Re:But what do you do? by Inoshiro · · Score: 3

    It's very, very simple.

    Step 1: make sure that the system's locale related stuff is owned by a secure account and permissioned accordingly so that others can't modify it.

    Step 2: Ensure any setuid and setgid programs ignore user specified or non-system locales.

    This way, the user can affect only their own account. They cannot give their specially made locales to setuid and setgid programs, and the setuid and setgid programs can still benefit from the system (presumed secure) locales.

    It's no different from having properly permissioned /etc directory, with programs which can read a config from /etc and a user specific location.
    --

    --
    --
    Internet Explorer (n): Another bug -- that is, a feature that can't be turned off -- in Windows.
  2. But what do you do? by Alan+Shutko · · Score: 5

    The base of the vulnerability is that people include format strings in their locale database. This has been a recommended practice, because it would let you restructure messages when you localize the strings.

    For example, you might have a message "Cannot open file %s". When translating the message to another language, the grammar of the language might require placing words after the file ("annotcay ilefay %s openway"). This is easy to do if you translate the whole format string, but if you'd constructed it by strcat("Cannot open file ", file) the translator can't reorder the message.

    But this makes you vulnerable because attackers can specify the locale database they'd like to use, making the format string something absurd like "%s%s%s%s%s%s", smashing the stack and opening the door to exploits.

    Unfortunately, I haven't seen anyone give an alternative. The original advisories just say "This is bad coding practice, don't do it" but don't offer any alternatives and point to documents which RECOMMEND DOING EXACTLY THIS.

    So, a question to all... how to you write your code so that it's flexible enough for translation, but not open to attack?

    1. Re:But what do you do? by jekk · · Score: 3
      Many people have responded to this (5 rating) comment by describing possible ways to build code that's "flexible enough for translation but not open to attack". I could add my own way of doing it. But everyone is missing the point. The question asked (or intended) was "how do you write your code". So far, everyone has been speaking in the hypothetical, and that masks a VERY important point... we're clearly CAPABLE of writing code that is safe from this exploit, but (because of the faulty behavior of default libraries) we're not doing it! .

      So I'll try to answer the original question. Most of MY code lately has been written in Java. Java doesn't have this particular vulnerability, because it's not subject to stack over/underflows (normally). I HAVE written pleanty of code in C/C++, but nothing that used i18n. So other than suggesting "try a different language" (not always a useful suggestion) my answer is that I DON'T have a solution... at least not one thats so convenient that I use it in real life.

      So... this is a community forum... anyone willing to step up and address this problem? New libraries for Linux? It wouldn't be too difficult to build something that automatically checks the format strings in a string catalog against those in a standard catalog and refuses to load the string catalog if it's not validated. If a couple of other people will help me (because I'm not a linux hacker and would need the help of someone with more i18n experience) I'm willing to work on writing something like this!. Any takers?

      If I get no responses, I'll have to assume that the community is not interested (or that they just didn't see my post because it wasn't moderated up ;-) ), and I'll forget the whole issue.

      -- Michael Chermside
      michael.chermside@destiny.com

  3. Credibility by Nexx · · Score: 4

    The wording of the article tells me that the guywho wrote it doesn't have a slightest clue what he is talking about, but wants to scre everyone in sight to death

    Heard on NPR, quoting Jesse Ventura, the governor of Minnesota. He stated, and quite correctly, that many media outlets are no longer in the business of reporting the news, but instead, making the news. They're slaves to the almighty buck.

    He went on to state that there's nothing wrong with being a slave to the almighty buck, but if they are, they should not be misleading consumers by stating that they're "journalists" and not "tabloid artists".

    On the web, as with anywhere else, "consider the source". Many people no longer do this, but this is absolutely critical when judging the accuracy of any information, not limited to that shown in the news. Sensationalism in "professional" journalism is very much alive today as it were in the 1890's, when "yellow" journalism coursed through the pages of "credible" newspapers.


    --
  4. Re:C specific, not unix specific by Pflipp · · Score: 3

    That was the locale problem, yes. But as pointed out in some other replies here, it seems that it can affect _any_ program w. external input.

    Say, I make a remote client, it reads your login name, and password, and then says:

    printf ("Hello %s%s,", name, "this is your name again:"); # no problem

    printf (name); # problem

    'cause if I say that my name is "%d asdf" or so, this might cause troubles. Maybe there are more ways to harm than just exploit this weakly set up printf statement, but this is the example of above, and because in my example we are talking about a "remote client", I have demonstrated to you that this is not just a local problem ;-)

    So it's not just a _local_ "locale" thingy, it's all over.

    It's... It's...

    --
    "We can confirm that Debian does *not* ship the version with the trojan horse. Our version predates it." [CA-2002-28]
  5. Not new by imp · · Score: 5

    This isn't that new. Most of the *BSD issues
    have already been committed and are thus not vulnerable. Tehy make it sound a lot worse than
    it really is.

    Also, *ALL* Oses are impacted, since all oses have the sprintf-like functions.

    Warner Losh
    FreeBSD Security Officer.

  6. C specific, not unix specific by DaveTerrell · · Score: 3

    Anything that uses printf-like statements can be vunlerable to attack. Specifically, anything that uses printf-like statements improperly. Always printf("%s", string) instead of printf(string). Note that this has cropped up in lots of places, including openbsd's ftpd (if you turn on anonymous ftp, which is off by default).

    1. Re:C specific, not unix specific by mangino · · Score: 4

      This is actually a problem in the gettext routine. It allows a person With a local account to create a custom locale that includes format strings inside the internationalization code. The answer is simple, drop the locale related variables from setuid environments. What was not mentioned in the article is that for the current cases, this requires a local account on the machine and setuid that doesn't drop the correct variables from the environment. If you don't use internationalized setuid programs, you should be okay.

      Mike
      --
      Mike Mangino
      Sr. Software Engineer, SubmitOrder.com

      --
      Mike Mangino
      mmangino@acm.org
  7. yawn by Dalroth · · Score: 3

    *yawn*

    Any program written in C or C++ could potentially suffer from the same problems...

    And that INCLUDES Microsoft.
    And that INCLUDES BeOS.
    And that INCLUDES MacOS.

    Big deal! In fact, this is probably one of the most uninformed articles I've read yet (unless I'm totally missing something).

  8. Auditing anyone? by jailbrekr2 · · Score: 3

    Arce initially found the locale vulnerability on a Sun Microsystems server, but it affects all Linux and Unix operating systems except OpenBSD and FreeBSD, he said.

    And it is this comment that emphasises the need for a Linux project similar to OpenBSD (as asked in the previous /. article Here)

    This is not a flame, but we need a distribution that emphasizes security and code auditing, as opposed to the current trend of adding more and more bloat to an otherwise fast and stable kernel....

    --
    Feed The Need[goatse.cx]
  9. Re:Hmmm... by emerson · · Score: 5

    You're not following Bugtraq closely enough then.

    http://archives.ne ohapsis.com/archives/bugtraq/2000-08/0457.html describes a format string vulnerability (and sample exploit code) in the locale system of most Unixes; OpenBSD appears not to be vulnerable, and FreeBSD is not remotely exploitable, but all other major Unixes appear to be vulnerable.

    This isn't FUD; the article is pretty dead-on.


    --

  10. It has been by Dungeon+Dweller · · Score: 3

    It has been, hundreds of times, people just keep writing utilities with security flaws. That's life, then, you patch the hole and get on with life. These holes are potentially in all C/C++ programs, and even programs in other languages. A little overflow here, a little backspace character there, and you've royally screwed with the mind of the given program.

    --
    Eh...
  11. Re:Your example is wrong. by lamontg · · Score: 3
    The example isn't wrong, but perhaps a little confusing. I'm not exploiting the sprintf(), I'm exploiting the call to syslog() which also uses format strings.

    And really the best way to avoid these bugs is to avoid using anything other than fixed format strings. One way the bug occurs is (building on my previous example):

    mysyslog(char *foo) {
    syslog(LOG_DEBUG, foo);
    }

    (Obviously this is an example and mysyslog() in the real world probably does a few other things that the programmer always wanted to do when syslogging). Then the programer calls:

    mysyslog("foobar");

    All over the place and is fine until they start getting tricky and constructing error messages like:

    sprintf(buffer, "error message: %s", foo);
    mysyslog(buffer);

    Which looks perfect reasonable, but of course is exploitable if foo is user-supplied. The fix is that mysyslog() needs to be rewritten to look like:

    mysyslog(char *foo) {
    syslog(LOG_DEBUG, "%s", foo);
    }

    Hole closed.

  12. Re:Ok, so how exactly would this work? by Broccolist · · Score: 3
    (disclaimer: I've never cracked anything myself; this is just how I would guess this is done)

    I agree that using %s generally causes no possible root exploits. But there's a little known printf conversion character that allows you to *write* into the printf argument. It's %n. What it does is write the integer value of how many characters were written up to date by printf into an integer argument. (don't ask me why anyone would want this for legitimate purposes ...)

    So, for example, say the vulnerable printf is:

    char string[50];
    printf("blahblah: %s", string);

    From what I understand, the locale vulnerability allows you to replace the "%s" by anything you want. So you could tell the computer, for example, that in your country "blahblah" should be written "lots_of_random_characters...%n%n%n%n%n%n...(evil assembly code)". With a carefully calculated number of beginning characters and %ns, you could overwrite the function's return address (after the string on the stack) to contain the address of your evil assembly code, thus gaining root when the function returns. How this would work exactly would depend on the specific compiler/OS, more study would be needed to write a working exploit.

    There might be other ways to exploit the problem, but that's my theory.

  13. Talk about major misinformation by segmond · · Score: 3

    Bahahahahahaha

    //QUOTE
    These "format string" vulnerabilities started surfacing about two months ago, said Elias Levy, a moderator of the Bugtraq computer security mailing list. Some of them have lurked for years in basic Unix programs, but security experts only now have begun to find and fix them.

    To take advantage of a format string vulnerability, an attacker gets a computer to display a string of text characters with formatting commands. By carefully manipulating the formatting commands, the attacker can trick the computer into running a program.

    "Format string bugs are the new trend in computer security vulnerabilities," said Ivan Arce, president of Argentinian security company Core SDI and discoverer of the "locale" format string vulnerability that became public last Friday. "

    //QUOTE ENDS

    This is so F sad, cuz this is as old as UNIX, ie,
    gets(foo);
    sprintf(...);
    system(foo);

    This was exploited in late 70's and 80's, lol, my first penetration of a box to use gopher! was using this in early 90's. anyway, talk about misinformation.

    --
    ------ Curiosity killed the cat. {satisfaction brought it back | it didn't die ignorant | lack of it is killing mankind
  14. WTF by Valar · · Score: 3

    Personally, I've never had a daemon give me:

    segmentation fault(core dumped)
    root@localhost root>
    ,

    so it doesn't seem to me that this happens often, and even then, what kind of admin installs daemons without testing them thoroughly?

  15. Re:Can somebody explain? by BearCubSF · · Score: 3

    The general class of "format string" security holes relate to improper treatment of the format string passed to the *printf() family of library routines. The most common form of this that I've seen is when somebody does something like this:

    char *buff;
    char *output;
    ...
    [some code that sets buff through some
    user-supplied data, such as an entry to
    a prompt, environment variable, etc.]
    ...
    sprintf(output, buff);

    The user then supplies one or more formating sequences of his own into 'buff', and the *printf() functions then go looking for additional arguments.

    That sprintf() call should really be this:

    sprintf(output, "%s", buff);

    Depending on where this happens, what can be placed into 'buff', and a slew of other factors, this can result in many outcomes, including nothing at all, a core dump, buffer overflow, display of "hidden/protected" information, or even root access.

    Oh, and contrary to what the C|Net article says, this did not just start being exploited a couple of months ago, although there has been a decided increase in this over the last few months. For example, there was a problem in the qpopper POP3 software from Qualcomm that allowed easy root access via a missing "%s" format string, and that's well over a year old.

    Then again, C|Net -usually- gets the technical details of such issues wrong, or at least seriously distorted. They also tend to go for the "omigawd!" reaction in their writing, blowing some things out of proportion. When/if I read them, I always do so through the reality filter that takes that into account...

    --
    The ways of the underworld are perfect. They may not be questioned.
  16. Re:Can somebody explain? by devjoe · · Score: 3
    He said "as if he were a 6 year old", and most 6 year olds I know don't understand C.

    So, 6 year old's version:

    What printf is
    In the C programming language, one of the most common ways for displaying text is the printf function. When printf is used, it is given a string (a list of characters -- a bit of text, essentially) and optionally, some other variables that may contain various types of data. Printf then prints the string, modified by replacing certain special codes with formatted versions of the other variables. (Because the codes control how the other data is formatted, that first string is sometimes called the format string.)

    These format codes always start with the % character; %% is replaced by a single % character in the output, while % followed by various other characters is replaced by one of the other variables, formatted as defined by one or more of the characters after the %. The simplest of these formatting codes is %s which means "the variable is another string; print it here just as-is".

    There are also some variants of printf such as sprintf which do very similar things, and suffer from the same problems. Also, some programs written in other languages than C may be able to call C's printf function, so it's not necessarily limited to programs written in C.

    The problem
    If printf is called with more format codes in the format string that there are additional variables supplied to the function, then printf will grab some other data in memory to use as the additional variable, perhaps the next instruction that was supposed to be executed after printf. The result is that some garbage data is printed, and an instruction in the program is skipped. The result may pass unnoticed except for the weird output, but more likely, the program will do something other than it was supposed to do, and after a while, probably crash.

    If a user can control what data is in the format string, he can stick in format codes the program does not expect, and thus make programs crash that run fine as long as no % characters appear in their input. A skilled hacker with detailed knowledge of the workings of a program may be able to give it input that causes it to execute, as the next instruction, some piece of data which he has fed into the program elsewhere, and thereby make the program do some specific thing he wants it to do, and which the program was not designed to do.

    Setuid programs are UNIX programs that run with special privileges. These programs may be able to read or modify files that the user running them would ordinarily not be allowed to access. If a setuid program suffers from this problem, a skilled hacker may be able to use it to execute any code he wants with the program's privileges.

    The Solution
    You've seen this already as C code, since about a fourth of all the messages for this story consist of nothing but the answer. The problem occurs when the format string to printf is user-provided data; this most often happens when printf is used to simply print a string without doing any formatting, or in some situations involving the locale form of internationalization (see below). The cure to these problems is to never use a string containing user data as the format string for printf. Instead, use "%s" as the format string, and give the string of user data as the next variable. Thus, printf("%s",user_data) rather than printf(user_data).

    However, there are many places this bug can occur, and another possible way of reducing preventing this problem with respect to locale data is to have the locale library check whether it is running with special privileges, and when it is, to ignore user-supplied locale databases. (See below.)

    Locale
    Locale is a system used widely on UNIX systems for making programs friendly to people who speak different languages. The way this works is that the user sets a setting which specifies his locale. This is close to simply specifying his language, but a locale can be more specific than this. A user might specify a UK locale to have his programs use "colour" instead of "color" and "full stop" instead of "period".

    The way this works is that programs that support locales pass all their error/status messages through a function which searches the user's chosen locale database for that string. If it finds it, it returns the corresponding string localized for that user; otherwise, it just returns the original string.

    Users can also create custom locale databases, and use some additional settings to allow programs to find them. For instance, a user who prefers to think of his directories as "folders" could specify a "folder" locale which only changed "directory" to "folder" and left all other program output unchanged. The problem is that users can create locales which contain extra formatting codes in the "localized" strings. If programs use local strings as format strings to printf, the problems described above can occur.

  17. Re:Not new -- and can be stopped by the compiler by ryanr · · Score: 3

    I'm not sure why you would point that out in this context. Crispin (leader of the Stackguard project) makes no claim to being BO-proof, and Stackguard doesn't even address format string problems.

    Check out the thread on vuln-dev here

  18. Re:I didn't understand that. by Jason+Earl · · Score: 3

    What are those funny lines supposed to mean? Is it some sort of code that people in this site use? I'm sorry if I don't know the conventions you people use to communicate. I'm new to this site, and I'm not very technical oriented. All I want is to learn from you.

    The "funny lines" are snippets of code in the C language. Many (perhaps even most) of us here on this site read at least a little bit of C, but if you don't, that's just fine. The poster was simply pointing out the correct way to use the printf() function.

    /. is a great site, but it's not really a tutorial. I would suggest taking a look at Eric Raymond's Hacker Howto. Install Linux on a machine (it's not that hard) and get a good book on Python. Join a Linux Users Group, or just hang out on some of the excellent Linux mailing lists or IRC sites.

    Good Luck

  19. Hmmm... by Jeld · · Score: 3

    I follow bugtraq pretty close and I have never heard of a particular "format string" security vulnerability. Especially in many different unixes. There were quite a few different bugs exploited by sending a particularly formatted string to a certain program. The wording of the article tells me that the guywho wrote it doesn't have a slightest clue what he is talking about, but wants to scre everyone in sight to death. Looks very much like a fake or a misunderstanding so complete that mind starts spinning trying to grasp the depth of it.

    --

    Everybody Lies. But it doesn't matter since nobody listens.

  20. Taint mode solves this problem by vectro · · Score: 5

    Perl's 'taint mode' solves this problem very well. Basically all user input (enviornment, standard input, reading from files and network sockets, etc.) is considered 'tainted', and can't be used in an insecure manner (running commands, etc.) without a regular subexpression match.

    Basically, what this means is that perl forces you to check that the input you were given is secure. This makes perl more secure than C in many ways.

    For more information on taint mode and other security features in perl, see the perlsec manpage.

  21. Unix specific? Yes and no. by Forgotten · · Score: 5

    First off, the CNet story is a crock written by a hack with just enough understanding of the subject to screw it up. Par for the CNet course.

    There is a valid point made by the people suggesting that this problem is endemic to any software linked to the standard C library, or more specifically to software that abuses the printf() family of functions. This obviously isn't Unix-specific - the locale mechanism just happens to be the exploit that was described.

    However, there *is* a gem of truth to the Unix vulnerability idea, and it's rooted in the power of the shell as well as the existence of (and overeliance on) the system(2) call. This is why the US Army moved their web servers from NT to (gasp) the "classic" Mac OS - not just because it offers no network services by default (this can trivially be accomplished on any OS), but because it doesn't have a command-line shell that's easy to exploit (note that I don't agree with their decision and would never deploy the non-Unix Mac OS for any production network server - also note that their assumption isn't even correct, because AppleScript is quite comparable to the Bourne shell and *can* be remotely invoked in some cases).

    Part of the problem here is that we have come to rely on models for Unix network software that either need to put strings through the shell (and thus have to deal with baroque quoting issues) or can be tricked into doing so. CGIs are an example of this - it's now obvious that the CGI wasn't a particularly good choice for scalability *or* security. These issues do need to be addressed, so perhaps we can get a modicum of real use out of this latest CNet drivel.

  22. Format Strings 101 (fixed) by lamontg · · Score: 5
    (Sorry for the duplicate, hit the fscking submit button when I meant to hit preview...)

    The problem comes about when you accept user input and then send it to vsprintf(), setproctitle(), syslog() or similar C programs that accept format strings. The seemingly innocuous code usually looks something like this:

    char buffer[1024];
    [...]
    sprintf(buffer, "some message: %s", hostile_user_input);
    syslog(LOG_DEBUG, buffer);

    Now an attacker can shove a string into the hostile_user_input variable like "%s%s%s%s" which will then be passed to syslog which whill execute:

    syslog(LOG_DEBUG, "some message: %s%s%s%s");

    Notice that this isn't a "valid" format string. It tends to do odd things since it goes looking for function arguments that aren't actually there. Clever construction of the hostile format string will lead to an exploit. This was used in the wu-ftpd remote setproctitle() exploit and the recent linux rpc.statd syslog() remote exploit.

    All OSen which have code compiled from C and which use the vsprintf(), syslog(), setproctitle(), etc functions are potentially vulnerable to these attacks. There are undoubtably these kinds of vulnerabilities lurking within W2K somewhere...

  23. Script Kiddies have known this for years by spazimodo · · Score: 4

    y 3l53 d0 j00 th1nk th3y r1t3 lyk3 th1s?



    -Spazimodo

    Fsck the millennium, we want it now.

    --

    Fsck the millennium, we want it now.
    Millennium Crisis Line: 0890 900 2000 [calls cost 50p/min]
  24. This is a really old trick by meloneg · · Score: 3

    This used to be a pretty common type of attack on the old FidoNET systems. Almost everyone was using MS-DOS (or some version thereof) with ANSI.SYS.

    The ANSI.SYS driver allowed the F-keys to be reprogrammed via ESC sequences. The common technique was to reprogram F1 or F3 (used in the simplisitc command history function) to do something nasty.

    This sounds like the same basic thing.

  25. Just be carefull when you *printf() by acumen · · Score: 3
    Every OS that has implementation of *printf() is vulnerable at that point, and that's almost every OS.

    Problems with *printf() only occur when the programmer is not careful. Anyone who worries about his code can use stuff like PScan to automatically find any format mismatch. Even gcc itself is smart enough to warn about these kind of errors.

  26. Re:Intersteing quote by GrenDel+Fuego · · Score: 3

    Yes.

    Why aren't OpenBSD and FreeBSD affected? The article didn't.

    Someone earlier mentioned that the BSD ftp server was vunerable to this (when anonymous was enabled). Wouldn't this mean they would be affected? or is it only when the ftp server runs under one of the affected os's?