새로 Fedora 21을 설치하고, OpenVAS를 설치하려는데.. 공식 사이트에서 시키는 대로 하면 도저히 답이 안 나온다.

 ...
 
You could try using --skip-broken to work around the problem
 ...

하지만 머리를 좀 굴려서 결국 설치 성공!

방법은 의외로 간단하다(주의: 난 개빡쳐서 아래의 과정을 모두 root로 실행했다...)
1. Atomic Repository를 삭제.

 yum remove atomic-release

2. yum으로 openvas-cli, openvas-scanner, openvas-manager를 설치(updates repository에서 설치한다).

 yum install openvas-cli         # 까지 치고 <tab> 해서 자동완성
 yum install openvas-manager # 까지 치고 <tab> 해서 자동완성
 yum install openvas-scanner  # 까지 치고 <tab> 해서 자동완성

3. Atomic Repostiory를 추가.

 wget -q -O - http://www.atomicorp.com/installers/atomic | sh

4. yum으로 greenbone-security-manager를 설치.

 yum install greenbone-security-manager

5. Atomic Repository를 삭제.

 yum remove atomic-release

6. openvas-check-setup 쓰자

 openvas-check-setup

7. 이제부턴 알아서... openvas-check-setup이 시키는 대로 하면 되는데, 그것도 귀찮으면 아래 명령어들을 치면 (아마) 된다.

 #순서가 이게 아닐수도 있는데 알아서 잘 해보면 된다.
 openvas-mkcert
 openvas-mkcert-client -n -i
 openvassd
 openvasmd --rebuild --progress
 openvas-nvt-sync
 openvas-certdata-sync
 openvasmd --create-user=kcy1019 #어드민 계정 생성(비번은 알아서 만들어준다)
 gsad -p 9392                         #이제 https://localhost:9392로 접속 가능. 외부에서 하고싶으면 ssh 터널링 할 것.

