Contents

What is the honeypot ?

The definition of a honeypot

  • Honeypot 顧名思義稱為蜜罐,但通常中文有種說法叫做誘捕系統,就像個捕鼠籠一樣放置食物陷阱吸引上鉤。
  • 通常會模擬模擬入侵者目標服務(web, db, ssh …),將入侵訊息記錄下來。

How honeypots work

  • Honeypot 看起來像是一個真正的服務,使入侵者認為這是一個真實的系統。
  • Honeypot 通常會放置在真實服務旁邊,但使用者不會知道該服務或 IP 存在位置,若有接收到入侵訊息,即可判斷為攻擊。(大範圍 infra 掃描或是自動化工具造成)。
  • 通常會分為放置於內網和外網不同的形式:
    • 放置內網:用於收集內部攻擊、橫向移動、C2。
    • 放置外網:模擬 web 實際收集攻擊者入侵行為,提早防禦偵測有效收集入侵資訊。

Different types of honeypot

  • 簡單介紹現有的一些 open source honeypot
    • Glastopf:模擬 web 留言板功能,使入侵者有機會利用 SQL injection 攻擊,或是使用 brute force 猜測帳號密碼,可用於收集分析入侵者攻擊訊息。
    • Dionaea:模擬常見服務,包含 RDP、MSSQL、MYSQL、SIP、SMB,可收集 SQL 攻擊、惡意程式與一些遠端連線常用 protocol 攻擊資訊。
    • Cowrie:模擬 ssh、telnet,可用於收集帳號密碼資訊,與攻擊者連線進到 server 後行為或是下載的惡意程式也會自動收攏。
    • Conpot:模擬 OT protocol
    • T-pot:包含各式各樣的 honeypot 和分析工具,並且都容器化,方便於部署分析。

For example: Python3 socket

  • 利用 socket 建立假的服務,輸入 IP、Port、回應訊息
  • 收集入侵者資訊,包含 IP、Port、payload
import time
import socket

def get_input():
    host = input('IP Addr: ')
    message = input('Message: ')
    while True:
        try:
            port = int(input('Port: '))
        except TypeError:
            print('Error: Invalid port number.')
            continue
        else:
            if (port < 1) or (port > 65535):
                print('Error: Invalid port number.')
                continue
            else:
                return host, port, message

def write_log(client, data=''):
    separator = '=' * 50
    fopen = open('./honeypot.log', 'a')
    fopen.write(f'Time: {time.ctime()}\nIP: {client[0]}\nPort: {client[1]}\nData: {data}\n{separator}\n\n')
    fopen.close()

def main(host, port, message):
    print('Starting honeypot!')
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    s.listen(100)
    while True:
        insock, address = s.accept()
        print(f'Connection from: {address[0]}:{address[1]}')
        try:
            insock.send(message.encode())
            data = insock.recv(1024)
            insock.close()
        except socket.error:
            write_log(address)
        else:
            write_log(address, data.decode())

if __name__ == '__main__':
    re = get_input()
    main(re[0], re[1], re[2])