
ArcGIS Enterprise geoprocessing service that publishes a Python toolbox for command execution.
This repository contains an ArcGIS geoprocessing service definition that publishes a Python toolbox as a command-execution task. It is intended for authorized security testing.
Do not publish or use this service on systems where you do not have explicit authorization. A geoprocessing service runs server-side code as the ArcGIS Server service account, so this project can create a web-shell-like interface to the host.
The main artifact is ArcGIS_Shell, a Python toolbox task with one input parameter:
command
When the task runs, the server executes that command through the operating system shell and returns normal console output through the ArcGIS task result.
The repo includes two prebuilt ArcGIS service definition files:
ArcGIS_Shell_10.9.1_and_earlier.sd
ArcGIS_Shell_11_or_later.sd
It also includes extracted service-definition folders:
ArcGIS_Shell_10.9.1_and_earlier/
ArcGIS_Shell_11_or_later/
These folders contain the files that ArcGIS packages into the .sd archives, including the embedded ArcGIS_Shell.pyt files. Edit the extracted folders when changing the service definition, then rebuild the .sd files with package_sd.py.
An ArcGIS service definition (.sd) is a packaged deployment artifact. It contains service metadata, configuration, toolbox or map resources, and supporting files needed by ArcGIS Server to publish a service.
In this repo, each .sd is a 7-Zip archive using ArcGIS-compatible compression settings:
-ms=off
-m0=LZMA:d=14
The two service-definition folders differ mostly by ArcGIS packaging version:
10.9.1 and earlier: p20 paths, offlineSDVersion10x, ArcGIS 2.9 schema
11 or later: p30 paths, offlineSDVersion11, ArcGIS 3.1 schema
The embedded Python toolbox logic is the same in both.
ArcGIS geoprocessing services are normally used to expose GIS analysis workflows over HTTP. A common workflow is:
Legitimate examples include clipping features, running network analysis, processing rasters, generating reports, and performing batch GIS transformations.
The important security property is that geoprocessing tasks execute server-side Python. If a published task accepts user-controlled input and passes it into dangerous primitives such as subprocess.run(..., shell=True), the geoprocessing task becomes a command-execution interface. That is what this project demonstrates.
The Shell task accepts a string parameter named command. The Python toolbox runs that command on the ArcGIS Server host and returns stdout/stderr in the task result.
This means an operator with permission to publish or administer ArcGIS geoprocessing services can create a web-shell-like service through normal ArcGIS functionality. The command runs in the security context of the ArcGIS Server process account.
The service also enables the ArcGIS Uploads capability. This exposes the service upload endpoints:
/arcgis/rest/services/ArcGIS_Shell/GPServer/uploads
/arcgis/rest/services/ArcGIS_Shell/GPServer/uploads/upload
Uploads are stored by ArcGIS Server in the site system directory, typically under a path like:
<arcgisserver>/directories/arcgissystem/arcgisuploads/<itemID>
The exact path depends on the ArcGIS Server directory configuration. Administrators can view uploaded items through:
https://<server>/arcgis/admin/uploads?f=pjson
Do not manually modify or delete files in arcgissystem. Delete upload items through REST or the Administrator Directory.
Use the .sd file that matches the target ArcGIS version:
ArcGIS_Shell_10.9.1_and_earlier.sd
ArcGIS_Shell_11_or_later.sd
Typical Server Manager flow:
Open ArcGIS Server Manager:
https://<server>/arcgis/manager
Sign in with an account authorized to publish services. This typically includes portaladmin.
Go to Services.
Click Publish Service.
Upload the appropriate .sd file for the ArcGIS version. Click Next.
On the "Specify properties for your new service" page, modify the service name if desired. Click Next.
On the "Share your services with" page, you do not need to check any boxes. Click Publish.
The service automatically starts. Click the service name, then Capabilities, then the REST URL.
To delete the service, click the "X" next to the service name.
The prebuilt .sd files already include:
"capabilities": "Uploads"
They also include broad upload settings for testing:
"maxUploadFileSize": "2048",
"allowedUploadFileTypes": "<broad explicit extension list>"
maxUploadFileSize is in MB. The extension list is intentionally broad for assessment work, but it is still an explicit allowlist, not a true "allow everything" wildcard.
After publishing, open the service in the ArcGIS REST Services Directory:
https://<server>/arcgis/rest/services/ArcGIS_Shell/GPServer
If the service is published inside a folder, include the folder name:
https://<server>/arcgis/rest/services/<folder>/ArcGIS_Shell/GPServer
Open the task:
https://<server>/arcgis/rest/services/ArcGIS_Shell/GPServer/Shell
Click Execute Task.
Set your comand and submit the form. The task result should contain the command output.
Output is JSON formatted, so newlines are escaped (\r\n). You will need to post-process multi-line output.
Because the task uses the operating system shell, shell built-ins work:
dir
echo test
whoami /groups
On Linux targets, use Linux commands:
id
uname -a
pwd
Open the uploads resource:
https://<server>/arcgis/rest/services/ArcGIS_Shell/GPServer/uploads
Click Upload Item, or go directly to:
https://<server>/arcgis/rest/services/ArcGIS_Shell/GPServer/uploads/upload
The REST web GUI should show a file picker if uploads are enabled.
Use the form to choose a file and submit the upload. The response includes an itemID.
Inspect the uploaded item with:
https://<server>/arcgis/rest/services/ArcGIS_Shell/GPServer/uploads/<itemID>
Delete the uploaded item with:
https://<server>/arcgis/rest/services/ArcGIS_Shell/GPServer/uploads/<itemID>/delete
Use the REST web form on that page to submit the delete operation.
Uploaded files are also subject to the ArcGIS Server system directory cleanup policy. The default system directory cleanup age is commonly 24 hours, but administrators can change it.
ArcGIS stores service uploads in the ArcGIS Server site system directory, not in the service folder and not inside the .sd package. The usual location is:
<server-directories-root>/arcgissystem/arcgisuploads/<itemID>/
Common Windows layout:
C:\arcgisserver\directories\arcgissystem\arcgisuploads\<itemID>\
Common Linux layout:
/arcgis/server/usr/directories/arcgissystem/arcgisuploads/<itemID>/
Those are only examples. The exact path depends on how the ArcGIS Server site directories were configured.
To find the exact disk path, open the Administrator Directory:
https://<server>/arcgis/admin/uploads?f=pjson
Look for the uploaded item's itemID. The entry should include fields similar to: