Wade Not In Unknown Waters: Part Two

Published July 22, 2013 by Andrey Karpov, posted by Code_Analysis
Do you see issues with this article? Let us know.
Advertisement

This time I want to speak on the 'printf' function. Everybody has heard of software vulnerabilities and that functions like 'printf' are outlaw. But it's one thing to know that you'd better not use these functions, and quite the other to understand why. In this article, I will describe two classic software vulnerabilities related to 'printf'. You won't become a hacker after that but perhaps you will have a fresh look at your code. You might create similar vulnerable functions in your project without knowing that.

STOP. Reader, please stop, don't pass by. You have seen the word "printf", I know. And you're sure that you will now be told a banal story that the function cannot check types of passed arguments. No! It's vulnerabilities themselves that the article deals with, not the things you have thought. Please come and read it.

The previous post can be found here: Part one.

Introduction

Have a look at this line:

printf(name);

It seems simple and safe. But actually it hides at least two methods to attack the program.

Let's start our article with a demo sample containing this line. The code might look a bit odd. It is, really. We found it quite difficult to write a program so that it could be attacked then. The reason is optimization performed by the compiler. It appears that if you write a too simple program, the compiler creates a code where nothing can be hacked. It uses registers, not the stack, to store data, creates intrinsic functions and so on. We could write a code with extra actions and loops so that the compiler lacked free registers and started putting data into the stack. Unfortunately, the code would be too large and complicated in this case. We could write a whole detective story about all this, but we won't.

The cited sample is a compromise between complexity and the necessity to create a code that would not be too simple for the compiler to get it "collapsed into nothing". I have to confess that I still have helped myself a bit: I have disabled some optimization options in Visual Studio 2010. First, I have turned off the /GL (Whole Program Optimization) switch. Second, I have used the __declspec(noinline) attribute.

Sorry for such a long introduction: I just wanted to explain why my code is such a crock and prevent beforehand any debates on how we could write it in a better way. I know that we could. But we didn't manage to make the code short and show you the vulnerability inside it at the same time.

Demo sample

The complete code and project for Visual Studio 2010 can be found here: printf_demo.zip.

const size_t MAX_NAME_LEN = 60; enum ErrorStatus { E_ToShortName, E_ToShortPass, E_BigName, E_OK }; void PrintNormalizedName(const char *raw_name) { char name[MAX_NAME_LEN + 1]; strcpy(name, raw_name); for (size_t i = 0; name != '\0'; ++i) name = tolower(name); name[0] = toupper(name[0]); printf(name); } ErrorStatus IsCorrectPassword( const char *universalPassword, BOOL &retIsOkPass) { string name, password; printf("Name: "); cin >> name; printf("Password: "); cin >> password; if (name.length() < 1) return E_ToShortName; if (name.length() > MAX_NAME_LEN) return E_BigName; if (password.length() < 1) return E_ToShortPass; retIsOkPass = universalPassword != NULL && strcmp(password.c_str(), universalPassword) == 0; if (!retIsOkPass) retIsOkPass = name[0] == password[0]; printf("Hello, "); PrintNormalizedName(name.c_str()); return E_OK; } int _tmain(int, char *[]) { _set_printf_count_output(1); char universal[] = "_Universal_Pass_!"; BOOL isOkPassword = FALSE; ErrorStatus status = IsCorrectPassword(universal, isOkPassword); if (status == E_OK && isOkPassword) printf("\nPassword: OK\n"); else printf("\nPassword: ERROR\n"); return 0; }

The _tmain() function calls the IsCorrectPassword() function. If the password is correct or if it coincides with the magic word "_Universal_Pass_!", then the program prints the line "Password: OK". The purpose of our attacks will be to have the program print this very line.

The IsCorrectPassword() function asks the user to specify name and password. The password is considered correct if it coincides with the magic word passed into the function. It is also considered correct if the password's first letter coincides with the name's first letter.

Regardless of whether the correct password is entered or not, the application shows a welcome window. The PrintNormalizedName() function is called for this purpose.

The PrintNormalizedName() function is of the most interest. It is this function where the "printf(name);" we're discussing is stored. Think of the way we can exploit this line to cheat the program. If you know how to do it, you don't have to read further.

What does the PrintNormalizedName() function do? It prints the name making the first letter capital and the rest letters small. For instance, if you enter the name "andREy2008", it will be printed as "Andrey2008".

The first attack