Windows 환경에서 PHP를 사용할 일이 생겨서 생활코딩(http://opentutorials.org/course/62/5103)을 보고 Windows에 Apacahe + PHP + Mysql을 설치했다. 알아서 다 설치해주니까 편했지만(근데 이거 CakePHP나 CodeIgniter같은 화석 프레임워크는 왜 끼워서 설치하는지..) 모듈때문에 고민을 좀 했다. PHP의 LDAP 모듈을 따로 깔아야 하나? 하고 고민하다가, 에라 모르겠다 하고 그냥 활성화만 시켰는데 다행히 모듈도 같이 설치되었는지 잘 된다! ㅎㅎ

php.ini (위의 링크와 같이 설치했다면 C:/Bitnami/wampstack-5.4.39-0/php/php.ini) 수정
*주의: 관리자 권한을 가진 메모장으로 수정해야 저장이 됩니다.*

extension=php_intl.dll
extension=php_imap.dll
;extension=php_interbase.dll
;extension=php_ldap.dll
extension=php_ldap.dll
extension=php_mbstring.dll
;extension=php_exif.dll ; Must be after mbstring as it depends on it

그러니까, 앞의 세미콜론 하나만 지우면 된단겁니다! 주석만 풀어주면 바로 적용되는거죠 :D

*References:

가끔 다른 프로세스의 SysListView32를 읽고싶을 때가 있다.
그런데 막상 해보니까 쉬울줄 알았던 일이 잘 안돼서 고생을 좀 하다가.. 검색을 통해 해결했다.
우선 다음과 같은 코드를 생각해보자.
#define WIN32_LEAN_AND_MEAN // compile faster
#include <stdio.h>
#include <locale.h>
#include <windows.h>
#include <commctrl.h>

const int COLS(5), SZBUF(512);
int main(void)
{
	setlocale(LC_ALL, ""); // 한글 출력을 위해 기본 로케일 설정.
	HWND hParent = FindWindow(NULL, L"SW 찾기");
	HWND hListView = FindWindowEx(hParent, NULL, L"SysListView32", NULL);

	int numItems=(int)SendMessage(hListView, LVM_GETITEMCOUNT, 0, 0);

	LVITEM lvi;
	wchar_t subItems[COLS][SZBUF] = {};

	lvi.cchTextMax=SZBUF; // 텍스트 버퍼 사이즈를 설정

	for(int i = 0; i < numItems; i++) {
		for (int j = 0; j < COLS; j++) {
			// j번째 column의 값을 얻는다.
			lvi.iSubItem = j;
			lvi.pszText = subItems[j];
			wcscpy(subItems[j], L"끼야아앙");
			SendMessage(hListView, LVM_GETITEMTEXTW, (WPARAM)i, (LPARAM)&lvi);
			printf("%s%ls", j > 0 ? ";" : "", subItems[j]);
			// column1;column2;column3 형식으로 한 줄씩 출력.
		}
		puts("");
	}

	return 0;
}

완벽해보이...지만 실행해보면?

 C:\>a.exe
 끼야아앙;끼야아앙;끼야아앙;끼야아앙;끼야아앙
 끼야아앙;끼야아앙;끼야아앙;끼야아앙;끼야아앙
 C:\>

실제로 버퍼에 아무것도 쓰이지 않은 것을 확인할 수 있다.
원인이 뭘까 고민해보다가 reference에서 그 답을 찾았다.
요약하자면 "ListView를 가진 프로세스는 a.exe의 메모리에 접근 권한이 없음!" 이라고..
그러므로 일단 ListView를 가진 프로세스에 메모리를 할당하고,
우리는 ReadProcessMemory/WriteProcessMemory를 이용해서 해당 메모리에 접근하면 된다.
덕분에 코드는 더 지저분해졌지만, 어쨌든 돌아는 간다 :D

최종 결과물

#define WIN32_LEAN_AND_MEAN // compile faster
#include <stdio.h>
#include <locale.h>
#include <windows.h>
#include <commctrl.h>

const int COLS(5), SZBUF(512);
int main(void)
{
	setlocale(LC_ALL, ""); // 한글 출력을 위해 기본 로케일 설정.
	HWND hParent = FindWindow(NULL, L"SW 찾기");
	HWND hListView = FindWindowEx(hParent, NULL, L"SysListView32", NULL);

	int numItems=(int)SendMessage(hListView, LVM_GETITEMCOUNT, 0, 0);

	LVITEM lvi, *_lvi = NULL;
	wchar_t subItems[COLS][SZBUF] = {};
	wchar_t *_subItems[COLS] = {};
	unsigned long pid = -1;
	HANDLE process = NULL;
	
	// hWnd로부터 pid를 얻는다.
	GetWindowThreadProcessId(hListView, &pid);
	// 해당 pid를 가진 프로세스에 대해 VM조작 권한을 얻는다.
	process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
		PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);

	_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM),
		MEM_COMMIT, PAGE_READWRITE);
	// ListView를 가지고 있는 프로세스에 LVITEM 메모리를 할당한다.

	for (int i = 0; i < COLS; i++) {
		_subItems[i]=(wchar_t*)VirtualAllocEx(process, NULL,
							SZBUF * sizeof(wchar_t),
							MEM_COMMIT,
							PAGE_READWRITE);
		// ListView를 가지고 있는 프로세스에 wchar[] 메모리를 할당한다.
	}

	lvi.cchTextMax=SZBUF; // 텍스트 버퍼 사이즈를 설정

	for(int i = 0; i < numItems; i++) {
		for (int j = 0; j < COLS; j++) {
			// j번째 column의 값을 얻는다.
			lvi.iSubItem = j;
			lvi.pszText = _subItems[j];
			// 반환되는 텍스트는 타겟 프로세스의 wchar[] 버퍼에 써진다.
			WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
			// 타겟 프로세스의 LVITEM에 lvi의 설정값을 쓴다(복사).
			SendMessage(hListView, LVM_GETITEMTEXTW, (WPARAM)i, (LPARAM)_lvi);
			ReadProcessMemory(process, _subItems[j], subItems[j], SZBUF, NULL);
			// 타겟 프로세스의 wchar[] 버퍼를 읽는다.
			printf("%s%ls", j > 0 ? ";" : "", subItems[j]);
			// column1;column2;column3 형식으로 한 줄씩 출력.
		}
		puts("");
	}

	// 타겟 프로세스에 할당한 메모리를 해제한다.
	VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
	for (int j = 0; j < COLS; j++) {
		VirtualFreeEx(process, _subItems[j], 0, MEM_RELEASE);
	}

	return 0;
}


