simple c-code

T

Tommy

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

Joona I Palaste

Tommy said:
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.
 
U

Ulrich Eckhardt

Tommy said:
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
 
O

osmium

Tommy said:
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.
 
J

josh

Tommy said:
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
 
M

Malcolm

osmium said:
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.
 
C

Christian Bau

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

Jack Klein

Tommy said:
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).
 
M

Method Man

Christian Bau said:
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.
 
J

Joona I Palaste

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

dandelion

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

Steve Kemp

Method Man said:
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
 
R

Richard Tobin

Method Man said:
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
 
G

Guillaume

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

Richard Tobin

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

Guillaume

- The x86 series, back to the 286 (with the ability of marking memory
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.
 
R

Richard Tobin

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.
[/QUOTE]
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
 
M

Method Man

Steve Kemp said:
"Method Man" <[email protected]> wrote in message

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

dandelion

"Guillaume" <"grsNOSPAM at NOTTHATmail dot com"> wrote in message

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!
 
P

pete

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,150
Messages
2,570,853
Members
47,394
Latest member
Olekdev

Latest Threads

Top