Suppose we don't know the correct password. But we know that there is some magic password somewhere. Let's try to find it using printf(). If this password's address is stored somewhere in the stack, we have certain chances to succeed. Any ideas how to get this password printed on the screen?

Here is a tip. The printf() function refers to the family of variable-argument functions. These functions work in the following way. Some amount of data is written into the stack. The printf() function doesn't know how many data is pushed and what type they have. It follows only the format string. If it reads "%d%s", then the function should extract one value of the int type and one pointer from the stack. Since the printf() function doesn't know how many arguments it has been passed, it can look deeper into the stack and print data that have nothing to do with it. It usually causes access violation or printing trash. And we may exploit this trash.

Let's see how the stack might look at the moment when calling the printf() function:

image1.png

Figure 1. Schematic arrangement of data in the stack.

The "printf(name);" function's call has only one argument which is the format string. It means that if we type in "%d" instead of the name, the program will print the data that lie in the stack before the PrintNormalizedName() function's return address. Let's try:

Name: %d

Password: 1

Hello, 37

Password: ERROR

This action has little sense in it for now. First of all, we have at least to print the return addresses and all the contents of the char name[MAX_NAME_LEN + 1] buffer which is located in the stack too. And only then we may get to something really interesting.

If an attacker cannot disassemble or debug the program, he/she cannot know for sure if there is something interesting in the stack to be found. He/she still can go the following way.

First we can enter: "%s". Then "%x%s". Then "%x%x%s" and so on. Doing so, the hacker will search through the data in the stack in turn and try to print them as a line. It helps the intruder that all the data in the stack are aligned at least on a 4-byte boundary.

To be honest, we won't succeed if we go this way. We will exceed the limit of 60 characters and have nothing useful printed. "%f" will help us - it is intended to print values of the double type. So, we can use it to move along the stack with an 8-byte step.

Here it is, our dear line:

%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%x(%s)

This is the result:

image2.png

Figure 2. Printing the password. Click on the picture to enlarge it.

Let's try this line as the magic password:

Name: Aaa

Password: _Universal_Pass_!

Hello, Aaa

Password: OK

Hurrah! We have managed to find and print the private data which the program didn't intend to give us access to. Note also that you don't have to get access to the application's binary code itself. Diligence and persistence are enough.

Conclusions on the first attack

You should give a wider consideration to this method of getting private data. When developing software containing variable-argument functions, think it over if there are cases when they may be the source of data leakage. It can be a log-file, a batch passed on the network and the like.

In the case we have considered, the attack is possible because the printf() function receives a string that may contain control commands. To avoid this, you just need to write it in this way:

printf("%s", name);

The second attack

Do you know that the printf() function can modify memory? You must have read about it but forgotten. We mean the "%n" specifier. It allows you to write a number of characters, already printed by the printf() function, by a certain address.

To be honest, an attack based on the "%n" specifier is just of a historical character. Starting with Visual Studio 2005, the capability of using "%n" is off by default. To perform this attack, I had to explicitly allow this specifier. Here is this magic trick:

_set_printf_count_output(1);

To make it clearer, let me give you an example of using "%n":

int i; printf("12345%n6789\n", &i); printf( "i = %d\n", i );

The program's output:

123456789

i = 5

We have already found out how to get to the needed pointer in the stack. And now we have a tool that allows us to modify memory by this pointer.

Of course, it's not very much convenient to use it. To start with, we can write only 4 bytes at a time (int type's size). If we need a larger number, the printf() function will have to print very many characters first. To avoid this we may use the "%00u" specifier: it affects the value of the current number of output bytes. Let's not go deep into the detail.

Our case is simpler: we just have to write any value not equal to 0 into the isOkPassword variable. This variable's address is passed into the IsCorrectPassword() function, which means that it is stored somewhere in the stack. Do not be confused by the fact that the variable is passed as a reference: a reference is an ordinary pointer at the low level.

Here is the line that will allow us to modify the IsCorrectPassword variable:

%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f %n

The "%n" specifier does not take into account the number of characters printed by specifiers like "%f". That's why we make one space before "%n" to write value 1 into isOkPassword.

Let's try:

image4.png

Figure 3. Writing into memory. Click on the picture to enlarge it.

Are you impressed? But that's not all. We may perform writing by virtually any address. If the printed line is stored in the stack, we may get the needed characters and use them as an address.

For example, we may write a string containing characters with codes 'xF8', 'x32', 'x01', 'x7F' in a row. It turns out that the string contains a hard-coded number equivalent to value 0x7F0132F8. We add the "%n" specifier at the end. Using "%x" or other specifiers we can get to the coded number 0x7F0132F8 and write the number of printed characters by this address. This method has some limitations, but it is still very interesting.

Conclusions on the second attack

We may say that an attack of the second type is hardly possible nowadays. As you see, support of the "%n" specifier is off in contemporary libraries by default. But you may create a self-made mechanism subject to this kind of vulnerabilities. Be careful when external data input into your program manage what and where is written into memory.

Particularly in our case, we may avoid the problem by writing the code in this way:

printf("%s", name);

General conclusions

We have considered only two simple examples of vulnerabilities here. Surely, there are much more of them. We don't make an attempt to describe or at least enumerate them in this article; we wanted to show you that even such a simple construct like "printf(name)" can be dangerous.

There is an important conclusion to draw from all this: if you are not a security expert, you'd better follow all the recommendations to be found. Their point might be too subtle for you to understand the whole range of dangers on yourself. You must have read that the printf() function is dangerous. But I'm sure that many of you reading this article have learned only now how deep the rabbit hole is.

If you create an application that is potentially an attack object, be very careful. What is quite safe code from your viewpoint might contain a vulnerability. If you don't see a catch in your code, it doesn't mean there isn't any.

Follow all the compiler's recommendations on using updated versions of string functions. We mean using sprintf_s instead of sprintf and so on.

It's even better if you refuse low-level string handling. These functions are a heritage of the C language. Now we have std::string and we have safe methods of string formatting such as boost::format or std::stringstream.

P.S. Some of you, having read the conclusions, may say: "well, it's as clear as day". But be honest to yourself. Did you know and remember that printf() can perform writing into memory before you read this article? Well, and this is a great vulnerability. At least, it used to. Now there are others, as much insidious.

Cancel Save
0 Likes 37 Comments

Comments

Adam_42

It might be worth mentioning how this is relevant to games. For example a single player PC game that misuses printf() is probably not going to be a significant problem. You could easily fire up a compiler and write another program that does the same thing as any exploit, because games generally don't run with elevated permissions.

However in a multiplayer game with a string that's come via the network it's a serious problem.

You might also want to get someone to check for grammar issues. There are a few obvious errors like "are outlaw." right near the start.

August 04, 2013 02:06 AM
jacklive6113

Your Blog is awesome. It's a really helpful article that is helping me to know about blog writing. thank you. Bathurst 1000 Live Streaming

October 12, 2020 08:45 AM
furyvswilder

That is a good tip particularly to those new to the blogosphere.

Simple but very precise info… Thanks for sharing this one.

One must read post!

Watch Garcia vs Spence Live online

November 02, 2020 05:03 AM
jacklive6113

That genuinely is a pretty very invaluable name for me personally, since I'm in search of genuine estate organizers within just write informative articles for me writing products. You can visit my website here. Spence vs Garcia Fight Live Stream

November 02, 2020 05:07 AM
markjonson12

The Errol Spence Jr. vs Danny Garcia fight inside The AT&T Stadium, Arlington, Texas, USA is the hottest ticket on the Premier Boxing Champions schedule. Garcia, the two-time welterweight world champion titleholder, is ready to fight Spence Jr. for yet another title.

https://errolspencejrfight.com/

November 02, 2020 05:23 AM
furyvswilder

Link exchange is nothing else except it is simply placing the

other person's website link on your page at proper

place and other person will also do similar for you.

NFR Live stream

November 09, 2020 06:50 AM
furyvswilder

Link exchange is nothing else except it is simply placing the

other person's website link on your page at proper

place and other person will also do similar for you.

National Finals Rodeo live stream

November 10, 2020 04:27 AM
jacklive6113

Great post! We are very strong on the content front but could use some help with video. Any tips, hacks, etc for getting started with video production? See My Blog Monster Energy AMA Supercross Live Stream

November 10, 2020 04:43 AM
furyvswilder

Thanks for your page! It helped me alot! I pray for you to be happy and successful in your life.

I like your all post. You have done really good work. Thank you for the information you provide, it helped me a lot. I hope to have many more entries or so from you.

NFR 2020 Live Stream

November 10, 2020 05:04 AM
furyvswilder

I blog often and I seriously appreciate your information.

This great article has truly peaked my interest. I'm going to

take a note of your website and keep checking for

new details about once a week. I subscribed to your Feed as well.