https://github.com/kcy1019/img2term

GIF(애니메이션 포함!), PNG, JPG 등등을 지원합니다(ImageMagickncurses를 이용했습니다).

make 후 ./img2term <그림파일경로>를 입력하면 ㅇㅋ! *경로 자리에 웹주소를 입력해도 됩니다.



sudo usermod -a -G sudo 아이디

출처: http://askubuntu.com/questions/168280/how-do-i-grant-sudo-privileges-to-an-existing-user

자꾸 까먹어서...

(Lecture note from Coursera - Machine Learning - Advices for applying machine learning)
Keyword: High Bias, High Variance, Learning Curve, Cross Validation.

[1]Machine Learning을 적용할 때, 생각보다 결과가 좋지 않을 경우 다음과 같은 선택지중 어떤 것을 선택해야 할까?

  • training example을 더 많이 모은다.
  • Feature의 수를 줄여본다.
  • Feature의 수를 늘려본다.
  • Polynomial Feature를 늘려본다.
  • λ(regularization parameter)를 늘려본다.
  • λ(regularization parameter)를 줄여본다.

... 당연히 그냥 감으로 찍는 것 보다 훨씬 좋은 방법이 있다. 이제부터 살펴보자.,

[2]우선 학습을 통해 얻은 hypothesis를 평가하는 방법에 대해 알아보자.
이를 알아두면, model을 선택할 때 좋은 지표로 이용할 수 있다.
보통 학습시에 training example 전체를 이용해서 hypothesis를 결정하는데, 이러지 말고, 다음과 같이 나눠서 사용하자.

  1. training example set을 랜덤하게 섞는다.
  2. 앞의 80%를 training set으로 삼는다.
  3. 나머지 20%를 test set으로 삼는다.

이제 80%, 그러니까 training set만 가지고 여러 model에 대해 학습을 진행한 다음,
얻어낸 hypothesis를 이용, test set의 데이터를 이용해서 error를 계산해본다.
이를 통해서 Generalization이 얼마나 잘 되었는지 확인할 수 있다!
그러니까 test set에서의 error가 가장 작은 hypothesis를 선택하면 끝~~
이면 좋겠는데.. 사실 이 방식은 여전히 overfitting을 해결하지 못했다.
해당 hypothesis가 test set에 그냥 유난히 잘 맞는 것일 수 있기 때문이다 -_-..

따라서 다시, 다음과 같이 나눠서 사용하는게 더 좋다고 한다.

  1. training example set을 랜덤하게 섞는다.
  2. 앞의 60%를 training example로 삼는다.
  3. 다음 20%를 cross validation set으로 삼는다.
  4. 끝의 20%를 test set으로 삼는다.

이번엔 cross validation set이 새로 추가됐다.
이는 위에서 언급한 문제인, test set에 유난히 잘 맞는 hypothesis를 선택하는 것을 해결하기 위함이다.
이번에도 위와 비슷하게.. 일단 training set을 이용해서 학습한 hypothesis들 중 cross validation set의 error가 가장 작은것을 선택한다.
이렇게 선택한 hypothesis에 대해 test set을 이용해서 error를 계산할 경우 Generalization의 정도를 아까보다 훨씬 낫게 평가할 수 있다.

이제 본격적으로 [1]에서 어떤 선택지를 고르는 것이 좋은 것인지 확인하는 방법에 대해 공부해보자.

[3]일단 우리가 처해있는 상황이 어떤 것인지에 따라 어떤 것을 선택할지 결정할 수 있다.
지금 우리를 힘들게 하는 원인이 되는 두 가지를 살펴보자.

1. High Bias
간단히 말해 Bias가 높다는건 underfitting하게 된다는 뜻이다.
2. High Variance
Variance가 높다는건 overfitting하게 된다는 뜻이다.

