From c0a2f9da27937d9e255b31a746cf9ba7e85292d9 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Sat, 19 Sep 2026 20:55:44 +0000 Subject: [PATCH] Add content from: TiDB 8.5.2 Security Assessment: Unauthenticated Internal API... --- src/SUMMARY.md | 1 + .../4000-10080-pentesting-tidb.md | 157 ++++++++++++++++++ .../pentesting-web/golang.md | 6 + 3 files changed, 164 insertions(+) create mode 100644 src/network-services-pentesting/4000-10080-pentesting-tidb.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 05694bfec64..b0b1cc30f48 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -665,6 +665,7 @@ - [3632 - Pentesting distcc](network-services-pentesting/3632-pentesting-distcc.md) - [3690 - Pentesting Subversion (svn server)](network-services-pentesting/3690-pentesting-subversion-svn-server.md) - [3702/UDP - Pentesting WS-Discovery](network-services-pentesting/3702-udp-pentesting-ws-discovery.md) +- [4000,10080 - Pentesting TiDB](network-services-pentesting/4000-10080-pentesting-tidb.md) - [4369 - Pentesting Erlang Port Mapper Daemon (epmd)](network-services-pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md) - [4786 - Cisco Smart Install](network-services-pentesting/4786-cisco-smart-install.md) - [4840 - OPC Unified Architecture](network-services-pentesting/4840-pentesting-opc-ua.md) diff --git a/src/network-services-pentesting/4000-10080-pentesting-tidb.md b/src/network-services-pentesting/4000-10080-pentesting-tidb.md new file mode 100644 index 00000000000..00da97bf4d6 --- /dev/null +++ b/src/network-services-pentesting/4000-10080-pentesting-tidb.md @@ -0,0 +1,157 @@ +# 4000,10080 - Pentesting TiDB + +{{#include ../banners/hacktricks-training.md}} + +## Basic Information + +TiDB is a distributed SQL database with a MySQL-compatible client listener, but an assessment must also cover the HTTP status and control planes of TiDB, Placement Driver (PD), TiKV, and the monitoring stack. These interfaces are normally useful only from trusted cluster networks; if they are reachable after an SSRF, VPN foothold, container escape, or internal-host compromise, they can expose topology and runtime data or accept administrative operations without database credentials.[[1]](#references)[[3]](#references) + +Common listeners are shown below. Ports are configurable, and **9090** is the Prometheus listener observed in the assessed deployment rather than a TiDB protocol port.[[1]](#references)[[3]](#references) + +| Port | Component | Purpose | +| --- | --- | --- | +| `4000/tcp` | TiDB | MySQL protocol for applications and DBA tools | +| `10080/tcp` | TiDB | HTTP status, metrics, configuration, and profiling | +| `2379/tcp` | PD | TiDB-to-PD traffic and PD HTTP API | +| `2380/tcp` | PD | Communication between PD nodes | +| `20160/tcp` | TiKV | TiKV service traffic | +| `20180/tcp` | TiKV | HTTP status and metrics | +| `9090/tcp` | Prometheus | Monitoring UI and HTTP API when deployed | + +## Listener and transport enumeration + +From a cluster host, map each socket to its process; remotely, scan the complete component set instead of stopping at the MySQL-compatible listener. Then test HTTP and HTTPS separately because an open status port might be plaintext, server-authenticated TLS, or mTLS.[[1]](#references)[[3]](#references) + +```bash +# Local host +ss -lntp +netstat -tlnp + +# Remote host(s) +nmap -sV -Pn -p 2379,2380,4000,9090,10080,20160,20180 +curl -m 3 -i http://:10080/status +curl -m 3 -ki https://:10080/status +openssl s_client -connect :10080 -servername [[1]](#references)[[8]](#references) + +## TiDB status API - `10080/tcp` + +The status server exposes `/status`, `/metrics`, schema/storage metadata, configuration, and Go profiling handlers. In the audited v8.5.2 router, `GET /` also generated an HTML index from named routes, which makes it a useful first request; exact routes and methods vary by release.[[4]](#references)[[5]](#references) + +```bash +base=http://:10080 +curl -si "$base/" +curl -s "$base/status" | jq . +curl -s "$base/config" | jq . +curl -s "$base/info" | jq . +curl -s "$base/info/all" | jq . +curl -s "$base/schema_storage" | jq . +curl -s "$base/ddl/history" | jq . +curl -s "$base/metrics" | head +``` + +An unauthenticated `/config` response can disclose advertised addresses, PD endpoints, Unix sockets, temporary and storage directories, log and slow-query filenames, and operational limits. Use those values to build the cluster graph and identify follow-on hosts and paths; configuration disclosure alone is not code execution.[[1]](#references) + +The same router can include control handlers such as `/ddl/owner/resign`, `/upgrade/{op}`, and table scatter/stop-scatter operations. Confirm exposure with the route index and source/version mapping, but do not invoke state-changing routes outside an explicitly authorized disposable environment.[[1]](#references)[[5]](#references) + +### Exposed Go `pprof` + +TiDB and supporting Go services can publish `net/http/pprof` below `/debug/pprof/`. The index lists available profiles; `cmdline` returns NUL-delimited process arguments, while goroutine, heap, CPU, and trace handlers expose progressively more runtime data and can consume target resources while collecting a profile.[[1]](#references)[[7]](#references) + +```bash +base=http://:10080 +curl -s "$base/debug/pprof/" +curl -s "$base/debug/pprof/cmdline" | tr '\0' ' '; echo +curl -s "$base/debug/pprof/goroutine?debug=1" | head -n 100 +curl -s "$base/debug/pprof/heap" -o heap.pb.gz +go tool pprof -top heap.pb.gz +``` + +The command line can reveal binary and configuration paths; goroutine dumps expose function names and execution state; profiles can reveal memory addresses and other process details useful for exploit development or validating a separate compromise. Prefer the index, `cmdline`, and short textual samples during triage—CPU profiles and traces actively run for a requested duration and can add load.[[1]](#references)[[7]](#references) + +Repeat the path checks against other discovered Go management listeners. In the assessed deployment, `ng-monitoring-server` exposed its NUL-delimited command line at `localhost:12020/debug/pprof/cmdline`; port `12020` is deployment-specific, not a universal TiDB port.[[1]](#references) + +An SSRF primitive may reach this listener even when it is not directly routable; see [SSRF-vulnerable internal platforms](../pentesting-web/ssrf-server-side-request-forgery/ssrf-vulnerable-platforms.md#blind-ssrf-canaries-against-internal-software). For Go HTTP routing-specific checks, see [Go `net/http` path handling](pentesting-web/golang.md). + +## PD API - `2379/tcp` + +PD exposes cluster state at `/pd/api/v1/`. Start with read-only requests to enumerate stores, schedulers, operators, and configuration.[[4]](#references)[[6]](#references) + +```bash +pd=http://:2379/pd/api/v1 +curl -s "$pd/stores" | jq . +curl -s "$pd/schedulers" | jq . +curl -s "$pd/operators" | jq . +curl -s "$pd/config" | jq . +curl -s "$pd/cluster/status" | jq . +``` + +On the audited route set, the same unauthenticated API surface included state-changing methods: creating/deleting operators or schedulers, updating configuration and placement rules, changing store state/labels/weights/limits, and removing tombstone stores. A successful unauthenticated `GET` proves disclosure, but it does **not** by itself prove that every mutating method is reachable through the deployment's proxies or middleware; validate any write operation only with explicit authorization and a rollback plan.[[1]](#references)[[6]](#references) + +## TiKV status API - `20180/tcp` + +The audited TiKV v8.5.2 status server provided read-only routes such as `/status`, `/metrics`, `/config`, `/engine_type`, `/region`, `/resource_groups`, and `/async_tasks`, plus profiling endpoints below `/debug/pprof/`. These are implemented by TiKV's Rust service even though several paths resemble Go `pprof`.[[1]](#references)[[10]](#references) + +```bash +tikv=http://:20180 +curl -si "$tikv/status" +curl -s "$tikv/config" | jq . +curl -s "$tikv/engine_type"; echo +curl -s "$tikv/resource_groups" | jq . +curl -s "$tikv/debug/pprof/cmdline" | tr '\0' ' '; echo +curl -s "$tikv/metrics" | head +``` + +The same router also included `POST /config`, `PUT /config/reload`, log-level changes, and `PUT /pause_grpc` and `/resume_grpc`. Treat these as potentially disruptive administrative primitives: fingerprint them from the source and response methods, but do not execute them on a production cluster merely to prove that the read-only status API is exposed.[[1]](#references)[[10]](#references) + +## Prometheus and monitoring exposure + +The assessed monitoring host exposed Prometheus on `0.0.0.0:9090` without authentication or TLS, alongside Alertmanager, exporters, Grafana, PD, and an `ng-monitoring-server`. Treat the listener set as a topology fingerprint: the Prometheus HTTP API exposes targets and permits PromQL queries, which can disclose component names, addresses, roles, and operating behavior; any enabled management or lifecycle operation must be evaluated separately.[[1]](#references)[[9]](#references) + +```bash +prom=http://:9090 +curl -s "$prom/api/v1/status/buildinfo" | jq . +curl -s "$prom/api/v1/targets" | jq '.data.activeTargets[] | {scrapeUrl,health,labels}' +curl -sG "$prom/api/v1/query" --data-urlencode 'query=up' | jq . +``` + +Only claim administrative impact after verifying that a state-changing endpoint is enabled and reachable; an exposed query API and target inventory are already valuable reconnaissance but are not equivalent to host compromise.[[1]](#references) + +## Detecting plaintext component traffic + +TiDB supports TLS between components, but the assessed stock configuration did not enforce it. From an authorized network observation point, capture the component ports and distinguish TLS handshakes from plaintext HTTP or non-TLS component protocols. This validates transport exposure without attempting an active man-in-the-middle attack.[[1]](#references)[[8]](#references) + +```bash +sudo tcpdump -i -nn -s0 -w tidb-components.pcap \ + 'tcp port 2379 or tcp port 2380 or tcp port 10080 or tcp port 20160 or tcp port 20180' + +tshark -r tidb-components.pcap -Y 'tls.handshake or http.request' \ + -T fields -e frame.time -e ip.src -e ip.dst -e tcp.dstport -e http.request.full_uri +``` + +Absence of decoded TLS packets is not sufficient on its own: confirm that the capture contains complete new connections, then inspect for a TLS ClientHello with `tshark -Y 'tls.handshake.type == 1'` or test each listener with `openssl s_client`. Keep SQL client TLS on port 4000 conceptually separate from **between-component** TLS for TiDB, PD, TiKV, and their control/status endpoints.[[3]](#references)[[8]](#references) + +## Hardening checks + +Verify that status and control listeners are bound to loopback or a dedicated management network, and that firewalls limit `10080`, `20180`, `2379`, `2380`, `20160`, and monitoring ports to required peers. Where remote management is necessary, require trusted client certificates and verify the configured CA/CN policy; disabling or restricting `pprof` is preferable when profiling is not operationally required.[[1]](#references)[[8]](#references) + +After enabling component TLS, validate TiDB on `10080`, PD on `2379`, and TiKV on `20160` with the intended CA, certificate, and key. Also repeat the test **without** a client certificate: a securely configured mTLS endpoint should reject it rather than silently falling back to plaintext or server-only TLS.[[8]](#references) + +The demonstrated attack boundary is primarily internal-network reconnaissance, information disclosure, management-plane abuse, and on-path traffic interception. The assessment did not establish a complete RCE or privilege-escalation chain, so avoid inflating an exposed status endpoint into an unsupported compromise claim.[[1]](#references)[[2]](#references) + +## References + +- [1] [NCC Group - TiDB Security Assessment v1.1 (PDF)](https://www.nccgroup.com/media/qetaerqm/ncc_group_pingcap_e022582_report_2026-06-25_v11.pdf) +- [2] [NCC Group - Public Report: TiDB Security Assessment](https://www.nccgroup.com/research/public-report-tidb-security-assessment/) +- [3] [TiDB documentation - Software, hardware, and network port requirements](https://docs.pingcap.com/tidb/stable/hardware-and-software-requirements/) +- [4] [TiDB documentation - TiDB Monitoring API](https://docs.pingcap.com/tidb/stable/tidb-monitoring-api/) +- [5] [TiDB v8.5.2 status HTTP router source](https://github.com/pingcap/tidb/blob/f43a13324440f92209e2a9f04c0bbe9cf763978d/pkg/server/http_status.go) +- [6] [PD v8.5.2 API router source](https://github.com/tikv/pd/blob/4cd009c4db3c15215341a96521dd53e53c55e5bd/server/api/router.go) +- [7] [Go standard library - `net/http/pprof`](https://pkg.go.dev/net/http/pprof) +- [8] [TiDB documentation - Enable TLS between TiDB components](https://docs.pingcap.com/tidb/stable/enable-tls-between-components/) +- [9] [Prometheus documentation - HTTP API](https://prometheus.io/docs/prometheus/latest/querying/api/) +- [10] [TiKV v8.5.2 status server source](https://github.com/tikv/tikv/blob/a150e4569fda1c64763fda297f4e09775759de4a/src/server/status_server/mod.rs) + +{{#include ../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/golang.md b/src/network-services-pentesting/pentesting-web/golang.md index c224ae4a33c..df4dca8e6f2 100644 --- a/src/network-services-pentesting/pentesting-web/golang.md +++ b/src/network-services-pentesting/pentesting-web/golang.md @@ -18,6 +18,12 @@ curl --path-as-is -X CONNECT http://gofs.web.jctf.pro/../flag Compare the response with requests using a normal method and a canonical path. A different response is only an indicator; confirm that the discrepancy crosses an authorization boundary before reporting it. +For a concrete Go service where the HTTP management listener also exposes `pprof`, see: + +{{#ref}} +../4000-10080-pentesting-tidb.md +{{#endref}} + ## References - [1] [Go source - historical `ServeMux.Handler` handling of `CONNECT`](https://github.com/golang/go/blob/9bb97ea047890e900dae04202a231685492c4b18/src/net/http/server.go#L2354-L2364)