[목차]
1. SSH Public key Exchange : Linux
2. 중간자 공격 - SSL Strip 공격 : Linux
3. 중간자 공격 - SSL Strip 공격 : Linux-windows
4. RSA 공개키/개인키 생성하기 : python
[SSH Public Key Exchange]
■ SSH Publickey Authentication
SSH 공개키 인증(SSH Publickey Authentication) 과정을 이해한다.
■ 사용 시스템
kali
linux200
■ 명령어
ssh-keygen CMD : key 생성(private key, public key)
ssh-copy-id CMD : key 전송(public key)
■ 동작원리
----- ServerA ---- ----- ServerB -----
# ssh-keygen
$HOME/.ssh $HOME/.ssh
* id_rsa
* id_rsa.pub --------> authorized_keys
[실습] SSH - Public Key Authentication
① (kali) ssh-keygen 명령어 사용법 확인
# ssh-keygen --help
usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa] [-N new_passphrase] [-C comment] [-f output_keyfile] ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] ssh-keygen -i [-m key_format] [-f input_keyfile] ssh-keygen -e [-m key_format] [-f input_keyfile] ssh-keygen -y [-f input_keyfile] ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile] ssh-keygen -B [-f input_keyfile] ssh-keygen -D pkcs11 ssh-keygen -F hostname [-f known_hosts_file] [-l] ssh-keygen -H [-f known_hosts_file] ssh-keygen -R hostname [-f known_hosts_file] ssh-keygen -r hostname [-f input_keyfile] [-g] ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point] ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines] [-j start_line] [-K checkpt] [-W generator] ssh-keygen -s ca_key -I certificate_identity [-h] [-U] [-D pkcs11_provider] [-n principals] [-O option] [-V validity_interval] [-z serial_number] file ... ssh-keygen -L [-f input_keyfile] ssh-keygen -A ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number] file ... ssh-keygen -Q -f krl_file file ... |
② (kali) 키쌍 생성
# ssh-keygen (# ssh-keygen -t rsa|dsa|ecdsa|ed25519)
Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): <ENTER> Enter passphrase (empty for no passphrase): (soldesklove) Enter same passphrase again: (soldesklove) Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:elBLVshVyq7LH3yeagQvFT2BDj3l0F30/opgHAOQUl8 root@kali The key's randomart image is: +---[RSA 2048]----+ | .oo +E*+o oo| | . .o++=++ . .| | . *ooo.. .| | +.+o . | | . S++ .| | o.+oo .| | . oo* . .| | o o.= o . | | ooo.+ . | +----[SHA256]-----+ |
③ (kali) 공개키를 다른 서버로 전송
# cd ~/.ssh
# ssh-copy-id -i id_rsa.pub root@192.168.10.200
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.10.200's password: (soldesk1.)
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.10.200'" and check to make sure that only the key(s) you wanted were added. |
④ (kali) 서버쪽에 전송한 공개키 확인
# ssh IP
# ssh IP CMD
# ssh 192.168.10.200 cat ~/.ssh/authorized_keys
Enter passphrase for key '/root/.ssh/id_rsa': (soldesklove) ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2kN9G53j8up4TGoecmlw2Z9prPFTJfI7VQqXlIOtccZ+k7mK5JL8fKn/K6l14RZ2LgLED3+XKf0kqn65ho1X7C2kGk6KOoaaE0t2qmxi4aLoN3dGd1/OgpJbmPGPvROb5pnrJrFF91a/soJ/ItOz9484LP/0HC5f3D//1MxhOsIQLFjsrPVgEAv+HylJTp6U1t+epTa2MnjB7vkRg0vCCzl87jDv7n6iSgu4d3by+bkJpowlOfiOBhJg5Az1mjKTlKuj1N56cmjxq1jczFTLYQIHWgKrsJSXH3XnxeqMekohYilV0fiyyANJYrknOc9Ay7jNsKxSh7Zs+iSy3Gvs9 root@firewall.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjNZtK03fu7pChwf62FgmOQSZ94cZlfquLTQQdx91fNRdUMRS9hs+racjASUih6n25BU4wuscmDAmShmBFNoPrAV1ZECu/o2FQe9BOmELDIufORI6iSRo6JmwbN0S7p3UrCxyCD/J/V9nqXMwBAy8D38l1nLUo13ldOs1iCktTK2GrrxSE01GBnm0sYtew9UKYs035koejV1ZFLsQAn0xg3K5s5JSHjGrCSlc+clCfLJ9q5gMLSftM/H+DjjLrDkmpoLC6MlhLhyNHdgYuPRU1xYEIMKB1Yme22gSiWnDywtVUs1OhNOiO/ThWmtfVot4U13POGU6I6biZrVL3orL9 root@kali |
⑤ (kali) 자신의 공개키 확인
# cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjNZtK03fu7pChwf62FgmOQSZ94cZlfquLTQQdx91fNRdUMRS9hs+racjASUih6n25BU4wuscmDAmShmBFNoPrAV1ZECu/o2FQe9BOmELDIufORI6iSRo6JmwbN0S7p3UrCxyCD/J/V9nqXMwBAy8D38l1nLUo13ldOs1iCktTK2GrrxSE01GBnm0sYtew9UKYs035koejV1ZFLsQAn0xg3K5s5JSHjGrCSlc+clCfLJ9q5gMLSftM/H+DjjLrDkmpoLC6MlhLhyNHdgYuPRU1xYEIMKB1Yme22gSiWnDywtVUs1OhNOiO/ThWmtfVot4U13POGU6I6biZrVL3orL9 root@kali |
⑥ (kali) 서버 접속시 잘못된 암호 입력
# ssh 192.168.10.200
Enter passphrase for key '/root/.ssh/id_rsa': (1) Enter passphrase for key '/root/.ssh/id_rsa': (2) Enter passphrase for key '/root/.ssh/id_rsa': (3) root@192.168.10.200's password: (1) Permission denied, please try again. root@192.168.10.200's password: (2) Permission denied, please try again. root@192.168.10.200's password: (3) root@192.168.10.200: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). |
⑦ (kali) 자기 자신에 대한 처리
# cd ~/.ssh
# mv id_rsa.pub authorized_keys
# ssh localhost
The authenticity of host 'localhost (::1)' can't be established. ECDSA key fingerprint is SHA256:rXHT3i5+d1qPHrDiu6XUjhUKit73rpemVofCf9pyGY8. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts. Enter passphrase for key '/root/.ssh/id_rsa': (soldesklove) Linux kali 4.19.0-kali3-amd64 #1 SMP Debian 4.19.20-1kali1 (2019-02-14) x86_64
The programs included with the Kali GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Wed May 8 15:33:06 2019 from 192.168.20.202 |
# exit
#
[hydra 이용한 SSH 사전 공격 - Remote Attack]
■ 사용 시스템
kali
linux200
■ 준비 사항
사전 파일 준비
linux200 서버에 미리 사용자 존재(EX: user01)
■ 원격 공격(Remote Attack) - hydra CMD 이용한 dictionary attack
----- kali ---- ----- linux200 -----
xhydra ----------> sshd(22)
--------------- --------------------
■ hydra CMD 사용법
(CLI) hydra CMD
(GUI) xhydra
① (kali) 사전 파일 준비
# mkdir /python/dict && cd /python/dict
# cat << EOF > dict.txt
administration
admin
ibm
microsoft
oracle
hp
apple
root
user01
user02
soldesk
linux
windows
EOF
② (linux200) user01 사용자 생성 및 SSH 서비스 기동
[참고] 필요하면 수행
# useradd user01
# passwd user01
# grep user01 /etc/passwd
# grep user01 /etc/passwd
user01:x:1001:1001::/home/user01:/bin/bash |
[참고] 필요하면 수행
# systemctl restart sshd
# systemctl status sshd
# systemctl status sshd
● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: active (running) since 수 2020-02-19 13:31:21 KST; 14min ago Docs: man:sshd(8) man:sshd_config(5) Main PID: 1190 (sshd) Tasks: 1 CGroup: /system.slice/sshd.service └─1190 /usr/sbin/sshd -D
2월 19 13:31:21 linux200.example.com systemd[1]: Starting OpenSSH server da... 2월 19 13:31:21 linux200.example.com sshd[1190]: Server listening on 0.0.0.... 2월 19 13:31:21 linux200.example.com sshd[1190]: Server listening on :: por... 2월 19 13:31:21 linux200.example.com systemd[1]: Started OpenSSH server dae... Hint: Some lines were ellipsized, use -l to show in full. |
③ (kali) xhydra 툴 설정 및 실행
# nmap 192.168.10.200 (# nmap -p 22 -sV 192.168.10.200)
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-23 16:46 KST Nmap scan report for 192.168.10.200 Host is up (0.00051s latency). Not shown: 991 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.2 22/tcp open ssh OpenSSH 6.6.1 (protocol 2.0) 23/tcp open telnet Linux telnetd 25/tcp open smtp Sendmail 8.14.7/8.14.7 53/tcp open domain ISC BIND 9.9.4 (RedHat Enterprise Linux 7) 80/tcp open http Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips) 110/tcp open pop3 Dovecot pop3d 143/tcp open imap Dovecot imapd 443/tcp open ssl/http Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips) MAC Address: 00:0C:29:04:29:7D (VMware) Service Info: Host: mail.example.com; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel, cpe:/o:redhat:enterprise_linux:7
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.03 seconds |
# xhydra &
[Target 탭]
Target
* Single Target : 192.168.10.200
* Port : 22
* Protocol : ssh
Output Options
* [v] Show Attempts
[Passwords 탭]
Username
* Username : user01
Password
* [v] Password list : /python/dict/dict.txt
[Start 탭]
* Start
■ xhyra 공격 시도 화면 예제
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (http://www.thc.org/thc-hydra) starting at 2020-02-18 21:52:04 [DATA] max 13 tasks per 1 server, overall 13 tasks, 13 login tries (l:1/p:13), ~1 try per task [DATA] attacking ssh://192.168.10.200:22/ [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 [ATTEMPT] target 192.168.10.200 - login "user01" - pass "administration" - 1 of 13 [child 0] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "admin" - 2 of 13 [child 1] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "ibm" - 3 of 13 [child 2] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "microsoft" - 4 of 13 [child 3] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "oracle" - 5 of 13 [child 4] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "hp" - 6 of 13 [child 5] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "apple" - 7 of 13 [child 6] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "root" - 8 of 13 [child 7] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "user01" - 9 of 13 [child 8] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "user02" - 10 of 13 [child 9] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "soldesk" - 11 of 13 [child 10] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "linux" - 12 of 13 [child 11] (0/0) [ATTEMPT] target 192.168.10.200 - login "user01" - pass "windows" - 13 of 13 [child 12] (0/0) [22][ssh] host: 192.168.10.200 login: user01 password: user01 1 of 1 target successfully completed, 1 valid password found Hydra (http://www.thc.org/thc-hydra) finished at 2020-02-18 21:52:07 <finished> |
④ (kali) 크랙된 사용자로 접근 해 보기
# ssh user01@192.168.10.200
-> 로그인 가능 여부 확인
$ exit
#
(복원) SSH public authentication에서 사용했던 키를 삭제한다.
* (linux200) /root/.ssh/authorized_keys 삭제
* (kali) /root/.ssh/{id_rsa, authorized_keys} 삭제
[ hydra 이용한 SSH 사전 공격 - Remote Attack]
■ 중간자 공격
중간자 공격 대해서 - SSL Strip 공격에 대해 이해한다.
■ 사용시스템
GW(192.168.10.2)
kalilinux (192.168.10.60)
win7 (192.168.10.202)
[참고] SSLStrip 대해서
SSL Strip을 실습해 보자.
https://hsm-racoon.tistory.com/62
SSL strip attack (MITM on HTTPS)
https://www.youtube.com/watch?v=FC7SJXjbgyc
How To Perform Sslstrip With Ettercap To Sniff Https Passwords
https://www.youtube.com/watch?v=WglJdxqeDrk
SSL Strip 공격과 HSTS Bypassing
SSL Stripping and HSTS Bypass with BetterCap
https://www.youtube.com/watch?v=BfvoONHXuQA
■ MITM(Man-In-The-Middle) Attack 대해서
공격자와 Victim이 동일한 네트워크에 연결되어 있어야 한다. 따라서 외부에서 공격하는 Remote Exploit Attack에 비해 덜 흥미로운것으로 간주되곤 한다.
그러나 동일 네트워크라는 제약조건에도 불구하고 MITM 공격이 여전히 이슈가 되는 이유는, Victim 네트워크에 접근했을 때, 다음 단계 해킹을 위한 강력한 무기로 활용할 수 있기 때문이다.
일반적으로 SSL과 같이 전송 구간 암호화가 적용되어 있으면 MITM이 불가능하다고 여기기 쉬우나, 다양한 기법을 통해 통신 내용을 중간에 가로채는 것이 (혹은 변조하는 것이) 가능하다.
■ SSL Strip 기본 이론과 동작 원리
Client-Server간 암호화 통신을 위해 SSL이 적용된 경우에는 공격자가 중간에서 통신을 가로채더라도, 그 내용을 해독할 수 없기 때문에 MITM 공격이 불가능하다.
그러나 최초 서버와의 세션 연결시 HTTPS를 강제로 HTTP 통신을 하게끔 만들수만 있다면, 일반적인 MITM 공격으로 트래픽 내용을 훔쳐볼 수 있다.
이것을 SSL Strip 기법이며, 말 그대로 “SSL을 벗겨내서(Strip)” 강제로 HTTP통신을 하게끔 유도하는 기법이다.
SSL Strip 공격은 2009년 BlackHat DC 컨퍼런스에서 Moxie Marlinspike에 의해 처음 소개되었다. (소개 자료는 http://www.thoughtcrime.org/software/sslstrip/)
... <a href="https://www.facebook.com/">Login</a> .... |
다음과 같은 형태로 강제로 변경하여 전송하게 된다.
... <a href="http://www.facebook.com/">Login</a> .... |
이후 Victim은 HTTP로 변경된 사이트로 접속하게 되고, 공격자는 중간에서 트래픽을 가로채서
모든 전송 내용을 평문으로 볼 수 있다.
■ SSL Strip 방어기법과 우회 방법 => HSTS
HSTS(Http Strict Tansport Security)는 RFC-6797에 정의되어 있으며, 2012년 표준으로 지정되었다. HSTS를 사용하게 되면 사용자가 브라우저에 http 주소를 입력하더라도 Https를 사용하는 페이지로 자동으로 연결되어 SSL-Strip과 같은 MITM 공격을 사전에 방지할 수 있다.
(즉, Client 레벨에서 HTTPS 사용을 강제하게 된다)
대표적인 예로 Google의 gmail 같은 경우이다. http://www.gmail.com으로 접속해 보면, 자동으로 https://www.gmail.com에 연결되는 것을 확인할 수 있다.
[RSA 공개키/개인키 생성하기]
RSA 공개키 암호 구현하기
공개키/개인키가 생성되는 과정을 구현해 보자.
■ PyCryptodome에서 제공되는 대표적인 공개키 암호 알고리즘 : DSA, ElGamal, RSA, ECDSA
DSA, ECDSA : 공개키 서명
Elgamal, RSA : 공개키 암호 + 공개키 서명
■ PyCryptodome 키 객체 생성 방법 - 4가지
비대칭 키는 python 객체로 표시된다.
각 객체는 개인키 또는 공개키가 될수 있다.
(1st) generate() : Crypto.PublicKey.RSA.generate()
키가 무작위로 생성된다.(ex: RSA.generate(2048))
(2nd) import_key() : Crypto.PublicKey.RSA.import_key()
키를 메모리에 load 한다.
(3rd) construct() : Crypto.PublicKey.RSA.construct()
키를 일련의 하위 구성 요소로 구성된다.
(4th) publickey() : Crypto.PublicKey.RSA.RsaKey.publickey()
키는 주어진 객체와 일치하는 공개 키이다.
■ RSA Key 생성 형식 예제
private key를 생성하고, 생성된 private key를 이용하여 public key 생성하기
from Crypto.PublicKey import RSA
prikey = RSA.generate(2048) print(prikey)
pubkey = prikey.publickey() print(pubkey) |
Private RSA key at 0x1EE302BFF70 Public RSA key at 0x1EE2E2DCD60 |
from Crypto.PublicKey import RSA
prikey = RSA.generate(2048)
print(prikey)
pubkey = prikey.publickey()
print(pubkey)
■ RSA Key File(Private Key) 생성 형식 예제
키 웨핑 포멧(key wrapping format)
PEM(default) : Text encoding(RFC 1421, RFC 1423)
DER : Binary encoding
OpenSSH : Tetual encoding(OpenSSH에서만 사용, public key만(private key 아님))
from Crypto.PublicKey import RSA
pri_key = RSA.generate(2048)
print(pri_key)
fd = open('mykey.pem', 'wb') # 파일이 없으면 만들어짐
fd.write(pri_key.export_key('PEM'))
fd.close()
fd2 = open('mykey.pem', 'rt')
pri_key2 = RSA.import_key(fd2.read())
print(pri_key2)
or
from Crypto.PublicKey import RSA
prikey = RSA.generate(2048)
with open('mykey.pem', 'wb') as fd:
fd.write(prikey.export_key('PEM'))
with open('mykey.pem', 'r') as fd2:
prikey = RSA.import_key(fd2.read())
print(prikey)
■ RSA Key File(Public Key) 생성 형식 예제
from Crypto.PublicKey import RSA
prikey = RSA.generate(2048) pubkey = prikey.publickey() with open('mykey.pem', 'wb') as fd: fd.write(pubkey.export_key('PEM'))
with open('mykey.pem', 'r') as fd2: pubkey = RSA.import_key(fd2.read()) print(pubkey) |
Public RSA key at 0x191A9798CD0 |
from Crypto.PublicKey import RSA
pri_key = RSA.generate(2048)
pub_key = pri_key.publickey()
print(pub_key)
fd = open('mykey.pem', 'wb')
fd.write(pub_key.export_key('PEM'))
fd.close()
fd2 = open('mykey.pem', 'r')
pub_key2 = RSA.import_key(fd2.read()) # 인코딩된 값을 숫자값으로 전환
print(pub_key2)
or
from Crypto.PublicKey import RSA
prikey = RSA.generate(2048)
pubkey = prikey.publickey()
with open('mykey.pem', 'wb') as fd:
fd.write(pubkey.export_key('PEM'))
with open('mykey.pem', 'r') as fd2:
pubkey = RSA.import_key(fd2.read())
print(pubkey)
Private 키가 있으면 Public 키는 얼마든 만들 수 있다.
'정보보안공부 > 정보보안전문과정' 카테고리의 다른 글
정보보안 과정 Day87-1 : 하이브리드 암호 시스템 (0) | 2021.01.11 |
---|---|
정보보안 과정 Day87 : RSA 실습 (0) | 2021.01.11 |
정보보안 과정 Day86: 공개 키 암호2 (이론) (0) | 2021.01.08 |
정보보안 과정 Day85-1 : 무선 WEP 패킷 분석 / 공개 키 암호 (0) | 2021.01.07 |
정보보안 과정 Day85: 인코딩/디코딩 프로그램 개발 (0) | 2021.01.07 |