이해를 돕기 위해 Linear(Polynomial) Regression을 이용할 때, Polynomial의 Degree가 높아짐에 따른 Error의 변화량을 (개략적으로) 살펴보자.

연두색 부분과 주황색 부분의 실제 모습을 (역시 개략적으로) 그려본다면 다음과 같은 상황이 적당하겠다.
연두색 부분의 함수는 보다시피 너무 단순한 polynomial로 인해 training data를 제대로 표현하지 못하고,
주황색 부분의 함수는 보다시피 너무 복잡한 polynomial로 인해 training data를 너무 완벽하게 표현해서
generalization 성능이 떨어지고, 이는 곧 validation set에 대해서 큰 오차를 보여주게 된다.

또 중요한 발견으로는 연두색 부분, 즉 high bias인 상황에서는 validation error와 training error가 거의 비슷하다.
반면 주황색 부분, 즉 high variance인 상황에서는 validation error와 training error의 차이가 매우 크다.
이제 [2]를 이용해서 degree를 선택할 수 있다('degree가 몇인 model을 선택할 것인가'를 해결 가능).

[4]이제 regularization을 고려해서 살펴보자.
λ에 따른 training / validation error를 구할 수 있다.

(주의할 점: 위의 그래프의 Training / Validation Error는 Regularization Term이 제거된 채로 측정한 것이다.
 즉, regularization term은 learning process에서만 사용했다는 뜻)
λ가 작으면 training error에 맞게 학습하고, 자연히 higher variance를 갖게된다.
반면 
λ가 크면 hypothesis가 0에 가까워져서 higher bias를 갖게 된다.

최적의 λ를 찾는 것도 역시 [2]를 이용해서 할 수 있다.
이를테면 다음과 같이 
λ를 바꿔가며 평가하고, 가장 적절한 것을 선택하면 된다.
λ = 0, 0.01, 0.02, 0.04, 0.08, 0.16, ..., 10.24 (2배씩 키워가면서 결정)

[5]이제 마지막으로 training example set의 크기에 따른 변화를 살펴보자.
다음과 같은 그래프를 Learning Curve라고 부른다.


위 그래프는 그림만 봐도 알 수 있듯이 이 그래프는 high variance를 갖는 경우이다.
여기서 가장 중요한 것은... high variance를 가져서 overfitting하는 경우에는
1. validation error와 training error의 gap이 크다(연두색 박스친 부분).
2. training example의 수가 늘어날수록 두 error가 수렴한다.
특히 2번이 중요한데,
이를 통해서 high variance를 갖는 경우에는 training example을 늘리는 것이 효과를 가질 것이란 것을 알 수 있다!

이건 high bias를 갖는 경우인데, 보라색 박스와 주황색 박스를 겹쳐서 그린 이유는,
직선 형태로는 더 이상 error를 줄일 수 없기 때문에 둘의 직선이 거의 정확히 일치하기 때문이다.
이를 통해 알 수 있는건 high bias를 갖는 경우에는 training example을 늘려도 효과가 거의 없을 것이란 사실이다.
[6]자, 위에서 살펴본 것들을 이용해서 결국 [1]에서 고민하던 문제를 해결하는 방법을 알게 되었다!

  • training example을 더 많이 모은다.           -> high variance일 경우
  • Feature의 수를 줄여본다.                      -> high variance일 경우
  • Feature의 수를 늘려본다.                      -> high bias일 경우
  • Polynomial Feature를 늘려본다.               -> high bias일 경우
  • λ(regularization parameter)를 늘려본다.     -> high variance일 경우
  • λ(regularization parameter)를 줄여본다.      -> high bias일 경우

high bias인지 high variance인지 어떻게 아는가는... 당연히 [5]learning curve를 그려보면 됩니다.

나는 (특히 만화보기에 최적인아이패드를 사고 나서) 레진코믹스에서 만화를 많이, 물론 코인도 많이 내서(!) 본다. 최근 일 년간 스팀에 돈을 안 질렀는데, 지금 보니 그 돈을 모두 레진에 질렀던 것 같다 -_-;;

