malware reverse engineering iran scammers decrypt the strings adl iran malware with @mohammad0x07

Unfortunately, I didn't have anything to do today, so I made it for myself

Mohammad and I were really looking for fun, so this was the best thing

Follow mohammad on Twitter if you like: https://x.com/mohammad0x07

You can download the malware sample from here if you want to analyze it:

https://t.me/sample_abad/2

Today's story happened like this, one of my friends called me that he got a SMS for his father and we thought it was a malware.

First step I opened it in jadx And I saw that all the strings are encrypted for example:

   gatherLinks(arrayList, spannable, PatternsCompat.AUTOLINK_EMAIL_ADDRESS, new String[]{C0004.m114("ScKit-a36ea730c6bf55196a2268cf1662a470", "ScKit-55e2d74905834a25")}, null, null);
       

To get a readable string, function m114 is called

    public static String m114(String str, String key) {
        return new String(decode(hexToByteArray(str.replace("ScKit-", "")), key), defaultCharset);
    }

We can see that we see two interesting functions called decode and also hexToByteArray

    public static byte[] hexToByteArray(String inHex) {
        byte[] result;
        int hexlen = inHex.length();
        if (hexlen % 2 == 1) { 
            hexlen++;
            result = new byte[hexlen / 2];
            inHex = "0" + inHex;
        } else {
            result = new byte[hexlen / 2];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = (byte) Integer.parseInt(inHex.substring(i, i + 2), 16);
            j++;
        }
        return result;
    }

In the first line, we have a byte representation, and then the value of len is checked each time, then the remainder is checked to one, if it is correct, one is added to it, and then the result value is equal to 0 plus the value in the string and is equal to the variable it is inhex, otherwise it is divided by 2 in presentation and equal to the result

It is a counter in the j value and each time it takes the substring value according to the source code for the key

and

    private static byte[] decode(byte[] data, String keyStr) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(encodePass(keyStr).getBytes(), AESTYPE);
            Cipher cipher = Cipher.getInstance(AESTYPE);
            cipher.init(2, keySpec);
            byte[] decrypt = cipher.doFinal(data);
            return decrypt;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

We need two more functions for analysis to write decoder Here we see that the value of the key is first passed with two arguments, that is, the value of the encryption type, which is aes, and the encrypted value of the key.

    public static String encodePass(String pass) {
        return encodeToMD516(pass).toLowerCase();
    }


We can see that encodepass does not do anything special and calls another function

    public static String encodeToMD516(String encryptStr) {
        return encodeToMD5(encryptStr).substring(8, 24);
    }

and also these one...

    public static String encodeToMD5(String string) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 255);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result = result + temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }
    }

But here we see interesting things

To write the decoder, we put all the parts together, we could write all the functions in one function, but it is not bad to be busy.

import hashlib
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

def encode_to_md5(string):
    md5_hash = hashlib.md5()
    md5_hash.update(string.encode('utf-8'))
    return md5_hash.hexdigest()

def encode_to_md516(encryptStr):
    md5_hex = encode_to_md5(encryptStr)
    return md5_hex[8:24]

def encode_pass(pass_str):
    return encode_to_md516(pass_str).lower()

def hex_to_byte_array(hex_str):
    if len(hex_str) % 2 == 1:
        hex_str = '0' + hex_str
    return bytes.fromhex(hex_str)

def decrypt(data_hex, key_str):
    data = hex_to_byte_array(data_hex)
    key = encode_pass(key_str).encode('utf-8')
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
    decryptor = cipher.decryptor()
    decrypted_data = decryptor.update(data) + decryptor.finalize()
    return decrypted_data.decode('utf-8', errors='ignore')

encrypted_str = "f290a56029aa8d1ba33354a1f590e780"
key_str = "ScKit-55e2d74905834a25"

decrypted_message = decrypt(encrypted_str, key_str)
print(decrypted_message)

