By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,070 Members | 1,238 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,070 IT Pros & Developers. It's quick & easy.

simple c-code

P: n/a
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()

{ char buffer[1024];

GetPassword(buffer);

....
}

/*****/

int GetPassword (char *buffer,char *username)

{
....
}
Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it? Could this be misused`?

The asterix has something to do with pointers. *buffer means that it
is working on the original buffer-variable, or what?

I hope anyone can help me get some ideas out of this code.
Nov 14 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Tommy <to***********@hotmail.com> scribbled the following:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of. Here is the code: main ()

{ char buffer[1024]; GetPassword(buffer); ...
} /*****/ int GetPassword (char *buffer,char *username) {
...
}
Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it? Could this be misused`?
This is indeed incorrect design, but not necessarily fatal, as long
as GetPassword never uses the argument username for anything. If it
does, though, then it causes undefined behaviour, which can have
fatal results, for example the whole program crashing.
The asterix has something to do with pointers. *buffer means that it
is working on the original buffer-variable, or what?
Asterisk! "Asterix" is a comic book figure, a Gaulish warrior with a
yellow moustache, who lived in 50 B.C. and drank magic potion.
Yes, the unary asterisk operation means a pointer type. However, it
does not mean here that it is operating on the original buffer
variable. Such a thing is called "pass by reference" and is impossible
in C. What it does is operate on the *contents* of the original buffer
variable. If you use the [] operator on the buffer variable, you get
the same memory locations both in main and in GetPassword.
I hope anyone can help me get some ideas out of this code.


--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"Shh! The maestro is decomposing!"
- Gary Larson
Nov 14 '05 #2

