All posts by skoba

Secret MemberMouse Diagnostic Log Page

Ever noticed your mm_diagnostic_log table filling up? I did (it was 6.2GB at the time of writing), but I couldn’t find an obvious way to control/turn off MemberMouse’s logging.

After poking through the plugin source, I found reference to a “diagnostics” page, but couldn’t find a link in the admin section. But, it turns out you can visit the “diagnostics module” page directly. Sure enough, there is a config page and an option to turn off logging:

membermouse diagnostic config page

Execute Javascript in PHP using v8js on Ubuntu 18.04

Let’s say you want to log into a webpage using PHP.

You post the login credentials to the login form, and expect to get a cookie back.

But you get this back instead:

<html><title>You are being redirected…</title>
<noscript>Javascript is required. Please enable javascript before you are allowed to see this page.</noscript>
<script>var s={},u,c,U,r,i,l=0,a,e=eval,w=String.fromCharCode,sucuri_cloudproxy_js=,S=‘az0nNXZYOScuc3Vic3RyKDMsIDEpICsiOSIgKyAiMHN1Y3VyIi5jaGFyQXQoMCkrJ1lhJy5zbGljZSgxLDIpKydhWzEnLmNoYXJBdCgyKSsiMHN1Ii5zbGljZSgwLDEpICsgJ2YnICsgICI2c2VjIi5zdWJzdHIoMCwxKSArICI1Ii5zbGljZSgwLDEpICsgJzInICsgICdhWjQnLmNoYXJBdCgyKSsnYycgKyAgICcnICsnJysiNCIgKyAiN3N1Ii5zbGljZSgwLDEpICsgIiIgKyIwc3UiLnNsaWNlKDAsMSkgKyAiIiArJ3RAOCcuY2hhckF0KDIpKyIyIi5zbGljZSgwLDEpICsgImNzdWN1ciIuY2hhckF0KDApKyd0NGYnLmNoYXJBdCgyKSsnMScgKyAgJ2InICsgICJiIiArICdsPzgnLmNoYXJBdCgyKSsnM2InLnNsaWNlKDEsMikrJ1RsWmInLnN1YnN0cigzLCAxKSArJ0E2Jy5zbGljZSgxLDIpKyJmbiIuY2hhckF0KDApICsgIiIgKyJhc3VjdXIiLmNoYXJBdCgwKSsgJycgKyJhc3VjdXIiLmNoYXJBdCgwKSsiOHciLmNoYXJBdCgwKSArICczYk8zJy5zdWJzdHIoMywgMSkgKyIiICsiYmkiLmNoYXJBdCgwKSArICcnO2RvY3VtZW50LmNvb2tpZT0ncycrJ3UnKydjJysnJysndXN1Y3VyJy5jaGFyQXQoMCkrICdyJysnJysnc3VjdWknLmNoYXJBdCg0KSsgJ3NfJy5jaGFyQXQoMSkrJ2NzJy5jaGFyQXQoMCkrJ3N1Y3VybCcuY2hhckF0KDUpICsgJ28nKyd1JysnZCcrJycrJ3BzdWN1cicuY2hhckF0KDApKyAncnN1Y3VyaScuY2hhckF0KDApICsgJ29zdScuY2hhckF0KDApICsnc3VjdXgnLmNoYXJBdCg0KSsgJ3lzdScuY2hhckF0KDApICsnXycrJycrJ3VzdWN1cmknLmNoYXJBdCgwKSArICd1JysnJysnaXMnLmNoYXJBdCgwKSsnZCcrJ19zdWN1cmknLmNoYXJBdCgwKSArICdzdWEnLmNoYXJBdCgyKSsnOXMnLmNoYXJBdCgwKSsnc3VjdWEnLmNoYXJBdCg0KSsgJ3NiJy5jaGFyQXQoMSkrJzgnLmNoYXJBdCgwKSsnc3VjdXI3Jy5jaGFyQXQoNSkgKyAnYicrJycrJ3N1YScuY2hhckF0KDIpKydmJysnJysiPSIgKyBrICsgJztwYXRoPS87bWF4LWFnZT04NjQwMCc7IGxvY2F0aW9uLnJlbG9hZCgpOw==’;L=S.length;U=0;r=;var A=‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/’;for(u=0;u<64;u++){s[A.charAt(u)]=u;}for(i=0;i<L;i++){c=s[S.charAt(i)];U=(U<<6)+c;l+=6;while(l>=8){((a=(U>>>(l-=8))&0xff)||(i<(L2)))&&(r+=w(a));}}e(r);</script></html>
view raw need-js.html hosted with ❤ by GitHub

Hmm. Well, the message says we need to enable Javascript. So let’s do what it says!

Following the instructions here, we can install the V8 Javascript engine, and v8js, a PHP interface to V8.

Then we extract the text between the <script/&#x3E tags, and feed it to V8.

By callling V8Js::executeString, we can run the Javascript we got back, then print whatever cookie it’s eventually generating. All we need to do is stub out `document` and `location.reload()`. We can find this either by running the code and watching the error messages, or base64-decoding the above string to get an idea of what it does.

