'공부/코드'에 해당되는 글 8건
- 2011/09/06 [MFC] 파일 읽기
- 2009/01/16 Vista vs XP Registry 관련 함수
- 2008/09/09 MFC에서 윈도우 환경에 맞는 Control 만들기
- 2008/09/02 다이얼로그 타이틀바 없이 이동시키기
- 2008/07/08 CTRL + ALT + DELETE Task Manager 막기
- 2008/03/31 [MFC] 다이얼로그를 전체화면으로 작성
- 2008/02/14 커널모듈을 통한 vmsplice() local root exploit 취약점에 대한 방어 모듈 제작 공개[수정판] -hkpco-
- 2007/10/11 [Win32 Code] 트레이로 보내는 애니메이션
MFC에서 파일 읽고 쓰기
파일 읽고 내용을 리턴한다.
없으면 생성한다.
LPCTSTR testDlg::GetFileRead()
{
CFile theFile;
char* szFileName = "myfile.txt";
BOOL bOpenOK;
char szBuffer[256] = {0, };
UINT nActual = 0;
CString mFile;
CFileStatus status;
if(CFile::GetStatus(szFileName, status)) {
bOpenOK = theFile.Open(szFileName, CFile::modeRead);
theFile.Read(szBuffer, sizeof(szBuffer));
theFile.Seek(0, CFile::begin);
nActual = theFile.Read(szBuffer, sizeof(szBuffer));
mFile.Format("%s", szBuffer);
}
else {
bOpenOK = theFile.Open(szFileName, CFile::modeCreate | CFile::modeWrite);
}
return mFile;
}
msdn에서 참조했으며기타관련 함수 사용법은 msdn에서 찾길 바랍니다.
LONG WINAPI RegGetValue( __in HKEY hkey, __in_opt LPCTSTR lpSubKey, __in_opt LPCTSTR lpValue, __in_opt DWORD dwFlags, __out_opt LPDWORD pdwType, __out_opt PVOID pvData, __inout_opt LPDWORD pcbData );
LSTATUS SHGetValue( HKEY hkey, LPCTSTR pszSubKey, LPCTSTR pszValue, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData );
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif
방법 1. 윈도우 메시지중 WM_NCHITTEST를 추가하여 다음을 코딩한다.
{
CRect rect;
GetClientRect(&rect);
ClientToScreen(&rect);
if(rect.PtInRect(point))
{
return HTCAPTION;
}
return CDialog::OnNcHitTest(point);
}
방법 2. 왼쪽 버튼 다운 함수에서의 처리 방법
void CTestDlg::OnLButtonDown(UINT nFlag, CPoint point)
{
CDialog::OnLButtonDown(nFlag, point)
// 사용자가 캡션을 클릭한 것처럼 인식되게 끔 대화상자를 속인다.
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
}
int TaskManager_Enable_Disable(BOOL bEnableDisable)
{
#define KEY_DISABLETASKMGR "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
#define VAL_DISABLETASKMGR "DisableTaskMgr"
HKEY hKey;
DWORD val;
LONG r;
if (RegOpenKey(HKEY_CURRENT_USER, KEY_DISABLETASKMGR, &hKey) != ERROR_SUCCESS)
if (RegCreateKey(HKEY_CURRENT_USER, KEY_DISABLETASKMGR, &hKey) != ERROR_SUCCESS)
return 0;
if (bEnableDisable) // Enable
{
r = RegDeleteValue(hKey, VAL_DISABLETASKMGR);
}
else // Disable
{
val = 1;
r = RegSetValueEx(hKey, VAL_DISABLETASKMGR, 0, REG_DWORD, (BYTE *)&val, sizeof(val));
}
RegCloseKey(hKey);
return (r == ERROR_SUCCESS ? 1 : 0);
}
LONG style = ::GetWindowLong( m_hWnd, GWL_STYLE );
style &= ~WS_CAPTION;
style &= ~WS_SYSMENU;
::SetWindowLong( m_hWnd, GWL_STYLE, style );
int screenx = GetSystemMetrics( SM_CXSCREEN );
int screeny = GetSystemMetrics( SM_CYSCREEN );
// resize:
SetWindowPos( NULL, -4, -4, screenx+8, screeny+4, SWP_NOZORDER );
커널모듈을 통한 vmsplice() local root exploit 취약점에 대한 방어 모듈 제작 공개[수정판] -hkpco-