National Finals Rodeo live

November 10, 2020 05:43 AM
furyvswilder

Thanks for another informative website. Where else may I get that kind of information written in such a perfect approach? I have a challenge that I am simply now operating on, and I’ve been at the look out for such information.

Wrangler National Finals Rodeo Live stream

November 10, 2020 06:50 AM
furyvswilder

Aw, this was an extremely nice post. Taking the time and actual effort to create a

great article… but what can I say… I hesitate a lot and never seem to get nearly anything done.

NFR Live Stream 2020

November 10, 2020 07:41 AM
furyvswilder

I blog often and I seriously appreciate your information.

This great article has truly peaked my interest. I'm going to

take a note of your website and keep checking for

new details about once a week. I subscribed to your Feed as well.

Wrangler NFR live stream

November 14, 2020 06:56 AM
furyvswilder

Hello there, just became aware of your blog through Google, and found that it’s truly informative. I am gonna watch out for brussels. I’ll appreciate if you continue this in future. Numerous people will be benefited from your writing. Cheers!

National Finals Rodeo live

November 14, 2020 09:13 AM
furyvswilder

Hello everyone, it’s my first pay a visit at this

site, and post is truly fruitful designed for me,

keep up posting these types of articles or reviews.

NFR Live Stream

November 26, 2020 04:06 AM
furyvswilder

I don’t even understand how I finished up right here, but I

believed this put up was good. I don’t recognise who you are however certainly you are going to a well-known blogger when you are

not already. Cheers!

NFR Results Live

November 29, 2020 05:57 AM
furyvswilder

Hiya, I’m really glad I’ve found this info. Today bloggers publish only about gossip and web stuff and this is actually frustrating. A good site with interesting content, this is what I need. Thanks for making this web-site, and I’ll be visiting again. Do you do newsletters by email?

National Finals Rodeo live

November 30, 2020 07:59 AM
furyvswilder

Hello there, just became aware of your blog through Google, and found that it’s truly informative. I am gonna watch out for brussels. I’ll appreciate if you continue this in future. Numerous people will be benefited from your writing. Cheers!

Wrangler NFR Live stream

December 01, 2020 08:19 AM
laxmunj

Thought 2020 was crazy? Just wait until 2021. Boxer Floyd Mayweather vs Logan Paul announced Sunday that they will fight each other in an exhibition match set for Feb. 20, 2021. The event will air live on pay-per-view and more https://mayweathervspaul.com/

December 19, 2020 09:53 PM
jacklive6113

Great post! We are very strong on the content front but could use some help with video. Any tips, hacks, etc for getting started with video production? See My Blog how to watch 2020 supercross

December 28, 2020 04:24 AM
oxfordltds

YouTuber Logan Paul has struck a deal to fight former boxing megastar Floyd Mayweather Jr. in a “special exhibition” match on February 20th. The bout will be start..Watch Floyd Mayweather vs Logan Paul Live Stream Free, You Can Get Mayweather vs Paul Live Stream: Date, Start Time,Tv Channel, and how to watch online anywhere,

January 11, 2021 05:57 PM
touhidurrah

WWE WrestleMania 37 will air on April. The WWE WrestleMania 37 Live Stream will be in Raymond James Stadium, Tampa, Florida, United States. WWE wants to ensure that the above press release is an April Fool’s Day joke and is not meant to be taken seriously. <a href="https://wwewrestlemania37.live">WWE WrestleMania 37 Live</a><br>

https://wwewrestlemania37.live

March 22, 2021 03:03 PM
touhidurrah

WWE WrestleMania 37 will air on April. The WWE WrestleMania 37 Live Stream will be in Raymond James Stadium, Tampa, Florida, United States. WWE wants to ensure that the above press release is an April Fool’s Day joke and is not meant to be taken seriously. WWE WrestleMania 37 Live

https://wwewrestlemania37.live

March 22, 2021 03:04 PM
touhidurrah

UFC 261 Live Stream Reddit Full Fight HD TV Online Free. Get ready for yet another action parked the Big Match going to be UFC 261. How can Watch UFC 261 Live Stream Without Cable.

https://proinsiderdaily.com/ufc-live-stream/

April 03, 2021 04:17 PM
touhidurrah

Manchester United vs Brighton Live Stream Reddit Full Match HD TV Online Free. Get ready for yet another action parked the Big Match going to be Manchester United vs Brighton. How can Watch Manchester United vs Brighton Live Stream Without Cable.

https://proinsiderdaily.com/manchester-united-live-stream/

Brighton vs Man Utd Live Stream Reddit Full Match HD TV Online Free. Get ready for yet another action parked the Big Match going to be Brighton vs Man Utd. How can Watch Brighton vs Man Utd Live Stream Without Cable.

https://proinsiderdaily.com/brighton-live-stream/

Aston Villa vs Fulham Live Stream Reddit Full Match HD TV Online Free. Get ready for yet another action parked the Big Match going to be Aston Villa vs Fulham. How can Watch Aston Villa vs Fulham Live Stream Without Cable.

https://proinsiderdaily.com/aston-villa-live-stream/

April 04, 2021 11:01 AM
touhidurrah

How can Watch Chelsea vs Real Madrid Live Stream Without Cable. We Have all the information you need is here, it won’t surprise you to read that Soccer is getting started. Get ready for yet another action parked the Big Match going to be Chelsea vs Real Madrid. <a href="https://proinsiderdaily.com/chelsea-vs-real-madrid-live-stream/">Chelsea vs Real Madrid Live Stream</a><br>

https://proinsiderdaily.com/chelsea-vs-real-madrid-live-stream/

How to Watch Real Madrid vs Chelsea Live Stream Online Free on Reddit Live TV, CBS Channel, Fubo TV, Hulu With Live TV, CBS All-Access, DAZN, Android, iOS, Amazon Fire TV Stick and other devices. <a href="https://topsportsextra.com/real-madrid-vs-chelsea-live/">Real Madrid vs Chelsea Live</a><br>

https://topsportsextra.com/real-madrid-vs-chelsea-live/

May 05, 2021 08:44 AM
armen43333ras

Despite the controversy, Japan's Olympic Minister has said the Games would be held in 2021 “at any cost.” Olympic 2021 torch relay has already begun and the athletes are getting ready. McBean said the IOC and the Tokyo organizing committee “are doing everything they can to alleviate fears.” All you need to know about watching an Olympics live stream in 2021 - including Tokyo 2020 Olympic Games date https://tokyoolympic2021s.com/

June 15, 2021 09:44 PM
randyord

Fury vs Wilder will complete their trilogy at the T-Mobile Arena in Las Vegas on 24th July 2021, with an enormous fight on offer for the Englishman with rival Anthony Joshua if he prevails.

This would arguably be one among the most important fights within the history of boxing. But the Gypsy King will got to get the work done call at Sin City.

For Wilder, questions remain regarding his mental state following the defeat within the second bout and was uncharacteristically quiet during the pair's first news conference together in June 2021.

Having blamed almost everything for the loss but himself, even sacking his training team, time will tell whether Wilder will inherit the fight during a better, or worse physical and psychological state , than before.

July 01, 2021 06:59 PM
kukukala121

As revealed earlier this month, the July 24th Tyson Fury vs Wilder Fight pay-per-view will feature a additional trio of heavyweight tussles, including a clash of unbeaten prospects, long-brewing rematch, and the latest from one of the most promising up-and-comers in the division.

July 02, 2021 05:48 PM
alaxe

Youtuber turned professional boxer Jake Paul will next opponent Woodley. This would be Woodley debut as a professional boxer. Jake Paul vs Woodley fight date is announced, it is scheduled to take place on August 28, 2021. The American has lost his last four fights in the UFC. On the other hand, Paul has experience in 3 professional boxing fights, including a recent bout against the former professional mixed martial artist Ben Askren.

July 07, 2021 06:13 AM
aflgrandfinal

The league said the afl grand final would begin at 2:30pm (AEST) on September 25 after the 2020 season decider, played at the Gabba in Brisbane, was contested in the evening.

July 20, 2021 12:04 PM
jamesnike

The joshua vs usyk undercard has now been announced ahead of their fight on September 25 at Tottenham Hotspur Stadium.

August 29, 2021 06:49 AM
AFL Grand Final 2021

The AFL Grand Final 2021 will be played at Optus Stadium in Perth on Saturday, September 25.

August 31, 2021 05:46 PM
thecflgreycup

The Grey Cup 2021 is going to happen to conclude the Canadian Football League – CFL championship for the 2021 season. The CFL Grey Cup game will be available on Canada TV, TSN.

September 01, 2021 02:21 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!

We decided to write several small posts on how C/C++ programmers play with fire without knowing it. This time I want to speak on the 'printf' function.

Advertisement
Advertisement