Yo momma's so fat, Dr. Martens had to kill 3 cows just to make her a pair of shoes.
Het gaat niet zozeer om het escapen dus want als je die waarde zelf samenstelt en je weet dat daar geen onveilige karakters inzitten is er geen probleem. Valt me tegen dat niemand het ziet eigenlijk. Als je een hash geeft aan een entry in een database dan moet je eerst checken of die hash er al niet is... De kans op collisions is niet heel groot maar zeker aanwezig. 2 entries met dezelfde hashes kan een hoop problemen opleveren (kijk bijv. naar youtube die de hash uit de url gebruikt als id).quote:Patriot schreef op vrijdag 16 mei 2008 @ 22:36:
[...]
Je levert zelf anders ook wel erg weinig context hoor. Je wil gewoon zeggen dat men dingen moet escapen, maar sommige dingen hoef je echt niet te escapen. Als je als developer de gebruikte variabele declareert is het niet nodig (mits er geen tekens in staan die de boel opfucken), en zéker geen exploit.
EDIT:
En wat SchizoDuckie bedoelt is dat je impliceert dat het één bepaald type is, terwijl het zomaar een ander type zou kunnen zijn (maar daar ben je zelf bij I guess).
Nog een keer de code:
PHP:
| <?php
|
En over het prefixen: bij ons op t werk is het een code standaard. Iedereen houdt zich daar keurig aan en dat is echt handig tijdens het doorkijken van een script.
Cartman! wijzigde dit bericht 17-05-2008 11:41 (6%)
Zonder user input (hetzij via _POST, of via _GET) valt er natuurlijk weinig te exploiten...quote:Cartman! schreef op zaterdag 17 mei 2008 @ 11:41:
[...]
PHP:
1
2
3
4
5
6
7<?php
$strSql = '
INSERT INTO
video
SET
filename = "' . $strFilename . '",
hash = "' . sha1(time()) . '"
';
?>
Enige wat ik kan verzinnen is dat dit niet handig is en dat je misschien beter dit kan doen:
code:
1
| sha1(time() . $strFilename) |
onnovanbraam.com | The Blueprints - Ref. Image Database
You're good, you're real good, but as long as I'm around, you'll always be second best
Het probleem is dat met jouw voorbeeld niet direct duidelijk is waar de gemaakte hash voor dient. En het kan net zo goed zijn dat je daarnaast nog een kolom met auto_increment als primary key gebruikt.quote:Cartman! schreef op zaterdag 17 mei 2008 @ 12:57:
Het probleem is dat je dan nog steeds duplicates kunt krijgen in je database en dat wil je niet. Dus gewoon een functie maken die een hash genereert, checkt of ie niet voorkomt en als dat zo is recursief zichzelf aanroepen om een nieuwe te maken totdat je een unieke hebt. Je gaat toch ook geen nieuwsberichten hetzelfde id geven?
Bezoek eens een willekeurige pagina
Of help mee met Tweak-City
Ik wili minder Kb's
@hieronder: Wel volgens mijn C++ boek (C++ Grand Cru, Steve nogwat)
Sebazzz wijzigde dit bericht 17-05-2008 14:36 (20%)
main() behoeft geen return statement. Maar de return-type is wel altijd int.quote:Sebazzz schreef op zaterdag 17 mei 2008 @ 09:59:
Je returned niet uit main() dus deze zal zowieso niet compilen.
Waarom? main() is sowieso een special case (main() mag bijvoorbeeld ook niet aangeroepen worden door eigen code). 'return x' is in feite hetzelfde als 'exit(x)'. Waarom is dát dan geen goede gewoonte om neer te zetten? Als je een return-waarde onzinnig vind maak je 'm void, dat mag bij main() helaas niet. En in main() is geen return is hetzelfde als return 0 - iedere fatsoenlijke C++er weet datquote:@hieronder: Het is in ieder geval een goede gewoonte om het te doen
H!GHGuY: de bug is dat CFixedString::buffer nooit wordt afgesloten met een terminating 0. Je had gewoon strcpy() moeten gebruiken ipv strncpy(), wat mogelijk is omdat je de lengte daarvoor toch controleert.
er zit wel een terminating 0 in hoorquote:.oisyn schreef op zaterdag 17 mei 2008 @ 14:05:
[...]
main() behoeft geen return statement. Maar de return-type is wel altijd int.
[...]
Waarom? main() is sowieso een special case (main() mag bijvoorbeeld ook niet aangeroepen worden door eigen code). 'return x' is in feite hetzelfde als 'exit(x)'. Waarom is dát dan geen goede gewoonte om neer te zetten? Als je een return-waarde onzinnig vind maak je 'm void, dat mag bij main() helaas niet. En in main() is geen return is hetzelfde als return 0 - iedere fatsoenlijke C++er weet dat
H!GHGuY: de bug is dat CFixedString::buffer nooit wordt afgesloten met een terminating 0. Je had gewoon strcpy() moeten gebruiken ipv strncpy(), wat mogelijk is omdat je de lengte daarvoor toch controleert.
Ik ben echter niet helemaal zeker dat het voorbeeld 100% klopt, maar mits minimale aanpassingen moet het toch zeker lukken...
Verklap'k em ?
H!GHGuY wijzigde dit bericht 17-05-2008 14:39 (7%)
Yo momma's so fat, Dr. Martens had to kill 3 cows just to make her a pair of shoes.
je buffer moet je zo construeren:
code:
1
2
3
4
5
| 0:[256karakters zonder whitespace met minstens 1 \0 karakter - kan exploit code bevatten] 256:[vptr wijst naar 260] 260:[vptr0 wijst naar 268 of 0] 264:[vptr1 wijst naar 268 of 0] 268:[exploit code] |
inlezen van een std::string kijkt naar EOF of whitespace. NUL-karakters worden afaik gewoon mee ingelezen.
strlen leest tot de eerste NUL-byte, str.data geeft alle data + bijhorende .size() (groter dan de strlen)
dus je kopieert over de vptr pointer. Doordat de initiele CFixedSizeString op de stack staat kun je de offsets daarvan gebruiken om tijdens de laatste inleesopdracht je code te injecteren met gekende offsets.
Door uiteindelijk de print() opdracht op te roepen jump je naar je exploit code.
Ik vermoed echter dat de set pointers naar CFixedSizeString zal moeten bevatten of anders wordt tijdens de copy-constructor actie de vptr van het geinserteerde object juist gezet.
Yo momma's so fat, Dr. Martens had to kill 3 cows just to make her a pair of shoes.
Dat zal allemaal gerust zo zijn hoor, maar niks van dit alles is uit de code te halen die jij geeft. Je geeft alleen de declaratie van een variabele, dat het een query betreft impliceert dan nog dat je het waarschijnlijk uit zou voeren maar dan houdt het toch echt wel op..quote:Cartman! schreef op zaterdag 17 mei 2008 @ 13:35:
Maar dan nog, bij Youtube zal iedere video vast een id hebben maar je krijgt deze gepresenteert adhv. de hash. Als een hash niet uniek hoeft te zijn dan heb je er niks aan in een database imo, tenzij deze als checksum dient.
De fout is volgens jou dat er niet gekeken word of die hash al bestaat, maar uit je voorbeeld is onmogelijk te halen dat de hash uniek moet zijn. En dat een hash die niet uniek hoeft te zijn niet nuttig is, is ook niet waar. Je komt ze bijvoorbeeld vaak tegen in gebruikerssystemen. Een gebruiker die zijn wachtwoord is vergeten krijgt dan vaak een hash toegestuurd via de mail, waarna hij op een pagina alleen zijn wachtwoord kan veranderen als de hash klopt.
Je voorbeeld is leuk geprobeerd, maar helaas te abstract en ik kan me ook niet voorstellen dat het echt een exploit is.
Op die manier kan het nog steeds mis gaan. Twee users submitted verschillende files met toevallig dezelfde hash waarde. Eerste process queried de database of er duplicates zijn en vindt die niet. Op dat moment kicked het tweede process in, queried ook de database, en vindt ook geen duplicates. Vervolgens gaan ze allebei lekker insert queries draaien, en voila, een duplicate hash.quote:Cartman! schreef op zaterdag 17 mei 2008 @ 12:57:
Het probleem is dat je dan nog steeds duplicates kunt krijgen in je database en dat wil je niet. Dus gewoon een functie maken die een hash genereert, checkt of ie niet voorkomt en als dat zo is recursief zichzelf aanroepen om een nieuwe te maken totdat je een unieke hebt. Je gaat toch ook geen nieuwsberichten hetzelfde id geven?
maw. je moet dan een atomic query maken die eerst select en dan conditioneel insert. Maar dan moet je nieuwe hashes kunnen genereren en loopen in je query: niet handig. Dus moet je je database locken gedurende de tijd dat je select/insert script draait. Dan kan je je site DoS-en door heel veel files te submitten
concurrency exploits zijn natuurlijk ook leuk. Ik kan me wel iets indenken dat een Os een syncrhonized multiple producer/consumer buffer bijhoudt als event queue, maar dat op de simpelete manier met twee semaphores doet. Ik heb geen zin om een voorbeeld te geven, dat wordt te ingewikkeld. Het idee is in ieder geval dat je door een race-conditie naar hetzelfde slot kan schrijven als een ander process, en zo priviliged events zou kunnen faken ....
Zoijar wijzigde dit bericht 17-05-2008 15:48 (32%)
Nou wijs het maar aan dan, want ik zie het niet. strncpy() schrijft maximaal n characters. n is gelijk aan str.size(), dus strncpy() vult buffer met n characters zonder trailing 0.quote:H!GHGuY schreef op zaterdag 17 mei 2008 @ 14:37:
[...]
er zit wel een terminating 0 in hoorkijk nog maar eens goed...
kloptquote:H!GHGuY schreef op zaterdag 17 mei 2008 @ 14:54:
Ik kan er grandioos naast zitten
Fout, om drie redenen. De vtable pointer staat meestal vooraan in de class, en dus niet achter buffer. Dit is wel zo praktisch omdat typeid() en dynamic_cast ook op void pointers moet kunnen werken. Als de vtable pointer achter buffer staat is het daadwerkelijke type zo goed als niet te achterhalen.quote:strlen leest tot de eerste NUL-byte, str.data geeft alle data + bijhorende .size() (groter dan de strlen)
dus je kopieert over de vptr pointer.
De andere reden is dat ook strncpy() niet altijd n characters kopiëert, maar maximaal n characters. Hij ie een 0 tegenkomt en i<n dan stopt dus gewoon. Je functie kopiëert daarom nooit meer dan 255 tekens door de if die ervoor staat. Als je altijd exact n characters wilt kopiëren moet je memcpy() gebruiken. En sowieso zelf de trailing 0 erachter zetten, want ook strncpy() doet dat niet als er al n characters geschreven zijn.
De derde noemde je zelf al:
Klopt als een busquote:Ik vermoed echter dat de set pointers naar CFixedSizeString zal moeten bevatten of anders wordt tijdens de copy-constructor actie de vptr van het geinserteerde object juist gezet.
.oisyn wijzigde dit bericht 17-05-2008 22:11 (8%)
Reg. datum: 29 maart 2004
Reg. datum: 02 februari 2001
Normaal gebruik ik geen std::string, maar is deze aanname wel juist: strlen(str.c_str())==str.size(). Als de string meerdere '\0' characters heeft, kan dat evt mis gaan...quote:H!GHGuY schreef op zaterdag 17 mei 2008 @ 09:54:
C++:
1
2
3
4
5
6
7
8
9class CFixedSizeString
{
public:
CFixedSizeString(const std::string& str)
{
if (strlen(str.c_str()) > 255)
throw "badly sized string";
strncpy(buffer, str.data(), str.size());
}
Het zal je verbazen waar ik allemaal van gehoord hebquote:fl!pulI schreef op zaterdag 17 mei 2008 @ 21:35:
Ach Zojar, jammer dat je nog niet gehoord hebt van Database Transactions. Dat maakt je hypothetisch voorbeeld onmogelijk.
Zoijar wijzigde dit bericht 18-05-2008 11:52 (9%)
niet schieten is altijd misquote:.oisyn schreef op zaterdag 17 mei 2008 @ 19:12:
[...]
Nou wijs het maar aan dan, want ik zie het niet. strncpy() schrijft maximaal n characters. n is gelijk aan str.size(), dus strncpy() vult buffer met n characters zonder trailing 0.
[...]
klopt
[...]
Fout, om drie redenen. De vtable pointer staat meestal vooraan in de class, en dus niet achter buffer. Dit is wel zo praktisch omdat typeid() en dynamic_cast ook op void pointers moet kunnen werken. Als de vtable pointer achter buffer staat is het daadwerkelijke type zo goed als niet te achterhalen.
De andere reden is dat ook strncpy() niet altijd n characters kopiëert, maar maximaal n characters. Hij ie een 0 tegenkomt en i<n dan stopt dus gewoon. Je functie kopiëert daarom nooit meer dan 255 tekens door de if die ervoor staat. Als je altijd exact n characters wilt kopiëren moet je memcpy() gebruiken. En sowieso zelf de trailing 0 erachter zetten, want ook strncpy() doet dat niet als er al n characters geschreven zijn.
De derde noemde je zelf al:
[...]
Klopt als een bus
Leer ik zelf ook gelijk wat bij...
Yo momma's so fat, Dr. Martens had to kill 3 cows just to make her a pair of shoes.
Bezoek eens een willekeurige pagina
Of help mee met Tweak-City
Ik wili minder Kb's
Reg. datum: 20 maart 2001
code:
1
2
3
| $res = mysql_query('SELECT username FROM users WHERE name="pietje";');
$row = mysql_fetch_assoc($result);
$query2= mysql_query('update rechten set (adminright=True) where username="' . $row['username'] . '"'); |
Gomez12 wijzigde dit bericht 20-05-2008 20:34 (3%)
Talkin.nl daily photoblog
Day 1022: Meerkats
Foto specs: Canon 300D, Sigma 70-200 f/2.8 HSM, 1/500s, f/5.0, ISO 400
offtopic: het adminright=true is ook erg beperkend voor een applicatie...
Dan wordt het meer een "Debug mijn script" topic...quote:Cartman! schreef op dinsdag 20 mei 2008 @ 21:10:
Het is sowieso niet handig om in de rechtentabel de naam te gebruiken ipv. het userid, is dat wat je bedoeld? Moeten er trouwens geen quotes om True heen? En de haakjes zijn ook overbodig.
offtopic: het adminright=true is ook erg beperkend voor een applicatie...
Megamind wijzigde dit bericht 20-05-2008 21:12 (58%)
Tweak-city
Spel- of grammaticafout gevonden? Geef het even door via DM (en ook waarom het fout is).