그외의 용도에 대해서는 불법 스크랩을 허가 하지 않습니다.
커널모듈을 통한 vmsplice() local root exploit 취약점에 대한 방어 모듈 제작 공개
by hkpco(wowhacker&wowcode)
hkpco@korea.com
http://hkpco.kr/
--
커널 버전 2.6.23 이상에서 패치를 적용하신 분들은 새로 업데이트 된 모듈 코드(url동일)를 재적용 하시기 바랍니다.
테스트 결과 두 번째 발표된 "Linux Kernel 2.6.23 - 2.6.24 vmsplice Local Root Exploit" 취약점은 vmsplice() 와는
무관함을 확인하였고 vm86old()의 취약성으로 권한 상승을 하기 때문에 급한대로 vm86old()를 막아두었습니다.
감사합니다.
--
오늘(2/11) 우연히 vmsplice() root exploit이 공개된것을 보고 커널모듈을 통한 간단한 패치를 만들었습니다.
현재까지 kernel 2.6 버전대에서 root exploit이 2개나 공개되었고, 그에대한 패치는
sys_vmsplice() 내부에서 호출되는 몇가지 함수들의 내부에 kernel macro인 access_ok()를 사용해서
속성을 체크하는 루틴을 추가시키는 것으로써 예를들면 다음과 같습니다.
--- linux-2.6.orig/fs/splice.c
+++ linux-2.6/fs/splice.c
@@ -1237,6 +1237,9 @@ static int get_iovec_page_array(const st
if (unlikely(!base))
break;
+ if (unlikely(!access_ok(VERIFY_READ, base, len)))
+ break;
+
access_ok() macro는 사용자 공간의 메모리가 유효한지를 판단하는 함수로써 주로 사용자 영역을
검증하기 위해 쓰여지며 만약 주소값이 커널영역에 존재할 경우에는 false를 리턴합니다.
그러므로 익스플로잇 코드에서 커널 영역의 주소값이 삽입되는 부분(iov.iov_base = (void *)addr;) 혹은
유효하지 않은 사용자 영역을 access_ok()로 체크하여 취약점을 방어하는 것입니다.
또 하나는 vmsplice() system call을 제거하는 방법입니다.
하지만, 두가지 방법 모두 커널을 다시 컴파일 해야하는 단점이 있습니다.
( 그 이외에도 임시 패치에 대한 제시가 있었지만 불안정적이거나 vmsplice의 사용을 아예 막아버리는 등 비 효율적입니다. )
그래서 간단한 방어모듈을 제작해 봤습니다.
현재까지 나온 패치방법은 모두 커널 소스코드를 수정해야 하며,
외국에선 아래 커널 함수들을 수정하는 형태로 공개되었습니다.
vmsplice_to_pipe(), vmsplice_to_user(), get_iovec_page_array(), copy_from_user_mmap_sem()
그런데 위 함수들은 다음과 같은 순서로 호출됩니다.
-------
sys_vmsplice() -> vmsplice_to_pipe() -> get_iovec_page_array() -> copy_from_user_mmap_sem()
or
sys_vmsplice() -> vmsplice_to_user()
-------
그리고 각 kernel api들을 패치할 때 추가되는 루틴은 위 함수들에서 공통적으로 적용되는 인자값이기 때문에
아예 sys_vmsplice()에서 해당 인자값들을 체크하도록 한다면 보다 간단하게 취약점을 방어할 수 있습니다.
아래는 방어모듈 소스 코드와 이를 컴파일 하기위한 Makefile 입니다.
------------------------------
http://hkpco.kr/code/vmpatch.c
http://hkpco.kr/code/Makefile
------------------------------
다음은 방어모듈을 로드하기 전에 exploit을 테스트 한 결과입니다.
==========================
vmplice local root exploit
==========================
[hkpco@localhost ~]$ id
uid=500(hkpco) gid=500(hkpco) groups=500(hkpco) context=root:system_r:unconfined_t:SystemLow-SystemHigh
[hkpco@localhost ~]$ gcc -o vm_exploit vm_exploit.c
[hkpco@localhost ~]$ ./vm_exploit
-----------------------------------
Linux vmsplice Local Root Exploit
By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0xb7f85000 .. 0xb7fb7000
[+] root
[root@localhost ~]# id
uid=0(root) gid=0(root) groups=500(hkpco) context=root:system_r:unconfined_t:SystemLow-SystemHigh
다음은 방어모듈을 로드하는 과정입니다.
====================
protect module patch
====================
[root@localhost hkpco]# wget http://hkpco.kr/code/vmpatch.c
--05:32:18-- http://hkpco.kr/code/vmpatch.c
Resolving hkpco.kr... 220.80.107.55
Connecting to hkpco.kr|220.80.107.55|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2287 (2.2K) [text/plain]
Saving to: `vmpatch.c'
100%[====================================================================================>] 2,287 --.-K/s in 0s
05:32:18 (62.0 MB/s) - `vmpatch.c' saved [2287/2287]
[root@localhost hkpco]# wget http://hkpco.kr/code/Makefile
--05:32:33-- http://hkpco.kr/code/Makefile
Resolving hkpco.kr... 220.80.107.55
Connecting to hkpco.kr|220.80.107.55|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 210 [text/plain]
Saving to: `Makefile'
100%[====================================================================================>] 210 --.-K/s in 0s
05:32:33 (12.2 MB/s) - `Makefile' saved [210/210]
[root@localhost hkpco]# ls
Makefile vmpatch.c
[root@localhost hkpco]# make
make -C /lib/modules/2.6.18-1.2798.fc6/build SUBDIRS=/root/hkpco modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-1.2798.fc6-i586'
CC [M] /root/hkpco/vmpatch.o
/root/hkpco/vmpatch.c: In function 'get_sys_call_table':
/root/hkpco/vmpatch.c:57: warning: assignment makes pointer from integer without a cast
Building modules, stage 2.
MODPOST
CC /root/hkpco/vmpatch.mod.o
LD [M] /root/hkpco/vmpatch.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.18-1.2798.fc6-i586'
[root@localhost hkpco]# ls -l vmpatch.ko
-rw-r--r-- 1 root root 109481 Feb 11 05:42 vmpatch.ko
[root@localhost hkpco]# insmod vmpatch.ko
다음은 방어모듈을 로드한 후에 다시 익스플로잇을 적용시켜본 모습입니다.
==========================
vmplice local root exploit
protect module loaded
==========================
[hkpco@localhost ~]$ id
uid=500(hkpco) gid=500(hkpco) groups=500(hkpco) context=root:system_r:unconfined_t:SystemLow-SystemHigh
[hkpco@localhost ~]$ gcc -o vm_exploit vm_exploit.c
[hkpco@localhost ~]$ ./vm_exploit
-----------------------------------
Linux vmsplice Local Root Exploit
By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0xb7f85000 .. 0xb7fb7000
[-] vmsplice: Bad address
[hkpco@localhost ~]$ id
uid=500(hkpco) gid=500(hkpco) groups=500(hkpco) context=root:system_r:unconfined_t:SystemLow-SystemHigh
익스플로잇이 실패한것을 볼 수 있습니다.
리눅스 커널 배포판이 다양하고 커널 소스코드도 각 배포판마다 부분적으로 수정되기 때문에
시스템 콜 제어를 통한 방어모듈은 모든 리눅스 커널에서 적용되지는 못합니다.
!! 해당 커널모듈 코드는 2월에 출간될 와우해커에서 제작하는 기술서에서 Linux Kernel 2.6 Rootkit(제가씀ㅎㅎ)
이라는 주제로 소개되는 내용에서 설명하는 방법을 이용하고 있습니다.
-Wowhacker hkpco-
// SendTray
//
// 트레이로 보내는 애니메이션을 표시한다.
//
VOID SendTray(HWND hwnd, BOOL bTo)
{
RECT rcFrom, rcTo;
HWND hTrayP = FindWindow("Shell_TrayWnd", NULL);
HWND hTrayC = FindWindowEx(hTrayP, NULL, "TrayNotifyWnd", NULL);
if(hTrayC)
{
GetWindowRect(hTrayC, &rcTo);
}
else
{
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcTo, 0);
rcTo.left = rcTo.right - 118;
rcTo.top = rcTo.bottom - 30;
}
GetWindowRect(hwnd, &rcFrom);
if(bTo == TRUE)
DrawAnimatedRects(hwnd, 3, &rcFrom, &rcTo);
else
DrawAnimatedRects(hwnd, 3, &rcTo, &rcFrom);
}
Prev
