"On Friday, Carl Schou, a security researcher in Denmark, reported that his iPhone lost its Wi-Fi capability after attempting to connect to a Wi-Fi network named "%p%s%s%s%s%n"."
I can just imagine people rapidly adding wifi names to public access points called "%crash%your%iphone"
techies can read the gory details here
formatting link
Didn't find your answer? Ask the community — no account required.
Information here may be outdated?
M
Martin Brown
ITYM %cra%shy%o%ur%iphon%e
It seems it takes three %s's in a row to wipe it out. And they have to be valid printf escape codes expecting an argument to cause trouble.
I wonder if there are any other printf escape sequence misbehaviour vulnerabilities as well? \n\t\000 for instance.
It is rather funny. How daft can you get?
B
Brian Gaff (Sofa
Surely that should not break anything but on the other hand i do notice that sometimes Microsludge word saves filesa as my%file.docx, and this confused the heck out of search. Brian
M
Martin Brown
% has a special meaning in the formatting of C output.
It breaks it disastrously if some muppet has coded
printf(SSID_string)
which works OK in most cases as opposed to the correct and safe
printf("%s", SSID_string)
In the latter case the SSID is printed verbatim, but in the former any special characters found there are interpreted and acted upon. Bad idea!
The first example works just fine until you include special formatting escape characters like "%" in it and then it tells printf to expect a certain number parameters on the stack depending on how many "%" characters it sees. Where it lands afterwards when it exits is pot luck!
It is basically a simple form of injection attack where the right string carefully crafted can break some (very) badly implemented code.
It shouldn't be too hard to fix but it doesn't say much about their static code analysis tools that such a defect escaped into the wild.
M
Max Demian
It's because of the C function printf (print with formatting). If the (string) parameter contains %n it expects there to be another parameter representing a number which it prints in place of the %n. If %s the extra parameter should be a string. If no extra parameter(s) are provided it'll suck some garbage off the stack and try to "print" that.
(I think that's right; it's some time since I programmed in C.)
T
The Natural Philosopher
%d is a decimal number %x is hex %f is floating point and %s is a string
No %n...
J
jkn
Max got the description mostly right, but not exactly. There *is* an 'n' conversion letter in the printf() format specifier, and it behaves as he mentions, but it is not a '%n'.
The actual full details of the printf() function are worth careful study by those who seek to use them. It has many details that are seldom used but can be useful.
See eg: Harbison and Steele: "C: A reference Manual", 5th Edition
Pendantically-yours J^n
C
Chris Bacon
e.g.: int main(int b,char**i){long long n=B,a=I^n,r=(a/b&a)>>4,y=atoi(*++i),_=(((a^n/b)*(y>>T)|y>>S)&r)|(a^r);printf("%.8s\n",(char*)&_);}
N
NY
Don't you just love C. It's definitely a write-only language: it allows constructions which are very terse but understandable only to the person wrote wrote them, and which are impenetrable to the poor sod who has to maintain the code several years later when the writer has moved on to a new job.
What does this code do? Even after #including <stdlib.h> and <stdio.h>, it complains about variables B, I, T and S being undefined.
T
The Natural Philosopher
int main(int b,char**i) { long long /* that is nonsense to begun with*/ ) >> n=B,a=I^n,r=(a/b&a)>>4,y=atoi(*++i),_=(((a^n/b)*(y>>T)|y>>S)&r)|(a^r);printf("%.8s\n",(char*)&_); }
In fact its *all* nonsense.
It isn't C. Its troll speak.
THIS is Real C, designed so that it CAN be maintained (names passwords and headers excluded).
int main(int argc, char **argv) { // we will get handed a mysql select statement: this need querying and the result parsing into CSV format. MYSQL mysql; MYSQL_RES *result; MYSQL_ROW row; int rows; // number of db records int i,fields; if(argc<2) { printf("s*it\n"); exit(0); } // open da database if(!mysql_init(&mysql)) // initialise data structure { return (1); } if(!mysql_real_connect(&mysql,"127.0.0.1",USERNAME,PASSWORD,DATABASE,0,"",0)) // connect to database { printf("Connect failed -%s\n",mysql_error(&mysql)); mysql_close(&mysql); return 2; } mysql_query(&mysql,argv[1]);// go splat result=mysql_store_result(&mysql); fields=mysql_num_fields(result); // now to iterate through each row while(row=mysql_fetch_row(result)) { for(i=0;i<fields;i++) { if(i!=(fields-1)) printf("%s, ",row[i]); // simply push to stdout: PHP will pass it thru to the download else printf("%s\r\n",row[i]); } } mysql_free_result(result); mysql_close(&mysql); }
F
Fredxx
There is.
formatting link
at Memory write.
Where: %n number of bytes written so far by way of reference
For example: int i; printf ("1234%n", &i);
will write 4 into the variable 'i'.
It's a rare feature, and seemingly very dangerous in this situation.
F
Fredxx
No one in their right mind would write such garbage. Most code would be peer reviewed and the example should never pass that hurdle. Passing Lint would normally be a requirement where a fail would need a justification.
I would say C as a language is easily understood. There are so few commands to remember and functions above like atoi() and printf() are optional.
Comments and meaningful variable names help.
It's useful to remember that C is recommended in safety critical systems where the code conforms to certain standards like MISRA.