Guide to API Privilege Escalation - Application Files

Introduction

The application file contains the functions that you wish for the system to escalate.The application file performs the following steps:

  1. Receives and sanitizes the data.
  2. Authorizes the action.
  3. Performs the requested action.
  4. Returns the result.

How to write the application

You can write your AdminBin application in any programming language. However, in cPanel & WHM version 54 and newer, we recommend that you write the file as a Perl modulino that subclasses the  Cpanel::AdminBin::Script::Class module.

  • The root user must own the file.
  • You must set the file to 0700 permissions (writable, readable, and executable by owner).
  • You must shebang the AdminBin application properly, or compile it.
  • Store this file with the configuration file in a new namespace in the /usr/local/cpanel/bin/admin/ directory.
    • The namespace and the directory name that you create in the /usr/local/cpanel/bin/admin/must be identical.
    • For example, you could create the TheNameSpace namespace and /usr/local/cpanel/bin/admin/TheNameSpace directory.
  • The configuration file should contain the following text:

mode=full

The Call Method

File

Notes:

  • cPanel, Inc. introduced this functionality in cPanel & WHM version 54 for admin modules in Perl. We strongly recommend that you use this method.
  • This example file uses full mode, which the Cpanel::AdminBin::Script::Call module requires.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/local/cpanel/3rdparty/bin/perl
 
# Package the module.
package MyNamespace::MyExample;
 
# Use the strict pragma. (Manners!)
use strict;
 
#Make this module inherit from this “groundwork” admin module.
#This eliminates a large swath of the boilerplate code that admin #modules used to require!
use parent qw( Cpanel::AdminBin::Script::Call );
 
# Use any additional modules.
use Cpanel::Logger               ();
use Cpanel::PwCache              ();
 
#Run the module as a script if (and only if) it is called that way.
#This “modulino” approach helps to facilitate testing and code
#reusability; for example, you could put some of this class’s methods
#into a base class, then have 2 or more admin modules inherit
#from that base class.
__PACKAGE__->run() if !caller;
 
#This special function is a “whitelist” of actions that
#a caller may call. Anything not listed here cannot be called.
#
#By convention, these functions are named
#in ALLCAPS_SNAKE_CASE.
sub _actions {
    return qw(
        DEATH
        ECHO
        MIRROR
        BOUNCY
        HASHIFY
    );
}
 
#If, for some reason, you want to enable an admin action for a demo account,
#then list that action here.
sub _demo_actions { }
 
#------------------------
#Each “action” is its own method.
#It receives the arguments in list form as they were passed
#in to Cpanel::AdminBin::Call::call().
#
#For example, you could call the ECHO action thusly:
#
#Cpanel::AdminBin::Call::call(
#    'MyNamespace',
#    'MyExample',
#    'ECHO',
#    'the string',
#);
#
#...and ECHO would receive 'the string' as the $string argument.
#-----------------------
 
sub ECHO {
    my ($self$string) = @_;
    return $string;
}
 
sub MIRROR {
    my ($self$string) = @_;
    return scalar reverse $string;
}
 
sub BOUNCY {
    my ($self$string) = @_;
    return _bouncy($string);
}
 
sub HASHIFY {
    my ($self$string) = @_;
    return { ourdata => $string };
}
 
sub DEATH {
    die 'Arrgh!';
}
 
#This OPTIONAL function will be called before the function invocation.
#
#The $metadata_hr is a hash reference that contains, as of 11.54,
#a “wantarray” key that indicates the calling context: void, scalar, or list.
#(cf. perldoc wantarray)
#
#$args_ar is the array of arguments from the caller.
#
#NOTE: Both of the foregoing are “live” references. Take extra care
#not to modify them!
#
sub pre_execute_hook {
    my ($self$metadata_hr$args_ar) = @_;
    my $mod_name = (__PACKAGE__ =~ s<.*::><>r);
    Cpanel::Logger->new()->warn(
        sprintf(
            "User %s called the module “%s” with the function “%s” and arguments [%s]",
            $self->get_caller_username(),
            $self->get_action(),
            join( q< >, @$args_ar ),
        )
    );
    return;   #the actual return value(s) is/are ignored
}
 
sub _bouncy {
    my $data_in shift;
    my $data_out = q{};
 
    for my $i ( 0 .. length($data_in) - 1 ) {
        if ($i % 2) {
            $data_out .= substr$data_in,$i,1);
        }
        else {
            $data_out .= uc(substr$data_in,$i,1));
        }
    }
 
    return $data_out;
}
 
