letsencrypt for cPanel/WHM


First of all, I’m a huge fan of Let’s Encrypt.  Letsencrypt team has released a public beta version of ACME client, so we can obtain valid, trusted SSL certificates for our domains for free.

Unfortunately letsencrypt client does not support cPanel but same time we will be able to download certificates from their server and then we have to install it manually.  So, I have developed a  WHM plugin, which would help cPanel administrators to install and  setup letsencrypt  on cPanel/WHM servers very easily.


$> /usr/local/cpanel/3rdparty/bin/git clone https://github.com/Prajithp/letsencrypt-cpanel.git cd letsencrypt-cpanel 

$> ./install.sh

Please note that rate limits are currently in place for the Let’s Encrypt service, so you may get some warnings and errors while requesting for new certificates.

ApacheBooster V2.5 released

A new version of the ApacheBooster (2.5) is available at the download page!

We have made several changes in configuration and also fixed some bugs. Please see the new features and updates.

✔ Fixed domain dedicated IP issue
✔ Changed nginx embedded vhost template to perl template toolkit.
✔ Updated /scripts/generate_varnish_conf script to fix the varnish IP address conflict.
✔ Option to disable/enable apachebooster temporarily.
✔ Upgraded nginx and varnish to latest version

In this version, customers have the ability to customize nginx vhost config template as per their needs.
New nginx vhost config template file can be found in /var/ApacheBooster/templates directory.

You can use the below commands to disable or enable ApacheBooster, this will be helpful for administrators to troubleshoot some apache and php related issues.
$> /scripts/manage_apacheboooster --enable
$> /scripts/manage_apacheboooster --disable

For update and installation, feel free to contact our tech support.

Automation with Perl Rex

Today I’ve started to play with perl Rex which is one of the great tool for automating server management tasks. I have never used Chef or Puppet or Ansible, so I did not know what to expect and what are the options available in Chef, Puppet and Ansible, but so far I love it.

Since Rex is using SSH as its transport layer, so we only have to install Rex on one machine (it can be your laptop). We don’t need to install anything on client machines exept SSH server (openssh). Rex configuration is also simple (only if you know perl :D).

Rex runtime configration file name is “Rexfile” and its perl syntax with some Rex own methods. An example of Rexfile as follow:

use Rex -feature => ['1.0'];
use Data::Dumper;

user "root";

group web_server => "prajith.in", "repo.prajith.in";
group db_server  => "", "", "";

desc "Get Disk Free";

task "disk_free", group => "own_server", sub {
  my $output = run "uptime";
  print $output;

desc "Get server information";

task "get_os", group => "own_server", sub {
  my $os         = get_operating_system();
  my $os_version = operating_system_version();

  my $memory = memory();
  Rex::Logger::info("RAM: $memory->{total} Mb");
  my $cpu_stat = `grep '^cpu[0-9]' /proc/stat`;
  my $cpu = scalar ($cpu_stat =~ /(cpu[0-9])/g);

  my $data = {
    os         => $os,
    os_version => $os_version,
    memory     => $memory,
    cpu        => $cpu,
print Dumper $data;

You can run the abouve task with the following command:

$> rex get_os
$> rex disk_free

You can find more examples at (R)?ex commands

Rex has a great set of modules for managing different things like installing RHEL packages, and managing virtualization(Virtualbox, openvz, etc..)

error: field ‘st_atim’ has incomplete type FFMPEG

While installing ffmpeg-php-0.6.0  on centos server, if you may came across the below error , like ::

In file included from /usr/include/sys/stat.h:107,
 from /usr/include/php/main/php_streams.h:28,
 from /usr/include/php/main/php.h:395,
 from /root/ffmpeg-php-0.6.0/ffmpeg-php.c:40:
/usr/include/bits/stat.h:91: error: field ‘st_atim’ has incomplete type
/usr/include/bits/stat.h:92: error: field ‘st_mtim’ has incomplete type
/usr/include/bits/stat.h:93: error: field ‘st_ctim’ has incomplete type
/usr/include/bits/stat.h:152: error: field ‘st_atim’ has incomplete type
/usr/include/bits/stat.h:153: error: field ‘st_mtim’ has incomplete type
/usr/include/bits/stat.h:154: error: field ‘st_ctim’ has incomplete type
In file included from /usr/include/php/main/php_streams.h:28,
 from /usr/include/php/main/php.h:395,
 from /root/ffmpeg-php-0.6.0/ffmpeg-php.c:40:
/usr/include/sys/stat.h:367: error: array type has incomplete element type
/usr/include/sys/stat.h:374: error: array type has incomplete element type
In file included from /usr/include/php/main/php.h:401,
 from /root/ffmpeg-php-0.6.0/ffmpeg-php.c:40:
/usr/include/php/TSRM/tsrm_virtual_cwd.h:218: error: expected specifier-qualifier-list before ‘time_t’
/usr/include/php/TSRM/tsrm_virtual_cwd.h:246: error: expected declaration specifiers or ‘...’ before ‘time_t’
/root/ffmpeg-php-0.6.0/ffmpeg-php.c: In function ‘zm_startup_ffmpeg’:
/root/ffmpeg-php-0.6.0/ffmpeg-php.c:94: warning: implicit declaration of function ‘avcodec_init’

After looking up for hours, I found the issue that ffmpeg own time.h file was conflicting with centos own time.h file, unfortunately ffmpeg-php has not been updated in a long time, so decided to search ffmpeg php extension on github and I found a repo maintained by tony2001 who has made some changes to the original project and using his repo I’m able to install it  on CentOS-6.5  but I guess  it works on other centos versions too

Follow the steps below to install it

git clone https://github.com/pbek/ffmpeg-php.git
cd ffmpeg-php
make && make install


External XML entity injection in WHM locale upload interface.

The WHM/cPanel XML locale file uploads allowed the processing of external XML entities. This would permit resellers with the ‘locale-edit’ ACL to read any files on the system, make arbitrary network connections, and can also DoS the server with the billion laughs attack.

Fixed Version:
This issue is resolved in the following builds:

cPanel rewarded me $1000 for reporting this vulnerability :)

Just try:: chmod -x /bin/chmod

What will happen if you remove the executable flag from the chmod binary itself? 😀

root@server:~# chmod -x /bin/chmod
root@server:~# chmod +x /bin/chmod
-bash: /bin/chmod: Permission denied
root@server:~# ls -ld /bin/chmod
-rw-r--r-- 1 root root 51760 Apr  1  2012 /bin/chmod

How do you recover chmod in this case and make it executable again?  Here is a list of possible solutions 😀

1) perl -e 'chmod 0755, "/bin/chmod"'
2) 32 bit OS
     /lib/ld-linux.so.2 /bin/chmod +x /bin/chmod
   64 bit OS
     /lib64/ld-linux-x86-64.so.2 /bin/chmod +x /bin/chmod