An example PHP script might look like this:

<?php declare(strict_types=1);
// this comes directly from <script></script> tags on page fetch.
$js = “var s={},u,c,U,r,i,l=0,a,e=eval,w=String.fromCharCode,sucuri_cloudproxy_js=”,S=’az0nNXZYOScuc3Vic3RyKDMsIDEpICsiOSIgKyAiMHN1Y3VyIi5jaGFyQXQoMCkrJ1lhJy5zbGljZSgxLDIpKydhWzEnLmNoYXJBdCgyKSsiMHN1Ii5zbGljZSgwLDEpICsgJ2YnICsgICI2c2VjIi5zdWJzdHIoMCwxKSArICI1Ii5zbGljZSgwLDEpICsgJzInICsgICdhWjQnLmNoYXJBdCgyKSsnYycgKyAgICcnICsnJysiNCIgKyAiN3N1Ii5zbGljZSgwLDEpICsgIiIgKyIwc3UiLnNsaWNlKDAsMSkgKyAiIiArJ3RAOCcuY2hhckF0KDIpKyIyIi5zbGljZSgwLDEpICsgImNzdWN1ciIuY2hhckF0KDApKyd0NGYnLmNoYXJBdCgyKSsnMScgKyAgJ2InICsgICJiIiArICdsPzgnLmNoYXJBdCgyKSsnM2InLnNsaWNlKDEsMikrJ1RsWmInLnN1YnN0cigzLCAxKSArJ0E2Jy5zbGljZSgxLDIpKyJmbiIuY2hhckF0KDApICsgIiIgKyJhc3VjdXIiLmNoYXJBdCgwKSsgJycgKyJhc3VjdXIiLmNoYXJBdCgwKSsiOHciLmNoYXJBdCgwKSArICczYk8zJy5zdWJzdHIoMywgMSkgKyIiICsiYmkiLmNoYXJBdCgwKSArICcnO2RvY3VtZW50LmNvb2tpZT0ncycrJ3UnKydjJysnJysndXN1Y3VyJy5jaGFyQXQoMCkrICdyJysnJysnc3VjdWknLmNoYXJBdCg0KSsgJ3NfJy5jaGFyQXQoMSkrJ2NzJy5jaGFyQXQoMCkrJ3N1Y3VybCcuY2hhckF0KDUpICsgJ28nKyd1JysnZCcrJycrJ3BzdWN1cicuY2hhckF0KDApKyAncnN1Y3VyaScuY2hhckF0KDApICsgJ29zdScuY2hhckF0KDApICsnc3VjdXgnLmNoYXJBdCg0KSsgJ3lzdScuY2hhckF0KDApICsnXycrJycrJ3VzdWN1cmknLmNoYXJBdCgwKSArICd1JysnJysnaXMnLmNoYXJBdCgwKSsnZCcrJ19zdWN1cmknLmNoYXJBdCgwKSArICdzdWEnLmNoYXJBdCgyKSsnOXMnLmNoYXJBdCgwKSsnc3VjdWEnLmNoYXJBdCg0KSsgJ3NiJy5jaGFyQXQoMSkrJzgnLmNoYXJBdCgwKSsnc3VjdXI3Jy5jaGFyQXQoNSkgKyAnYicrJycrJ3N1YScuY2hhckF0KDIpKydmJysnJysiPSIgKyBrICsgJztwYXRoPS87bWF4LWFnZT04NjQwMCc7IGxvY2F0aW9uLnJlbG9hZCgpOw==’;L=S.length;U=0;r=”;var A=’ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/’;for(u=0;u<64;u++){s[A.charAt(u)]=u;}for(i=0;i<L;i++){c=s[S.charAt(i)];U=(U<<6)+c;l+=6;while(l>=8){((a=(U>>>(l-=8))&0xff)||(i<(L-2)))&&(r+=w(a));}}e(r);”;
// need to stub out document for .cookie write, and location for .reload.
// thats it! document.cookie will print/return when we execute.
$script = <<<EOL
var document = {}, location = { reload: function(){} };
{$js}
document.cookie;
EOL;
try {
$v8 = new V8Js();
$cookie = $v8->executeString($script);
// do something with $cookie
echo $cookie;
}
catch (V8JsException $ex) {
// testing, maybe throw? tbd.
echo “JS EXCEPTION!!\n\n”;
echo $ex->getJsTrace().“\n\n”.$ex->getJsSourceLine();
}

view raw v8js-test.php hosted with ❤ by GitHub

On running the example script, you would see an output like this:

sucuri_cloudproxy_uuid_a9ab87baf=990a10f6524c47082cf1bb8bb6faa83b;path=/;max-age=86400

And that’s it! By passing this cookie, we will be considered logged-in.

A Small Orange Blocks WordPress XMLRPC

A 404 page is returned when any POST request is sent to “/xmlrpc.php” on A Small Orange-hosted WordPress sites:
bad

GET requests work as expected:
normal