1;


The Standard Method

 File

Warning:

The application file must sanitize its own inputs. The system does not sanitize them.

Note:

This example file uses simple mode. However, we recommend that you use full mode whenever possible.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/local/cpanel/3rdparty/bin/perl
use strict;
use Cpanel::AdminBin::Serializer ();
use Cpanel::Logger               ();
use Cpanel::PwCache              ();
  
my $stdin = <STDIN>;
chomp $stdin;
my ($uid,$function,$data) = split (/ /,$stdin,3);
#
 sanitize the input; in this case, only alphanumeric, underscore, space,
 period, and exclamation are allowed $data =~ s/![\w \.\!]//g;  
  
# make a note in the logs! my $user = (Cpanel::PwCache::getpwuid($uid))[0];
my $logger = Cpanel::Logger->new();
$logger -> warn("Myexample called by user $user with function: $function");
  
if ($function eq 'ECHO') {
        print $data;
        exit(0);
}
  
elsif ($function eq 'MIRROR') {
        print scalar reverse($data);
        exit(0);
}
  
elsif ($function eq 'BOUNCY') {
        print _bouncy($data);
        exit(0);
}
  
elsif ($function eq 'HASHIFY') {
        print ".\n" . Cpanel::AdminBin::Serializer::Dump ({ 'ourdata' =>  $data} );
        exit(0);
}
  
else {
        print "Invalid function specified to MyExample adminbin function";
        exit(1);
}
  
1;
  
sub _bouncy {
        my $data_in shift;
        my $data_out = q{};
        for my $i (0..length($data_in)-1) {
                if ($i % 2) {
                        $data_out .= substr$data_in,$i,1); }
                else {
                        $data_out .= uc(substr$data_in,$i,1)); }}
        return $data_out;
}

Parameters

The parameter order that the system passes to the Cpanel::Wrap::send_cpwrapd_request method is constant. However, some parameters' behavior depends on the configuration file's mode value.

 Parameter 

Type

Description

Possible values

Example

version

string

Always set this value toCpanel::AdminBin::Serializer::VERSION

Cpanel::AdminBin::Serializer::VERSION

 Cpanel::AdminBin::Serializer::VERSION 

uid

integer

Required

The authenticated user's user ID. The system passes this value automatically.

Note:

The configuration file's mode value determines this parameter's behavior. 

 

A valid system user ID.

1000

stream

string

A filehandle to which the system streams the application's output.

Warning:

Only use this parameter if you set the action parameter to stream.

A valid filehandle.

Filehandle

namespace

string

Required

The application's namespace.

The application's namespace. This value is identical to the directory name.

NameSpace

module

string

Required

The application's filename.

The application file's filename.

Example

function

string

Required

The application's pseudo-function.

 

Error rendering macro 'multiexcerpt-include' : null

 

A valid string.

ECHO

env

hash reference

Required

A hash reference of keys and values to set in the environment before the AdminBinapplication executes.

  • REMOTE_PASSWORD
  • CPRESELLER
  • CPRESELLERSESSION
  • CPRESELLERSESSIONKEY
  • WHM50
  • cp_security_token
  • Cpanel::Wrap::Config::safe_hashref_of_allowed_env

WHM50

data

scalar or data structure

Required

The data to process.

 

Error rendering macro 'multiexcerpt-include' : null

 

  • A scalar value, if the configuration mode value is simple.
  • A data structure, if the configuration mode value is full.

data

action

string

Required

The output's behavior.

Notes:

  • This value defaults to run.
  • If the AdminBin application module return starts with .\n, the system automatically switches the action to fetch.
  • run — Return the output as a string.
  • fetch — Serialize the output into a JSON structure.
  • stream — Streams the results. This causes the AdminBinserver to send the output directly to the filehandle that the system passed in the stream key to theCpanel::Wrap::send_cpawrapd_request call.
 

run

 

 

  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

The cPanel Interface

For  cPanel  &  WHM  version  58 Overview The cPanel interface is...

User Preferences

For cPanel & WHM version 58 Overview This document outlines how to access your cPanel...

Manage External Authentications

For cPanel & WHM version 58 Overview Manage credentials Additional documentation...

What is cPanelID?

In This Article:  Overview ServicesHow to get a cPanelID cPanelID External...

Guide to cPanel Interface Customization - cPanel Style Development

Introduction You can develop custom styles that modify the appearance of the cPanel interface....