په ICMP باندې اټومي خولۍ

په ICMP باندې اټومي خولۍ

د تمديد؛ DR: زه د کرنل ماډل لیکم چې د ICMP پیلډ څخه به کمانډونه ولولي او په سرور کې یې اجرا کړي حتی که ستاسو SSH حادثه شي. د خورا بې صبرۍ لپاره، ټول کوډ دی github.

احتیاط تجربه لرونکي C پروګرام کونکي د وینې په اوښکو کې د مینځلو خطر لري! زه حتی په اصطلاحاتو کې غلط هم یم، مګر هر ډول نیوکه ښه راغلاست ده. پوسټ د هغو کسانو لپاره دی چې د C برنامه کولو خورا سخت نظر لري او غواړي د لینکس دننه وګوري.

زما لومړی ته په نظرونو کې مقالې د SoftEther VPN ذکر شوی، کوم چې کولی شي ځینې "منظم" پروتوکولونه نقل کړي، په ځانګړې توګه HTTPS، ICMP او حتی DNS. زه تصور کولی شم یوازې د دوی لومړی کار کوي، ځکه چې زه د HTTP (S) سره ډیر پیژنم، او ما باید د ICMP او DNS په اړه د تونل کولو زده کړه وکړي.

په ICMP باندې اټومي خولۍ

هو ، په 2020 کې ما زده کړل چې تاسو کولی شئ د ICMP پاکټونو کې خپل سري تادیه داخل کړئ. مګر د هیڅکله نه ناوخته ښه! او څرنګه چې د دې په اړه یو څه ترسره کیدی شي، نو دا باید ترسره شي. څنګه چې زما په ورځني ژوند کې زه ډیری وختونه د کمانډ لاین کاروم ، پشمول د SSH له لارې ، د ICMP شیل نظر لومړی زما ذهن ته راغی. او د بشپړ بیلشیلډ بینګو راټولولو لپاره ، ما پریکړه وکړه چې دا په یوه ژبه کې د لینکس ماډل په توګه ولیکئ چې زه یې یوازې په اړه دقیق نظر لرم. دا ډول شیل به د پروسو په لیست کې نه لیدل کیږي، تاسو کولی شئ دا په کرنل کې پورته کړئ او دا به د فایل سیسټم کې نه وي، تاسو به د اوریدلو بندرونو په لیست کې هیڅ شکمن ونه ګورئ. د دې وړتیاو په شرایطو کې ، دا یو بشپړ شوی روټ کټ دی ، مګر زه امید لرم چې دا ښه کړم او دا د وروستي ریسارټ شیل په توګه وکاروم کله چې د بار اوسط د SSH له لارې ننوتلو لپاره خورا لوړ وي او لږترلږه اجرا کړئ. echo i > /proc/sysrq-triggerد ریبوټ کولو پرته لاسرسی بحالولو لپاره.

موږ په پایتون او C ، ګوګل او کې د متن مدیر ، د برنامې لومړني مهارتونه اخلو مجازی کوم چې تاسو د چاقو لاندې ایښودلو کې فکر نه کوئ که هرڅه مات شي (اختیاري - محلي ورچوئل بکس/KVM/etc) او راځئ چې لاړ شو!

د پیرودونکي اړخ

ماته داسې بریښي چې د پیرودونکي برخې لپاره زه باید د شاوخوا 80 لینونو سره سکریپټ ولیکم ، مګر داسې مهربان خلک وو چې زما لپاره یې وکړل. ټول کار. کوډ په غیر متوقع ډول ساده وګرځید، په 10 مهمو لینونو کې مناسب:

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

سکریپټ دوه دلیلونه اخلي، یو پته او یو تادیه. د لیږلو دمخه، تادیه د کیلي څخه مخکې ده run:، موږ به دې ته اړتیا ولرو چې د تصادفي تادیاتو سره کڅوړې لرې کړو.

کرنل د کڅوړو جوړولو لپاره امتیازاتو ته اړتیا لري، نو سکریپټ باید د سوپر یوزر په توګه پرمخ بوځي. مه هیروئ چې د اعدام اجازه ورکړئ او پخپله سکیپي نصب کړئ. دبیان په نوم یوه بسته لري python3-scapy. اوس تاسو کولی شئ وګورئ چې دا ټول څنګه کار کوي.

