360 Security Guard · 2016/01/05 18:33
Author: Wang Yangdong (Cloud security researcher)@360 Information Security Department
0 x00 probe,
Recently, the “360 Eye Threat awareness system” deployed on 360 cloud platform (cloud.360.cn) found that the system alarm of abnormal traffic existed in the cloud host just opened by a partner. After joint investigation, it was found that malicious attackers used Redis Crackit vulnerability to invade the server and planted malicious programs named Unama. 360 cloud security researcher — “Wang Yangdong” conducted in-depth analysis of this malicious program, and this sample may be a variation of the Billgates botnet.
0x01 Introduction to the BillGates Rear Door
Billgates is one of the most active DDoS botnets in recent years, with botnets all over the world. Bot nodes in the network are mostly Linux hosts with weak passwords or software vulnerabilities. Attackers attack a large number of IP addresses by means of SSH blasting, exploits, 1day, 2day and so on to try to gain control of the server, and expand the botnet by deploying bottrojan horses to the controlled end. Botnets can perform various operations such as DDoS attacks and shell bounces based on server commands.
0x02 Sample analysis
Capture the sample file size of 1223123 bytes, MD5 value of EFF1CB4E98BCC8FBCBDCA671D4C4A050.
Readelf has 44 source file names, which can be inferred from the source file names that the program has many worker threads.
After static analysis, it is found that the code styles of different parts of the sample are quite different: the code of main function is relatively simple and crude, while the CManager and accessory classes of main function show the virus author’s skillful use of C++.
Arjun ain functions
Initialization operations:
The program uses a custom algorithm to decrypt the configuration information from the. Rodata segment and save it, obtain the program file size and the corresponding value in the configuration information to achieve simple self-verification, and then find GDB in the parent process path to achieve reverse debugging.
Call the custom decryption function, get the hard-coded data for concatenation, get strings such as DbSecuritySpt, selinux, Getty, / TMP /moni.lod, / TMP /gates.lod and store them in global variables. Check the current program path to determine the function to perform. The relationship between paths and functions is as follows:
The program path | The back door type | functions | The main function |
---|---|---|---|
/usr/bin/.sshd |
MainMonitor | Monitor, the daemon process | |
Unknown path (does not match other types) | 1 | MainBeikong installation and other operations, and perform the main functions | |
/usr/bin/bsd-port/getty |
2 | MainBackdoor | Main function execution program |
/bin/ ,/usr/bin/ ,/usr/sbin/ Run netstat, LSOF, ps, or SS |
3 | MainSystool | run/usr/bin/dpkgd Backup system tools and filter the output information |
The 0,1, and 2 backdoors are hardcoded to concatenate a string of hexadecimal numbers (actually two hexadecimal numbers separated by a capital O),
Decrypt the corresponding part of the hexadecimal number depending on the type of the back door series, 0, 1 kind of configuration of the back door is 173.254.230.84:3411:1: z: 1,
2 the configuration of the back door is fk.appledoesnt.com: 30000:1: z: 1. Use colon-delimited strings to get six configuration items and save.
Check whether the file name is update_TEMPORARY. If yes, run DoUpdate and exit.
Execute the corresponding function function.
MainMonitor:
Log in to daemon, generate pid file/TMP /moni.lod, read/TMP /notify.file and save, create thread CThreadMonGates and start monitoring thread, main thread loop sleep suspends. Every minute the monitor thread determines the/TMP /gates.lod file (the pid file of the MainBackdoor function process). If the file does not exist, it copies itself to the file path obtained from notify.file and executes the program in the new path.
MainBeikong(program installation) :
/ TMP /moni.lod and/TMP /gates.lod (virus author got STRCMP return value wrong, so this code is not useful). / TMP /moni.lod End/TMP /bill.lock and delete bill.lock. End/TMP /gates.lod again and set its own PID file. Set the S97DbSecuritySpt boot option in /etc/init.d or /etc/rc(1-5).d.
End In /usr/bin/bsd-port-/, delete the processes corresponding to getty. Lock and udevd.lock, copy itself to /usr/bin/bsd-port-/ getty(corresponding to MainBackdoor), and start the process. Write the current program path to/TMP /notify.file(used by the daemon), copy the current file to /usr/bin/.sshd(corresponding to MainMonitor), and start. Execute the MainProcess function. The MainProcess function contains the main functions of the Trojan horse.
The guesswork in the installation is due to a misconfiguration of the virus:
Because the order of the two strings of HEX separated by the letter O was reversed, the type 2 backdoor (Trojan function main) got the invalid domain name fk.appledoesnt.com, while the type 1 backdoor (installer) got the valid IP address 173.254.230.84:3411. So adding the MainProcess at the end of the install function is a temporary solution without finding the cause of the problem.
MainSystool(System Tools replacement) :
Obtain the current program name and parameters, and call the corresponding original system program (netstat, lsof, ps, ss) under /usr/bin/dpkg/. Lines containing information about the directory where the Trojan is located, server communication ports, and so on are filtered from the output of the original system program.
MainBackdoor(Trojan horse function main body) :
Enter the daemon, set the PID file, and create a startup item using S99selinux as the service name. Move system programs ps, SS, netstat, and lsof to /usr/bin/dpkg/, copy itself to /bin, /usr/bin, and /usr/sbin to replace system programs ps, ss, netstat, and lsof, and run the MainProcess function.
MainProcess function:
MainProcess suspends for 2 seconds to delete temporary files used for the update (./update_temporary). Initialize g_dnsCache, an instance of the CDNSCache class, according to /etc/resolv.conf and Google DNS (8.8.8.8, 8.8.4.4).
Initialize g_cnfgDoing(try to read conf.n file), g_cmdDoing(try to read cmd.n file), g_statBase class instances, convert 330 IP addresses in g_sProvinceDns into digital form and store them in g_provinceDns objects. An attempt was made to load the xpacket.ko driver in the current directory via insmod (this file was not found). Read the IP store g_AmpResource structure from /usr/lib/libamplify. So (this file was not found). Initialize the CManager(1076 bytes), set up the signal handler, and loop through sleep indefinitely.
B.CManager class (Painting style mutation) :
CManager class contains all the functions of bot. This class has many members, and each member realizes certain functions. The corresponding list of its main members is roughly as follows:
Members of the | The offset | function |
---|---|---|
vectorIPs | 0x00 | Control server IP address (there can be more than one) |
CThreadSignaledMessageList | 0x0c | CCmdMsg message queue (thread-safe) CCmdMsg contains control instructions issued by the control server |
CThreadTaskGates | 0xe4 | The task dispatch thread class waits for the CCmdMsg message queue |
CThreadClientStatus | 0xe8 | Status update thread class, updates CPU and network usage every second |
CThreadSignaledMessageList | 0xf0 | Queues for CThreadConnection (thread-safe) |
CThreadLoopCmd | 0x1c8 | The loop waits for the signal and finally executes the command configured in the cmd.n file |
CThreadFakeDetect | 0x1cc | Classes that test bot effectiveness |
CThreadSignaledMessageList | 0x1d0 | CThreadShell queue (thread-safe) The CThreadShell is used to keep a shell session connected backwards |
CThreadDoFun | 0x2ac | Determine the validity of bot file and set it through some calculationsg_bReal variable |
CThreadKillChaos | 0x2b0 | Check the PID file every 5 minutes and perform cleanup |
CInitResponse | 0x2b4 | Initializes a packet containing some state data about the current controlled machine |
CThreadMutex_Operation | 0x378 | CManager mutex, thread safe |
SetOfCThreadFXConn | 0x390 | CThreadFXConnection set (C++ STL) |
CTask | 0x400 | Contains the command information sent by the control server |
The CManager::Initialize function initializes the members and checks g_cmdDoing to see if there are any unprocessed commands, and executes them immediately if there are.
After initializing the member variables, execute CManager::MainProcess and set the program to work in controlled mode based on the value of g_iGatsIsFx (now 1). Get the IP in the vectorIPs (only the one strConnTgts points to at this point) and initialize a CThreadFXConnection for each IP and add a set, then loop through an infinite sleep.
CThreadFXConnection thread class final call CManager: : FXConnectionProcess established TCP connection and control server, After the connection is established call CManager: : ConnectionProcess initialization CInitResponse object and send a notification packets:
CInitResponse contains IP(C0 A8 7A 87) 192.168.122.135, system version information, Cpu and memory information, etc.
After sending the initialization package, CManager: : ConnectionProcess into the cycle of sending and receiving data, through the CManager: : RecvCommand receiving data and encapsulated into CCmdMsg structure, Adding CCmdMsg CThreadSignaledMessageList < CCmdMsg > queue.
Through CManager: : SendClientStatus send bot mode.
CCmdMsg by CManager: : TastGatesProcess thread responsible for take out from the receive queue and distribution (CThreadTaskGates thread class start threads).
The general types of CCmdMsg are as follows:
type | function |
---|---|
1 | Call the CManager: : DoAtkStartCommand initialize a DDoS attack |
2 | Run CManager::StopUpdate to stop updates or CManager::StopAtkTask to stop attacks based on the CManager status |
3 | Call CManager: : update DoConfigCommand g_cnfgDoing and conf. N configuration file |
5 | Call the CManager: : DoUpdateCommand to update the program files |
7 | Call the CManager: : update DoCommandCommand CCmdDoing object |
8 | Call the CManager: : DoFakeDetectCommand |
9 | Call CManager::DoShellCommand to establish a rebound shell connection to the specified IP address and port |
The general structure of the CManager class is as follows:
DDoS attack finally passed CManager: : DoAtkStartCommand implementation, this function reads the CTask CCmdMsg object, according to the CConfigDoing (conf., n) global configuration Settings CThreadAtkCtrl thread object. CThreadAtkCtrl: : ProcessMain attack or kernel-level attacks can be carried according to the configuration. Attack by CThreadAtkCtrl: : DoNormalSubTask execution, eventually the function call CThreadAtkCtrl: : StartNormalSubTask, according to each task initializes a CThreadNormalAtkExcutor thread class. Eventually thread function is CThreadNormalAtkExcutor: : ProcessMain, this function will be based on CSubTask. TaskType value to initialize a CPacketAttack subclasses used to perform the corresponding attack, the type value and attack types of corresponding relation is as follows:
CSubTask.taskType | A subclass | attacks |
---|---|---|
0 x10, 0 x11 (var_06 = 0) | CAttackSyn | The SYN half connection |
0 x10, 0 x11 (var_06 = 1) | CAttackCompress | You can customize the IP address and TCP header |
0x20 | CAttackUdp | UDP |
0x21, 0x23, 0x24 | CAttackDns | Random subdomain attacks |
0x22 | CAttackAmp | DNS amplification |
0x25 | CAttackPrx | Some kind of DNS attack |
0x30 | CAttackIcmp | ping |
0x40 | CTcpAttack | Any TCP data is sent with the attacker’s customized data content |
0x41 | CAttackCc | CC |
0x42 | CAttackIe | If not, reset to 0x41 |
CThreadNormalAtkExcutor: : ProcessMain call the Create member structure according to the configuration needed for certain types of data.
The member function Do is called, MakePacket is called to construct the attack packet, UpdateCurVariant is called to modify some attributes of the packet (such as TCP sequence number), and SendPacket is called to send the packet. The Do function is called in a loop until a predetermined number of attacks have been completed.
Kernel attacks by calling CThreadAtkCtrl: : DoKernelSubTask execution (type 0 x43),
This function calls eventually CThreadAtkCtrl: : StartKernelSubTask, initialize CThreadKernelAtkExcutor.
Eventually the execution thread for CThreadKernelAtkExcutor: : ProcessMain.
The current process, this function fork executive function on each CPU CThreadKernelAtkExcutor: : KCfgDev, This function sends the commands rem_device_all(remove all devices), add_device ethN(add NIC N), max_before_softirq(change packet kernel interrupt threshold) to the PKtgen device with N being 0, 1, 2, etc., pointing to the nic name. Pktgen equipment located in the/proc/net/pktgen/kpktgend_X, where X is the current CPU number. The X in kpktgend_X refers to the CPU number associated with the current packet producer, but the virus author uses the network card number here. This error results in the virus using only one CPU to generate packets, which cannot take full advantage of the multi-core, multi-CPU performance. After finish initializing pktgen equipment, CThreadKernelAtkExcutor: : ProcessMain call CThreadKernelAtkExcutor: : KCfgCfg, this function through the/proc/net/pktgen/ethN configuration package generator. The configuration includes the target IP port, number of attack packets to be sent, random range of packet size, waiting time between packets, random range of source IP addresses, and random range of source ports. After setting the parameters of pktgen CThreadKernelAtkExcutor: : ProcessMain to/proc/net/pktgen PGCTRL write start to launch the attack.
0x03 Attack Simulation
Modify the CONTROL server IP of BOT to the machine and write a simple script of the control side to conduct TCP RST attack experiment in the virtual machine:
After setting the attack target to 192.168.122.1:9876, packet size to 128-500, number of threads to 200, attack times to 100, and disabling the Cpu load balancing switch, the attack packets are as follows:
It can be seen that a single bot sent a total of 21,268,252 attack packets in this attack, an astonishing number.
Since the Cpu usage limit option was set to off, the bot maximized the use of system resources and the dual-core Cpu achieved 192.4% utilization.
0 x04 summary
Through this sample, it can be found that the DDoS attack strength of the black production team has reached the point of “relatively skilled”, and according to the different code styles of different parts of the sample, it is speculated that the black production team may have the programming method of multi-team cooperation or the code theft of “black eating black”, maybe.
Today, with the continuous development of IT basic technology, the profit-seeking black production team is still making unremitting use of the newly exposed vulnerabilities to attack those negligent operating systems, threatening the user’s data security. Users are willing to put their data, process implementation and ideas on our cloud platform because they trust us to ensure the privacy and security of their data. The 360 Cloud security team continues to build a secure cloud for you.