The Genealogy of Malware

While working on Jetpack Security, one thing I have a greater opportunity than most to do is inspect naughty bits of code that get injected into a user’s site.

One that I stumbled upon this past week reminded me of another from a bit ago — I can’t say precisely what reminded me of it, but my brain connected the two. So I looked back to find the prior infection and this is what turned up:

https://www.diffchecker.com/MYId3pFX

Clearly — a number of similarities between the two files. Of the four hundred plus lines in question, only fifty or so contain any changes, and most of those are namespace changes — changing mont to ccode, or perhaps some subtle refinements on how it detects the remote visitor’s IP address.

One of the most interesting aspects — to me anyways — is tracing the source of various snippets used in the code.

Good artists copy. Great artists steal.

Steve Jobs, misattributing a quotation to Pablo Picasso

So firstly, when skimming the code, around line 20, I found the following:

add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'salcode_add_plugin_page_settings_link');
function salcode_add_plugin_page_settings_link( $links ) {
	$links[] = '<a href="' .
		admin_url( 'options-general.php?page=monit' ) .
		'">' . __('Settings') . '</a>';
	return $links;
}

Huh — it references salcode — I know that namespace, it’s commonly used by Sal Ferrarello! Figuring it may have been lifted off an article he’d written, I reached out to check. Sure enough, he had a 2014 article called “WordPress Plugin Add Settings Link” that he pointed me towards — and sure enough, the code was a straight copy/paste job in the Monitization variant. In the Custom Code variant of the malware, it was tweaked to be namespaced a bit further (changing the trailing link to ccode, but the similarities are still there.

We also can glean a bit from the tags that the code tries to inject. The original attempts:

<script type="text/javascript" src="//ofgogoatan.com/apu.php?zoneid=3260072" async data-cfasync="false"></script>
<script src="https://pushsar.com/pfe/current/tag.min.js?z=3260077" data-cfasync="false" async></script>
<script type="text/javascript" src="//inpagepush.com/400/3324386" data-cfasync="false" async="async"></script>

Where the latter Custom Code implementation attempts:

<script>(function(s,u,z,p){s.src=u,s.setAttribute('data-zone',z),p.appendChild(s);})(document.createElement('script'),'https://iclickcdn.com/tag.min.js',3388587,document.body||document.documentElement)</script>
<script src=\"https://propu.sh/pfe/current/tag.min.js?z=3388595\" data-cfasync=\"false\" async></script>
<script type=\"text/javascript\" src=\"//inpagepush.com/400/3388600\" data-cfasync=\"false\" async=\"async\"></script>

Beside the swap from which quotes need escaping due to single vs double in the wrapping string, we can see a couple notable bits:

  • The first tag seems to have been swapped out in its entirety.
  • The second tag seems to have swapped from pushsar.com to propu.sh — with the general url structure remaining the same. This can indicate the service just changed domains, and kept everything else business as usual.
  • The last tag remained as before — inpagepush.com — but just changing the identifier on the end.

A bit later on, we can find several instances where the mont namespace (possibly typo’d from monit) was not changed to ccode

    register_setting( 'ccode-settings', 'default_mont_options' );
if(get_option('default_mont_options') !=='on')

At the end of the file, we’re confronted with this bit:

function hide_plugin_trickspanda() {
  global $wp_list_table;
  $hidearr = array('monit.php');
  $myplugins = $wp_list_table->items;
  foreach ($myplugins as $key => $val) {
    if (in_array($key,$hidearr)) {
      unset($wp_list_table->items[$key]);
    }
  }
}

Here again, we’ve got a strong hint from the namespace, trickspanda. So in this case, it came from an article that Hardeep Asrani wrote on Tricks Panda — again, back in 2014. The Monitization variant didn’t seem to change the namespace, leaving it as trickspanda, but the later Custom Code variant swapped it out to ccode.

Finally, at the conclusion of the Custom Code variant (not present in the original) we can see the following:

        function getVisIpAddr_ccode() { 
      
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 
        return $_SERVER['HTTP_CLIENT_IP']; 
    } 
    else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
        return $_SERVER['HTTP_X_FORWARDED_FOR']; 
    } 
    else { 
        return $_SERVER['REMOTE_ADDR']; 
    } 
}

As it is, this seems to have been lifted from a Geeks For Geeks article dated May 2019. The code uses it up above to handle instances where traffic comes through a load balancer or proxy or the like, with original IP addresses in the header. Interestingly enough, for anyone else who has a need for similar functionality, WordPress Core ships with a similar function already, get_unsafe_client_ip().

So what have we found? Code gets reused, a lot. Old tutorials from 2014 can still offer information going strong years afterwards. Be wise what bits of bad code you use to fingerprint it and identify future infections, as it’s far better to find the unremarkable but unique bits, than the bits they may change to conceal it from future iterations.

Star Wars Galaxy’s Edge Set Dressing

Here’s a bunch of photos I took last week at Star Wars Galaxy’s Edge – Black Spire Outpost in Disneyland. I thought they may be useful for anyone trying to build a similar thematic structure, either for dressing up a home theater room, or just to add some spice to a family room.

So that I don’t lose it: Stifado Recipe

Ingredients: 

  • 2-3 lbs beef, cubed
  • 2-3 lbs pearled onions
  • 1 large yellow onion, chopped
  • 1 28 oz can tomatoes
  • 1 cup dry red wine
  • ¼ cup red wine vinegar
  • ⅓ cup olive oil
  • 3 cloves garlic, bruised
  • 1 tsp sugar
  • Spice bag:
    • 2 bay leaves
    • 1 tablespoon allspice berries
    • 2 3-inch cinnamon sticks
  1. In a stew pot / dutch oven, over medium-low heat, add the chopped onion, half the olive oil, and ¼ cup water.  Cook until the wayer has evaporated and the onion is soft and translucent, about 10 minutes.
  2. To the onions, add the garlic and tomatoes.  Cook, stirring, until the sauce is thick, about 20 minutes.
  3. Rinse the beef, drain, pat dry.  Season lightly with salt and pepper.  Heat the remaining olive oil in a skillet until hot.  Brown the beef over high heat, add to the tomato sauce.
  4. Add the red wine to the skillet to deglaze, and bring to a boil while scraping up any fond from the bottom of the pan.  Add the pearled onions and sugar, and cook over medium-high heat, stirring, until the wine is reduced to a glaze and the onions are lightly browned, about 5 minutes.
  5. Add 3 tablespoons of the red wine vinegar to the onions, and bring to a boil.
  6. Add the spice bag and the onions and wine sauce to the beef and tomato sauce mixture.
  7. Cover and cook over low heat for 2-2½ hours.

 

When Mike Pence Comes to Your Alma Mater

I’ll be writing a similar letter to my alma mater’s leadership shortly.

Very disappointed right now.

Grace Leuenberger

caleb-woods-166819.jpgBelow is a letter I sent to my alma mater. I am sharing it here not because I want to make people mad, but because I spent four years hardly ever discussing my political views as a student. I believe the choice to bring Mike Pence to our college is short-sighted, and that many wise, remarkable individuals could have better aligned with the viewpoints and values of the college, its students, its staff, and its alumni. I care about my college too much not be disappointed and worried about the implications this invitation has. I invite respectful dialogue and alternative viewpoints in the comments below. 


Dear Grove City College leadership,

I send this letter today with a desire to respectfully disagree with the recent decision to invite Vice President Michael Pence to speak at this year’s Commencement exercises. Though I recognize that my letter will not alter the decision or…

View original post 1,424 more words

On Anti-Transgender Bathroom Bills

I’ve found myself now writing the same (or fundamentally similar, at least) responses to several individuals on Facebook.  To save myself time and frustration in the future, I’m just stashing it here, so I can copypasta it out as needed.

This specific variant of the response was inspired by someone posting an article from thefederalist.com by a rape survivor.

Okay, so the impetus for the recent transgender bathroom legislation is the idea that without it, a cisgendered man could claim to be a transgendered woman and enter the women’s restroom (or vice versa) for nefarious purposes, yeah? And this legislation will prevent it by assigning additional penalties for their entering that restroom, in addition to the already illegal ‘nefarious purposes’ they entered to conduct?

Well, post-legislation, what is to prevent that same cisgendered man from entering a women’s restroom, asserting that they are in fact a transgendered man, having been born a woman (again, or vice versa) and are therefore compelled by law to use the women’s restroom?

How exactly would you propose resolving that situation? Show ID to Pee? Must they also provide an original birth certificate, which you know everyone carries with them when they’re out and about, because gender can be changed on your drivers license (and just hope that they didn’t get their gender changed on their birth certificate)? And then, will you also make them wait to pee while you phone it in to the state to confirm their birth sex, because they could have photoshopped and printed a forged birth certificate?