P: n/a
Tommy wrote:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if ^ logically? used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()
Missing return value.
{ char buffer[1024];

GetPassword(buffer);
Missing function declaration. Fixed size buffer without passing bounds.
int GetPassword (char *buffer,char *username)
Real function signature does not match usage above.
Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it?
The function wants two arguments but it is called with only one.
Could this be misused`?
Anything could happen, you have left the grounds of well-formed C.
The asterix has something to do with pointers. *buffer means that it
is working on the original buffer-variable, or what?


Sorry, but you seriously need to get a book on C, it would take too long to
explain. What you could do to understand this code is to compile it and
look at the generated assembly, in case you can read that.

Uli

Nov 14 '05 #3

P: n/a
"Tommy" writes:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()

{ char buffer[1024];

GetPassword(buffer);

...
}

/*****/

int GetPassword (char *buffer,char *username)


Are you sure you copied this correctly? This should not even run. Code
that can not run does not present a security problem.
Nov 14 '05 #4

P: n/a
"osmium" <r1********@comcast.net> wrote

Are you sure you copied this correctly? This should not even run. Code
that can not run does not present a security problem.

C compilers tend to be rather lax on prototyping, because of backwards
compatibility. It is possible to call a function returning an integer with
the wrong number of arguments and no prototype in scope.
Nov 14 '05 #5

P: n/a
Tommy wrote:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()

{ char buffer[1024];

GetPassword(buffer);

...
}

/*****/

int GetPassword (char *buffer,char *username)

{
...
}

Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it? Could this be misused`?


That is a syntactic fault, not a logical fault. Were the syntax errors
fixed, there would probably still be a logical fault, a buffer overflow
vulnerability. Whether or not this would actually be present depends on
the details of GetPassword. (Unless you consider passwords limited to
1023 characters to be a fault. I don't often push that limit, myself.)

-josh

Nov 14 '05 #6

P: n/a
In article <7c**************************@posting.google.com >,
to***********@hotmail.com (Tommy) wrote:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()

{ char buffer[1024];

GetPassword(buffer);

...
}

/*****/

int GetPassword (char *buffer,char *username)

{
...
}
Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it? Could this be misused`?

The asterix has something to do with pointers. *buffer means that it
is working on the original buffer-variable, or what?

I hope anyone can help me get some ideas out of this code.


1. If you are lucky, then the program will crash all the time because
when "GetPassword" tries to user "username", it will just get garbage.

2. If you are very lucky then the compiler will catch this error.

3. If you are unlucky, people will use the code, and then comes Joe E.
Hacker and takes control of their computers.

4. That is why a programmer who still hasn't heard of a "buffer overflow
vulnerability" shouldn't be let anywhere near a computer.
Nov 14 '05 #7

P: n/a
On 7 Nov 2004 18:59:34 GMT, Joona I Palaste <pa*****@cc.helsinki.fi>
wrote in comp.lang.c:
Tommy <to***********@hotmail.com> scribbled the following:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()

{ char buffer[1024];

GetPassword(buffer);

...
}

/*****/

int GetPassword (char *buffer,char *username)

{
...
}


Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it? Could this be misused`?


This is indeed incorrect design, but not necessarily fatal, as long
as GetPassword never uses the argument username for anything. If it
does, though, then it causes undefined behaviour, which can have
fatal results, for example the whole program crashing.


What you say in the paragraph above is totally and completely wrong.
Calling a function in the absence of a prototype results in undefined
behavior if the number and types of all arguments, after the default
promotions, does not match the definition of the function.

There is absolutely no dispensation for unused arguments. None
whatsoever. If the function actually works, whether or not it
accesses the second argument, is just a matter of luck (good or bad).

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #8

P: n/a

"Christian Bau" <ch***********@cbau.freeserve.co.uk> wrote in message
news:ch*********************************@slb-newsm1.svr.pol.co.uk...
In article <7c**************************@posting.google.com >,
to***********@hotmail.com (Tommy) wrote:
Hi all. I am studying computer security, and I got this short and
simple (?) c-code. Something is logical wrong in this code, and if
used in the wrong hands of someone, it could be taken advantage of.

Here is the code:

main ()

{ char buffer[1024];

GetPassword(buffer);

...
}

/*****/

int GetPassword (char *buffer,char *username)

{
...
}
Now, I am not a programmer, but is it correct that the logical fault
in this program is that the function takes to arguments, and only 1
argument is sent to it? Could this be misused`?

The asterix has something to do with pointers. *buffer means that it
is working on the original buffer-variable, or what?

I hope anyone can help me get some ideas out of this code.


1. If you are lucky, then the program will crash all the time because
when "GetPassword" tries to user "username", it will just get garbage.

2. If you are very lucky then the compiler will catch this error.

3. If you are unlucky, people will use the code, and then comes Joe E.
Hacker and takes control of their computers.

4. That is why a programmer who still hasn't heard of a "buffer overflow
vulnerability" shouldn't be let anywhere near a computer.


This is off-topic, but theoretically, how would a hacker be able to take
control of a system by exploiting buffer overflow? On a typical Windows
system, the executable would be running with its own stack space. The worst
I can see happening is the program crashing due to an invalid memory
read/write. I doubt OS code/data would be anywhere in or near the program's
address space.
Nov 14 '05 #9

P: n/a
Jack Klein <ja*******@spamcop.net> scribbled the following:
On 7 Nov 2004 18:59:34 GMT, Joona I Palaste <pa*****@cc.helsinki.fi>
wrote in comp.lang.c:
This is indeed incorrect design, but not necessarily fatal, as long
as GetPassword never uses the argument username for anything. If it
does, though, then it causes undefined behaviour, which can have
fatal results, for example the whole program crashing.
What you say in the paragraph above is totally and completely wrong.
Calling a function in the absence of a prototype results in undefined
behavior if the number and types of all arguments, after the default
promotions, does not match the definition of the function. There is absolutely no dispensation for unused arguments. None
whatsoever. If the function actually works, whether or not it
accesses the second argument, is just a matter of luck (good or bad).


OK, thanks for correcting me.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"You could take his life and..."
- Mirja Tolsa
Nov 14 '05 #10

P: n/a

"Method Man" <a@b.c> wrote in message
news:m%*******************@read2.cgocable.net...
This is off-topic, but theoretically, how would a hacker be able to take
control of a system by exploiting buffer overflow?
You can create doctored arguments such that the buffer overwrites the stack.
If you doctor carefully (which is not enormously difficult) you can them
modify the functions return addres (which resides on stack) and effectively
jump to every bit of code you want.

Doctering the input still further and including some "black hat" code into
the call, you can jump to the code that (for instance) opens a back-door by
merely listening on a socket start a virus, which IIRC is the way
SQL-Slammer did it using a buffer overrun in the handling of UDP packets..
On a typical Windows
system, the executable would be running with its own stack space. The worst I can see happening is the program crashing due to an invalid memory
read/write.
That's good luck. Bad luck is when it doesn't as described above.
I doubt OS code/data would be anywhere in or near the program's
address space.


My knowledge of Windows internals is insufficient to say Ay or Nay here.
However, the proliferation of Windows viruses suggests this may actually not
be much of a problem.
Nov 14 '05 #11

P: n/a
"Method Man" <a@b.c> wrote in message news:<m%*******************@read2.cgocable.net>...
This is off-topic, but theoretically, how would a hacker be able to take
control of a system by exploiting buffer overflow? On a typical Windows
system, the executable would be running with its own stack space. The worst
I can see happening is the program crashing due to an invalid memory
read/write. I doubt OS code/data would be anywhere in or near the program's
address space.


The arguments to functions tend to be stored on the stack adjacent to
the return address of the function.

If the buffer can be overflown the memory adjacent to the buffer
on the stack, ie the return address, can be overwritten with arbitary
contents.

This allows the attacker to control program execution by directing it
at some code of his own. "shellcode" is the name usually given to
this code as traditionally it runs a shell, but it could do more.

(Essentially the return address is overwritten with an arbitary value
and the normal function termination finishs with a 'ret' instruction
which causes an effective jump to the address stored).

Google for more details. The classic intro paper is called
"Smashing The Stack For Fun And Profit" and can be easily found. It's
Unix centric but the principle is the same.

The main source of your belief the program will crash is that you seem
to believe that the OS code/data is important. It isn't. (Now a
non-executable stack, or stackguard protection would make it more challenging
but still not insurmountable).

Steve
---
http://shellcode.org/
Nov 14 '05 #12

P: n/a
In article <m%*******************@read2.cgocable.net>,
Method Man <a@b.c> wrote:
This is off-topic, but theoretically, how would a hacker be able to take
control of a system by exploiting buffer overflow?


On a typical general-purpose operating system, modifying the stack
will only directly affect the process whose stack it is. Whether that
lets them do more depends on what privileges the process has.

-- Richard
Nov 14 '05 #13

P: n/a
> On a typical general-purpose operating system, modifying the stack
will only directly affect the process whose stack it is. Whether that
lets them do more depends on what privileges the process has.


And only provided that the system in question allows execution of any
code that's on the "local stack", which is, in my opinion, a *major
flaw* of the system in itself. The ability of separating data and code
spaces has existed for decades in a lot of different processors.

Too bad very few systems have ever used this feature (except in some
embedded systems, mostly). This is the one feature that would have
saved most of security problems.

I'll list here just a few of the very popular processors/processor lines
which would allow such data/code separation in a sensible manner:

- Most of harvard-like architectures (so, a lot of RISC processors);
- The 68k processors, back to the 68000 (albeit a bit crude on this);
- The x86 series, back to the 286 (with the ability of marking memory
segments as executable or not);
- A whole lot of other processors.

But we're getting a bit off-topic. Sorry.
Nov 14 '05 #14

P: n/a
In article <41***********************@news.club-internet.fr>,
Guillaume <"grsNOSPAM at NOTTHATmail dot com"> wrote:
- The x86 series, back to the 286 (with the ability of marking memory
segments as executable or not);


I believe that the inability to prevent execution of pages, rather
than segments, has made this impractical on x86s for many operating
systems up to now. No doubt someone else remembers the detail better
than I do.

-- Richard
Nov 14 '05 #15

P: n/a
>>- The x86 series, back to the 286 (with the ability of marking memory
segments as executable or not);

I believe that the inability to prevent execution of pages, rather
than segments, has made this impractical on x86s for many operating
systems up to now. No doubt someone else remembers the detail better
than I do.


Back to my old x86 manuals...

Nope: descriptors could allocate different segments with each its own
priviledge level, access rights (read, write, executable...).

The issue here is that most "multitask, protected" OS's have implemented
protection in a crude manner: each task would get its own segment (which
is good, but not enough) and 'see' its whole address space has a flat
memory model. "Tasks" can't meddle with each other, but they can still
do bad things on their own. Usually, the only area that use better
protection is the 'kernel' of the system. This is true in Linux, as well
as Windows and most other desktop/server OS's...

As I said, some embedded OS's actually make a very nice use of the code
protection feature. As you noticed, though, most OS's on the market just
don't, mainly for complexity reasons.

What infuriates me though, is that some companies are now going to make
huge amounts of money for promoting security features in new systems
that could have been implemented decades ago, surfing on the security
wave. And again, they're going to make people pay for what they failed
to do earlier.

Ok, end of rant. Just to say that here, as well as in a lot of other
areas, such as History, memory's not the most commonly shared thing.

And for those who'd complain this doesn't belong in c.l.c, I beg to
differ. A good understanding of the underlying reality in programming
is an invaluable skill.
Nov 14 '05 #16

P: n/a
In article <41***********************@news.club-internet.fr>,
Guillaume <"grsNOSPAM at NOTTHATmail dot com"> wrote:
I believe that the inability to prevent execution of pages, rather
than segments, has made this impractical on x86s for many operating
systems up to now. No doubt someone else remembers the detail better
than I do.
Nope: descriptors could allocate different segments with each its own
priviledge level, access rights (read, write, executable...).
I think that's what I said: you can control execution of segments, not
pages.
The issue here is that most "multitask, protected" OS's have implemented
protection in a crude manner: each task would get its own segment (which
is good, but not enough) and 'see' its whole address space has a flat
memory model.


Having used a few machines which didn't give the programmer a flat
memory model, I can see why they're not popular. I wouldn't use
such a machine now (as a general purpose computer), and I don't imagine
we'll be seeing many.

So yes, you *could* control stack execution on the x86, but only by
providing a model that most people don't want to program to. The fact
that you can't control it with the usual model is just a mistake that
Intel made years ago and apparently hasn't been able to change until now.

-- Richard
Nov 14 '05 #17

P: n/a

"Steve Kemp" <sp**@steve.org.uk> wrote in message
news:aa**************************@posting.google.c om...
"Method Man" <a@b.c> wrote in message news:<m%*******************@read2.cgocable.net>...
This is off-topic, but theoretically, how would a hacker be able to take
control of a system by exploiting buffer overflow? On a typical Windows
system, the executable would be running with its own stack space. The worst I can see happening is the program crashing due to an invalid memory
read/write. I doubt OS code/data would be anywhere in or near the program's address space.
The arguments to functions tend to be stored on the stack adjacent to
the return address of the function.

If the buffer can be overflown the memory adjacent to the buffer
on the stack, ie the return address, can be overwritten with arbitary
contents.

This allows the attacker to control program execution by directing it
at some code of his own. "shellcode" is the name usually given to
this code as traditionally it runs a shell, but it could do more.

(Essentially the return address is overwritten with an arbitary value
and the normal function termination finishs with a 'ret' instruction
which causes an effective jump to the address stored).

Google for more details. The classic intro paper is called
"Smashing The Stack For Fun And Profit" and can be easily found. It's
Unix centric but the principle is the same.

The main source of your belief the program will crash is that you seem
to believe that the OS code/data is important. It isn't. (Now a
non-executable stack, or stackguard protection would make it more

challenging but still not insurmountable).

Steve


Thanks, I'll do some research. I'd like to smash the stack "for fun" so I
can learn a thing or two. ;-)

I'd like to clarify that this is OT for the thread but not for the
newsgroup. I think learning about the stack and how to write secure C code
is critical for real-world applications and very much on topic.
Nov 14 '05 #18

P: n/a

"Guillaume" <"grsNOSPAM at NOTTHATmail dot com"> wrote in message
news:41***********************@news.club-internet.fr...

<snip>
And for those who'd complain this doesn't belong in c.l.c, I beg to
differ. A good understanding of the underlying reality in programming
is an invaluable skill.


Bravo!
Nov 14 '05 #19

P: n/a
Method Man wrote:
I'd like to clarify that this is OT for the thread but not for the
newsgroup. I think learning about the stack and how to
write secure C code
is critical for real-world applications and very much on topic.


"the stack" isn't part of C.

--
pete
Nov 14 '05 #20

P: n/a
Method Man wrote:
I'd like to clarify that this is OT for the thread but not for the
newsgroup. I think learning about the stack and how to write secure C code
is critical for real-world applications and very much on topic.


Problem is that this will be different between platforms. Sometimes
subtly, sometimes wildly different.

The lessons learned in one system might be completely irrelevant
for others.

--
Thomas.
Nov 14 '05 #21

P: n/a

In article <H4*******************@read2.cgocable.net>, "Method Man" <a@b.c> writes:

I'd like to clarify that this is OT for the thread but not for the
newsgroup. I think learning about the stack and how to write secure C code
is critical for real-world applications and very much on topic.


Discussion of the conditions that produce Undefined Behavior in C is
on-topic for comp.lang.c.

Discussion of the effects of Undefined Behavior, including disruption
of the "stack", which is neither defined nor mandated by the standard,
is relevant only to particular C implementations, and so is off-topic
for comp.lang.c (other than in illustrative asides).

One good forum for discussing exploiting Undefined Behavior in
typical (or specific) C implementations is the Vuln-Dev mailing list
maintained by SecurityFocus.

--
Michael Wojcik mi************@microfocus.com

An intense imaginative activity accompanied by a psychological and moral
passivity is bound eventually to result in a curbing of the growth to
maturity and in consequent artistic repetitiveness and stultification.
-- D. S. Savage
Nov 14 '05 #22

P: n/a

In article <41***********************@news.club-internet.fr>, Guillaume <"grsNOSPAM at NOTTHATmail dot com"> writes:
On a typical general-purpose operating system, modifying the stack
will only directly affect the process whose stack it is. Whether that
lets them do more depends on what privileges the process has.
And only provided that the system in question allows execution of any
code that's on the "local stack",


False. Stack-smashing attacks which exploit implementations with
non-executable stacks are well-documented. See so-called "return
into libc" exploits, for example.
I'll list here just a few of the very popular processors/processor lines
which would allow such data/code separation in a sensible manner:

- Most of harvard-like architectures (so, a lot of RISC processors);
But not the POWER family, which is the most popular RISC processor
for general-purpose computing (thanks to Apple). The POWER MMU lacks
separate read and execute page-protection bits.
- The 68k processors, back to the 68000 (albeit a bit crude on this);
- The x86 series, back to the 286 (with the ability of marking memory
segments as executable or not);
But not pages, so this facility is useless for the dominant x86 OSes.

The merits of separate I&D have been debated endlessly in any number
of places. This is not the forum to bring them up again. Try
alt.folklore.computers or comp.arch. They're probably sick of it
too, but at least it's on-topic there.
But we're getting a bit off-topic. Sorry.


Entirely off-topic. The effects of Undefined Behavior are OT for
comp.lang.c. Regardless of the value of "a good understanding of the
underlying reality", not every topic related to programming belongs
here. Further, what you refer to as "underlying reality" is not the
same for all C implementations. Are you prepared to discuss how
every conforming implementation deals with Undefined Behavior caused
by overwriting an automatic variable?

--
Michael Wojcik mi************@microfocus.com

Even though there may be some misguided critics of what we're trying
to do, I think we're on the wrong path. -- Reagan
Nov 14 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.