Auteursarchief: David (admin)

wp-time-capsule < 1.17.0 Unrestricted File Upload vulnerability

Yesterday, one of my customers had their WordPress website hacked. An out-of-date plugin had allowed uploading an arbitrary PHP file, and someone had used this to drop a few files on serveral locations on the website. Luckily the IDS picked up on this quickly, and we could remove the infection and fix the hole.

What happened?

If we just restore the website, and do not plug the hole, the website will be hacked again in no time. So how did they gain access?

According to the webserver logs, a POST was performed to /wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/upload/php/index.php. That index.php file is just including /wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/upload/php/UploadHandler.php and instantiating the UploadHandler class. After sending the POST request to index.php, a webshell was created on the server, which was then used to drop the other files.

There was a .htaccess file in /wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge that could have prevented this, but not every webserver even supports .htaccess files.

First thing I did was compare UploadHandler.php to the most recent version of the file. Apart from a few empty lines, the difference between UploadHandler.php in 1.16.3 and 1.17.0 is:

@@ -377,10 +379,21 @@
             return false;
         }

-        if (!in_array($file->type, $this->options['accept_file_types'])) {
+
+
+        $allowed_extensions = array('.sql', '.gz', '.crypt');
+        $found = false;
+        foreach ($allowed_extensions as $extension) {
+            if(strrpos($file->name, $extension) + strlen($extension) === strlen($file->name)){
+                $found = true;
+            }
+        }
+
+        if (!$found) {
             $file-&>error = $this->get_error_message('accept_file_types');
             return false;
         }
+
         if ($uploaded_file && is_uploaded_file($uploaded_file)) {
             $file_size = $this->get_file_size($uploaded_file);
         } else {

The version 1.16.3 used content-type (a untrusted field) to check for file type, the new version checks the actual file extension. If you can modify the headers of the HTTP-request to spoof a application/sql type of file, you can basically upload anything you like.

Lets just make a proof of concept here. First create a file test.php with some malicious code. Then upload it using:

curl -H Expect: -F "files=@test.php;type=application/sql" http://www.example.com/wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/upload/php/index.php

Now your file is available through http://www.example.com/wp-content/plugins/wp-time-capsule/wp-tcapsule-bridge/upload/php/text.php

Version 1.17.0 of the wp-time-capsule plugin patches the vulnerability by implementing a file extension check, but the changelog does not mention this at all. I believe making a coding error could happen, but covering it up is unpermissible. I prefer to stay away from software developers that don't report on their security problems.

Had this vulnerability been reported transparently, then the WP management software this customer uses would probably have flagged this update as necessary.

Why?

Why was wp-time-capsule out of date in the first place? Because the customer installed a plugin to defer and hide updates... They install updates through some central WordPress management platform like InfiniteWP or ManageWP.

© GeekLabInfo wp-time-capsule < 1.17.0 Unrestricted File Upload vulnerability is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Update KB4011086 sets Outlook 2007 language to Swedish

Last night Microsoft released several updates. One of them sets the language of parts of Outlook 2007 installations to Swedish.

Turns out, this is KB4011086. Uninstalling KB4011086 reverts all of outlook to the correct language.

Scripted fix:
msiexec /package {90120000-001A-040E-0000-0000000FF1CE} /uninstall {BBE4FD45-34D1-4497-8F75-77965C4E044D} /qn /quiet /norestart

Or remotely:
psexec \\computername "msiexec.exe" /package "{90120000-001A-040E-0000-0000000FF1CE} /uninstall {BBE4FD45-34D1-4497-8F75-77965C4E044D} /qn /quiet /norestart"

Update: Turns out more people have experienced this problem:
http://www.helpmij.nl/forum/showthread.php/923889-Outlook-is-ineens-tweetalig
https://gathering.tweakers.net/forum/list_messages/1801205
https://social.technet.microsoft.com/Forums/office/en-US/72037dce-f8bb-475f-8f2d-4af6b3a9ea88/latest-outlook-2007-security-patch-kb4011086-wrong-patch-change-app-language-to-swedish
https://www.reddit.com/r/sysadmin/comments/6zsxs3/outlook_2007_suddenly_in_2_languages_uninstall/

© GeekLabInfo Update KB4011086 sets Outlook 2007 language to Swedish is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5,00 out of 5)
Loading...

Update KB4011086 sets Outlook 2007 language to Swedish

Last night Microsoft released several updates. One of them sets the language of parts of Dutch Outlook 2007 installations to Swedish.

Turns out, this is KB4011086. Uninstalling KB4011086 reverts all of outlook to the correct language.

Scripted fix:
msiexec /package {90120000-001A-040E-0000-0000000FF1CE} /uninstall {BBE4FD45-34D1-4497-8F75-77965C4E044D} /qn /quiet /norestart

Or remotely:
psexec \\computername "msiexec.exe" /package "{90120000-001A-040E-0000-0000000FF1CE} /uninstall {BBE4FD45-34D1-4497-8F75-77965C4E044D} /qn /quiet /norestart"

Update: Turns out more people have experienced this problem:
http://www.helpmij.nl/forum/showthread.php/923889-Outlook-is-ineens-tweetalig
https://gathering.tweakers.net/forum/list_messages/1801205
https://social.technet.microsoft.com/Forums/office/en-US/72037dce-f8bb-475f-8f2d-4af6b3a9ea88/latest-outlook-2007-security-patch-kb4011086-wrong-patch-change-app-language-to-swedish
https://www.reddit.com/r/sysadmin/comments/6zsxs3/outlook_2007_suddenly_in_2_languages_uninstall/

© GeekLabInfo Update KB4011086 sets Outlook 2007 language to Swedish is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5,00 out of 5)
Loading...

