Nuclei testa in ICMP

Nuclei testa in ICMP

TL, DR: moduli nuclei scribo qui mandata de ICMP payload leget et ea in servo facient, etiamsi SSH fragores tuos. Impatientissimi omnes codice GitHub.

Cautus esto! Periti C programmarii periculum prorumpens in lacrimas sanguinis! Ut in terminologia quidem erro, sed aliqua reprehensio grata est. Propositum destinatur illis qui de C programmandi ratione asperrima habent et Linux interiora inspicere volunt.

In commentaria ad primam articulus memorata SoftEther VPN, quae protocolla quaedam "regularia" imitari possunt, praesertim HTTPS, ICMP et etiam DNS. Solum primum eorum operandi excogitare possum, quia familiariter sum cum HTTP(S), et discendum habui super ICMP et DNS effosso.

Nuclei testa in ICMP

Ita, anno 2020 didici te arbitrarium stipendii in IMP facis inserere posse. Sed melius sero quam numquam! Et cum de eo aliquid fieri possit, necesse est fieri. Cum in vita cotidiana mea saepissime utar linea praecepti, in via SSH, idea crustae ICMP in mentem meam venit. Et ad integram bullshield bingo conveniendam, decrevi illud moduli Linux in lingua scribere, me solum rudem de idea habere. Testa talis non apparebit in processuum numero, in nucleum onerare potes et in tabella ratio non erit, nihil suspectum videbis in indice portuum audientium. Secundum facultates suas hoc est radixkit flexae plenae, sed spero eam meliorem esse et uti concha ultimae rei, cum Load Average is celsior est ut in via SSH aperias et saltem exerceas echo i > /proc/sysrq-triggeraditus ad restituet sine rebooting.

Textum editorem accipimus, artes programmandi fundamentales in Pythone et C, Google et virtual quod sub cultro non sapis si omnia frangit (libitum - local VirtualBox/KVM/etc) et abeamus!

Clientem latus

Mihi visum est pro parte clientis litteras scribere cum lineis circiter LXXX, sed erant tales qui pro me fecerunt. omni opere. In codice simplex evasit latu, conveniens in X lineas significantes;

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

Scriptum duo argumenta sumit, oratio et payload. Priusquam mitto, antecedit key payload run:, necesse erit ut fasciculos temere payload excludere.

nucleus privilegia ad sarcinas artis requirit, itaque scriptura superuser currere debet. Noli oblivisci permissiones exsecutioni mandare et ipsum squamosum instituere. Debian habet sarcina vocatur python3-scapy. Nunc quomodo omnia opera potes inspicere.

Running and outputting the command
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!

Hoc est quod spectat sicut in 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

Payload in sarcina responsionis non mutat.

Kernel modulus

Debian aedificare in virtualis apparatus saltem opus erit make ΠΈ linux-headers-amd64reliqua in modum clientelas venient. Non totum codicem in articulum praebebo, in Github clon potes.

Hamo setup

Incipiendum est, duabus functionibus opus est ut modulum oneratis et exonerare. Munus exonerandi non requiritur, sed tunc rmmod non operabitur, modulus modo cum submissus exoneretur.

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

Quid hic agitur;

  1. Duae tabulae header trahuntur ad ipsum modulum et reticulum manipulare.
  2. Omnes operationes per reticulum eunt, hamos in eo ponere potes. Ad hoc debes declarare structuram in qua uncus configurabitur. Praecipuum est munus denotare quod hamus exsecutus est; nfho.hook = icmp_cmd_executor; Munus ipsum postea petam.
    Tum processui tempus posuit in sarcina: NF_INET_PRE_ROUTING dat speciem sarcinae processus cum primum in nucleo apparet. Potest esse NF_INET_POST_ROUTING ut aliquid fasciculum exeat nucleum.
    colum ad IPv4 posui: nfho.pf = PF_INET;.
    Dabo hamum summae prioris: nfho.priority = NF_IP_PRI_FIRST;
    Et subcriptio notitias structuras ut hamum ipsum; nf_register_net_hook(&init_net, &nfho);
  3. Postrema munus hamo aufert.
  4. Licentia evidenter indicatur ut compilator non queritur.
  5. munera module_init() ΠΈ module_exit() alia munera pone ad modulum initialize ac terminandum.

Retrieving payload

Nunc opus est extrahere payload, hoc difficillimum evasit. Acinum nucleum in muneribus ad operas cum stipendiis non aedificavit, tantum parse capitis protocolla altioris gradus potes.

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

