Paull Skrevet 11. mai 2013 Del Skrevet 11. mai 2013 Tenkte det kunne være moro med en sikkerhetstråd, der man poster og finner sikkerhetsissues i forskjellig kode. Tanken er at man kan få litt hjernetrim, og samtidig kan andre lære av det. Språk valgfritt, men jo mer obskurt, jo mindre respons naturligvis Starter lett med denne gamle C-klassikeren: #include <string.h> void foo (char *bar) { char c[12]; strcpy(c, bar); } int main(int argc, char* argv[]) { foo(argv[1]); } Hva er problematisk her? Lenke til kommentar
etse Skrevet 11. mai 2013 Del Skrevet 11. mai 2013 Stackoverflow om argv[1] er > 12 bytes. I værste fall kan det føre til at man kan putte inn kjørbar kode inn på stacken og samtidig overskrive EIP-pekeren på stacken slik at den kaller koden du ga som input når funksjonen returnerer. Lenke til kommentar
Paull Skrevet 11. mai 2013 Forfatter Del Skrevet 11. mai 2013 Riktig! Fyll gjerne på med eksempler om du har noen Nok en sak fra C-verdenen: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { int x, y, z=0x00000001; char *table = NULL; if(argc<2) _exit(1); x=atoi(argv[1]); if(x>0) { table = (char *)malloc(x * sizeof(char *)); if(table == NULL) _exit(2); } for(y=0; y<x; y++) table[y]=z++; for(y=0; y<x; y++) printf("tab[y]=0x%x\n", table[y]); return 0; } Lenke til kommentar
etse Skrevet 11. mai 2013 Del Skrevet 11. mai 2013 Du mener så bortsett fra at den ene linjen skulle vært: table = (char *)malloc(x * sizeof(char)); ? Sånn første øyekast er at x,y,z, er integere, mens tabellen er en char-table. og siden char ofte er 1 byte, og int 4 bytes så vil du hele tiden overskrive deler av tabellen hver gang du setter inn ting i den. Lenke til kommentar
zotbar1234 Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 Du mener så bortsett fra at den ene linjen skulle vært: table = (char *)malloc(x * sizeof(char)); ? Sånn første øyekast er at x,y,z, er integere, mens tabellen er en char-table. og siden char ofte er 1 byte (...) sizeof(char) er definert til å være 1 byte (alltid). Derfor er det heller ikke nødvendig å skrive sizeof(char) i malloc(). Lenke til kommentar
etse Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 sizeof(char) er definert til å være 1 byte (alltid). Derfor er det heller ikke nødvendig å skrive sizeof(char) i malloc(). men han skrev sizeof(char *), når det skulle være sizeof(char), som gjør at han i de fleste systemer setter av mye mer minne enn han trenger. Lenke til kommentar
MikkelRev Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 Verdens vanskeligste: include($_GET[$file]); Lenke til kommentar
etse Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 Verdens vanskeligste: include($_GET[$file]); Orker ikke svare, men de fleste forstår nok hva som er farlig der. Men siden det kanskje ikke er like obvious for alle, det der er PHP-kode. Lenke til kommentar
slacky Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 (endret) men han skrev sizeof(char *), når det skulle være sizeof(char), som gjør at han i de fleste systemer setter av mye mer minne enn han trenger. Altså, slik jeg ser det (uten C-erfaring), så vil sizeof(char *) være størrelsen på adressen. Du vil da altså allokere 4 eller 8 byte (kommer ann på om det er 32 eller 64 bit OS)? :-) Da ved å gjøre: >>> table = (char *)malloc(x * sizeof(char *)); Så vil han allokere nok plass til en eller to 32bit-integers (4, eller 8 byte), men hvert element kan kun romme 8 bit, så resultatet er at han har allokert 4, eller 8 ganger så mange elementer/chars. Edit: Fjernet litt tekst, da jeg tro jeg PLUTSELIG forsto noe (= Endret 12. mai 2013 av warpie Lenke til kommentar
Paull Skrevet 12. mai 2013 Forfatter Del Skrevet 12. mai 2013 (endret) Dere er inne på noe, har med malloc'en å gjøre. Hint: Hva skjer om man sender inn 1073741824 som argument? Edit: Antar 32-bit kode i dette tilfellet, burde kanskje spesifisert det tidligere.. Endret 12. mai 2013 av Paull Lenke til kommentar
slacky Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 (endret) ... Hva skjer om man sender inn 1073741824 som argument? Summen du viser til er (2^31)/2 (eller 2^30), så summen er 30 bits, men størrelsen på hvert element i table er for liten - hendelse avhengig av hvordan C fungerer, men tenker noe slik: Sett att hvert element er størrelsen av en char (8 bit), så vil vel summen bli redusert til max 255, kan tenke meg at kun de 3 første tallene vises: 107. Er usikker på om at tallet vil forsette inn i neste element, men det er irrelevant. Men, jeg ser ikke hvorfor det er nødvendig å poengtere den mere, det er da ingen som får noen form for hjelp ved å lese dette. Det er klare FEIL i koden, hvorfor i all verden skulle en pakke 32 bit integer i en Char-array? >>> int *table = NULL; >>> ... >>> table = (int *)malloc(x * sizeof(int)); Er vel korrekt, eller noe i den duren. Endret 12. mai 2013 av warpie Lenke til kommentar
Paull Skrevet 12. mai 2013 Forfatter Del Skrevet 12. mai 2013 (endret) Greit nok, å endre fra char* til int* har egentlig ikke noe å si i dette tilfellet. Poenget er i alle fall at multiplikasjonen x * sizeof(..) overflower. Siden både sizeof(char *) og sizeof(int) er 4 for 32-bit kode, så vil 1073741824 * 4 == 0. Dermed blir det malloc(0), som er implementasjonsavhengig og skumle ting skjer når man følger pekeren. Poenget var i alle fall integer overflowen. La oss se på litt Python: def validate_password(actual_pw, typed_pw): if len(actual_pw) <> len(typed_pw): return 0 for i in len(actual_pw): if actual_pw[i] <> typed_pw[i]: return 0 return 1 Endret 12. mai 2013 av Paull Lenke til kommentar
etse Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 (endret) Altså, slik jeg ser det (uten C-erfaring), så vil sizeof(char *) være størrelsen på adressen. Du vil da altså allokere 4 eller 8 byte (kommer ann på om det er 32 eller 64 bit OS)? :-) Da ved å gjøre: >>> table = (char *)malloc(x * sizeof(char *)); Så vil han allokere nok plass til en eller to 32bit-integers (4, eller 8 byte), men hvert element kan kun romme 8 bit, så resultatet er at han har allokert 4, eller 8 ganger så mange elementer/chars. Edit: Fjernet litt tekst, da jeg tro jeg PLUTSELIG forsto noe (= Han prøver å lage et array av chars, hvor man ønsker adressen til det første elementet i arrayet. Siden det er et char-array er det størrelsen på chars * antall_elementer som er interesant, ikke å allokere av størrelsen på pekeren, det hadde i så fall vært et array med pekere (og altså da en dobbelt-peker merket med char **table)videre vil det da si at siden det er merket som et char-array, så vil man ved dinne koden få uønsket oppførsel: int x=10, y=20; table[0] = x; table[1] = y; printf("%d %d\n", table[0], table[1]); Jeg er litt usikker på detaljene på hva som vil skje der, har ikke testet selv akkurat nå - men var den første feilen jeg så som ville skape problemer. Men ser jo nå, etter det ble forklart, at det er helt klart integer-overflowen som er det kritiske problemet her. Men om koden hadde gitt mening, altså man hadde brukt sizeof(char) i stede for sizeof(char *), så hadde ikke problemet eksistert. Men la oss endre koden til noe som gir mening, la oss bruke en "int"-tabell i stede for chars. #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { int x, y, z=0x00000001; int *table = NULL; if(argc<2) return(1); x=atoi(argv[1]); if(x>0) { table = (int *)malloc(x * sizeof(int)); if(table == NULL) return(0); } for(y=0; y<x; y++) table[y]=z++; for(y=0; y<x; y++) printf("tab[y]=0x%x\n", table[y]); free(table); return(0); } Her vil du framprovosere en segmentation-fault i tilfellene hvor x*4 > int_max grunner integer overflow. Endret 12. mai 2013 av etse 1 Lenke til kommentar
zotbar1234 Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 men han skrev sizeof(char *), når det skulle være sizeof(char), som gjør at han i de fleste systemer setter av mye mer minne enn han trenger. Desto større grunn å bruke den kanoniske: T *ptr = malloc(N * sizeof *ptr); ... for en vilkårlig type T. Lenke til kommentar
Matsemann Skrevet 12. mai 2013 Del Skrevet 12. mai 2013 Verdens vanskeligste: include($_GET[$file]); ?file=../../../../../../../../../etc/passwd og man har plutselig litt større innsyn enn man burde i mange tilfeller. ?file=../../../../../../../etc/passwd%00 null-byte, oopps ?file=data://text/plain;base64lololololol= om include_over_url eller hva det eheter er aktivert kan jeg selv velge koden som kjøres. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå