Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Malicious module on CPAN

by choroba (Cardinal)
on Jul 29, 2020 at 10:56 UTC ( [id://11119952]=perlnews: print w/replies, xml ) Need Help??

If you use Module::AutoLoad, consider switching to something else. The module was removed from CPAN as it used string eval on data obtained from the internet.

More details in the perl.modules e-mail archive.

Link to the related StackOverflow question with replies from the very author of the distribution.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re: Malicious module on CPAN
by aitap (Curate) on Jul 29, 2020 at 14:07 UTC
    What was this code supposed to do, anyway? Here is what I managed to piece together, starting from Module-AutoLoad-0.05/contrib/RCX.pl and substituting eval unpack or eval <$b> with string values available to me, also feeding stuff to perl -MO=Deparse | perltidy (which I consider to be safe in the absence of BEGIN blocks):

    (updated the code after I threw off some of the red herrings)

    Note that the evals are followed by if 0 (does the server return different payloads for select clients?), but eval is run line-by-line, so the code actually gets executed. Also note manually-crafted errors to populate $@ with the next key to the puzzle.. Where is the definition of botstrap that is referenced so many times? Is package EPROM.block supposed to be available anywhere for this script to run?I ran this in a sandbox and captured the traffic using Wireshark. Indeed, the definition of botstrap (both package and subroutine) is downloaded later in a very convoluted way. I wouldn't be surprised to know that most of it is red herrings.

    Added later:

    From there on, it downloads and evaluates http://46.246.28.22:80/dl/RCX.pm:

    # Tell botstrap where to load RCX modules ${^INC} = "http://www.r.cx/dl";
    then, using the second address, downloads and evaluates a different file http://r.cx/dl/RCX.pm:
    package RCX; use strict; sub import { print "Congratulations! The RCX framework has been loaded.\n"; } 1;
    then, on use sword, does the same with http://r.cx/dl/sword.pm:
    package sword; print "RCX Sword has been drawn.\n"; sub drop { print "RCX Sword has been dropped.\n"; } 1;
    (Note how the server response is a bit different whether the code does HTTP/1.0 requests manually with some tricks in User-Agent: header or you follow the link in a browser: in the latter case you get a 302 redirect to www.r.cx/...)

    To summarise, what I have been able to observe looks benign, but entirely irresponsible. Also, it is impossible to prove good intentions of this code, since the remote server (or a MITM) could serve an entirely different payload to select clients and/or depending on time (related reading).

    See also: http://46.246.28.22/dl

    Merry Christmas!

    Congratulations! You figured it all out.
    Or did I? We may never know.

      Essentially allows the execution of remote code (the horror), the author claims to install missing perl modules, without bothering to ask for user consent.

      To @aitap I think you're the first one to deobfuscate this code publicly like this. Very nice explanations and I can really appreciate your time doing that! It wasn't so much the HTTP/1.0 or HTTP/1.1 that made any difference. It's that some of my endpoints actually rely on HTTP/0.9 protocol to work properly. Yeah, I admit it's gross, I know. And yes, the RCX.pm is just a useless benign test, as you've observed. But the actual use of Module::AutoLoad never touches RCX.pm except in that RCX.pl test suite just to make sure all the obfuscation endpoints are still up. Maybe your reasoning for failing to actually explain how AutoLoad.pm works (which is what would actually be used) is because it's probably easy enough to follow anyways and thus doesn't need any explanation. So at least you already did the hard part. Fair enough.
        Maybe your reasoning for failing to actually explain how AutoLoad.pm works (which is what would actually be used) is because it's probably easy enough to follow anyways and thus doesn't need any explanation.
        Yeah, the live code botstraps "AutoLoad" instead of "RCX", and once the code evaluates http://perl.rob.com/dl/AutoLoad.pm, it fetches the real Module::AutoLoad, which is much easier to understand and uses MetaCPAN v1 API.
Re: Malicious module on CPAN
by marto (Cardinal) on Jul 29, 2020 at 14:01 UTC

    Thanks for spreading the word. This isn't the first really dodgy thing I've seen on cpan (e.g. rt://100658), metacpan grep timed out while I searched for similar. Perhaps some work can be done regarding smoke testing, optionally attempting to determine potentially dangerous modules then flag them for review in some way. I'll have a think.

Re: Malicious module on CPAN
by hookbot (Acolyte) on Jul 29, 2020 at 20:41 UTC

    First of all, thanks to everyone for all these deobfuscation spoilers! But I must say I was surprised to see my code labeled "Malicious" when that was never the intention.

    And yes, it's true that my Module::AutoLoad code was removed from CPAN, which suddenly broke everyone attempting to utilize it, but Andreas restored it back. Sorry for those several hours of downtime last night.

    Also, I named it botstrap because it acts sort of like bootstrap but is shorter and sounds more like hookbot of course.

    Hopefully it will help if I walk through the hello_app.cgi example. You'll notice how it still works even if CGI::Ex isn't actually installed. Check out my console:

    $ perl -MCGI::Ex -e '' Can't locate CGI/Ex.pm in @INC (@INC contains: /usr/local/lib64/perl5 +/usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/ +vendor_perl /usr/lib64/perl5 /usr/share/perl5 .). BEGIN failed--compilation aborted. $ perl hello_app.cgi Content-Type: text/html Hello World! $

    So while this actually functions fine for most uninstalled CPAN module dependencies, it doesn't actually "install" the module. It simply copies the code from CPAN into your local ./lib/* folder. (That's the reason modules with XS code can't work with this.) The entire purpose is NOT to have to install anything and your Perl script can simply use the CPAN modules desired and it will just work automagically. So in order to minimize the amount of work for the super lazy, I wanted my snippet paste to be small enough to be worth bothering to do. That's why I decided to use TCP network to download the actual code that does the work to install the modules. But I frankly agree that it's generally NOT a good idea to run strings you get from sockets that you don't have total control over. So if you don't trust me, you should only try this in a throw-away Virtual Machine or some kind of more controlled environment. USE AT YOUR OWN RISK! I think that Grinnz probably said it best in his response, "while this approach might work fine for you it is not suitable to recommend to others".

    So the moral is that if you are someone that trusts me, then you may continue to use my code if you want, and it will probably work fine, but just know that it could be dangerous or something could malfunction. Of course, I feel safe using it for my own stuff because I know how everything works and because I control all the endpoints it goes through and I know I will never put anything nefarious in it and I was just wanting to be helpful for others.

    Again, I'm sorry if this code caused any fear or frustration or confusion for anyone. Feel free to let me know if you have any questions or suggestions about anything. Happy to spray out more spoilers for fellow Monks!

      FWIW, I agree that malicious was the wrong word choice here. I would have said potentially dangerous or risky myself. There is a long standing tradition against doing any external calls for any reason. I found myself on the wrong side of it with a module of my own once that used an external URL for a test. Even that fairly innocuous use case was called out by someone and I changed it.

Re: Malicious module on CPAN
by perlfan (Vicar) on Jul 29, 2020 at 21:27 UTC
    Maybe we should stop this kind of shit, too.
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/ +install/master/install.sh)"
    curl -L https://install.perlbrew.pl | bash
    curl -L https://cpanmin.us | perl - --sudo App::cpanminus
    I use these myself bc it's easy and I trust those site, but I always feel bad after.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlnews [id://11119952]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-03-28 22:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found