د کمانډ چلول او تولید کول
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!

دا هغه څه دي چې په سینیفر کې ورته ښکاري
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

د ځواب بسته کې تادیه نه بدلیږي.

د کرنل ماډل

د دیبیان مجازی ماشین جوړولو لپاره تاسو لږترلږه اړتیا لرئ make и linux-headers-amd64، پاتې به د انحصار په بڼه راشي. زه به په مقاله کې ټول کوډ چمتو نه کړم؛ تاسو کولی شئ دا په ګیتوب کې کلون کړئ.

د هک تنظیم کول

د پیل کولو لپاره، موږ د ماډل د پورته کولو او پورته کولو لپاره دوه افعال ته اړتیا لرو. د پورته کولو لپاره فعالیت ته اړتیا نشته، مګر بیا rmmod دا به کار ونکړي، ماډل به یوازې هغه وخت پورته شي کله چې بند شي.

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

دلته څه روان دي:

  1. دوه سرلیک فایلونه د ماډل پخپله او د نیټ فلټر د مینځلو لپاره ایستل شوي.
  2. ټول عملیات د نیټ فلټر له لارې پرمخ ځي، تاسو کولی شئ په هغې کې هکونه تنظیم کړئ. د دې کولو لپاره، تاسو اړتیا لرئ هغه جوړښت اعلان کړئ په کوم کې چې هک به ترتیب شي. ترټولو مهمه خبره د هغه فنکشن مشخص کول دي چې د هک په توګه به اجرا شي: nfho.hook = icmp_cmd_executor; زه به وروسته پخپله فنکشن ته ورشم.
    بیا ما د کڅوړې لپاره د پروسس کولو وخت ټاکلی: NF_INET_PRE_ROUTING د کڅوړې پروسس کولو لپاره مشخص کوي کله چې دا په لومړي ځل په کرنل کې څرګندیږي. کارول کیدی شي NF_INET_POST_ROUTING د کڅوړې پروسس کولو لپاره لکه څنګه چې دا د کرنل څخه وځي.
    ما فلټر IPv4 ته تنظیم کړ: nfho.pf = PF_INET;.
    زه خپل هک ته ترټولو لوړ لومړیتوب ورکوم: nfho.priority = NF_IP_PRI_FIRST;
    او زه د معلوماتو جوړښت د ریښتیني هک په توګه ثبتوم: nf_register_net_hook(&init_net, &nfho);
  3. وروستی فعالیت هک لرې کوي.
  4. جواز په واضح ډول ښودل شوی ترڅو تالیف کونکی شکایت ونه کړي.
  5. دندې module_init() и module_exit() د ماډل پیل کولو او پای ته رسولو لپاره نورې دندې تنظیم کړئ.

د تادیاتو بیرته ترلاسه کول

اوس موږ اړتیا لرو چې تادیه راوباسئ ، دا خورا ستونزمن کار وګرځید. کرنل د تادیاتو سره کار کولو لپاره جوړ شوي افعال نلري؛ تاسو یوازې د لوړې کچې پروتوکولونو سرلیکونه پارس کولی شئ.

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