Quid fit;

  1. Habui insuper fasciculos header includendi, hoc tempus IP et ICMP capitis capitis tractandi.
  2. Maximam lineam longitudinis ponam; #define MAX_CMD_LEN 1976. Quid istuc? Quia compilator de eo queritur! Iam mihi suggesserunt me ACERVUM et acervum intelligere, aliquando certum facere et fortasse etiam codicem corrigere. Protinus constituam lineam, quae imperium continebit; char cmd_string[MAX_CMD_LEN];. In omnibus functionibus visibile sit, ego de hoc in paragrapho 9 fusius dicam.
  3. Nunc opus est ut initialize (struct work_struct my_work;) construere et cum alio munere coniungere ( .DECLARE_WORK(my_work, work_handler);). Dicam etiam de causa quare hoc in nono paragrapho necessarium est.
  4. Nunc munus profiteor, quae camur erit. Genus et argumenta receptae retiarii dictantur, nos tantum interest skb. Hoc quiddam nervum est, praecipua notitia compages quae omnia in promptu notitias de fasciculo continet.
  5. Ad munus operandum, duabus structuris et pluribus variabilibus indigebis, duobus iteratoribus inclusis.
      struct iphdr *iph;
      struct icmphdr *icmph;
    
      unsigned char *user_data;
      unsigned char *tail;
      unsigned char *i;
      int j = 0;
  6. Logica incipere possumus. Ad modulum ad operandum nullae fasciculi praeter ICMP Echo requiruntur, ergo quiddam in functionibus aedificatum utentes partiamur et omnia non-ICMP et non-Echo deprendimur. Redi NF_ACCEPT significat acceptionem sarcinae, sed etiam sarcinas decidere potes 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;
      }

    Non probavi quid futurum sit sine reprimendo capitis IP. Mea minima cognitio de C mihi narrat sine adiectis cotibus, aliquid terribile accidere debere. laetabor, si me hoc dissuadet!

  7. Nunc involucrum genus exacte opus est, data extrahere potes. Sine aedificato in functione, primum monstratorem habere debes initio payload. Hoc uno in loco fit, debes monstratorem ad principium IMP capitis sumere et ad magnitudinem capitis huius movere. Omnia utitur structuram icmph: user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
    Finis header est inserere finem payload in skbergo eam obtinemus utendo instrumentis nuclei ex structura respondente: tail = skb_tail_pointer(skb);.

    Nuclei testa in ICMP

    Imago furto sublatus hic, plura de nervum quiddam legere potes.

  8. Cum indicia ad principium et finem habes, notitias in chorda imitari potes cmd_string, reprime hanc praesentiam praepositionis run: et, si desit, vel sarcinam abiicias, vel lineam iterum rescribe, hac praepositione tollenda.
  9. Hoc est, nunc alium tractorem vocare potes; schedule_work(&my_work);. Cum ad talem vocationem modulum transire non poterit, linea cum imperio global esse debet. schedule_work() munus cum transacta structura ponet in queue generale negotii schedulae ac completae, permittens te non expectare mandatum ut perficiat. Hoc necesse est, quia hamus velocissimus debet esse. Alioquin tuum arbitrium est, quod nihil incipiet, aut terrorem acinum accipiet. Mora mors similis est!
  10. Hoc est, sarcinam cum reditu respondenti accipere potes.

Vocans progressio in userspace

Hoc munus est maxime intelligibile. Nomen eius datum est in DECLARE_WORK()ratio et argumenta non placent. Recta cum imperio sumimus, et conchae totum transimus. Parsing agat, binarios et omnia quaerendo.

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. Constitue rationes ad chordarum ordinata argv[]. Pono quod quisque scit programmata actu sic perfici, et non ut linea continua cum spatiis.
  2. Posuere mauris varius. Semitam tantum adposui cum limitibus minimis, sperans se omnes iam coniunctos esse /bin с /usr/bin и /sbin с /usr/sbin. Aliae semitae raro usu respiciunt.
  3. Factum, faciamus! Kernel function call_usermodehelper() accipit ingressum. iter ad binarium, argumentum argumentorum, ordinatio variabilium rerum. Hic etiam suppono quod omnes intellegant sensum transeundi ad documentum exsecutabile sicut argumentum separatum, sed interrogare potes. Postrema ratio determinat utrum processus ad perficiendum exspectet.UMH_WAIT_PROC) Processus satus (UMH_WAIT_EXEC) Aut omnino non expectare (UMH_NO_WAIT). Estne aliquid amplius? UMH_KILLABLEEgo non inspicio.

conventus

Coetus modulorum nuclei per nucleos fabricationis fabricatur. vocatus make intra peculiare directorium ligatum ad versionis nuclei (hic definitur:) KERNELDIR:=/lib/modules/$(shell uname -r)/build) et locus moduli ad variabilem transitur M in argumentis. In icmpshell.ko et scuta munda hac compage omnino utuntur. IN' obj-m indicat documentum objectum quod in modulum convertetur. Syntax quae reficit main.o Π² icmpshell.o (icmpshell-objs = main.o) Non multum logicum ad me spectat, sed ita esto.

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

Colligimus: make. Loading: insmod icmpshell.ko. Factum, potes inspicias; sudo ./send.py 45.11.26.232 "date > /tmp/test". Si lima in machina /tmp/test et continet datam requisitionem missum, per quod fecistis omne ius et omne ius feci.

conclusio,

Prima experientia cum evolutione nuclei multo facilius fuit quam exspectavi. Etiam sine experientia in C evolutionis, ambages in compilator et Google proventus, operantem moduli scribere potui et sicut kernel piratice sentire, simulque scriptionem kiddie. Praeterea ad canalem Kernel Newbies accessi, ubi uti mihi nuntiatum est schedule_work() loco vocantem call_usermodehelper() intus autem ipsum hamum confundens, recte scam suspicans. Centum lineae codicis mihi constant circiter septimana evolutionis in libero tempore. Prospera experientia, quae meam fabulam personalem delevit de nimia multiplicitate systematis evolutionis.

Si quis codicem recensionis in Github facere consentit, gratus ero. Satis certo scio me stultis erratis multa fecisse, praesertim cum chordis laborat.

Nuclei testa in ICMP

Source: www.habr.com