Re: gets and scanf
- From: "Douglas A. Gwyn" <DAGwyn@xxxxxxxx>
- Date: 25 Jul 2006 10:53:59 GMT
Eric wrote:
Douglas A. Gwyn wrote:
gets can be safely used when you have sufficient controlJust out of curiosity, can you post a short routine that actually
over the input. The lack of safety occurs when code finds
its way into applications where the inputs are crafted by
others; there are well-known ways under those conditions
to exploit gets' lack of a limit on the amount of data it
transfers, for nefarious purposes such as injecting and
executing code created specially by the person providing
the input. There have in fact been several such attacks.
does this?
The following might or might not actually work, dependning on
details, but it shows the essential idea:
/* change-a-flag-attack victim's code: */
void Dialogue(void) {
char cmd[80];
bool priv = Privilege_Check();
for (prompt("Enter command: "); gets(cmd);
prompt("Enter command: "))
Process(cmd, priv);
}
A malicious user could enter 81 nonnewline, nonnull characters
followed by a newline; that would overwrite the "priv" flag,
process the command (perhaps rejecting it as misspelled), then
continue processing more commands, all of which will be treated
as having advanced privilege (adminstrator, super-user, etc.).
The more interesting exploitation inserts some code, which
typically would have to be generated by compilation (but could
be hand-crafted) at the attacker's end. Again, this example
might not quite work, but it conveys the idea:
/* insert-code-attack victim's code: */
void Dialogue(void) { // ... same as above ...
// "priv" is irrelevant for this attack
/* attacker's program: */
void my_func(void) {
// ... code to be run in context of victim
// upon return from Dialogue function ...
// crafted to not generate any 0x0a code bytes;
// we'll assume it is position-independent, or
// else a preliminary "relocation" adjustment
// must be applied
}
void marker(void) { } // to determine length of my_func
void insert_code(const unsigned char *funcp,
size_t funcsz) {
unsigned long at = 0x12345678; // stack frame loc.
// (victim virtual addr.)
size_t i;
for (i = 0; i < 82; ++i) // cmd, priv
send_byte('x');
for (i = 0; i < sizeof at; ++i) // return address
send_byte(((unsigned char *)&at)[i]);
for (i = 0; i < 12; ++i) // saved regs
send_byte(1);
for (i = 0; i < funcsz; ++i) // unused stack
send_byte(funcp[i]);
send_byte('\n');
}
int main() {
connect_to(victim_address);
await_prompt("Enter command: ");
// relocate_code(); // if position-dependent
insert_code((unsigned char *)my_func,
(char *)marker - (char *)my_func);
await_prompt("Enter command: ");
send_command("Quit");
return 0;
}
The malicious user program overwrites not only the input buffer
(and "priv", but ignore that for this attack), but also part of
the "stack frame" that contains the "caller's" return address;
when Dialogue returns (after the "Quit" command is seen), instead
of returning to the original caller it will instead jump to the
newly inserted code (which was created on the stack, in this
example). Details are highly dependent on the specific architecture,
and the correct stack frame location has to be determined, but these
are minor obstacles that a determined hacker can readily overcome.
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.
- Prev by Date: Re: memory allocation of an n dimensional array
- Next by Date: Re: [comp.lang.c.moderated]Pointer to a 2-D array
- Previous by thread: tolower macro
- Next by thread: Re: gets and scanf
- Index(es):
Relevant Pages
|