Windows 7 and Windows 8 updates slow

The last few months, I've noticed brand new clean Windows 7 installs have a hard time updating for the first time. Doesn't matter if they are updating from the original Microsoft update service of from a WSUS server, the time until the first update sometimes can be hours.

This update is supposed to fix that. I haven't tried it myself yet:
https://support.microsoft.com/en-us/kb/3161608

© GeekLabInfo Windows 7 and Windows 8 updates slow is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Fix idealcheckout_unserialize

Sorry, I don't feel like typing a message dedicated to this fix I made. Let's just post the code.

Original code:

function idealcheckout_unserialize($sString)
    {
        // Recalculate multibyte strings
        $sString = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $sString);
        return unserialize($sString);
    }

Error:

PHP Deprecated:  preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in ... on line ..

This means idealcheckout_unserialize is not php7 compatible.

My fix:

    // Unserialize data
    function idealcheckout_unserialize($sString)
    {
        // Recalculate multibyte strings
        $sString = preg_replace_callback('!s:(\d+):"(.*?)";!s',
            function($matches){
                return 's:'.strlen($matches[2]).':"'.$matches[2].'";';
            }, $sString);
        return unserialize($sString);
    }
© GeekLabInfo Fix idealcheckout_unserialize is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Delete KB3035583 to remove Windows 10 nag screen.

KB3035583 is the annoying "please update to windows 10" nag screen.

(This post is mostly a note to self.)

© GeekLabInfo Delete KB3035583 to remove Windows 10 nag screen. is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

How to check connection between windows and anywhere usb with nagios

The easiest way to monitor the connection between your Digi Anywhere USB device and a server is to monitor the USB device connected it. I use Nagios to monitor several indicators in each server, and the following script can be used to monitor if USB devices are connected:

strComputer = "."
 
Set objWMIService = GetObject("winmgmts:\\" &amp; strComputer &amp; "\root\cimv2")
Set colDevices = objWMIService.ExecQuery ("Select * From Win32_USBControllerDevice")
 
For Each objDevice in colDevices
    strDeviceName = objDevice.Dependent
    strQuotes = Chr(34)
    strDeviceName = Replace(strDeviceName, strQuotes, "")
    arrDeviceNames = Split(strDeviceName, "=")
    strDeviceName = arrDeviceNames(1)
    Set colUSBDevices = objWMIService.ExecQuery ("Select * From Win32_PnPEntity Where DeviceID = '" &amp; strDeviceName &amp; "'")
    For Each objUSBDevice in colUSBDevices
        'Wscript.Echo objUSBDevice.Description
        If objUSBDevice.Description="SCR3311 USB Smart Card Reader" Then
           WScript.Echo "OK - Card reader detected"
           WScript.Quit 0
        End If
    Next
Next
 
WScript.Echo "WARNING - No card reader detected"
WScript.Quit 1

In my case, I monitor a card reader that identifies as "SCR3311 USB Smart Card Reader". You should type the exact name of the device you're monitoring at that spot. If you don't know the exact name of the device, uncomment the line
'Wscript.Echo objUSBDevice.Description
and then execute
cscript //nologo //t:10 "check_cardreader.vbs"