دا څه روان دي:

  1. زه باید اضافي سرلیک فایلونه شامل کړم، دا ځل د IP او ICMP سرلیکونو سمبالولو لپاره.
  2. ما د کرښې اعظمي حد ټاکلی دی: #define MAX_CMD_LEN 1976. ولې په حقیقت کې دا؟ ځکه چې تالیف کوونکی یې په اړه شکایت کوي! دوی لا دمخه ما ته وړاندیز کړی چې زه اړتیا لرم د سټیک او هپ په اړه پوه شم ، یوه ورځ به زه حتما دا وکړم او ممکن حتی کوډ سم کړم. ما سمدلاسه هغه کرښه جوړه کړه چې کمانډ ولري: char cmd_string[MAX_CMD_LEN];. دا باید په ټولو دندو کې ښکاره شي؛ زه به پدې اړه په 9 پراګراف کې په تفصیل سره خبرې وکړم.
  3. اوس موږ باید پیل کړو (struct work_struct my_work;) جوړښت او دا د بل فنکشن سره وصل کړئ (DECLARE_WORK(my_work, work_handler);). زه به په دې اړه هم وغږیږم چې ولې دا په نهم پراګراف کې اړین دی.
  4. اوس زه یو فنکشن اعلانوم، کوم چې یو هک وي. ډول او منل شوي دلیلونه د netfilter لخوا ترتیب شوي، موږ یوازې لیوالتیا لرو skb. دا د ساکټ بفر دی، د معلوماتو بنسټیز جوړښت چې د کڅوړې په اړه ټول موجود معلومات لري.
  5. د فعالیت د کار کولو لپاره، تاسو به دوه جوړښتونو او څو متغیرونو ته اړتیا ولرئ، په شمول دوه تکرارونکي.
      struct iphdr *iph;
      struct icmphdr *icmph;
    
      unsigned char *user_data;
      unsigned char *tail;
      unsigned char *i;
      int j = 0;
  6. موږ کولی شو د منطق سره پیل وکړو. د ماډل کار کولو لپاره، د ICMP اکو پرته بل هیڅ پاکټ ته اړتیا نشته، نو موږ د جوړ شوي فنکشنونو په کارولو سره بفر پارس کوو او ټول غیر ICMP او غیر اکو پاکټونه یې وباسو. بیرته راګرځي NF_ACCEPT د کڅوړې منلو معنی لري، مګر تاسو کولی شئ د بیرته راستنیدو له لارې کڅوړې هم پریږدئ 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;
      }

    ما ازموینه نه ده کړې چې د IP سرلیکونو چک کولو پرته به څه پیښ شي. د C په اړه زما لږ تر لږه پوهه ماته وايي چې پرته له اضافي چکونو، یو څه ناوړه پیښیږي. زه به خوښ شم که تاسو ما له دې څخه منع کړئ!

  7. اوس چې بسته د دقیق ډول ده چې تاسو ورته اړتیا لرئ، تاسو کولی شئ ډاټا استخراج کړئ. د جوړ شوي فنکشن پرته ، تاسو باید لومړی د تادیې پیل ته اشاره ترلاسه کړئ. دا په یو ځای کې ترسره کیږي، تاسو اړتیا لرئ چې د ICMP سرلیک پیل ته اشاره وکړئ او د دې سرلیک اندازې ته یې حرکت ورکړئ. هر څه جوړښت کاروي icmph: user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
    د سرلیک پای باید د پایلوډ پای سره سمون ولري skbله همدې امله موږ دا د اړوند جوړښت څخه د اټومي وسیلو په کارولو سره ترلاسه کوو: tail = skb_tail_pointer(skb);.

    په ICMP باندې اټومي خولۍ

    عکس غلا شوی و له دې ځایه، تاسو کولی شئ د ساکټ بفر په اړه نور ولولئ.

  8. یوځل چې تاسو پیل او پای ته اشارې ولرئ، تاسو کولی شئ ډاټا په تار کې کاپي کړئ cmd_string، دا د مخکینۍ شتون لپاره چیک کړئ run: او، یا د بسته بندۍ له منځه یوسي که دا ورکه وي، یا لاین بیا ولیکئ، د دې مخکینۍ لرې کولو سره.
  9. دا دی، اوس تاسو کولی شئ بل سمبالونکي ته زنګ ووهئ: schedule_work(&my_work);. څرنګه چې دا به امکان ونلري چې داسې تلیفون ته پیرامیټر انتقال کړي، د کمانډ سره کرښه باید نړیواله وي. schedule_work() د منظور شوي جوړښت سره تړلي فعالیت به د کاري مهالویش عمومي کتار کې ځای په ځای کړي او بشپړ شي، تاسو ته اجازه درکوي چې د قوماندې بشپړیدو ته انتظار ونه کړئ. دا اړینه ده ځکه چې هک باید ډیر چټک وي. که نه نو، ستاسو انتخاب دا دی چې هیڅ شی به پیل نشي یا تاسو به د کرنل ویره ترلاسه کړئ. ځنډ د مرګ په څیر دی!
  10. بس، تاسو کولی شئ بسته د ورته بیرته ستنیدو سره ومنئ.

په کاروونکي ځای کې د برنامه زنګ وهل

دا فنکشن ترټولو د پوهیدو وړ دی. نوم یې په کې ورکړل شوی و DECLARE_WORK()، ډول او منل شوي دلیلونه په زړه پوري ندي. موږ کرښه د کمانډ سره اخلو او په بشپړه توګه شیل ته یې انتقالوو. اجازه راکړئ هغه د پارس کولو ، د بائنریونو لټون او نور هرڅه سره معامله وکړي.

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. دلیلونه د تارونو لړۍ ته تنظیم کړئ argv[]. زه به فرض کړم چې هرڅوک پوهیږي چې برنامې واقعیا پدې ډول اجرا کیږي ، نه د ځایونو سره د دوامداره کرښې په توګه.
  2. د چاپیریال تغیرات تنظیم کړئ. ما یوازې PATH د لږترلږه لارو سیټ سره داخل کړ، په دې هیله چې دا ټول دمخه یوځای شوي وي /bin с /usr/bin и /sbin с /usr/sbin. نورې لارې په ندرت سره په عمل کې مهم دي.
  3. بشپړ شو، راځئ چې دا وکړو! د کرنل فعالیت call_usermodehelper() ننوتل مني. بائنری ته لاره، د دلیلونو لړۍ، د چاپیریال متغیرونو لړۍ. دلته زه دا هم فرض کوم چې هرڅوک د جلا دلیل په توګه د اجرا وړ فایل ته د لارې تیرولو په معنی پوهیږي ، مګر تاسو کولی شئ پوښتنه وکړئ. وروستی دلیل مشخص کوي چې ایا د پروسې بشپړیدو ته انتظار کول (UMH_WAIT_PROCد پروسې پیل (UMH_WAIT_EXEC) یا هیڅ انتظار مه کوئ (UMH_NO_WAIT). ایا یو څه نور هم شته؟ UMH_KILLABLE، ما ورته ونه کتل.

شورا

د کرنل انډولونو راټولول د کرنل جوړونې چوکاټ له لارې ترسره کیږي. بللی شو make د ځانګړي لارښود دننه د کرنل نسخه پورې تړلی (دلته تعریف شوی: KERNELDIR:=/lib/modules/$(shell uname -r)/build)، او د ماډل موقعیت متغیر ته لیږدول کیږي M په دلیلونو کې. icmpshell.ko او پاک هدفونه دا چوکاټ په بشپړه توګه کاروي. IN obj-m د اعتراض فایل ته اشاره کوي کوم چې به په ماډل کې بدل شي. ترکیب چې بیا جوړیږي main.o в icmpshell.o (icmpshell-objs = main.o) ماته ډیر منطقي نه ښکاري، مګر همداسې وي.

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

موږ راټولوو: make. بارول: insmod icmpshell.ko. بشپړ شوی، تاسو کولی شئ وګورئ: sudo ./send.py 45.11.26.232 "date > /tmp/test". که تاسو په خپل ماشین کې فایل لرئ /tmp/test او دا هغه نیټه لري چې غوښتنه لیږل شوې وه، پدې معنی چې تاسو هرڅه سم کړي او ما هرڅه سم کړي.

پایلې

د اټومي پراختیا سره زما لومړۍ تجربه زما د تمې په پرتله خورا اسانه وه. حتی پرته له دې چې په C کې تجربه رامینځته کړي ، د کمپیلر اشارو او ګوګل پایلو باندې تمرکز کول ، زه وکولی شوم یو کاري ماډل ولیکم او د کرنل هیکر په څیر احساس وکړم ، او په ورته وخت کې د سکریپټ ماشوم. سربیره پردې ، زه د کرنل نیوبیز چینل ته لاړم ، چیرې چې ما ته ویل شوي و چې کارول شي schedule_work() د زنګ وهلو پرځای call_usermodehelper() پخپله د هک دننه او هغه یې شرمنده کړ، په سمه توګه د درغلۍ شک. د کوډ سل لینونه زما په وړیا وخت کې د یوې اونۍ پراختیا په اړه لګښت کوي. یوه بریالۍ تجربه چې د سیسټم پراختیا پراخه پیچلتیا په اړه زما شخصي افسانه ویجاړه کړه.

که څوک موافق وي چې په ګیتوب کې د کوډ بیاکتنه وکړي، زه به مننه وکړم. زه ډاډه یم چې ما ډیری احمقانه غلطي کړې ، په ځانګړي توګه کله چې د تارونو سره کار کول.

په ICMP باندې اټومي خولۍ

سرچینه: www.habr.com

Add a comment