3) install -m a+x /bin/chmod /root/chmod
   /root/chmod +x /bin/chmod
4)  cat > chmod.c << EOF
    printf("Hello World");

gcc chmod.c -o /tmp/chmod
cat /bin/chmod > /tmp/chmod
/tmp/chmod +x /bin/chmod 


mod_reveseproxy: extract client IP from reverse proxy

If you setup Apache 2.4 With mod_remoteip, the apache extendedstatus always gives you the proxy IP, instead of client IP, actually this is due to that the mod_status  set client IP very early when there is a TCP connection but no headers, Apache 2.4 allows per-request notion of overriding the client address, but not at this early stage. To overcome this issue, I would suggest you to use mod_reveseproxy apache module, the modules is completely based on mod_cloudflare and mod_remoteip.

To install, follow the instructions on:


   wget https://raw.github.com/Prajithp/mod_reverseproxy/master/mod_reverseproxy.c
   apxs -i -c -n mod_reverseproxy.so mod_reverseproxy.c  

Configuration Directives

ReverseProxyEnable           (On|Off)          - Enable reverse proxy

ReverseProxyRemoteIPHeader   X-Real-IP         - The header to use for the real IP
ReverseProxyRemoteIPTrusted         -  What IPs to adjust requests for

Example Configuration

LoadModule reverseproxy_module modules/mod_reverseproxy.so

<IfModule reverseproxy_module>
  ReverseProxyEnable  On
  ReverseProxyRemoteIPHeader X-Real-IP


  • If mod_cloudflare or mod_remoteip are already loaded on the same web server, the web server will crash because both modules try to set the remote IP to a different value.


WHM/cPanel Cross-Site Scripting Vulnerability

WHM/cPanel is prone to  cross-site scripting vulnerabilities because it fails to properly sanitize users inputs and datastore files.

Due to the nature of this security flaw,  I will not be posting a Proof of Concept until much later.


Type: XSS
Product: cPanel
Website: http://www.cpanel.net
Vulnerable Version: WHM 11.40 and prior.
Date: 11/11/2013
By: Prajith P <http://prajith.in>

Vendor Contact Timeline:

2013-111-11: 3:37 AM IST – Vendor contacted via email.

2013-111-11: 7:44 AM IST –  Vendor confirmed vulnerability. and filed security report(case number 82701).

Don’t restore cPanel backup from untrusted source

In WHM, there is a feature  “restore account”  which is used to restore a full account backup. Normal users can generate the backup  from cPanel and  It contains all the information for an account including the files and  meta data.

One of the meta data items is MySQL grants which is located inside the backup file. When you are restoring the account using WHM UI or restorepkg command, the mysql meta file will be restored as root user.
Now you may be thinking that there’s nothing wrong, and everything looks normal. But this is really really bad because you can embed arbitrary commands in SQL files and those commands will execute when the file is restored as  root user. Let me explain it.


root@server1 [/home/prajith]# cat mysql.sql
\! id
root@server1 [/home/prajith]# mysql < mysql.sql
uid=0(root) gid=0(root) groups=0(root)
root@server1 [/home/prajith]

so we can insert any linux commands to mysql meta file and this will be execute as root while restoring the account.

Here is an example:

  GRANT USAGE ON *.* TO 'whmtest'@'localhost' IDENTIFIED BY PASSWORD '*A4E12252EACEA5A79<XXXXX>E11D47296FE237D5897'\g system /etc/.my.cnf >> /tmp/test.txt;
GRANT ALL PRIVILEGES ON `whmtest\_pop`.* TO 'whmtest'@'localhost';

while restoring the account,  mysql will execute the linux commands using system function and the output will be saved to /tmp/test.txt and later we can read this file using http request. so don’t restore the backup from untrusted source 😀