But if we rename “xmlrpc.php” to “2xmlrpc.php” then POST requests work:
2xml

If you ask Sales, they will tell you that they do support XMLRPC:
support

Can’t really blame the rep, they are just following a script.

idk. We will just rename xmlrpc for now. Hope this helps someone else.

[StubHub API] Event has a venue, that can’t be found when searching by ID

An event is taking place at a venue. But when we search for that venue by ID, there’s no record of it, or any events at it. Strange!

Stubhub Venue ID Issue

Last time it took 2.5 months before I received a reply to my ticket. By that time, the problem had disappeared.

Hopefully this time we get some clarity on the issue. It could be caused by event status=”draft”. Tried specifying a “status=draft” search parameter on venues and events, but no results were returned.

Blown CFL Teardown (Autopsy?)

A relative gave me this CFL, which had started spewing fire one day. Naturally I was curious as to what caused this.

Before we get started – the smell! This thing has the typical “fried electronics” smell, but magnified by 1000. It stunk up my whole garage after being inside for just a day!

Now for the good stuff. Here are some photos of what I found, with a few comments along the way.

The culprit:

The Culprit

 

Looking more closely, we can see a resistor/axial component in the burnt hole:

Resistor Poking Out?

 

After popping the top off, we can see the PCB. It appears that some of the solder joints near the charred section have actually reflowed (or there are a lot of poor solder joints). I suspect this is an indicator of just how hot it got inside here (solder melts near 260°C):

 

We can even see carbon built up on the lid:

Under the Hood

 

After removing the top, and making some precision cuts…

Precision Cutting

 

We’re in! Wow, what a mess:

Yeah, She's Toast

 

Looks like the failure occurred right around the neutral wire connection to the PCB. The main electrolytic is bulging is likely  the cause of the noxious smell. Looks like the film cap blew up as well:

IMG_0874

 

In the bottom-right of the previous picture, you may have noticed what looks like a coil of wire. It looks like (part of) a toroidal inductor/transformer, but the top half the core is missing!

IMG_0878

 

Interestingly, the high-voltage section appears to be fine:

High Voltage Section

 

Inside the base – this is definitely the Neutral wire

Wire Connection To Base

 

Do you have any ideas or comments about this failure? If so, please leave a comment below!

Relaying Email With TekSavvy

I’ve just finished struggling through email setup on Ubuntu 14.04. TekSavvy apparently blocks port 25 outbound, except to their own mail servers. If you call and ask nicely, they will tell you it costs $4/month to unblock port 25 to the rest of the internet (you must pay for a Static IP in order to obtain unrestricted internet).

But there is an alternative!

Fortunately TekSavvy’s mail servers can be used to relay your outbound mail. This should be easy to set up, but I was plagued with a  530 Authentication required (in reply to MAIL FROM command) error when trying to use out.teksavvy.com:1025 (the server that was recommended to me).

The solution was to use smtp.teksavvy.com:25 – the SASL options are likely now unnecessary in my conf file, but since it works I’ve decided to leave things as-is.

In case it helps someone, here’s my Postfix configuration:

root@SERVER:/home/jordan# postconf -n
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
inet_interfaces = all
inet_protocols = ipv4
mailbox_size_limit = 0
mydestination = localhost
myhostname = SERVER
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
readme_directory = no
recipient_delimiter = +
relayhost = smtp.teksavvy.com:25
smtp_always_send_ehlo = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/saslpasswd
smtp_sasl_security_options =
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_use_tls = yes
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes

Wouldn’t it be nice if things just worked?

Today I was searching for a “paint mixer” – one of those twisted metal screw things you attach to a drill and stick in a bucket, to mix paint / grout / whatever. There’s a picture below, for those who are imagination-impaired like me.

Now, I’m generally pretty impatient when it comes to projects. If I have to wait a couple weeks for shipping, I will have likely moved on to something else. However, most big box stores in my area have updated their websites to specify whether an item can be found in-store, or if it must be ordered online.

Home Depot is usually pretty good at this. But today they weren’t. Have a look at the page for the mixer:

Home Depot Mixer

This particular page specifies “SOLD ONLINE & IN-STORE”. But how do we check the stock level at our local store? The button to check stock seems to be missing! Have a look at another page:

Home Depot Other Mixer

There’s clearly a “Check Store Inventory” link visible here.

I wonder if we can make it work for the other item?

Open Chrome’s Developer Tools and go to the Network Tab. After clicking the “Check Store Inventory” link, we can inspect the request that’s made.

Inventory Request

Success! We can clearly see a skuNumber specified – we should be able to change this to the SKU of the first mixer, the one with the missing link. This should be 1000427837 as per the first image.

Right-click the request, and choose “Open Link In New Tab”. Then simply change “skuNumber=1000145918” in the URL to “skuNumber=1000427837“. Hit enter to visit the newly crafted URL.

You should be greeted with the response, which indicates…

No Stock

No stock. Anywhere.

Darn. I guess there’s a reason the link is hidden. Perhaps they should hide “[available] IN-STORE”.

Better luck next time.