During 2020 Leonardo analysts discovered and published a very in depth analysis of a threat known as Penquin, attributed to the APT group Turla. 32-bit samples of this threat had been detected and analyzed by Kaspersky before, but the analysis in this most recent publication was focused on a new 64-bit sample.
It firstly caught our attention the fact that this threat does not have its own command and control server, but rather stands by waiting for a very specific packet generated by the attacker and from that packet it extracts its command and control server.
This results in the following logical scenario for an attacker to take control of the threat:
In the report published by Leonardo there is a lot of information related to the structure of such packet and the threat activation protocol, in fact, they published a version of an UDP scanner with a specific packet contacting an internal IP, in order to allow scanning internal networks for threats.
This threat, despite being a compiled and relatively complex binary, has the same capabilities that are usually found in webshells. Furthermore, the group itself could be said to use them in a similar way than other less advanced groups using webshells since it has been observed how in servers infected by this threat, command and controls from other Turla tools have been deployed in order to use them as infrastructure in recent campaigns.
This fact implies that the possibility of detecting new infections of this threat all over the Internet may allow identifying the infrastructure of current, and even future, Turla campaigns.
For this, we firstly need to be able to generate activation packets for public IPs controlled by us. Secondly, we are interested in being able to scan TCP ports as well, since there are cases of servers that have specific TCP ports exposed to the Internet and all UDP ports blocked.
Starting from public samples and the work already done and documented as a resource, we decided to implement a function that emulates the threat’s logic of checking the validity of that “Magic” packet and extracting the IP address of the C2 it is ordered to contact.
This allows us to quickly and automatically validate an inferred activation packet.
Rather than completely reverse the validation logic, in order to reverse the algorithm and try to generate specific packets we first tried brute-forcing the different elements within the UDP and TCP packets, and then leverage the function we had extracted from the threat to validate each combination for a public target IP controlled by us.
We know that the sample first extracts 32 bits from the packet, and compares them with the mask “0xbdbd0560”. In case it passes this first filter, it extracts another 32 bits and the source port, and passes this extracted information to the validation function we already have. The problem was that brute-forcing so many bytes would be too slow and not feasible.
Fortunately, there is a good part of the algorithm already described. Some of these elements are the fixed bits of the first mask and the bits that compose the IP address with which Penquin will contact (our controlled IP, in this case).
The fixed bits of the first check take away most of the second block of 32 bits, and since we will want to generate the packets for an IP address controlled by us, we can subtract another 28 bits from the two blocks of 32, since these will have to be exactly those that build the IP of our server. In fact we could subtract 4 more bits from the source port that will also be dependent on the final IP, although in our case we consider it unnecessary. So instead of brute-forcing all possible combinations of two 32-bit blocks plus the port (16 bits more), we only have to brute-force 4 bits + 4 bits + 2 bits + 3 bits + the source port, which becomes trivial.
This would allow us to generate combinations for a destination IP and then check if the result is valid and it still generates the IP we expected it to generate.
However, there is still one last element to take into account:
The function that checks the validity of the packet within the threat (in the screenshot renamed to MagicStuff), returns as a parameter an ID extracted from the calculations it performs, which can contain a value between 0 and 3. Just before contacting the target server it compares this ID with the ID of the last contact with a C2, and it is initialized to 0 when the threat is executed for the first time. This avoids accepting the same packet twice, (and at the same time, the first packet cannot result in 0 after that calculation). Therefore, we need to generate two different packets if we want to make sure that in case we send it to an infected server, it will reply and avoid not receiving contact simply because we have sent the same ID as the attacker in the last contact.
Once two packets with different IDs and a controlled public IP have been generated, the last thing is to send them to a TCP or UDP port that is open on as many servers as possible and wait to receive responses on our server’s IP from the scanned IP addresses.
For this, in the case of UDP we already have the work done, but in the case of TCP the payload that checks the threat is not in the body of the TCP packet received, but in the headers, specifically in the Sequence Number and Aknowledgement Number, so we need to generate the packet in RAW to be able to control these elements:
Once all the elements are prepared and finished with a close resemblance to this one:
Now we finally can perform the scan 🙂
Different strategies have been used for the scanning. We have scanned ports 25 (TCP), 53 (UDP/ TCP), 80(TCP), 443(TCP), 8080(TCP) and we have tried to vary the “callback” port. To avoid unnecessary traffic, the sending and receiving packets are placed in different ip addresses. The IP address from where it is activated (source of our crafted packets) and the “supposed” C2 (server expected to be contacted) are in different servers. In the case of receiving packets in the expected address, a double check is made sending only to that IP, in order to verify that we are still receiving a response from Penquin.
After a first scan in June 2020 we registered 86 ip addresses hosting Penquin.
First of all, we were struck by the distribution of these infections, as they were all located in Europe, Russia and the United States.
The IP’s found correspond in most of the cases with VPS from a wide variety of providers.
On the other hand, Shodan offers us information suggesting that many of the IPs, as expected, have multitude of vulnerabilities.
In the image above we can see the vulnerabilities in RED color and the IPs in ORANGE color.
In total, vulnerabilities have been identified in 65% (+ or -) of the detected IPs.
Among the detections observed, these two IP addresses stand out:
At “first sight”, it can be observed how in VT this address is related to a binary that some antivirus vendors along with Intezer catalog as Turla.
Researching for more details about this sample, we find that it is mentioned in an AnhLab Report about a Turla campaign against the Korean Defense sector, which, along with this paragraph from Cisto Talos from July 2021 “One public reason why we attributed this backdoor to Turla is the fact that they used the same infrastructure as they used for other attacks that have been clearly attributed to their Penguin Turla Infrastructure.” Related to their analysis of Tinyturla, reinforces the hypothesis that they use Penquin as a tool to control machines that are then used as command and control servers or intermediate node servers for their operations.
Customers with Lab52’s APT intelligence private feed service already have more tools and means of detection for this campaign.
In case of having threat hunting service or being client of S2Grupo CERT, this intelligence has already been applied.
If you need more information about Lab52’s private APT intelligence feed service, you can contact us through the following link