After this, I told Mohammad that nox would not open for me, so he took over the testing of this section

He saw that requests are going to this server for phishing https://iryns.com/%F0%9D%90%9C%E2%80%8C%E2%80%8C/pay/

so much fun

so much fun

i think to my self to whois is but nothing...

Domain name: iryns.com
Registry Domain ID: 2913172473_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.namecheap.com
Registrar URL: http://www.namecheap.com
Updated Date: 0001-01-01T00:00:00.00Z
Creation Date: 2024-09-01T21:26:17.00Z
Registrar Registration Expiration Date: 2025-09-01T21:26:17.00Z
Registrar: NAMECHEAP INC
Registrar IANA ID: 1068
Registrar Abuse Contact Email: 
Registrar Abuse Contact Phone: +1.9854014545
Reseller: NAMECHEAP INC
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Registry Registrant ID: 
Registrant Name: Redacted for Privacy
Registrant Organization: Privacy service provided by Withheld for Privacy ehf
Registrant Street: Kalkofnsvegur 2 
Registrant City: Reykjavik
Registrant State/Province: Capital Region
Registrant Postal Code: 101
Registrant Country: IS
Registrant Phone: +354.4212434
Registrant Phone Ext: 
Registrant Fax: 
Registrant Fax Ext: 
Registrant Email: 
Registry Admin ID: 
Admin Name: Redacted for Privacy
Admin Organization: Privacy service provided by Withheld for Privacy ehf
Admin Street: Kalkofnsvegur 2 
Admin City: Reykjavik
Admin State/Province: Capital Region
Admin Postal Code: 101
Admin Country: IS
Admin Phone: +354.4212434
Admin Phone Ext: 
Admin Fax: 
Admin Fax Ext: 
Admin Email: 
Registry Tech ID: 
Tech Name: Redacted for Privacy
Tech Organization: Privacy service provided by Withheld for Privacy ehf
Tech Street: Kalkofnsvegur 2 
Tech City: Reykjavik
Tech State/Province: Capital Region
Tech Postal Code: 101
Tech Country: IS
Tech Phone: +354.4212434
Tech Phone Ext: 
Tech Fax: 
Tech Fax Ext: 
Tech Email: 
Name Server: achiel.ns.cloudflare.com
Name Server: addilyn.ns.cloudflare.com
DNSSEC: unsigned
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
For more information on Whois status codes, please visit https://icann.org/epp

so i fuzz for sql injection on phishing page but its also have nothing......

POST /%F0%9D%90%9C%E2%80%8C%E2%80%8C/pay/pay.php HTTP/2
Host: iryns.com
Cookie: PHPSESSID=grg4e0l7lomj2c59m48ph1aoo4
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 206
Origin: https://iryns.com
Referer: https://iryns.com/%F0%9D%90%9C%E2%80%8C%E2%80%8C/pay/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers

{"pan":"5047061000000000","selectedPanIndex":-1,"pin":"131231231231","cvv2":"0000","expireMonth":"07","expireYear":"07","captcha":"13123","payerId":null,"email":"","code":"8D20573198BF12D1","savePan":false}

Maybe we can look for people and hackers in it, we found a few people in the phase of decoding the string, but they were innocent, so we went to other parts by examining the behavior in several other malwares.

like :https://www.virustotal.com/gui/file/e11b47d5ff10d354a6fdd5189e6dcfcb5b0cc6f63c896eead34c8b57ae4bf993?nocache=1

Here I saw some interesting things by someone I don't know about the results of different antiviruses compared to subsidized malware.

so much fun

And I saw some interesting things The behavior of both malware is the same

For example, both of them first look for credentials with the same method and have similar activities

For example, the names of some functions and libraries were also the same

I have to skip and say at the end that we found them with these similarity

virustotal link adl iran malware:

https://www.virustotal.com/gui/file/3589914ac5d022667b0e76c7771c1aba2c7524d2dcf4fb06a78e9a590364f876/detection