Put above file in c:\program files (x86)\nrpe\check_cardreader.vbs and update nrpe.cfg to contain:
command[check_cardreader]=cscript //nologo //t:10 "c:\program files (x86)\nrpe\check_cardreader.vbs"

After restarting the NRPE service, you're ready to monitor the USB device.

© GeekLabInfo How to check connection between windows and anywhere usb with nagios is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

iptables and dynamic DNS – part 3

This is an updated post for this updated article.

I just found back an old note about using iptables in combination with dyndns to open up access from a remote location. For instance, if you have a laptop that you take everywhere and you want to connect to your home or office. The script the other site suggested was broken, so let's write a new one.

Step 1: Create a new chain in the firewall

Create a new chain in the firewall where we can plug in the dynamic rules. On my Fedora machine, the firewall is located in /etc/sysconfig/iptables. I added the bold lines to this example.


*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
<b>:DYNAMICPARENT - [0:0]
-A INPUT -j DYNAMICPARENT</b>
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

Step 2: Write a script

#!/bin/bash
 
HOSTNAME=myname.dyndns.org
CHECK_INTERVAL=60 #once a minute
 
IP="" #initialize $IP
while [ true ]; do
        OIP=$IP
        IP=$(dig +short $HOSTNAME | grep -iE "^[0-9]+.[0-9]+.[0-9]+.[0-9]+$"|head -n 1)
        if [ "$OIP" != "$IP" -a "$IP" != "" ]; then
                echo "Changing ip to $IP"
                /sbin/iptables -N DYNAMICNEW                    # create new rule
                /sbin/iptables -I DYNAMICNEW -s $IP -j ACCEPT   # allow new ip
                /sbin/iptables -I DYNAMICPARENT -j DYNAMICNEW   # attach new rule to its parent
 
                while [ true ]; do  # unlink old rule - if multiple exist, remove all
                        /sbin/iptables -D DYNAMICPARENT -j DYNAMICCHILD 2>/dev/null || break
                done
                /sbin/iptables -F DYNAMICCHILD #flush all old rules
                /sbin/iptables -X DYNAMICCHILD #flush all old rules
 
                /sbin/iptables -E DYNAMICNEW DYNAMICCHILD #rename new to "current"
        fi
        sleep $CHECK_INTERVAL
done

In this case, the firewall accepts all traffic from $IP, but of course you could restrict it to 1 port. Also, I focussed on IPv4, but you could easily rewrite this script to IPv6 using ip6tables. I saved the file to /usr/local/bin/dynfirewall.sh

Step 3: Run the script

I'd prefer running the script from inittab, but since Fedora doesn't work like this anymore, I put the following line in /etc/rc.d/rc.local:

/usr/local/bin/dynfirewall.sh >>/var/log/dynfirewall 2>>/var/log/dynfirewall &

Please don't forget the ampersand at the end to fork the script!!

Why is this script better than previous version?

- This script can handle cnames
- The old script used to delete old rules, before creating new ones. This one does not. Therefore, it will never leave a second where you cannot connect.

© GeekLabInfo iptables and dynamic DNS - part 3 is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5,00 out of 5)
Loading...

iptables and dynamic DNS – part 2

In 2011, I wrote this post on Dynamic DNS: https://www.geeklab.info/2011/02/iptables-and-dynamic-dns. While this is still useful, I found a newer, cooler way to do Dynamic DNS in combination with iptables. It's called libnetfilter_queue.

iptables is used to change the inner netfilter tables of the kernel. And because the kernel has no internal resolver, it is impossible for the kernel to do on-the-fly dns lookups. But by offloading this decision to userspace, it is possible. The libnetfilter_queue lib offers that functionality.

libnetfilter_queue is a userspace library providing an API to packets that have been queued by the kernel packet filter. It has bindings for Python and several other languages.

Requirements for my setup

python-NetfilterQueue - https://github.com/kti/python-netfilterqueue

libnfnetlink

libnetfilter_queue

libmnl

You may need to build the first dependency yourself. The other 3 are available in Fedora 20 by default. If you're running RHEL/CentOS, the Fedora packages can be recompiled for your setup.

iptables rule

First, you need to get iptables to enqueue specific packets to your queue.

iptables -I INPUT -p tcp --dport 631 -m state --state NEW -j NFQUEUE --queue-num 6789 -m comment --comment "Remote CUPS printer"

Queue handler

Then we write a script that handles the queue. A quick-and-dirty implementation:

#!/usr/bin/python
 
import socket
from netfilterqueue import NetfilterQueue
 
def getIP(d):
    """
    This method returns the first IP address string
    that responds as the given domain name
    """
    try:
        data = socket.gethostbyname(d)
        #ip = repr(data)
        return data
    except Exception:
        # fail gracefully!
        return False
 
def dnsfilter(pkt):
        if pkt.get_payload_len() < 0x10:
                "Don't know how to handle this too small packet"
                pkt.drop()
                return False
 
        payload=pkt.get_payload()
        srcip=".".join("{:d}".format(ord(c)) for c in payload[0x0c:0x10])
        allowedip=getIP('localhost')
        print "Debug: SRC="+srcip+" ALLOWED="+allowedip+" RESULT=",
        if srcip==allowedip:
                print "Accept"
                pkt.accept()
        else:
                print "Drop"
                pkt.drop()
 
nfqueue = NetfilterQueue()
nfqueue.bind(6789, dnsfilter)
try:
        nfqueue.run()
except KeyboardInterrupt:
        print

This is a quick-and-dirty implementation that misses basic features such as caching the result of gethostbyname. This may introduce terrible delays if used wrong.

Ubuntu/Debian

I'm running RedHat-based software on all of my machines. Above information may be useful for Ubuntu/Debian users, but it's not tested and I'm not supporting it.

Servers: RedHat Enterprise Linux/CentOS is more suitable for servers, as there's a lot of professional level support available. I think that's important, because if I say, get a car accident, I want the servers to be managable by another professional.

Desktops/Laptops: RPM packages are pretty exchangable between RedHat-based platforms. That's a good reason to run Fedora on the desktop.
© GeekLabInfo iptables and dynamic DNS - part 2 is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

How to monitor a Konica-Minolta printer’s settings using Nagios

For some reason, some users seem not to be able to keep their hands off the settings of my KonicaMinolta Bizhub 283. They keep changing the paper format for tray 2 to PlainPaper, causing all kinds of problems. Since there is no way to lock the settings, I started to monitor them and report them.

This is my Nagios script:

#!/usr/bin/python
 
import os
import pycurl
import cStringIO
import re
import random
import time
import tempfile
import sys
 
from lxml import etree
 
newcookiefile = tempfile.NamedTemporaryFile()
 
if len(sys.argv)!=2:
        print "Usage: "+sys.argv[0]+" [printer ip or hostname]"
        sys.exit(1)
 
buf = cStringIO.StringIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, "http://"+sys.argv[1]+"/wcd/index.html")
c.setopt(pycurl.COOKIEFILE, newcookiefile.name)
c.setopt(pycurl.COOKIEJAR, newcookiefile.name)
c.setopt(pycurl.WRITEFUNCTION, buf.write)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.ENCODING, "")
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.SSL_VERIFYHOST, 0)
c.setopt(pycurl.USERAGENT, "Something")
c.perform()
curlData = buf.getvalue()
buf.close()
 
buf = cStringIO.StringIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, "http://"+sys.argv[1]+"/wcd/system.xml")
c.setopt(pycurl.COOKIEFILE, newcookiefile.name)
c.setopt(pycurl.COOKIEJAR, newcookiefile.name)
c.setopt(pycurl.WRITEFUNCTION, buf.write)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.ENCODING, "")
c.setopt(pycurl.SSL_VERIFYPEER, 0)
c.setopt(pycurl.SSL_VERIFYHOST, 0)
c.setopt(pycurl.USERAGENT, "Something")
c.perform()
curlData = buf.getvalue()
buf.close()
 
#print curlData
 
tree = etree.fromstring(curlData)
root = etree.Element("root")
paperformat=tree.xpath('/MFP/DeviceInfo/Input/TrayList/Tray/TrayID[text()="Tray2"]/../CurrentPaper/MediaType')[0].text
 
if "PlainPaper" == paperformat:
        print "Someone touched the settings - again!"
        sys.exit(2)
 
print "OK"
sys.exit(0)
© GeekLabInfo How to monitor a Konica-Minolta printer's settings using Nagios is a post from GeekLab.info. You are free to copy materials from GeekLab.info, but you are required to link back to http://www.geeklab.info
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...