본문 바로가기

프로그래밍/Python

C++과 Python으로 XSS 취약점 자동 분석 툴 만들기 (3)

체크 박스 선택 후 Next 눌렀을 때 발생할 이벤트 코딩

URL 연결을 확인하지 않으면 다음으로 넘어갈 수 없게끔 하였다.

void CKCFMFCDlg::OnBnClickedButton2()
{
	if (URLisAvailable)
	{
		if (((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck()) {
			LoginDlg LoginWindow;
			LoginWindow.DoModal();
		}
		else
			MessageBox(L"Check box is empty");
	}
	else
	{
		MessageBox(L"Please check URL");
	}
}

 

리소스 뷰에서 Login 다이얼로그를 디자인해주고,

Login 다이얼로그

 

Detection 버튼 클릭 시 발생할 이벤트를 코딩해준다.

void LoginDlg::OnBnClickedLoginbutton()
{
	Attacking* pDialog = NULL;
	pDialog = new Attacking(this);
	pDialog->Create(IDD_KCFMFC_DIALOG3, NULL);
	pDialog->SetWindowPos(NULL, pos.x, pos.y, 0, 0, SWP_NOSIZE);
	pDialog->ShowWindow(SW_SHOW);
	EnableWindow(FALSE);

	Assignment();

	GetDlgItemText(IDC_INPUT_ID, ID, 500);
	GetDlgItemText(IDC_INPUT_PASSWORD, Password, 500);
	GetDlgItemText(IDC_INPUT_PATH, LoginActionInput, 500);
	GetDlgItemText(IDC_INPUT_PATH2, bbsWriteInput, 500);
	GetDlgItemText(IDC_INPUT_PATH3, bbsDeleteInput, 500);

	wcscpy(LoginAction, httpURL);
	wcscpy(bbsWrite, httpURL);
	wcscpy(bbsDelete, httpURL);

	wcscat(LoginAction,LoginActionInput);
	wcscat(bbsWrite, bbsWriteInput);
	wcscat(bbsDelete, bbsDeleteInput);

	if (wcslen(ID) == 0 || wcslen(Password) == 0 || wcslen(LoginActionInput) == 0
		|| wcslen(bbsWriteInput) == 0 || wcslen(bbsDeleteInput) == 0)
	{
		MessageBox(L"Check input value");
	}
	else
	{
		wcscat(ID,L" ");
		wcscat(Password, L" ");
		wcscat(LoginAction, L" ");

		int i = 0;
		wchar_t ExcuteCode[4000];
		while(AttackCode[i] != nullptr)
		{
			wcscpy(ExcuteCode, L"python writeContent.py ");
			wcscat(ExcuteCode, ID);
			wcscat(ExcuteCode, Password);
			wcscat(ExcuteCode, L" \"");
			wcscat(ExcuteCode, ConverCtoWC(AttackCode[i]));
			wcscat(ExcuteCode, L"\" ");
			wcscat(ExcuteCode, LoginAction);
			wcscat(ExcuteCode, bbsWrite);

			Sleep(2500);
			WinExec(URLConvert(ExcuteCode), SW_HIDE);
			i++;
		}
		//system(URLConvert(ExcuteCode));
		MessageBox(L"Complete");
		EnableWindow(TRUE);
	}
}
void LoginDlg::Assignment()
{
	ifstream Attacks;
	
	int len = 0;
	int i = 0;

	if (xssisOpen) {
		Attacks.open("data.txt",ios_base::in);

		while (!Attacks.eof())
		{
			Attacks.getline(tmp, 3000);
			len = strlen(tmp) + 1;
			AttackCode[i] = (char*)malloc(sizeof(char) * len);
			strcpy(AttackCode[i], tmp);
			i++;
		}
		Attacks.close();
	}
	else {
		CCmdTarget::BeginWaitCursor();

		remove("xssKrolling.txt");
		WinExec("xssKrolling.exe", SW_HIDE);

		ifstream CheckStatus;

		bool LoadingData = true;

		while (LoadingData)
		{
			CheckStatus.open("xssKrolling.txt");

			if (CheckStatus.is_open())
			{
				LoadingData = false;
				CCmdTarget::EndWaitCursor();
				CheckStatus.close();

				xssisOpen = true;

			}
		}
		Attacks.open("data.txt", ios_base::in);

		while (!Attacks.eof())
		{
			Attacks.getline(tmp, 3000);
			len = strlen(tmp) + 1;
			AttackCode[i] = (char*)malloc(sizeof(char) * len);
			strcpy(AttackCode[i], tmp);
			i++;
		}
		Attacks.close();
	}
}

메모리 할당할 때 자꾸 오류 나서 1시간 정도 헤매었다. 알고 보니 공격코드가 2000자가 넘어가는 코드가 있더라.. 아까운 내 시간

 

writeContent.py도 코딩해준다.

import requests
import sys

ID = sys.argv[1]
PW = sys.argv[2]
Script = sys.argv[3]
LoginURL = sys.argv[4]
bbsURL = sys.argv[5]

#로그인 유저 정보
LOGIN_INFO = {
    'userID': ID,
    'userPassword': PW
}

BBS_INFO = {
    'bbsTitle': Script,
    'bbsContent': Script
}

#로그인 후 쿠키값 받아오기
s =  requests.Session()
login_req = s.post(LoginURL, data=LOGIN_INFO)
print(login_req.status_code)
print(login_req.cookies.get_dict())

#게시글 작성
r = s.post(bbsURL,data=BBS_INFO)
print(r.status_code)

C++에서 파이썬으로 인자 값을 넘겨준다. 처음부터 파이썬으로 만들었으면 이러지 않아도 됐는데....

중복 세션이 허용되지 않는 웹 사이트에서는 제대로 동작하지 않을 수도 있다. 다음에 추가할 예정

 

웹 서버를 열어놓고 테스트해본다.

실행 결과

스크립트 실행 전

 

정보 입력 후 Detection버튼 클릭

 

정상적으로 게시글이 올라가고 있다.

 

공격 성공

 

공격 중에서 큰 따옴표가 있는 공격이 있는데, 문자열을 끝내버려서 정상적으로 게시글을 등록하지 못한다.

내가 가진 지식으로는 어떻게 고쳐야 할지 도저히 감이 안 잡힌다. 아시는 분 있으시면 댓글 남겨주세요!