Mi0r4sora

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

Hello! As always, I’m back with something interesting and new. In a way, I kind of love the times when people send me malware or try to gain access to my system — hopefully, this isn't some form of masochism. Recently, I was even the target of an advanced piece of malware that I still haven’t found, but I’ll be back with it soon.

hello bro im hacker

Before this, we had fully reverse-engineered and analyzed the previous class. We made the various structures and obfuscation systems in that malware public and reviewed our overall perspective together.

But for today, we have a new class of malware from the Iranian Judiciary. Recently, a new class has been spreading, and I happened to receive one of them.

About two weeks ago, I received a strange message with an unusual font, which was quite interesting. Let me tell you two reasons why I use the word interesting for these otherwise simple pieces of malware — something I’ve recently learned is behavioral analysis of malware developers. For example, I received the suspicious message twice:

  1. The first time, the website didn’t work and gave me an error (which you’ll see below), telling me I was using a VPN. That was interesting — it meant the site was down, and the attacker had temporarily paused the operation due to some issue.

hello bro im hacker

  1. The attacker sent me another message, again using the same weird font. But this time too, the website had issues — which I also found curious.

when we open the url in phone hello bro im hacker

This means we received two messages from two different phone numbers. From these two messages, it seems clear that the person using the malware isn’t the original developer. Someone else is behind the deployment, actively using it. The developer likely had a dedicated task, or perhaps we’re witnessing a new class of this malware with a different type of obfuscation and encryption.

when bro read this blog: hello bro im hacker

Now, after two weeks, I finally managed to write this article — that’s why I don’t have a screenshot of what comes after the CAPTCHA. But it’s still interesting. Anyway, after solving the CAPTCHA and logging in, we can see two forms that need to be filled out. If I remember correctly, after completing them, you're redirected to a payment gateway, and then an APK file is downloaded, which the victim is expected to install.(like other type of this malware)

The interesting thing about this malware was that it couldn’t be opened with JADX — which is unusual. So I started thinking differently and said to myself, *Why not try unpacking it with apktool, then rebuilding it?*

Well… that didn’t work either.

So, I turned to one of my secret tools — the Emblem of the Great Overlord: a very powerful tool called JEB — and it worked.

But I still love JADX — what should I do? I used 7-Zip to extract it and then found a classes.dex file.

hello bro im hacker

I first check the permissions and activities in JEB, and then I examine the rest — like the encryption structure and communications — in other parts.

I also saw interesting things like Firebase communications. If I had dug a little deeper, I might have found tokens and communication keys as well. But I just got back from university and I’m really tired, so I’m only writing about the parts that let us make fun of these people even more.

Things I checked:

  • Photo metadata
  • Certificates check
  • Communications check
  • Encryptions
  • A bit of this and that for more fun

hello bro im hacker hello bro im hacker

oh bro dont hack me

After extracting with 7z, I saw several txt files. After that, I searched in jadx about where and how they are used, and I found this:

hello bro im hacker

NOTE: I renamed them myself

so after that what happened bro?

After seeing this, I opened the key_gen function

hello bro im hacker

soooooooooo

Let’s take a step back to where we saw key_gen heh bro

        String key_gen = utilsVar.key_gen(File.ReadString(File.getDirAssets(), "URL.txt"), storedb._secret_key, storedb._v0);
        File file3 = Common.File;
        File file4 = Common.File;

yooooo we have iv and key

heh bro

    public static String _process_globals() throws Exception {
        _secret_key = main.vvv13(new byte[]{85, 95, 31, 78, 93, 90, 34, 86, 84, 89, 94, 84, 54, 74, 23, 66, 33, 95, 87, Base64.padSymbol, 55, 23, 69, 85, 83, 41, 66, 69, 91, 95, 86, 67}, 23024);
        _v0 = main.vvv13(new byte[]{85, 93, -49, -107, 93, 88, -14, -115, 84, 91, -114, -113, 54, 72, -57, -103}, 945708);
        return "";
    }
}

and other part:

heh bro

so with this we can decrypt it and get the C&C of the attacker

heh bro

this is the argument we most used to decrypt the text file

from Crypto.Cipher import AES
from Crypto.Util import Counter
import binascii


