1<!doctype html> 2<!-- 3 Minimal Mistakes Jekyll Theme 4.19.2 by Michael Rose 4 Copyright 2013-2019 Michael Rose - mademistakes.com | @mmistakes 5 Free for personal and commercial use under the MIT license 6 https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE 7--> 8<html lang="en" class="no-js"> 9 <head> 10 <meta charset="utf-8"> 11 12<!-- begin _includes/seo.html --><title>Auto-color - Linux backdoor - ZW01f</title> 13<meta name="description" content="A deep dive into the stealthy Linux âAuto-colorâ Backdoor "> 14 15 16 <meta name="author" content="Mohamed Ezzat"> 17 18 19<meta property="og:type" content="article"> 20<meta property="og:locale" content="en_US"> 21<meta property="og:site_name" content="ZW01f"> 22<meta property="og:title" content="Auto-color - Linux backdoor"> 23<meta property="og:url" content="https://zw01f.github.io/malware%20analysis/auto-color/"> 24 25 26 <meta property="og:description" content="A deep dive into the stealthy Linux âAuto-colorâ Backdoor "> 27 28 29 30 <meta property="og:image" content="https://zw01f.github.io/assets/images/malware-analysis/auto_color/thumbnail.png"> 31 32 33 34 35 36 <meta property="article:published_time" content="2025-03-28T00:00:00+00:00"> 37 38 39 40 41 42 43 44 45 46 47<link rel="canonical" href="https://zw01f.github.io/malware%20analysis/auto-color/"> 48 49 50 51
52<script type="application/ld+json"> 53 { 54 "@context": "https://schema.org", 55 56 "@type": "Person", 57 "name": "Mohamed Ezzat", 58 "url": "https://zw01f.github.io/" 59 60 } 61</script>
61 62 63 64 <meta name="google-site-verification" content="J3MnMF94zaZhTUoNtUiRt9cKsr7hiMyTxEdAvQ3GfmY" /> 65 66 67 68 69 70<!-- end _includes/seo.html --> 71 72 73<link href="/feed.xml" type="application/atom+xml" rel="alternate" title="ZW01f Feed"> 74 75<!-- https://t.co/dKP3o1e --> 76<meta name="viewport" content="width=device-width, initial-scale=1.0"> 77
78<script> 79 document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/g, '') + ' js '; 80</script>
80 81 82<!-- For all browsers --> 83<link rel="stylesheet" href="/assets/css/main.css"> 84 85<!--[if IE]> 86 <style> 87 /* old IE unsupported flexbox fixes */ 88 .greedy-nav .site-title { 89 padding-right: 3em; 90 } 91 .greedy-nav button { 92 position: absolute; 93 top: 0; 94 right: 0; 95 height: 100%; 96 } 97 </style> 98<![endif]--> 99 100 101 102 <!-- start custom head snippets --> 103 104<!-- insert favicons. use https://realfavicongenerator.net/ --> 105 106<!-- end custom head snippets --> 107 108<!-- favicon --> 109<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/site_data/favicon-32x32.png"> 110<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/site_data/favicon-16x16.png"> 111<meta name="theme-color" content="#ffffff"> 112 113 </head> 114 115 <body class="layout--single wide"> 116 <nav class="skip-links"> 117 <h2 class="screen-reader-text">Skip links</h2> 118 <ul> 119 <li><a href="#site-nav" class="screen-reader-shortcut">Skip to primary navigation</a></li> 120 <li><a href="#main" class="screen-reader-shortcut">Skip to content</a></li> 121 <li><a href="#footer" class="screen-reader-shortcut">Skip to footer</a></li> 122 </ul> 123</nav> 124 125 <!--[if lt IE 9]> 126<div class="notice--danger align-center" style="margin: 0;">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience.</div> 127<![endif]--> 128 129 130 131<div class="masthead"> 132 <div class="masthead__inner-wrap"> 133 <div class="masthead__menu"> 134 <nav id="site-nav" class="greedy-nav"> 135 136 <a class="site-logo" href="/"><img src="/assets/images/site_data/logo.png" alt=""></a> 137 138 <a class="site-title" href="/"> 139 ZW01f 140 141 </a> 142 <ul class="visible-links"><li class="masthead__menu-item"> 143 <a href="/categories/#malware-analysis">Malware Analysis</a> 144 </li><li class="masthead__menu-item"> 145 <a href="/categories/#ctf-writeups">CTF Writeups</a> 146 </li><li class="masthead__menu-item"> 147 <a href="/categories">All Categories</a> 148 </li></ul> 149 150 <button class="search__toggle" type="button"> 151 <span class="visually-hidden">Toggle search</span> 152 <svg class="icon" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.99 16"> 153 <path d="M15.5,13.12L13.19,10.8a1.69,1.69,0,0,0-1.28-.55l-0.06-.06A6.5,6.5,0,0,0,5.77,0,6.5,6.5,0,0,0,2.46,11.59a6.47,6.47,0,0,0,7.74.26l0.05,0.05a1.65,1.65,0,0,0,.5,1.24l2.38,2.38A1.68,1.68,0,0,0,15.5,13.12ZM6.4,2A4.41,4.41,0,1,1,2,6.4,4.43,4.43,0,0,1,6.4,2Z" transform="translate(-.01)"></path> 154 </svg> 155 </button> 156 157 <button class="greedy-nav__toggle hidden" type="button"> 158 <span class="visually-hidden">Toggle menu</span> 159 <div class="navicon"></div> 160 </button> 161 <ul class="hidden-links hidden"></ul> 162 </nav> 163 </div> 164 </div> 165</div> 166 167 168 <div class="initial-content"> 169 170 171 172 173<div id="main" role="main"> 174 175 <div class="sidebar sticky"> 176 177 178 179<div itemscope itemtype="https://schema.org/Person"> 180 181 182 <div class="author__avatar"> 183 184 <img src="/assets/images/site_data/avatar.jpg" alt="Mohamed Ezzat" itemprop="image"> 185 186 </div> 187 188 189 <div class="author__content"> 190 191 <h3 class="author__name" itemprop="name">Mohamed Ezzat</h3> 192 193 194 <div class="author__bio" itemprop="description"> 195 <p>Malware Analysis and RE</p> 196 197 </div> 198 199 </div> 200 201 <div class="author__urls-wrapper"> 202 <button class="btn btn--inverse">Follow</button> 203 <ul class="author__urls social-icons"> 204 205 206 207 208 209 <li><a href="mailto:[email protected]" rel="nofollow noopener noreferrer"><i class="fas fa-fw fa-envelope-square" aria-hidden="true"></i><span class="label">Email</span></a></li> 210 211 212 213 214 215 <li><a href="https://twitter.com/ZW01f" rel="nofollow noopener noreferrer"><i class="fab fa-fw fa-twitter-square" aria-hidden="true"></i><span class="label">Twitter</span></a></li> 216 217 218 219 220 221 <li><a href="https://www.linkedin.com/in/zw01f/" rel="nofollow noopener noreferrer"><i class="fab fa-fw fa-linkedin" aria-hidden="true"></i><span class="label">LinkedIn</span></a></li> 222 223 224 225 <li><a href="https://github.com/ZW01f" rel="nofollow noopener noreferrer"><i class="fab fa-fw fa-github" aria-hidden="true"></i><span class="label">GitHub</span></a></li> 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 <!-- 281 <li> 282 <a href="http://link-to-whatever-social-network.com/user/" itemprop="sameAs" rel="nofollow noopener noreferrer"> 283 <i class="fas fa-fw" aria-hidden="true"></i> Custom Social Profile Link 284 </a> 285 </li> 286--> 287 </ul> 288 </div> 289</div> 290 291 292 </div> 293 294 295 296 <article class="page" itemscope itemtype="https://schema.org/CreativeWork"> 297 <meta itemprop="headline" content="Auto-color - Linux backdoor"> 298 <meta itemprop="description" content="Meet Auto-color"> 299 <meta itemprop="datePublished" content="2025-03-28T00:00:00+00:00"> 300 301 302 <div class="page__inner-wrap"> 303 304 <header> 305 <h1 id="page-title" class="page__title" itemprop="headline">Auto-color - Linux backdoor 306</h1> 307 308 <p class="page__meta"><i class="far fa-clock" aria-hidden="true"></i> 309 310 311 312 313 17 minute read 314 315</p> 316 317 </header> 318 319 320 <section class="page__content" itemprop="text"> 321 322 <aside class="sidebar__right "> 323 <nav class="toc"> 324 <header><h4 class="nav__title"><i class="fas fa-file-alt"></i> On this page</h4></header> 325 <ul class="toc__menu"> 326 <li><a href="#meet-auto-color">Meet Auto-color</a></li> 327 <li><a href="#technical-in-points">Technical in Points</a></li> 328 <li><a href="#first-look">First look</a></li> 329 <li><a href="#string-decryption">String Decryption</a></li> 330 <li><a href="#malware-installation">Malware Installation</a></li> 331 <li><a href="#running-in-the-background---demonstration">
331Running in the Background - Demonstration</a></li> 332 <li><a href="#auto-color-s-c2-functionality">Auto-color âs C2 Functionality</a> 333 <ul> 334 <li><a href="#config-extraction">Config extraction</a></li> 335 <li><a href="#connecting-to-c2-server">Connecting to C2 Server</a></li> 336 <li><a href="#executing-c2-commands">Executing C2 Commands</a></li> 337 </ul> 338 </li> 339 <li><a href="#analysis-of-libcextso2">Analysis of libcext.so.2</a> 340 <ul> 341 <li><a href="#protecting-etcldpreload">Protecting /etc/ld.preload</a></li> 342 <li><a href="#persistance">Persistance</a></li> 343 <li><a href="#hiding-network-activity">Hiding Network Activity</a></li> 344 </ul> 345 </li> 346 <li><a href="#yara-rule">YARA Rule</a></li> 347 <li><a href="#python-automated-configuration-extraction">Python Automated Configuration Extraction</a></li> 348 <li><a href="#references">References</a></li> 349</ul> 350 351 </nav> 352 </aside> 353 354 <h1 id="meet-auto-color">Meet Auto-color</h1> 355 356<p>Auto-color is a Linux backdoor that has been seen in cyberattacks targeting government organizations and universities in North America and Asia. It was first observed between November and December 2024 and is designed to avoid detection while remaining hidden in systems for a long time. The malware acts as be benign color-enhancement tool and uses common file names like âdoor,â âegg,â and âlogâ to disguise itself.</p> 357 358<p>Auto-color gets its name from the file name that the initial payload uses to rename itself after it is installed.</p> 359 360<h1 id="technical-in-points">Technical in Points</h1> 361<ul> 362 <li> 363 <p>Auto-Color encrypts its strings to prevent easy extraction of its functionality. Additionally, it dynamically resolves APIs at runtime, loading libc and retrieving function addresses with dlsym. This makes static detection harder by avoiding direct system calls.</p> 364 </li> 365 <li> 366 <p>Auto-Color uses multiple evasion techniques to avoid detection. It hides itself with a benign name merged with system files and operates as a background process without user interaction. If executed with root privileges, more advanced tactics are used. Dropping a shared library that hooks libc functions to hide network connections, stop uninstallation, and ensure its activities remain undetected.</p> 367 </li> 368 <li> 369 <p>Auto-Colorâs data section contains an embedded custom encrypted configuration, including information about its Command-and-Control (C2) server. It then sets a communication channel with the C2 server using a TCP socket and validates the exchange via a random value handshake.</p> 370 </li> 371 <li> 372 <p>Auto-Color receives remote commands to execute on the infected machine, including gathering system and host information, reading, writing, deleting, and modifying files, creating a reverse shell backdoor, configuring the device as a proxy, and self-destructing to erase all traces of its presence. This gives the attacker full control over the compromised system.</p> 373 </li> 374</ul> 375 376<h1 id="first-look">First look</h1> 377 378<p align="center"> 379 <a href="/assets/images/malware-analysis/auto_color/VT.png"> 380 <img src="/assets/images/malware-analysis/auto_color/VT.png" alt="API Response Process" /> 381 </a> 382</p> 383<center><font size="3"><u>Figure</u>(1): <u>Sample on VT</u></font> </center> 384<p><br /></p> 385 386<p>The sample is <strong>a C/C++ ELF64 binary compiled for Ubuntu Linux</strong>. On the writing date, only 15 security vendors flagged it as malicious.</p> 387 388<p>Auto-color seems to require explicit execution by the victim and follows two main paths based on root privileges.</p> 389 390<p align="center"> 391 <a href="/assets/images/malware-analysis/auto_color/flow.png"> 392 <img src="/assets/images/malware-analysis/auto_color/flow.png" alt="API Response Process" /> 393 </a> 394</p> 395<center><font size="3"><u>Figure</u>(2): <u>Main function</u></font> </center> 396<p><br /></p> 397 398<p>If running as root, it checks its execution path against the target path <code class="language-plaintext highlighter-rouge">/var/log/cross/auto-color</code> to determine if it has already been installed and executed before. If not, it tries to install itself and prints âinstall okâ if successful.</p> 399 400<p>If it is not running as root or the path check fails, it follows another path called âgreen mode.â</p> 401 402<p>Regardless of the path taken, Auto-color daemonizes itself to run in the background before connecting to a command-and-control (C2) server for further instructions.
402</p> 403 404<h1 id="string-decryption">String Decryption</h1> 405<p>Auto-color obfuscated its strings using an XOR operation and additional arithmetic transformations to make analysis more difficult.</p> 406 407<p align="center"> 408 <a href="/assets/images/malware-analysis/auto_color/str_dec.png"> 409 <img src="/assets/images/malware-analysis/auto_color/str_dec.png" alt="API Response Process" /> 410 </a> 411</p> 412<center><font size="3"><u>Figure</u>(3): <u>Sring decryption function </u></font> </center> 413<p><br /></p> 414 415<p>The decryption function always follows the same instruction sequence:</p> 416 417<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">lea</span> <span class="n">rsi</span><span class="p">,</span> <span class="n">enc_str_ptr</span> 418<span class="n">mov</span> <span class="n">rdi</span><span class="p">,</span> <span class="n">rax</span> 419<span class="n">call</span> <span class="n">mw_string_decryption</span> 420</code></pre></div></div> 421<p>We can use this pattern to write an IDAPython script that automatically finds and decrypts obfuscated strings, making analysis easier.</p> 422 423<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">idautils</span> 424<span class="kn">import</span> <span class="nn">idc</span> 425<span class="kn">import</span> <span class="nn">idaapi</span> 426 427<span class="k">def</span> <span class="nf">decrypt_string</span><span class="p">(</span><span class="n">enc_data</span><span class="p">):</span> 428 <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span> 429 <span class="k">for</span> <span class="n">byte</span> <span class="ow">in</span> <span class="n">enc_data</span><span class="p">:</span> 430 <span class="n">dec_byte</span> <span class="o">=</span> <span class="p">((</span><span class="nb">int</span><span class="p">(</span><span class="n">byte</span><span class="p">)</span> <span class="o">+</span> <span class="mi">123</span><span class="p">)</span> <span class="o">^</span> <span class="mh">0x1F</span><span class="p">)</span> <span class="o">-</span> <span class="mi">123</span> <span class="o">&</span> <span class="mh">0xFF</span> 431 432 <span class="k">if</span> <span class="n">dec_byte</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> 433 <span class="k">break</span> 434 <span class="n">res</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">dec_byte</span><span class="p">)</span> 435 <span class="k">return</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">res</span><span class="p">).</span><span class="n">
435decode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s">'replace'</span><span class="p">)</span> 436 437 438<span class="k">def</span> <span class="nf">read_enc_data</span><span class="p">(</span><span class="n">ptr</span><span class="p">):</span> 439 <span class="c1"># read memory until a null byte 440</span> <span class="n">address</span> <span class="o">=</span> <span class="n">idc</span><span class="p">.</span><span class="n">get_name_ea_simple</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> 441 <span class="k">if</span> <span class="n">address</span> <span class="o">==</span> <span class="n">idc</span><span class="p">.</span><span class="n">BADADDR</span><span class="p">:</span> 442 <span class="k">return</span> <span class="bp">None</span> 443 444 <span class="n">data</span> <span class="o">=</span> <span class="p">[]</span> 445 <span class="k">while</span> <span class="p">(</span><span class="n">byte</span> <span class="p">:</span><span class="o">=</span> <span class="n">ida_bytes</span><span class="p">.</span><span class="n">get_byte</span><span class="p">(</span><span class="n">address</span><span class="p">))</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> 446 <span class="n">data</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">byte</span><span class="p">)</span> 447 <span class="n">address</span> <span class="o">+=</span> <span class="mi">1</span> 448 449 <span class="k">return</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> 450 451<span class="k">def</span> <span class="nf">find_decryption_function_xrefs</span><span class="p">():</span> 452 <span class="c1"># (i + a2) + 123) ^ 0x1F) - 123 453</span> <span class="n">pattern</span> <span class="o">=</span> <span class="s">"0F B6 00 83 C0 7B 83 F0 1F 83 E8 7B 89 C2 8B 85 ?? ?? ?? ??"</span> 454 <span class="n">ea</span> <span class="o">=</span> <span class="n">idaapi</span><span class="p">.</span><span class="n">find_binary</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">idc</span><span class="p">.</span><span class="n">BADADDR</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="n">idc</span><span class="p">.</span><span class="n">SEARCH_DOWN</span><span class="p">)</span> 455 <span class="k">if</span> <span class="n">ea</span> <span class="o">==</span> <span class="n">idc</span><span class="p">.</span><span class="n">BADADDR</span><span class="p">:</span> 456 <span class="k">return</span> <span class="p">[]</span> 457 458 <span class="n">func_ea</span> <span class="o">=</span> <span class="n">idc</span><span class="p">.</span><span class="n">get_func_attr</span><span class="p">(</span><span class="n">ea</span><span class="p">,</span> <span class="n">idc</span><span class="p">.</span><span class="n">FUNCATTR_START</span><span class="p">)</span> 459 <span class="k">if</span> <span class="n">func_ea</span> <span class="o">==</span> <span class="n">idc</span><span class="p">.</span><span class="n">BADADDR</span><span class="p">:</span> 460 <span class="k">return</span> <span class="p">[]</span> 461 462 <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">idautils</span><span class="p">.</span><span class="n">CodeRefsTo</span><span class="p">(</span><span class="n">func_ea</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> 463 464<span class="k">def</span> <span class="nf">set_hexrays_comment</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span> 465 <span class="n">cfunc</span> <span class="o">=</span> <span class="n">idaapi</span><span class="p">.</span><span class="n">decompile</span><span class="p">(</span><span class="n">address</span><span class="p">)</span> 466 <span class="n">tl</span> <span class="o">=</span> <span class="n">idaapi</span><span class="p">.</span><span class="n">treeloc_t</span><span class="p">()</span> 467 <span class="n">tl</span><span class="p">.</span><span class="n">ea</span> <span class="o">=</span> <span class="n">address</span> 468 <span class="n">tl</span><span class="p">.</span><span class="n">itp</span> <span class="o">=</span> <span class="n">idaapi</span><span class="p">.</span><span class="n">ITP_SEMI</span> 469 <span class="n">cfunc</span><span class="p">.</span><span class="n">set_user_cmt</span><span class="p">(</span><span class="n">tl</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span> 470 <span class="n">cfunc</span><span class="p">.</span><span class="n">save_user_cmts</span><span class="p">()</span> 471 472<span class="k">def</span> <span class="nf">main</span><span class="p">():</span> 473 <span class="n">xrefs</span> <span class="o">=</span> <span class="n">find_decryption_function_xrefs</span><span class="p">()</span> 474 475 <span class="k">for</span> <span class="n">ref</span> <span class="ow">in</span> <span class="n">xrefs</span><span class="p">:</span>
476 <span class="n">prev_ins_addr</span> <span class="o">=</span> <span class="n">idc</span><span class="p">.</span><span class="n">prev_head</span><span class="p">(</span><span class="n">ref</span><span class="p">)</span> 477 <span class="n">prev_ins_addr</span> <span class="o">=</span> <span class="n">idc</span><span class="p">.</span><span class="n">prev_head</span><span class="p">(</span><span class="n">prev_ins_addr</span><span class="p">)</span> <span class="c1"># go up twice 478</span> 479 <span class="k">if</span> <span class="p">(</span><span class="n">idc</span><span class="p">.</span><span class="n">print_insn_mnem</span><span class="p">(</span><span class="n">prev_ins_addr</span><span class="p">)</span> <span class="o">==</span> <span class="s">'lea'</span> <span class="ow">and</span> 480 <span class="n">idc</span><span class="p">.</span><span class="n">print_operand</span><span class="p">(</span><span class="n">prev_ins_addr</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="s">'rsi'</span><span class="p">):</span> 481 <span class="n">ind</span> <span class="o">=</span> <span class="n">idc</span><span class="p">.</span><span class="n">print_operand</span><span class="p">(</span><span class="n">prev_ins_addr</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> 482 <span class="n">enc_data</span> <span class="o">=</span> <span class="n">read_enc_data</span><span class="p">(</span><span class="n">ind</span><span class="p">)</span> 483 <span class="n">dec_str</span> <span class="o">=</span> <span class="n">decrypt_string</span><span class="p">(</span><span class="n">enc_data</span><span class="p">)</span> 484 <span class="n">idc</span><span class="p">.</span><span class="n">set_cmt</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="sa">f</span><span class="s">"String : </span><span class="si">{</span><span class="n">dec_str</span><span class="si">}</span><span class="s">"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> 485 <span class="n">set_hexrays_comment</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span><span class="sa">f</span><span class="s">"String: </span><span class="si">{</span><span class="n">dec_str</span><span class="si">}</span><span class="s">"</span><span class="p">)</span> 486 487<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> 488 <span class="n">main</span><span class="p">()</span> 489</code></pre></div></div> 490<p>This script finds the decryption function by searching for its instruction pattern, determines all cross-references to the function and locates the <code class="language-plaintext highlighter-rouge">lea</code> instruction that loads the encrypted string. It then reads the bytes, decrypts them, and finally adds comments in both the disassembly and decompiled views.</p> 491 492<p><strong>
492full strings list</strong></p> 493<details style="color: #EEFFFF; font-family: monospace !default; font-size: 0.85em; background: #263238; border: 1px solid #263238; border-radius: 3px; padding: 10px; line-height: 1.8"> 494 <summary style="outline: none; cursor: pointer"> 495 <span style="color: darkgray"> 496 Expand to see more 497 </span><br /> 498   config-err-<br /> 499   %d<br /> 500   %x<br /> 501   /var/log/cross<br /> 502 </summary> 503   config-err-<br /> 504  config-err-<br /> 505  /libcext.so.2<br /> 506  auto-color<br /> 507  /etc/ld.so.preload<br /> 508  /etc/ld.so.preload.bak<br /> 509  auto-color<br /> 510  /etc/ld.so.preload<br /> 511  /etc/ld.so.preload.bak<br /> 512  /bin/bash<br /> 513  -i<br /> 514  HISTFILE=/dev/null<br /> 515  TERM=<br /> 516  /bin/bash<br /> 517  /usr/bin/curl<br /> 518  curl  -k  --connect-timeout  10  %s<br /> 519  /usr/bin/wget<br /> 520  wget  --no-check-certificate  -T30  -t1  -q  -O  -  %s<br /> 521  TCP://<br /> 522  URL://<br /> 523  URL://<br /> 524  TCP<br /> 525  %4.4d-%2.2d-%2.2d  %2.2d:%2.2d:%2.2d<br /> 526  cat  /etc/redhat-release<br /> 527  cat  /etc/os-release  |  grep  "PRETTY_NAME"  |  awk  -F\"  '{print  $2}'<br /> 528  cat  /proc/cpuinfo  |  grep  "model  name"  |  awk  -F:  '{print  $2}'<br /> 529  cat  /proc/meminfo  |  grep  "MemTotal"  |  awk  -F:  '{print  $2}'<br /> 530  /proc/self/exe<br /> 531  HTTP<br /> 532  HTTPS <br /> 533</details> 534 535<p><br /></p> 536 537<h1 id="malware-installation">Malware Installation</h1> 538 539<p>Auto-color first creates a directory <code class="language-plaintext highlighter-rouge">/var/log/cross</code> to mix in with system logs and avoid suspicion. It sets <strong>777 permissions</strong>, allowing it to read, write, or execute files inside. Then, it copies itself into this folder and renames its file to âauto-colorâ to appear benign.</p> 540 541<p>It also drops a malicious shared library named <code class="language-plaintext highlighter-rouge">libcext.so.2</code> into the systemâs library path. This library mimics the legitimate <code class="language-plaintext highlighter-rouge">libcext.so.0</code> to avoid suspicion. Auto-color dynamically resolves the systemâs standard library directory using the <code class="language-plaintext highlighter-rouge">dladdr()</code> function with the <code class="language-plaintext highlighter-rouge">strerror()</code> symbol. If successful, it extracts the directory path from <strong>info.dli_fname</strong>, removes the filename, and constructs the final path. If <code class="language-plaintext highlighter-rouge">dladdr()</code> fails, it defaults to <code class="language-plaintext highlighter-rouge">/lib</code> as the base directory, to Make sure it works on various Linux versions.</p> 542 543<p>It finally modifies the <strong><code class="language-plaintext highlighter-rouge">/etc/ld.preload</code></strong> , a Linux file that forces specified libraries to load into every process . By adding <code class="language-plaintext highlighter-rouge">libcext.so.2</code> to this file, <strong>it ensures its library is loaded even before legitimate system libraries</strong>. This enables it to hook and override critical functions , which I will explain later in the blog.</p> 544 545<p align="center"> 546 <a href="/assets/images/malware-analysis/auto_color/installation.png"> 547 <img src="/assets/images/malware-analysis/auto_color/installation.png" alt="API Response Process" /> 548 </a> 549</p> 550<center><font size="3"><u>Figure</u>(4): <u>Malware Installation function </u></font> </center> 551<p><br /> 552It also unlinks (deletes) any previous executable and malicious shared library to remove traces of old installations. This avoids conflicts and ensures a clean setup.</p> 553 554<h1 id="running-in-the-background---demonstration">
554Running in the Background - Demonstration</h1> 555 556<p>Auto-color ensures that only one instance runs by using a file-based locking mechanism. It creates a lock file in <code class="language-plaintext highlighter-rouge">/tmp</code> based on the userâs ID, opens it, and tries to lock it using <code class="language-plaintext highlighter-rouge">flock()</code> . If another instance has already locked the file, it exits to prevent multiple copies from running.</p> 557 558<p align="center"> 559 <a href="/assets/images/malware-analysis/auto_color/lock_file.png"> 560 <img src="/assets/images/malware-analysis/auto_color/lock_file.png" alt="API Response Process" /> 561 </a> 562</p> 563<center><font size="3"><u>Figure</u>(5): <u>file-based locking mechanism used </u></font> </center> 564<p><br /></p> 565 566<p>Auto-color then daemonizes itself, following a famous technique to run in the background without a controlling terminal. It first creates a child process and exits the parent, then calls <code class="language-plaintext highlighter-rouge">setsid()</code> to start a new session and fully separate from the terminal. A second <strong>fork</strong> is used to stop the process from accidentally retrieving a terminal connection.</p> 567 568<p align="center"> 569 <a href="/assets/images/malware-analysis/auto_color/fork.png"> 570 <img src="/assets/images/malware-analysis/auto_color/fork.png" alt="API Response Process" /> 571 </a> 572</p> 573<center><font size="3"><u>Figure</u>(6): <u>Demonstration function</u></font> </center> 574<p><br /></p> 575 576<p>To complete the process, Auto-color shifts input, output, and error to <code class="language-plaintext highlighter-rouge">/dev/null</code> to control unwanted interactions. It also closes all open file descriptors, removes file permission restrictions with <code class="language-plaintext highlighter-rouge">umask(0)</code>, and changes its working directory to <code class="language-plaintext highlighter-rouge">/</code> to avoid issues with folders.</p> 577 578<p>These steps ensure the malware runs smoothly in the background, making it harder to detect and stop.</p> 579 580<h1 id="auto-color-s-c2-functionality">Auto-color âs C2 Functionality</h1> 581 582<p>Before connecting to its C2 servers, Auto-color first extracts the C2 address from an encrypted configuration.</p> 583 584<h2 id="config-extraction">Config extraction</h2> 585 586<p>Auto-color contains an embedded custom encrypted configuration within its .data section.</p> 587 588<p align="center"> 589 <a href="/assets/images/malware-analysis/auto_color/enc_config.png"> 590 <img src="/assets/images/malware-analysis/auto_color/enc_config.png" alt="API Response Process" /> 591 </a> 592</p> 593<center><font size="3"><u>Figure</u>(7): <u>Encrypted config .</u></font> </center> 594<p><br /></p> 595 596<p>This decryption algorithm uses a key-based transformation, where the key is extracted from the last four bytes of the encrypted data. The key is dynamically updated at each step using a mathematical formula. Each byte of the data is modified through bit shifts, subtraction, and XOR operations.</p> 597 598<p align="center"> 599 <a href="/assets/images/malware-analysis/auto_color/config_decryption.png"> 600 <img src="/assets/images/malware-analysis/auto_color/config_decryption.png" alt="API Response Process" /> 601 </a> 602</p> 603<center><font size="3"><u>Figure</u>(8): <u>Custom decryption algorithm used .</u></font> </center> 604<p><br /></p> 605 606<p>Here is the Python version of the decryption function:</p> 607 608<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">decryption_algo</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">enc_data</span><span class="p">):</span> 609 <span class="n">dec_data</span> <span class="o">=</span> <span class="nb">bytearray</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">enc_data</span><span class="p">))</span> 610 611 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">dec_data</span><span class="p">)):</span>
612 <span class="n">key</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1023</span> <span class="o">*</span> <span class="n">key</span> <span class="o">-</span> <span class="mh">0x70E52827</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0xFFFFFFFF</span> 613 <span class="n">dec_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">((</span><span class="n">enc_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">-</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">19</span><span class="p">))</span> <span class="o">^</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">11</span><span class="p">))</span> <span class="o">-</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">3</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0xFF</span> 614 615 <span class="k">return</span> <span class="n">dec_data</span> 616 617<span class="n">hex_input</span> <span class="o">=</span> <span class="s">"5B742B73F5A211A1FB87436A463AE1BBF27BB3D9EA6CD9A725AC2B059FFFE9E18902FBBE25D201379347FB775B08E97E861C4423088ACDA973AEEBA1C87F2C4B66346BD3D56351E1DB47839B35774DED13F2E2ED28223C05707A7E6BD33B3057C0174C7AE6BEF24A566E7847684B6DF2D3CC5E65066A"</span> 618 619<span class="n">data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">hex_input</span><span class="p">)</span> 620<span class="n">key</span> <span class="o">=</span> <span class="nb">int</span><span class="p">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="o">-</span><span class="mi">4</span><span class="p">:],</span> <span class="s">"big"</span><span class="p">)</span> 621<span class="n">output</span> <span class="o">=</span> <span class="n">encryption_algo</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> 622 623</code></pre></div></div> 624 625<p>Auto-color will store the encrypted configuration in a file for later use. If running as root, it uses <code class="language-plaintext highlighter-rouge">/var/log/cross/config-err-X</code>. If not, it will use <code class="language-plaintext highlighter-rouge">/tmp/cross/config-err-X</code>. This X is a hexadecimal value generated dynamically using the following formula; the used seed is extracted from the decrypted configuration:</p> 626 627<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">a4</span> <span class="o">=</span> <span class="mh">0xCE7C0B42</span><span class="p">;</span> 628<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">v20</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> 629 <span class="n">a4</span> <span class="o">=</span> <span class="p">(</span><span class="mh">0x3FFFF</span> <span class="o">*</span> <span class="n">a4</span><span class="p">)</span> <span class="o">+</span> <span class="o">*</span><span class="p">(</span><span class="n">seed</span> <span class="o">+</span> <span class="n">i</span><span class="p">);</span> 630 631</code></pre></div></div> 632 633<h2 id="connecting-to-c2-server">Connecting to C2 Server</h2> 634 635<p>Auto-color establishes a communication channel with its Command and Control (C2) server using a TCP socket. This allows the malware to re
635ceive commands from the attacker and send back responses.</p> 636 637<p>It first parses the decrypted config to extract the required network components protocol, hostname (C2 domain or IP), and port. Once extracted, it resolves the hostname into an IP address, ensuring it can communicate directly with the server (some configs come with direct IPs ). The resolved IP is then stored in a shared memory segment used to track previously used IPs for C2 communication.</p> 638 639<p>Finally, Auto-color establishes a non-blocking TCP socket. And performs an authentication step. It generates a pseudo-random number and derives three challenge values by XOR-ing it with constants. These values are sent to the C2 server, which must respond with the correct transformed values. If the response is incorrect, the connection is terminated.</p> 640 641<p align="center"> 642 <a href="/assets/images/malware-analysis/auto_color/checksum.png"> 643 <img src="/assets/images/malware-analysis/auto_color/checksum.png" alt="API Response Process" /> 644 </a> 645</p> 646<center><font size="3"><u>Figure</u>(9): <u>The authentication step</u></font> </center> 647<p><br /></p> 648 649<p>Each sent message consists of a header and a payload. The header includes a dynamically generated encryption key, a session ID, a status flag, and the payload size. It first encrypts and sends the header, followed by encrypting and sending the payload. If any step fails, an error code is returned. Both of them are encrypted using a custom encryption algorithm, which is the reverse of the algorithm used for decrypting the configuration.</p> 650 651<p align="center"> 652 <a href="/assets/images/malware-analysis/auto_color/send_message.png"> 653 <img src="/assets/images/malware-analysis/auto_color/send_message.png" alt="API Response Process" /> 654 </a> 655</p> 656 657<p>Hereâs its python version :</p> 658 659<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">size</span><span class="p">):</span> 660 <span class="n">key</span> <span class="o">=</span> <span class="mi">1023</span> <span class="o">*</span> <span class="n">key</span> <span class="o">-</span> <span class="mh">0x70E52827</span> 661 <span class="n">res_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">((</span><span class="n">key</span> <span class="o">>></span> <span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="n">enc_data</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">^</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">11</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">19</span><span class="p">)</span> 662 <span class="k">return</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span> 663</code></pre></div></div> 664 665<p>Each received message consists of an encrypted header followed by an encrypted payload. Auto-color first receives the encrypted header and decrypts it using a custom decryption algorithm, the same algorithm used for decrypting the configuration.</p> 666 667<p>The decrypted header includes a key, a command ID, a status flag, and the payload size. After validating the header, Auto-color receives the encrypted payload and decrypts it using the same algorithm, but with the key extracted from the header.</p> 668 669<p align="center"> 670 <a href="/assets/images/malware-analysis/auto_color/recieved.png"> 671 <img src="/assets/images/malware-analysis/auto_color/recieved.png" alt="API Response Process" /> 672 </a> 673</p> 674 675<h2 id="executing-c2-commands">Executing C2 Commands</h2> 676 677<p>After retrieving the C2 command ID and performing the necessary decryption, the malware validates the command and routes it for execution.</p> 678 679<h3 id="command---0x1">Command - 0x1</h3> 680 681<p>This command gathers detailed information about the infected system and then sends that data to a Command and Control (C2) server.</p> 682 683<p align="center"> 684 <a href="/assets/images/malware-analysis/auto_color/command_1.png"> 685 <img src="/assets/images/malware-analysis/auto_color/command_1.png" alt="API Response Process" /> 686 </a> 687</p> 688<center><font size="3"><u>
688Figure</u>(10): <u>Collect data about the host</u></font> </center> 689<p><br /></p> 690 691<table> 692 <thead> 693 <tr> 694 <th><strong>Info Collected</strong></th> 695 <th><strong>Description</strong></th> 696 </tr> 697 </thead> 698 <tbody> 699 <tr> 700 <td><strong>System Date</strong></td> 701 <td>The current date (year, month, day).</td> 702 </tr> 703 <tr> 704 <td><strong>OS Version</strong></td> 705 <td>Details about the operating system (e.g., version, release).</td> 706 </tr> 707 <tr> 708 <td><strong>Hostname</strong></td> 709 <td>The name of the system (unique identifier).</td> 710 </tr> 711 <tr> 712 <td><strong>Username</strong></td> 713 <td>The name of the currently logged-in user.</td> 714 </tr> 715 <tr> 716 <td><strong>IP Addresses</strong></td> 717 <td>The systemâs internal or external IP addresses.</td> 718 </tr> 719 <tr> 720 <td><strong>Processor Info</strong></td> 721 <td>The model of the systemâs CPU</td> 722 </tr> 723 <tr> 724 <td><strong>Total Memory</strong></td> 725 <td>The total amount of system RAM (memory).</td> 726 </tr> 727 <tr> 728 <td><strong>Total Disk Space</strong></td> 729 <td>The total available disk space on the system.</td> 730 </tr> 731 <tr> 732 <td><strong>Process ID</strong></td> 733 <td>The ID of the currently running process.</td> 734 </tr> 735 <tr> 736 <td><strong>Executable Path</strong></td> 737 <td>The file path of the program that is currently running.</td> 738 </tr> 739 </tbody> 740</table> 741 742<p>It also sends the configuration associated with the sample, as this configuration can change between different infections.
742</p> 743 744<h3 id="command---0xf">Command - 0xF</h3> 745 746<p>This command deletes system files and directories associated with the malware, including the <code class="language-plaintext highlighter-rouge">/var/log/cross directory</code> and its contents, as well as the modified <code class="language-plaintext highlighter-rouge">/etc/ld.so.preload</code>. After cleaning up these files, it terminates the malware itself by calling <code class="language-plaintext highlighter-rouge">kill()</code> with its process ID .</p> 747 748<p align="center"> 749 <a href="/assets/images/malware-analysis/auto_color/command_15 750.png"> 751 <img src="/assets/images/malware-analysis/auto_color/command_15 752.png" alt="API Response Process" /> 753 </a> 754</p> 755 756<h3 id="command---0x400">Command - 0x400</h3> 757 758<p>This command reads the configuration and sends it to the C2 server. If no config is found, it sends a default value instead.</p> 759 760<p align="center"> 761 <a href="/assets/images/malware-analysis/auto_color/command_400 762.png"> 763 <img src="/assets/images/malware-analysis/auto_color/command_400 764.png" alt="API Response Process" /> 765 </a> 766</p> 767 768<h3 id="command---0x401">Command - 0x401</h3> 769 770<p>This command modifies the configuration and the config file using a received payload. If successful, it sets a global flag to 1. Finally, it sends a response back to the C2 server</p> 771<ul> 772 <li>0 if it failed</li> 773 <li>the new config file path if successful.</li> 774</ul> 775 776<h3 id="command---0x201">Command - 0x201</h3> 777 778<p>This command scans a selected directory obtained from the C2 server, gathers metadata about its files and subdirectories, and sends the collected information back.</p> 779 780<p>It checks whether each path is a file or a directory and collects details such as permissions (read, write, execute), timestamps (creation, modification, access), and file size. If it finds a directory, it looks for subdirectories and marks them accordingly.</p> 781 782<p>All gathered data is structured and transmitted in an encrypted packet.</p> 783 784<h3 id="command---0x202">Command - 0x202</h3> 785 786<p>This command is used to send or receive files between the infected machine and the C2 server.</p> 787 788<p>If the task is to download a file (âR2Lâ), it opens the file and sends its contents in chunks. If the task is to upload a file (âL2Râ), it creates or opens a file and writes the incoming data from the C2 server.</p> 789 790<h3 id="command---0x204">Command - 0x204</h3> 791 792<p>This command creates a directory or file on the host based on the command received from the C2 server. Finally, It sends a response back to the C2 server with the status of the operation.</p> 793 794<p align="center"> 795 <a href="/assets/images/malware-analysis/auto_color/dir_or_file 796.png"> 797 <img src="/assets/images/malware-analysis/auto_color/dir_or_file 798.png" alt="API Response Process" /> 799 </a> 800</p> 801 802<h3 id="command---0x205">Command - 0x205</h3> 803 804<p>This renames a file or directory based on a command from the C2 server. It retrieves the old and new names tries to rename the target and sends a response back to the C2 server indicating success or failure .</p> 805 806<h3 id="command---0x206">Command - 0x206</h3> 807 808<p>This deletes a file or directory as it retrieves the file or directory name and tries to remove it. Finally, it sends a response back to the C2 server indicating success or failure.</p> 809 810<h3 id="command---0x100">Command - 0x100</h3> 811 812<p>Auto-color creates a reverse shell, allowing a remote server to interact directly with the victim host. It sets up communication channels using pipes, forks a new process, and launches an interactive Bash shell <code class="language-plaintext highlighter-rouge">/bin/bash -i</code> . The child process shifts input/output, clears the command record, and modifies environment variables to evade detection.</p> 813 814<p>The parent process sets an encrypted connection with the remote server, manages execution threads, and ensures cleanup by terminating the shell if needed.</p> 815 816<p align="center"> 817 <a href="/assets/images/malware-analysis/auto_color/reverse_shell 818 819.png"> 820 <img src="/assets/images/malware-analysis/auto_color/reverse_shell 821 822.png" alt="API Response Process" /> 823 </a> 824</p> 825 826<h3 id="command---0x300">Command - 0x300</h3> 827 828<p>This command lets Auto-color use the infected machine as a proxy, relaying connections between the attacker and a remote target. It does this by using two sockets: one for receiving connections from the command-and-control (C2) server and another for connecting to a target IP, which is retrieved from the C2 server.</p> 829 830<p>The first socket listens for incoming connections, while the second establishes communication with the target. It then uses <code class="language-plaintext highlighter-rouge">select()</code> to monitor both sockets for incoming data. When data is received from the attacker, it is forwarded to the target, and when data is received from the target, it is sent back to the attacker.</p> 831 832<p align="center"> 833 <a href="/assets/images/malware-analysis/auto_color/proxy 834 835.png"> 836 <img src="/assets/images/malware-analysis/auto_color/proxy 837 838.png" alt="API Response Process" /> 839 </a> 840</p> 841 842<p><br /></p> 843 844<h1 id="analysis-of-libcextso2">Analysis of libcext.so.2</h1> 845 846<p>This library is designed with two primary goals: evading detection and ensuring persistence.</p> 847 848<h2 id="protecting-etcldpreload">Protecting /etc/ld.preload</h2> 849 850<p>Auto-colorâs malicious library employs various hooks to manipulate system calls, ensuring that <code class="language-plaintext highlighter-rouge">/etc/ld.so.preload</code> remains protected, and persistent by turning any operation involving it to <code class="language-plaintext highlighter-rouge">/etc/ld.so.preload.xxx</code>. If an attempt is made to delete <code class="language-plaintext highlighter-rouge">/etc/ld.so.preload.xxx</code>, the operation is allowed since only the malware creates this file.</p> 851 852<p align="center"> 853 <a href="/assets/images/malware-analysis/auto_color/hook_example 854 855.png"> 856 <img src="/assets/images/malware-analysis/auto_color/hook_example 857 858.png" alt="API Response Process" /> 859 </a> 860</p> 861 862<table> 863 <thead> 864 <tr> 865 <th><strong>Hooked API</strong></th> 866 <th><strong>Purpose</strong></th> 867 </tr> 868 </thead> 869 <tbody> 870 <tr> 871 <td><code class="language-plaintext highlighter-rouge">chmod</code>, <code class="language-plaintext highlighter-rouge">fchmodat</code></td> 872 <td>Prevents permission changes</td> 873 </tr> 874 <tr> 875 <td><code class="language-plaintext highlighter-rouge">remove</code>, <code class="language-plaintext highlighter-rouge">unlink</code>, <code class="language-plaintext highlighter-rouge">unlinkat</code></td> 876 <td>Prevents deletion</td> 877 </tr> 878 <tr> 879 <td><code class="language-plaintext highlighter-rouge">rename</code>, <code class="language-plaintext highlighter-rouge">renameat</code></td> 880 <td>Prevents renaming</td> 881 </tr> 882 <tr> 883 <td><code class="language-plaintext highlighter-rouge">stat</code>, <code class="language-plaintext highlighter-rouge">lstat</code>, <code class="language-plaintext highlighter-rouge">fstat</code>, <code class="language-plaintext highlighter-rouge">fstatat</code>, <code class="language-plaintext highlighter-rouge">statx</code>, <code class="language-plaintext highlighter-rouge">_lxstat</code></td> 884 <td>Hides presence</td> 885 </tr> 886 <tr> 887 <td><code class="language-plaintext highlighter-rouge">access</code>, <code class="language-plaintext highlighter-rouge">faccessat</code></td> 888 <td>Hides presence</td> 889 </tr> 890 <tr> 891 <td><code class="language-plaintext highlighter-rouge">realpath</code>, <code class="language-plaintext highlighter-rouge">getattr</code></td> 892 <td>Prevents file path resolution</td> 893 </tr> 894 <tr> 895 <td><code class="language-plaintext highlighter-rouge">open</code>, <code class="language-plaintext highlighter-rouge">openat</code>, <code class="language-plaintext highlighter-rouge">fopen</code></td> 896 <td>Prevents access</td> 897 </tr> 898 <tr> 899 <td><code class="language-plaintext highlighter-rouge">read</code>, <code class="language-plaintext highlighter-rouge">pread</code></td> 900 <td>Hides malicious content</td> 901 </tr> 902 <tr> 903 <td><code class="language-plaintext highlighter-rouge">opendir</code>, <code class="language-plaintext highlighter-rouge">readdir</code>, <code class="language-plaintext highlighter-rouge">scandir</code></td> 904 <td>Hides directory entries</td> 905 </tr> 906 </tbody> 907</table> 908 909<h2 id="persistance">Persistance</h2> 910 911<p>It retrieves the name of the calling process and checks if it matches one of the following system daemons :</p> 912 913<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/sbin/auditd 914/sbin/cron 915/sbin/crond 916/sbin/acpid 917/sbin/atd 918/usr/sbin/auditd 919/usr/sbin/cron 920/usr/sbin/crond 921/usr/sbin/acpid 922/usr/sbin/atd 923</code></pre></div></div> 924 925<p>As these daemons (background processes) run continuously in a normal system, they are a perfect choice for persistence. If a match is found, it forks a new process and then uses <code class="language-plaintext highlighter-rouge">execl()</code> to launch the auto-color, ensuring it runs within a trusted system service while the parent process exits to stay stealthy.</p> 926 927<p align="center"> 928 <img src="/assets/images/malware-analysis/auto_color/run_auto.png" alt="API Response Process" /> 929</p> 930<center><font size="3"> <u>Figure</u>(11): <u>Persistence function</u></font> </center> 931<p><br /></p> 932 933<h2 id="hiding-network-activity">Hiding Network Activity</h2> 934 935<p>Auto-colorâs malicious library also hides its Command and Control (C2) network activity by blocking tries to read <code class="language-plaintext highlighter-rouge">/proc/net/tcp</code>. This special Linux file lists all active TCP connections, including source/destination IPs and ports.</p> 936 937<p>
937By hooking different file access functions [open, openat64, fopen, and fopen64 ], it detects when a process tries to read this file. Instead of returning the actual data, It parses each entry, compares it against specific C2-related IPs and ports stored by Auto-color previously in shared memory, and filters them out.</p> 938 939<p>The cleaned-up data is saved in a temporary file at <code class="language-plaintext highlighter-rouge">/tmp/17EF88CF</code>, allowing the malware to reuse it while keeping the changes hidden from tools like <strong>netstat</strong> or system monitors.</p> 940 941<p align="center"> 942 <a href="/assets/images/malware-analysis/auto_color/hide_network 943.png"> 944 <img src="/assets/images/malware-analysis/auto_color/hide_network 945.png" alt="API Response Process" /> 946 </a> 947</p> 948 949<p><br /></p> 950<h1 id="yara-rule">YARA Rule</h1> 951 952<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">rule</span> <span class="nt">detect_Auto_Color</span> 953<span class="p">{</span> 954 <span class="py">meta</span><span class="p">:</span> 955 <span class="n">description</span> <span class="err">=</span> <span class="s1">"Detects Auto-color malware family "</span> 956 <span class="n">author</span> <span class="err">=</span> <span class="s1">"Mohamed Ezzat (@ZW01f)"</span> 957 <span class="n">hash1</span> <span class="err">=</span> <span class="s1">"815b74947d3a78a1b7d2aece43596ddc0ffc264e26092f1f9b6409c62e1437d6"</span> 958 <span class="n">hash2</span> <span class="err">=</span> <span class="s1">"270fc72074c697ba5921f7b61a6128b968ca6ccbf8906645e796cfc3072d4c43"</span> 959 960 <span class="n">strings</span><span class="p">:</span> 961 <span class="err">$</span><span class="n">elf</span> <span class="err">=</span> <span class="s1">"\x7fELF"</span> <span class="p">//</span> <span class="n">ELF</span> <span class="n">header</span> 962 <span class="err">$</span><span class="n">s1</span> <span class="err">=</span> <span class="s1">"/var/log/cross"</span> 963 <span class="err">$</span><span class="n">s2</span> <span class="err">=</span> <span class="s1">"/tmp/cross"</span> 964 <span class="err">$</span><span class="n">s3</span> <span class="err">=</span> <span class="s1">"/door-%d.log"</span> 965 <span class="err">$</span><span class="n">s4</span> <span class="err">=</span> <span class="s1">"/etc/ld.so.preload.xxx"</span> 966 <span class="err">$</span><span class="n">s5</span> <span class="err">=</span> <span class="s1">"%s/auto-color"</span> <span class="n">ascii</span> <span class="n">wide</span> 967 <span class="err">$</span><span class="n">s6</span> <span class="err">=</span> <span class="s1">"%s memory dump %d bytes..."</span> <span class="n">wide</span> <span class="n">ascii</span> 968 969 <span class="n">condition</span><span class="p">:</span> 970 <span class="p">(</span><span class="n">filesize</span> <span class="err"><</span> <span class="m">300</span><span class="n">KB</span><span class="p">)</span> <span class="n">and</span> <span class="p">(</span><span class="err">$</span><span class="n">elf</span> <span class="n">at</span> <span class="m">0</span><span class="p">)</span> <span class="n">and</span> <span class="p">(</span><span class="m">5</span> <span class="n">of</span> <span class="p">(</span><span class="err">$</span><span class="n">s</span><span class="err">*</span><span class="p">))</span> 971<span class="p">}</span> 972</code></pre></div></div> 973 974<p><br /></p> 975 976<h1 id="python-automated-configuration-extraction">Python Automated Configuration Extraction</h1> 977 978<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 979<span class="kn">from</span> <span class="nn">elftools.elf.elffile</span> <span class="kn">import</span> <span class="n">ELFFile</span> 980<span class="kn">import</span> <span class="nn">re</span> 981 982<span class="k">def</span> <span class="nf">extract_data_section</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span> 983 <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
984 <span class="n">elf</span> <span class="o">=</span> <span class="n">ELFFile</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> 985 986 <span class="k">for</span> <span class="n">section</span> <span class="ow">in</span> <span class="n">elf</span><span class="p">.</span><span class="n">iter_sections</span><span class="p">():</span> 987 <span class="k">if</span> <span class="n">section</span><span class="p">.</span><span class="n">name</span> <span class="o">==</span> <span class="s">".data"</span><span class="p">:</span> 988 <span class="k">return</span> <span class="n">section</span><span class="p">.</span><span class="n">data</span><span class="p">()</span> 989 990 <span class="k">return</span> <span class="bp">None</span> 991 992<span class="k">def</span> <span class="nf">custom_crypto_algo</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> 993 <span class="n">length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> 994 <span class="n">decrypted</span> <span class="o">=</span> <span class="nb">bytearray</span><span class="p">(</span><span class="n">length</span><span class="p">)</span> 995 996 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">length</span><span class="p">):</span> 997 <span class="n">key</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1023</span> <span class="o">*</span> <span class="n">key</span> <span class="o">-</span> <span class="mh">0x70E52827</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0xFFFFFFFF</span> 998 <span class="n">decrypted</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">((</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">-</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">19</span><span class="p">))</span> <span class="o">^</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">11</span><span class="p">))</span> <span class="o">-</span> <span class="p">(</span><span class="n">key</span> <span class="o">>></span> <span class="mi">3</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0xFF</span> 999 1000 <span class="k">return</span> <span class="n">decrypted</span> 1001 1002<span class="k">def</span> <span class="nf">extract_c2_urls</span><span class="p">(</span><span class="n">text</span><span class="p">):</span> 1003 <span class="n">pattern</span> <span class="o">=</span> <span class="sa">r</span><span class="s">'TCP://[a-zA-Z0-9.-]+:\d+'</span> <span class="c1"># c2 URL come in : TCP://hostname_or_ip:PORT 1004</span> <span class="k">return</span> <span class="n">re</span><span class="p">.</span><span class="n">findall</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">re</span><span class="p">.</span><span class="n">IGNORECASE</span><span class="p">)</span> 1005 1006<span class="k">def</span> <span class="nf">main</span><span class="p">():</span> 1007 <span class="n">file_path</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">"Enter the file path: "</span><span class="p">)</span> 1008 <span class="n">data_section</span> <span class="o">=</span> <span class="n">extract_data_section</span><span class="p">(</span><span class="n">file_path</span><span class="p">)</span> 1009 1010 <span class="n">enc_data_offset</span> <span class="o">=</span> <span class="mh">0x24</span> <span class="c1">#The config data begins at offset 0x24 inside the .data section 1011</span> <span class="n">size_offset</span> <span class="o">=</span> <span class="mh">0x20</span> 1012 1013 <span class="n">size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">data_section</span><span class="p">[</span><span class="n">size_offset</span><span class="p">:</span><span class="n">enc_data_offset</span><span class="p">],</span> <span class="n">
1013byteorder</span><span class="o">=</span><span class="s">'big'</span><span class="p">)</span> 1014 <span class="n">enc_config</span> <span class="o">=</span> <span class="n">data_section</span><span class="p">[</span><span class="n">enc_data_offset</span><span class="p">:</span><span class="n">enc_data_offset</span> <span class="o">+</span> <span class="n">size</span><span class="p">]</span> 1015 <span class="n">key</span> <span class="o">=</span> <span class="nb">int</span><span class="p">.</span><span class="n">from_bytes</span><span class="p">(</span><span class="n">enc_config</span><span class="p">[</span><span class="o">-</span><span class="mi">4</span><span class="p">:],</span> <span class="s">"big"</span><span class="p">)</span> <span class="c1"># key is the last 4 bytes 1016</span> 1017 <span class="n">decrypted_data</span> <span class="o">=</span> <span class="n">custom_crypto_algo</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">enc_config</span><span class="p">).</span><span class="n">
1017decode</span><span class="p">(</span><span class="s">"utf-8"</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s">"ignore"</span><span class="p">)</span> 1018 <span class="k">print</span><span class="p">(</span><span class="s">"Decrypted config :"</span> <span class="p">,</span><span class="n">decrypted_data</span><span class="p">)</span> 1019 1020 <span class="n">extracted_url</span> <span class="o">=</span> <span class="n">extract_c2_urls</span><span class="p">(</span><span class="n">decrypted_data</span><span class="p">)</span> 1021 <span class="k">if</span> <span class="n">extracted_url</span><span class="p">:</span> 1022 <span class="k">print</span><span class="p">(</span><span class="s">"Extracted C2 URLs :"</span><span class="p">)</span> 1023 <span class="k">for</span> <span class="n">address</span> <span class="ow">in</span> <span class="n">extracted_url</span><span class="p">:</span> 1024 <span class="k">print</span><span class="p">(</span><span class="n">address</span><span class="p">)</span> 1025 1026<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span> 1027 <span class="n">main</span><span class="p">()</span> 1028 1029</code></pre></div></div> 1030 1031<h1 id="references">References</h1> 1032 1033<ul> 1034 <li><a href="https://thehackernews.com/2025/02/new-linux-malware-auto-color-grants.html">New Linux Malware âAuto-colorâ Grants Hackers Full Remote Access to Compromised Systems</a></li> 1035</ul> 1036 1037 1038 1039 </section> 1040 1041 <footer class="page__meta"> 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 <p class="page__taxonomy"> 1054 <strong><i class="fas fa-fw fa-folder-open" aria-hidden="true"></i> Categories: </strong> 1055 <span itemprop="keywords"> 1056 1057 1058 1059 <a href="/categories/#malware-analysis" class="page__taxonomy-item" rel="tag">Malware Analysis</a> 1060 1061 </span> 1062 </p> 1063 1064 1065 1066 <p class="page__date"><strong><i class="fas fa-fw fa-calendar-alt" aria-hidden="true"></i> Updated:</strong> <time datetime="2025-03-28T00:00:00+00:00">March 28, 2025</time></p> 1067 1068 </footer> 1069 1070 1071 1072 1073 <nav class="pagination"> 1074 1075 <a href="/malware%20analysis/apt37/" class="pagination--pager" title="APT37 - RokRat 1076">Previous</a> 1077 1078 1079 <a href="#" class="pagination--pager disabled">Next</a> 1080 1081 </nav> 1082 1083 </div> 1084 1085 1086 </article> 1087 1088 1089 1090</div> 1091 1092 </div> 1093 1094 1095 <div class="search-content"> 1096 <div class="search-content__inner-wrap"><form class="search-content__form" onkeydown="return event.key != 'Enter';"> 1097 <label class="sr-only" for="search"> 1098 Enter your search term... 1099 </label> 1100 <input type="search" id="search" class="search-input" tabindex="-1" placeholder="Enter your search term..." /> 1101 </form> 1102 <div id="results" class="results"></div></div> 1103 1104 </div> 1105 1106 1107 <div id="footer" class="page__footer"> 1108 <footer> 1109 <!-- start custom footer snippets --> 1110 1111<!-- end custom footer snippets --> 1112 <div class="page__footer-follow"> 1113 <ul class="social-icons"> 1114 1115 <li><strong>Follow:</strong></li> 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 <li><a href="/feed.xml"><i class="fas fa-fw fa-rss-square" aria-hidden="true"></i> Feed</a></li> 1135 </ul> 1136</div> 1137 1138<div class="page__footer-copyright">© 2025 Mohamed Ezzat. Powered by <a href="https://jekyllrb.com" rel="nofollow">Jekyll</a> & <a href="https://mademistakes.com/work/minimal-mistakes-jekyll-theme/" rel="nofollow">Minimal Mistakes</a>.</div> 1139 1140 </footer> 1141 </div> 1142 1143 1144
1144<script src="/assets/js/main.min.js"></script>
1144 1145
1145<script src="https://kit.fontawesome.com/4eee35f757.js"></script>
1145 1146 1147 1148 1149
1150<script src="/assets/js/lunr/lunr.min.js"></script>
vendor: 1 bytes, line 1150
1150
1151<script src="/assets/js/lunr/lunr-store.js"></script>
vendor: 1 bytes, line 1151
1151
1152<script src="/assets/js/lunr/lunr-en.js"></script>
1152 1153 1154 1155 1156 1157
1157<script> 1158 window.ga=function(){ga.q.push(arguments)};ga.q=[];ga.l=+new Date; 1159 ga('create','UA-165194559-1','auto'); 1160 ga('set', 'anonymizeIp', false); 1161 ga('send','pageview') 1162</script>
vendor: 1 bytes, line 1162
1162
1163<script src="https://www.google-analytics.com/analytics.js" async></script>
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 </body> 1174</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.