For all the conservatives oppose new gun laws saying that they won’t stop criminals and only impede the rights of legal gun owners, why are so many in favor of these bathroom bills, that — again — will not stop determined criminals, and just impede the rights of transgender individuals?

What, apart from making transgendered individuals lives a pure hell, does this legislation actually accomplish? Add on a second charge as a potential deterrent? What rape or assault would that possibly prevent?

Yes, the author of the article in question is a rape survivor. Okay. Was her rapist pretending to be transgendered to gain access to her? Was she raped in a public restroom? Because many Trans individuals are harassed and attacked in public restrooms. And this legislation increases that — as well as increasing the likelihood that they are going to be raped in turn.

Laws should be to secure the safety of the most vulnerable of society. And if you look at the statistics, those are transgendered individuals, who are raped and assaulted and killed at rates far exceeding the general population.

And this legislation makes it worse.

If anyone would like to offer suggestions or additions to “The Blurb” please feel free to leave a comment below.  If anyone would like to use “The Blurb” on social media, please feel free.

Dancing to a Calypso Beat

Sidenote: I wrote this article two months back, at WordCamp US, and am only now getting around to posting it. Sorry for the delay.

A few months ago, the culmination of nearly two years of internal work was open-sourced to the world. A new WordPress admin interface built by Automattic on top of Javascript technologies like Node.js and React, codenamed Calypso.

A lot of folks got excited and a few got scared. Some folks got a bit confused. But I haven’t heard many folks drawing the parallel and writing the explanation that I’ve cobbled together, so here’s my take on it:

For a while now, there’s been a variety of WordPress apps — iOS, Android, and some defunct ones for Blackberry, Windows Phone, WebOS, and the like. They all interact with WordPress via the existing XML-RPC API. They’re not really extensible for plugins — if someone installs “The Events Calendar,” events don’t start showing up in the app as they would in your traditionally PHP-generated WordPress Admin UI.

Calypso currently mirrors those mobile apps more than anything else, just shifted to a wholly different space. Instead of using the legacy XML-RPC API, which is meant primarily as a way to publish content and has a host of issues (sending user passwords in plaintext with every request, for one), it uses a REST API with far better authentication. Instead of running on mobile devices, it runs either in your web browser at WordPress.com or encapsulated in a Desktop app. But at its core, it’s a self-contained administrative application for WordPress sites.

I feel that the biggest win in releasing the Calypso interface, though, is that it can remedy a situation that’s festered for some time now. The current WordPress mobile apps are maintained by a crew of mobile developers that work for Automattic.

Development happens in the open, and community contributions are welcomed, but they are comparatively few and far between — largely due to the fact that the majority of folks who are really passionate about WordPress are primarily familiar with the languages that WordPress is written in — PHP, CSS, Javascript, MySQL, etc. Very few have much interest in leaping into App development. Likewise, most mobile developers have their own set of problems that they are passionate about solving, and volunteering their free time to build and maintain an administrative app for WordPress would ordinarily be low on their list of priorities.

So, it falls to someone to find and hire Mobile developers to maintain the assorted WordPress mobile apps.

With the release of Calypso, though, there is a bit of a paradigm shift. Calypso, being written in Javascript, is already in the skill set of many of the folks who are already passionate about building the core software, as well as those that leverage WordPress to build sites.

This, I think, will mean a significant renaissance of community interest in API-driven apps for maintaining a WordPress site. I also predict that we’ll see a lot of folks passionate about WordPress forking Calypso and tweaking it to make customized apps and distributions for specific clients and use cases — which will only expand further once REST API endpoints ship in WordPress Core, and Calypso migrates to use those, instead of the WordPress.com REST API.

Two-Factor in the Real World

I’m locked out of my Apple account.

I know my password. I still have my cell phone number that is set as a recovery number.

So how could I be locked out?

Several months back, I changed my cell carrier to Project Fi — the Google amalgamation of T-Mobile, Sprint, and WiFi networks to provide better coverage at lower cost. I’ve been thrilled with the service (like, seriously ecstatic), but there are some odd issues that have cropped up.

For one, it seems that text messages from SMS ‘short codes‘ don’t go through.  This has been a known issue for some time now with Project Fi. I first found out about it when trying to set up Google Wallet with USAA — which runs through an automated SMS short codes system. Many automated texts do work without issue — Dropbox, for one.