package_name = "ir.novinpardaz.kish"
version_name = "1.5.9.9"
version_code = 1599


encrypted_hex = "9A5F90C06DEF31F0E470CFB7C06F8713B8EBDC17D2F5E9E62349DDFB7EB44840585F9FD8FAFD6D1E97A7837CCA2BBACA44EA1DD682B3FB13D007D08DFB3C892E5C038FB92F88FC57CFB151FBFE5283A1971901DFA8EA92A0C880A5656AEF3CC22E26E287C01F97095C59A308A27E01318B9B12A455AD5880DF918580F8D5587643F442E920DA9FEAF4AB951A0F752C71CE05B9D4ABDFA273F81F62A0B5A6FFC6B810D34A8757892B60A4332752C27E09D5469B93A0B33E5C52DD2EEBD26355DD483F968E4FD5A14AB0AA9EE7EB7B57F548558447C5755317A0230A66D565DAB7F74ADB0C9F55DDC085FE05ABD970317AB7104E070C8B5F7EE0"

def vvv13(byte_arr, seed, package_name, version_name, version_code):
    i2 = (seed // 5) + 326661
    bb = [None] * 4
    bb[0] = package_name.encode('utf-8')
    bb[1] = version_name.encode('utf-8') if version_name else b'jsdkfh'
    bb[2] = bytes([version_code & 0xFF])  # only one byte of version code is used
    bb[3] = bytes([(i2 >> 24) & 0xFF, (i2 >> 16) & 0xFF, (i2 >> 8) & 0xFF, i2 & 0xFF])

    for b in bb:
        for i in range(len(byte_arr)):
            byte_arr[i] ^= b[i % len(b)]

    return byte_arr.decode('utf-8')


key_raw = bytes([85, 95, 31, 78, 93, 90, 34, 86, 84, 89, 94, 84, 54, 74, 23, 66, 33, 95, 87, 61, 55, 23, 69, 85, 83, 41, 66, 69, 91, 95, 86, 67])
iv_raw = bytes([85, 93, 207, 149, 93, 88, 242, 141, 84, 91, 142, 143, 54, 72, 199, 153])


secret_key = vvv13(bytearray(key_raw), 23024, package_name, version_name, version_code)
iv = vvv13(bytearray(iv_raw), 945708, package_name, version_name, version_code)


def decrypt_url_txt(encrypted_hex, key, iv):
    encrypted_bytes = bytes.fromhex(encrypted_hex)
    iv_bytes = iv.encode('utf-8')
    ctr = Counter.new(128, initial_value=int.from_bytes(iv_bytes, byteorder='big'))
    cipher = AES.new(key.encode('utf-8'), AES.MODE_CTR, counter=ctr)
    decrypted = cipher.decrypt(encrypted_bytes)
    return decrypted.decode('utf-8', errors='replace')


result = decrypt_url_txt(encrypted_hex, secret_key, iv)
print("[Decrypted C2 URL]:", result)

heh bro

Data is uploaded here. Also, during the first installation, the phone’s information is fully sent to the server, along with some data sent to Firebase. If you’re interested in digging deeper, you can download the sample. It doesn’t have much, but it’s interesting. The Firebase token is also completely leaked. The information is already exposed; the only thing left is to read the rest of the parts during dynamic analysis.

if you want to download sample you can download it from here:

https://www.virustotal.com/gui/file/34aa2aa2b4fb955956ae366887f2efa621b85c91857aa0595a0c5ec079cd3590

heh bro

heh bro

And then it's time for sleep, friends! (good night)

heh bro

oh bro you f*ed up

currently i found the other sms on my fathers phone also but the domain is down and i cant download the malware :(

if someone again send me this shity stuff i gonna find you nigga

so hello to day i want to tell you story how i get the drone and how i hack it i cant tell you the name of company sorry about it but about other part of it we will research on structures and protocols and part of drones i search for vulnerability i have some other vulnerability also but this part of it is best

first is the h256 encoding and decoding vulnerability on it

  if ((((*frame == '\0') && (frame[1] == '\0')) && (frame[2] == '\0')) && (frame[3] == '\x01')) {
    for (i = 4; i < frame_size - 4; i = i + 1) {
      if (((frame[i] == '\0') && (frame[i + 1] == '\0')) &&
         ((frame[i + 2] == '\0' && ((frame[i + 3] == '\x01' && ((frame[i + 5] & 0xf) == 1)))))) {
        return i;
      }
    }
  }

in this part of code as you can see we have to conditions first is for frame parameters and nal unit and the frame size hmmm

as you can see in for loop we have the i is equal to 4 and if the i is smaller than frame size-4 the for loop will be start so we notice this is actually start from 4 bytes back?

but the all part of it is in my control it and we have the out of bounds read

on this structure

  size_t __n;
  companyname_CHAR (*__ptr) [512];
  companyname_U32 _u32FrameSize-local;
  companyname_CHAR *_pu8Frame-local;
  Rtp_H265_Proc *this-local;
  timezone td;
  timeval tv;
  time_t logtimet;
  FILE *pTxtFp;
  tm *ptimetm;
  companyname_U32 i;

as you can see its have the uint 32 for i and we can controll it

after that i search for how the webrtc on drones work and i found on the some reference on internet

the structure of sending and interaction with mobile and also with the controller is like the messengers with parameters like the mime type and etc...

    track header (tkhd) : volume = 0, width = 0, height = 0

    track reference (tref) : reference_type = cdsc, track_IDs[0] = video track ID

    handler reference (hdlr) : handler_type = meta

    null media header nmhd

    sample description (stsd) : type TextMetaDataSampleEntry, mime_format = application/octet-stream;type=<mime_type>, where <mime_type> is:

        com.parrot.videometadata1 for the v1 format

        com.parrot.videometadata2 for the v2 format

        com.parrot.videometadata3 for the v3 format

        com.parrot.videometadataproto for the proto format

The MIME type in the sample description box is enough to describe the metadata format. Further modification to the data format will require an update of the MIME type.

its also the information about the media type

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

so with this structure we have the rtp protocol or Transport Protocol for Real-Time applications

Consequently, the frame metadata are embedded in the RTP stream as packet header extensions with a known 16 bits defined by profile field value.

The defined by profile field is used to recognize the format and version of the data and can have the following values

0x5031, i.e. P1 in ASCII, for the v1 format

0x5032, i.e. P2 in ASCII, for the v2 format

0x5033, i.e. P3 in ASCII, for the v3 format

0x5062, i.e. Pb in ASCII, for the proto format

and also we have this

#define ALTITUDE_MASK       (0xFFFFFF00)  /* Altitude mask */
#define ALTITUDE_SHIFT      (8)           /* Altitude shift */
#define GPS_SV_COUNT_MASK   (0x000000FF)  /* GPS SV count mask */
#define GPS_SV_COUNT_SHIFT  (0)           /* GPS SV count shift */
#define FLYING_STATE_MASK   (0x7F)        /* Flying state mask */
#define FLYING_STATE_SHIFT  (0)           /* Flying state shift */
#define BINNING_MASK        (0x80)        /* Binning mask */
#define BINNING_SHIFT       (7)           /* Binning shift */
#define PILOTING_MODE_MASK  (0x7F)        /* Piloting mode mask */
#define PILOTING_MODE_SHIFT (0)           /* Piloting mode shift */
#define ANIMATION_MASK      (0x80)        /* Animation mask */
#define ANIMATION_SHIFT     (7)           /* Animation shift */

enum flying_state
{
    FLYING_STATE_LANDED = 0,         /* Landed state */
    FLYING_STATE_TAKINGOFF,          /* Taking off state */
    FLYING_STATE_HOVERING,           /* Hovering state */
    FLYING_STATE_FLYING,             /* Flying state */
    FLYING_STATE_LANDING,            /* Landing state */
    FLYING_STATE_EMERGENCY,          /* Emergency state */
    FLYING_STATE_USER_TAKEOFF,       /* User take off state */
    FLYING_STATE_MOTOR_RAMPING,      /* Motor ramping state */
    FLYING_STATE_EMERGENCY_LANDING,  /* Emergency landing state */
};

enum piloting_mode
{
    PILOTING_MODE_MANUAL = 0,      /* Manual piloting by the user */
    PILOTING_MODE_RETURN_HOME,     /* Automatic return home in progress */
    PILOTING_MODE_FLIGHT_PLAN,     /* Automatic flight plan in progress */
    PILOTING_MODE_TRACKING,        /* Automatic tracking in progress */
    PILOTING_MODE_FOLLOW_ME = PILOTING_MODE_TRACKING,
    PILOTING_MODE_MAGIC_CARPET,    /* Automatic "magic carpet" test in progress */
    PILOTING_MODE_MOVE_TO,         /* Automatic "move to" in progress */
};

enum followme_anim
{
    FOLLOW_ME_ANIMATION_NONE = 0,  /* No animation in progress */
    FOLLOW_ME_ANIMATION_ORBIT,     /* Follow-me orbit animation in progress */
    FOLLOW_ME_ANIMATION_BOOMERANG, /* Follow-me boomerang animation in progress */
    FOLLOW_ME_ANIMATION_PARABOLA,  /* Follow-me parabola animation in progress */
    FOLLOW_ME_ANIMATION_ZENITH,    /* Follow-me zenith animation in progress */
};

enum automation_anim
{
    AUTOMATION_ANIMATION_NONE = 0,         /* No animation in progress */
    AUTOMATION_ANIMATION_ORBIT,            /* Orbit animation in progress */
    AUTOMATION_ANIMATION_BOOMERANG,        /* Boomerang animation in progress */
    AUTOMATION_ANIMATION_PARABOLA,         /* Parabola animation in progress */
    AUTOMATION_ANIMATION_DOLLY_SLIDE,      /* Dolly slide animation in progress */
    AUTOMATION_ANIMATION_DOLLY_ZOOM,       /* Dolly zoom animation in progress */
    AUTOMATION_ANIMATION_REVEAL_VERT,      /* Vertical reveal animation in progress */
    AUTOMATION_ANIMATION_REVEAL_HORZ,      /* Horizontal reveal animation in progress */
    AUTOMATION_ANIMATION_PANORAMA_HORZ,    /* Horizontal panorama animation in progress */
    AUTOMATION_ANIMATION_CANDLE,           /* Candle animation in progress */
    AUTOMATION_ANIMATION_FLIP_FRONT,       /* Front filp animation in progress */
    AUTOMATION_ANIMATION_FLIP_BACK,        /* Back flip animation in progress */
    AUTOMATION_ANIMATION_FLIP_LEFT,        /* Left flip animation in progress */
    AUTOMATION_ANIMATION_FLIP_RIGHT,       /* Right flip animation in progress */
    AUTOMATION_ANIMATION_TWISTUP,          /* Twist up animation in progress */
    AUTOMATION_ANIMATION_POSITION_TWISTUP, /* Postion twist up animation in progress */
};

enum thermal_calib_state {
	THERMAL_CALIB_STATE_DONE = 0,
	THERMAL_CALIB_STATE_REQUESTED,
	THERMAL_CALIB_STATE_IN_PROGRESS,
};

struct metadata_v2_base
{
    uint16_t id;                   /* Identifier = 0x5032 */
    uint16_t length;               /* Structure size in 32 bits words excluding the id and length
                                    * fields and including extensions */
    int32_t  ground_distance;      /* Best ground distance estimation (m), Q16.16 */
    int32_t  latitude;             /* Absolute latitude (deg), Q10.22 */
    int32_t  longitude;            /* Absolute longitude (deg), Q10.22 */
    int32_t  altitude_and_sv;      /* Bits 31..8 = altitude AMSL/EGM96 (m) Q16.8, bits 7..0 = GPS SV count */
    int16_t  north_speed;          /* North speed (m/s), Q8.8 */
    int16_t  east_speed;           /* East speed (m/s), Q8.8 */
    int16_t  down_speed;           /* Down speed (m/s), Q8.8 */
    int16_t  air_speed;            /* Speed relative to air (m/s), negative means no data, Q8.8 */
    int16_t  drone_w;              /* Drone quaternion W, Q2.14 */
    int16_t  drone_x;              /* Drone quaternion X, Q2.14 */
    int16_t  drone_y;              /* Drone quaternion Y, Q2.14 */
    int16_t  drone_z;              /* Drone quaternion Z, Q2.14 */
    int16_t  frame_w;              /* Frame view quaternion W, Q2.14 */
    int16_t  frame_x;              /* Frame view quaternion X, Q2.14 */
    int16_t  frame_y;              /* Frame view quaternion Y, Q2.14 */
    int16_t  frame_z;              /* Frame view quaternion Z, Q2.14 */
    int16_t  camera_pan;           /* Camera pan (rad), Q4.12 */
    int16_t  camera_tilt;          /* Camera tilt (rad), Q4.12 */
    uint16_t exposure_time;        /* Frame exposure time (ms), Q8.8 */
    uint16_t gain;                 /* Frame ISO gain */
    uint8_t  state;                /* Bit 7 = binning, bits 6..0 = flyingState */
    uint8_t  mode;                 /* Bit 7 = animation, bits 6..0 = pilotingMode */
    int8_t   wifi_rssi;            /* Wifi RSSI (dBm) */
    uint8_t  battery_percentage;   /* Battery charge percentage */
};

struct metadata_v3_base
{
    uint16_t id;                   /* Identifier = 0x5033 */
    uint16_t length;               /* Structure size in 32 bits words excluding the id and length
                                    * fields and including extensions */
    int32_t  ground_distance;      /* Best ground distance estimation (m), Q16.16 */
    int32_t  latitude;             /* Absolute latitude (deg), Q10.22 */
    int32_t  longitude;            /* Absolute longitude (deg), Q10.22 */
    int32_t  altitude_and_sv;      /* Bits 31..8 = altitude AMSL/EGM96 (m) Q16.8, bits 7..0 = GPS SV count */
    int16_t  north_speed;          /* North speed (m/s), Q8.8 */
    int16_t  east_speed;           /* East speed (m/s), Q8.8 */
    int16_t  down_speed;           /* Down speed (m/s), Q8.8 */
    int16_t  air_speed;            /* Speed relative to air (m/s), negative means no data, Q8.8 */
    int16_t  drone_w;              /* Drone quaternion W, Q2.14 */
    int16_t  drone_x;              /* Drone quaternion X, Q2.14 */
    int16_t  drone_y;              /* Drone quaternion Y, Q2.14 */
    int16_t  drone_z;              /* Drone quaternion Z, Q2.14 */
    int16_t  frame_base_w;         /* Frame base view quaternion W (without pan/tilt), Q2.14 */
    int16_t  frame_base_x;         /* Frame base view quaternion X (without pan/tilt), Q2.14 */
    int16_t  frame_base_y;         /* Frame base view quaternion Y (without pan/tilt), Q2.14 */
    int16_t  frame_base_z;         /* Frame base view quaternion Z (without pan/tilt), Q2.14 */
    int16_t  frame_w;              /* Frame view quaternion W, Q2.14 */
    int16_t  frame_x;              /* Frame view quaternion X, Q2.14 */
    int16_t  frame_y;              /* Frame view quaternion Y, Q2.14 */
    int16_t  frame_z;              /* Frame view quaternion Z, Q2.14 */
    uint16_t exposure_time;        /* Frame exposure time (ms), Q8.8 */
    uint16_t gain;                 /* Frame ISO gain */
    uint16_t awb_r_gain;           /* White balance R/G gain, Q2.14 */
    uint16_t awb_b_gain;           /* White balance B/G gain, Q2.14 */
    uint16_t picture_hfov;         /* Picture horizontal FOV (deg), Q8.8 */
    uint16_t picture_vfov;         /* Picture vertical FOV (deg), Q8.8 */
    uint32_t link_quality;         /* Bits 31..8 = link goodput (kbit/s),
                                    * bits 7..0 = link quality (0-5) */
    int8_t   wifi_rssi;            /* Wifi RSSI (dBm) */
    uint8_t  battery_percentage;   /* Battery charge percentage */
    uint8_t  state;                /* Flying state */
    uint8_t  mode;                 /* Bit 7 = animation, bits 6..0 = pilotingMode */
};

struct metadata_ext
{
    uint16_t ext_id;               /* Extension structure id */
    uint16_t ext_length;           /* Extension structure size in 32 bits words excluding the
                                    * ext_id and ext_size fields */
    [...]                          /* Extension fields */
};

struct metadata_timestamp_ext
{
    uint16_t ext_id;               /* Extension structure id = 0x4531 */
    uint16_t ext_length;           /* Extension structure size in 32 bits words excluding the
                                    * ext_id and ext_size fields */
    uint32_t frame_timestamp_h;    /* Frame timestamp (µs, monotonic), high 32 bits */
    uint32_t frame_timestamp_l;    /* Frame timestamp (µs, monotonic), low 32 bits */
};

struct metadata_followme_ext
{
    uint16_t ext_id;               /* Extension structure id = 0x4532 */
    uint16_t ext_length;           /* Extension structure size in 32 bits words excluding the
                                    * ext_id and ext_size fields */
    int32_t  target_latitude;      /* Target latitude (deg), Q10.22 */
    int32_t  target_longitude;     /* Target longitude (deg), Q10.22 */
    int32_t  target_altitude;      /* Target altitude ASL (m) Q16.16 */
    uint8_t  followme_mode;        /* Follow-me feature bit field
                                    *  - bit 0: follow-me enabled (0 = disabled, 1 = enabled)
                                    *  - bit 1: mode (0 = look-at-me, 1 = follow-me)
                                    *  - bit 2: angle mode (0 = unlocked, 1 = locked)
                                    *  - bit 3-7: reserved for future use */
    uint8_t  followme_animation;   /* Follow-me animation (0 means no animation in progress) */
    uint8_t  reserved1;            /* Reserved for future use */
    uint8_t  reserved2;            /* Reserved for future use */
    uint32_t reserved3;            /* Reserved for future use */
    uint32_t reserved4;            /* Reserved for future use */
};

struct metadata_automation_ext
{
    uint16_t ext_id;                   /* Extension structure id = 0x4533 */
    uint16_t ext_length;               /* Extension structure size in 32 bits words excluding the
                                        * ext_id and ext_size fields */
    int32_t  framing_target_latitude;  /* Framing target latitude (deg), Q10.22 */
    int32_t  framing_target_longitude; /* Framing target longitude (deg), Q10.22 */
    int32_t  framing_target_altitude;  /* Framing target altitude ASL (m) Q16.16 */
    int32_t  flight_destination_latitude;   /* Flight destination latitude (deg), Q10.22 */
    int32_t  flight_destination_longitude;  /* Flight destination longitude (deg), Q10.22 */
    int32_t  flight_destination_altitude;   /* Flight destination altitude ASL (m) Q16.16 */
    uint8_t  automation_animation;     /* Automation animation (0 means no animation in progress) */
    uint8_t  automation_flags;         /* Automation features bit field
                                        *  - bit 0: follow-me enabled (0 = disabled, 1 = enabled)
                                        *  - bit 1: look-at-me enabled (0 = disabled, 1 = enabled)
                                        *  - bit 2: angle locked (0 = unlocked, 1 = locked)
                                        *  - bit 3-7: reserved for future use */
    uint16_t reserved;                 /* Reserved for future use */
};

struct metadata_thermal_ext
{
    uint16_t ext_id;               /* Extension structure id = 0x4534 */
    uint16_t ext_length;           /* Extension structure size in 32 bits words excluding the
                                    * ext_id and ext_size fields */
    int16_t  min_x;                /* Minimum temperature spot x-coordinate (relative to frame width), Q11.5 */
    int16_t  min_y;                /* Minimum temperature spot y-coordinate (relative to frame height), Q11.5 */
    int16_t  min_temp;             /* Minimum temperature spot temperature value (K) Q11.5 */
    int16_t  max_x;                /* Maximum temperature spot x-coordinate (relative to frame width), Q11.5 */
    int16_t  max_y;                /* Maximum temperature spot y-coordinate (relative to frame height), Q11.5 */
    int16_t  max_temp;             /* Maximum temperature spot temperature value (K) Q11.5 */
    int16_t  probe_x;              /* Probe temperature x-coordinate (relative to frame width), Q11.5 */
    int16_t  probe_y;              /* Probe temperature y-coordinate (relative to frame height), Q11.5 */
    int16_t  probe_temp;           /* Probe temperature temperature value (K) Q11.5 */
    uint8_t  calib_state;          /* Calibration state */
    uint8_t  flags;                /* Validity flags
                                    *  - bit 0: minimum temperature spot (0 = invalid, 1 = valid)
                                    *  - bit 1: maximum temperature spot (0 = invalid, 1 = valid)
                                    *  - bit 2: probe temperature (0 = invalid, 1 = valid)
                                    *  - bit 3-7: reserved for future use */
};

so after that we have the everything we need to know about it.....

so to exploit it we have some steps: 1. we need vulnerability from the controller or the protocols like the wifi or other protocols its being used..

  1. exploit the controller or drone its self with other protocols like http and ntp and like RTP ...

NOTE: we can use the cellular network exploits also :)

By checking the news, we reach a specific structure In the first step, let's start by examining the exploded models * solar panels * walkie talkie's ic-v82 * pager's ar-924 * iphone's iphone 14 pro * Attendance device's unknown... idk bro

so what kind of attack we have? Considering the various types of devices that have been exploding, it is really difficult to put a bomb in all of them, but what really happened?

In the first scenario, we examine what has been published and the general scenario

The first step is the presence of counterfeit devices

Mossad, in cooperation with Vidisco, has controlled all incoming packages to Lebanon by installing a backdoor in the transmitters of this device. This device is a 3D xray

https://www.youtube.com/watch?v=AXeZnKsByMg

About 84 percent of ports and airports use this device

After controlling them and controlling the importers, they tried to import fake devices

Explosives were placed in lithium-ion type batteries in pagers by adding another printed circuit board under the main board in this way, the explosives have been used without changing the weight.

That is, in pagers, one of the batteries contains explosives and the other one is healthy and supplies the device with electricity

All this is possible with the presence of Bekdur and the combination of these with electronic warfare

By controlling different values, it is possible to explode through several scenarios in several types of devices

They have used this type of backdoor for the explosion. Backdoor has set the condition that by sending a special message, it will explode in a chain, that is, the message will be spread to each person and it will form a wide network of multiple explosions.

In walkie talkies, but the scenarios are simpler, all the items are ready to make a dynamite, considering its high weight, there is no need to worry about it anymore.

The attack is likely to be carried out blindly in the pager, and the target is the most killed, but in the walkie talkie, only specific targets have been blown up using drones.

This work has been done over a long period of time and carefully planned

But the other case is the possibility of electromagnetic signal injection attacks due to different types of devices All situations must be considered

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

This vulnerability can be exploited by an attacker through an infected mp3 and has the potential to implement different scenarios in the mp3 structure through the clubhouse android app like rce

the vulnerable lib –> libmpg123 https://github.com/gypified/libmpg123/

the attacker send the mp3 –> client play –> attacker got rce

https://de.wikipedia.org/wiki/MP3
https://id3.org/id3v2.4.0-structure

structure of mono and stereo conditions

                  mpeg 1                   mpeg 2/2.5
stereo   32                              17
 mono    17                               9
lame_offset = (fr->stereo == 2) ? (fr->lsf ? 17 : 32 ) : (fr->lsf ? 9 : 17);

The stereo and lsf values ​​in this code can be controlled through mp3 and also the flags are read from the file according to this structure.

// input frames
    off_t track_frames;
    off_t track_samples;
    double mean_framesize;
    off_t mean_frames;
    int fsizeold;
    int ssize;
    unsigned int bitreservoir;
    unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
    unsigned char *bsbuf;
    unsigned char *bsbufold;
    int bsnum;

to handle by these function code the xing header must be 120 byte

if(fr->framesize >= 120+lame_offset)

After that here as you can see fr->bsbuf[i] all of them can be controlled by the attacker without any restrictions and they will check and search it. attacker can control the bsbuf and can control it to where it point on frame so the array controllable by attacker

idk why its marked as informative? :/

for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) break;
            (
                       (fr->bsbuf[lame_offset] == 'I')
                && (fr->bsbuf[lame_offset+1] == 'n')
                && (fr->bsbuf[lame_offset+2] == 'f')
                && (fr->bsbuf[lame_offset+3] == 'o')
            )

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 ble login 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