그렇게 여러 가지 만화를 봤는데, 그중에서 볼 때마다, 언제 봐도 감탄하는 만화는 <심해의 조각들>이다. 물론 흑백에 푸른 색을 더한 특유의 그림체가 정말 아름다운 것도 있지만, 그보다 더 아름다운 이야기들에 반했다. 특히 65번째 이야기인 '한 낮에 꾼 꿈(4)'를 읽었을 때는 정말 ㅠㅠ 내가 다 눈물이 날 것 같더라.. 

"좋아진 것도 한 순간이었으니까, 잊는 것도 한 순간이 될 거다."
"... 제가 그쪽을 구해줬다고 하셨었죠, 그쪽이야말로 절 구해줬어요."


'Random' 카테고리의 다른 글

GMail 전달 기능에 대한 불평  (0) 2015.11.03
새 블로그  (0) 2015.08.08
심해의 조각들  (0) 2015.03.03
옛날 생각  (0) 2014.07.27
  (0) 2013.06.23
월욜이 개강이라구요?  (0) 2012.08.23

$_SESSION에 그냥 string을 저장하는 것은 쉽다.

$_SESSION['var_name'] = "value"; 로 하면 되니까.

하지만 class의 경우에는 이게 쉽지 않다 -_-;

$_SESSION['var_name'] = new MyClass();

라고 하면 저장이 잘 된것 같아보이지만.. 새로고침을 하고 var_dump($_SESSION['var_name]);를 해보면?

Case 1) __PHP_Incomplete_Class Name

          -> Class의 정의를 session_start() 하기 전에 포함시킨다(include를 하든 뭘 하든).

Case 2) null

          -> class MyClass implements Serializable { /* ... */ public function serialize(){/*...*/} public function unserialize($data){/*...*/} }

             처럼 Serializable 를 상속한 다음, [un]serialize 메소드를 구현한다 (좋은 링크).

(주의: 케이스를 나눠놓았지만 사실 둘 다 해야합니다!)

왜 이래야 하냐면, $_SESSION 안의 Object는 자동으로 각 페이지가 끝날 때 serialize()되어 세션에 저장되고, 각 페이지가 로드될 때 다시 unserialize() 되기 때문이다!

php에서 ldap_bind()를 써서 코딩하려고 했는데,
하...
LDAP가 안 된다 ㅠㅠ ldap_bind만 하면 에러..

 ldap_bind(): Unable to bind to server: Can't contact LDAP server in ...

ldapsearch 유틸로는 잘 되는데 이건 안돌아가서 멘탈붕괴가 시작되던 찰나,
아 설마.. 하고 php를 명령줄에서 실행했더니 결과가 정상..

 $ php ldap_test.php
   true

결국 apache가 실행하면 안되는거였다 ㅠㅠ
이걸 해결하기 위해서는 httpd가 network 접속을 수행할 수 있도록 selinux 설정을 변경해야 한다.

 # setsebool -P httpd_can_network_connect=1 


$ sed 's/asdf/qwer/g' a.txt
qwerqwerqwerqwerqwer...(생략)

위의 커맨드처럼 sed를 파일에 대해 그냥 사용하면 결과가 다시 파일에 써지는 것이 아니라, stdout으로 출력된다 -_-
그래서 "아! 리다이렉션을 사용하면 되겠구나" 하고 다음 커맨드를 입력하면(절대 안됩니다 절대)..

 시도: $ sed 's/asdf/qwer/g' a.txt > a.txt

 결과: $ ls -l
        -rw-rw-r--. 1 kcy1019 kcy1019 0  2월  2 12:12

절대 하면 안됩니다... 절대로..
이럴 땐 그냥 아래처럼 하면 여러모로 안전하고 편리하게 할 수 있습니다.

$ sed -i.bak 's/asdf/qwer/g' a.txt
$ ls -l
-rw-rw-r--. 1 kcy1019 kcy1019 100  2월  2 12:12 a.txt
-rw-rw-r--. 1 kcy1019 kcy1019 100  2월  2 12:12 a.txt.bak

참고: http://stackoverflow.com/questions/5171901/sed-command-find-and-replace-in-file-and-overwrite-file-doesnt-work-it-empties