At this point, it should be noted that Project Fi is not listed on the list of carriers that Apple officially supports for sending out two-factor login codes.

So I just spent a full hour (I clocked it at the end) on the phone with a very empathetic and understand customer service rep from Apple.  Unfortunately:

  • I don’t have any iOS or OSX devices currently logged into my iCloud account (I had just voluntarily switched my primary computer to Windows for work)
  • I can’t receive txt messages from their automated system at the phone number I have on file (despite the fact that I called them from that number and they can call me back at that same number)
  • I don’t have my recovery key (it was about three years back when I first turned on two-factor authentication, and I have absolutely no idea where I would have stored it)

So there is absolutely nothing that they can do for me, it seems.

I mean, I understand this to a point. The rep I had on the phone was very apologetic, but the system that they built just doesn’t account for the fact that perhaps sometimes phone numbers lose the ability to receive text messages.

They knew I was who I said I was — I was calling from my number on file, I had all my credit card information, I could authenticate the first step of logging in.  They could even call me at the phone number they have on file.  But because they couldn’t text me, they couldn’t — not wouldn’t, but actually couldn’t — help me.

But this isn’t meant to be a sob story, or a tirade against Apple. Okay, maybe a little bit of a gripe, but I’d like it to be more a focus on the importance of considering edge cases in development.

The customer support reps are incredibly constrained. They knew without a doubt that I could receive calls at the phone number in question. But they weren’t empowered to do anything about it. They escalated the issue, and it seems no-one was about to do anything, apart from offering their condolences that I won’t be able to log into my account.

If there is one take-away from this, I suppose it’s to enable your customer support reps to actually do their jobs. I know Apple has gotten burned in the past on hackers gaming the system, but it’s the importance of being judicious when dealing with requests, not barring the doors against any.

As a semi-related note, I’m heading up the group working on bringing Two-Factor support to WordPress core.  Two-Factor is something that I believe in deeply, I just also believe in the importance of carefully building out the systems that serve as back ends to such methods of authentication.

Update: I’m learning that it’s possible to get some short codes unblocked for a single account specifically … maybe.  Apple authentication texts seem to come from a number `50472` and I’ll be reaching out to Project Fi support tomorrow to see if I can get them to manually unblock that number for my account.

Perfect Faro Shuffles

Faro Shuffling is a technique where two packets of cards are pressed together and stitch themselves together, one to one. It takes a goodly amount of practice to actually pull it off reliably, but if you can, it’s a tremendously fun skill to have.

There are two primary kinds of faros performed on a 52-card deck, that being an ‘In’ and an ‘Out’ faro.  An ‘Out’ faro is one where the top and bottom cards of the deck are preserved on the outside of the deck, an ‘In’ is where they are moved to the interior of the deck.

If the user can perform perfect cuts and faro shuffles, it will take 26 ‘In’ shuffles to completely reverse the deck of 52 cards, and another 26 shuffles to return it to original order. However, by performing ‘Out’ shuffles, the full deck will be returned to the original sequence in only eight shuffles.

I’m working on mastering this, because it’s dang fun and appeals to my brain.  And, as a predictable way of reordering decks and can be rolled into some fun illusions.

For reference, standard new deck order is A♠️-K♠️,A♦️-K♦️,K♣️-A♣️,K♥️-A♥️.

While performing eight perfect cuts and ‘Out’ faros, if you start with standard new deck order, these are the eight cut cards:

  1. K♣️
  2. A♦️
  3. 7♣️
  4. 4♦️
  5. 9♠️
  6. 5♠️
  7. 3♠️
  8. 2♠️

Or, if you prefer Emoji,

🃞🃁🃗🃄🂩🂥🂣🂢

Safari is the new IE

Read the Tea Leaves

Last weekend I attended EdgeConf, a conference populated by many of the leading lights in the web industry. It featured panel talks and breakout sessions with a focus on technologies that are just now starting to emerge in browsers, so there was a lot of lively discussion around Service Worker, Web Components, Shadow DOM, Web Manifests, and more.

EdgeConf’s hundred-odd attendees were truly the heavy hitters of the web community. The average Twitter follower count in any given room was probably in the thousands, and all the major browser vendors were represented ? Google, Mozilla, Microsoft, Opera. So we had lots of fun peppering them with questions about when they might release such-and-such API.

There was one company not in attendance, though, and they served as the proverbial elephant in the room that no one wanted to discuss. I heard them referred to cagily as “a company in California”…

View original post 1,420 more words