VPC 생성은 딸깍 이라 제외

서브넷 연결 설정

퍼블릭 서브넷들은 서브넷 설정 편집 -> 자동 할당 활성화 해준다

 

 

인터넷게이트웨이 설정

igw 는 VPC에 각각 하나씩 만들고 연결해주고 

라우팅 테이블 -> 퍼블릭A,B 라우팅테이블에 라우팅 설정 편집 ->로컬은 냅두고 0.0.0.0/ + igw 설정 

 

 

라우팅테이블 설정

라우팅 테이블은 기본적인 테이블을 제외하고 총 서브넷에 각각 하나씩 4개를 만들어준다

 

NAT 게이트웨이 설정

NAT 게이트웨이는 프라이빗을 위한 통로이다 

그렇기 때문에 프라이빗 말고 퍼블릭에 만들어줘야한다. 

퍼블릭 서브넷 A,B에 만들어주자.

 

PCX (피어링) 설정

요청자에 A VPC 를 넣고 수락자에 B VPC 를 넣고 
내 계정과 현재 리전 을 선택해준다.
설정을 마치고 피어링 연결 생성 을 누르면 Peering 상태에 수락 대기중 이라는 글이 뜨는데 

해당 VPC Peering을 선택하고 작업 버튼을 눌러 요청 수락을 눌러준다.

 

 

VPC_A의 아이피를 복사해서 

public b, private b 라우팅 테이블에 라우팅 편집에 들어가서 붙여넣고 -> 피어링 연결에 생성된 피어링을 선택해준다  

 

VPC_B의 아이피를 복사해서 

똑같이 public a, private a에 설정해준다

 

선배님이 알려주신 비유는.. 

피어링을 생성한것 = > VPC끼리 연결해주는 다리를 놓은것

라우팅테이블에 설정해준것 = > 다리 놓았다고 홍보한것 

ㅋㅋㅋㅋ 하나도 몰랐는데 알아먹음.

 

 

남은건 ec2, 피어링,웹서버구축 등등등.. 이 남았는데 문제가 뭐 이래 오류가 많은건지 ec2 하다가 던짐 2023 하러 감.

ec2 초반 글은 있음.....

정수 모듈로 n으로 이루어진 집합은 덧셈과 곱셈의 연산을 포함하여 링(Ring)이 됩니다.
이는 집합 내의 두 요소를 더하거나 곱하는 경우에도 집합 내의 다른 요소가 반환된다는 것을 의미합니다.
모듈러스가 소수일 때: n = p인 경우, 우리는 집합 내의 모든 요소에 대한 역원을 보장받으며, 이로 인해 링은 필드(Field)로 승격됩니다. 이 필드를 유한체 Fp라고 합니다.Diffie-Hellman 프로토콜은 일반적으로 큰 소수인 유한체 Fp의 요소들로 작동합니다.
소수 p = 991과 요소 g = 209가 주어진 경우, g * d mod 991 = 1을 만족하는 역원 d를 찾아보겠습니다.

 

역원으로 d를 구하면 되는 문제이다 역원은 RSA에서도 했듯이 pycrypto 안에있는 inverse함수로 구할 수 있다.

from Crypto.Util.number import inverse
print(inverse(209, 991))

g(209) inverse 991 을 하면 당연히 d 가 나온다 

569 가 flag

'Cryptography' 카테고리의 다른 글

RSA CRT Attack 중국인 나머지 정리  (2) 2024.05.08
[python] .pem 파일에서 e,n 얻기  (0) 2024.03.27
RSA 낮은 지수 공격 cyling Attack code  (0) 2024.03.03
BraekerCTF Write up - Thus spoke machine  (0) 2024.02.29
RSA 역원  (0) 2024.02.17

wiener 공격과는 반대로 e값이 매우 작을때 사용된다 이때 e 값은 주로 3으로 설정된다 

 

from gmpy2 import iroot, local_context

c = 

with local_context() as ctx:
    ctx.precision = 3000
    m = iroot(c,3)[0]
   
    print(bytes.fromhex('%x' % int(m)))

'Cryptography' 카테고리의 다른 글

[python] .pem 파일에서 e,n 얻기  (0) 2024.03.27
[Cryptohack] Diffie-Hellman Starter 1 write up  (0) 2024.03.04
BraekerCTF Write up - Thus spoke machine  (0) 2024.02.29
RSA 역원  (0) 2024.02.17
RSA Wiener attack code  (0) 2024.02.17

wiener attack 이란 단순히 말해 e 값이 클때 사용할수 있는 공격이다.

대게 확률적으로 e값이 증폭적으로 크다면 d값이 작을 확률이 매우 높기때문에 

wiener 공격을 하면 d를 알아낼수있어 RSA 취약점인 개인키가 공개되기 때문에 이를 이용하여 flag를 알아낼수있다

 

RSA에서 텍스트파일로 저장된 Public key.pem 파일을 읽어와서 키 파일을 얻어오는 코드와 

wiener 공격을 한 파일에 담아 정리했다

https://github.com/pablocelayes/rsa-wiener-attack/blob/master/RSAwienerHacker.py

E,n값과 public key 텍스트 파일을 입력해 긁어오는 방식

키를 직접 추가 하고 싶다면 키를 가지고 오는 코드를 삭제후 본인이 입력하면 제대로 동작한다.

from Crypto.Util.number import*
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from base64 import b64encode

# Get public key from a file
pubkey_file = open("public_key.pem", 'r')
pubkey = pubkey_file.read()
pubkey_file.close()

flag_file = open("flag.txt", 'r')
flag = int(flag_file.read(), 16)
flag_file.close()

msg = "plain text"           

# Create key using public key
keyPub = RSA.importKey(pubkey)
cipher = Cipher_PKCS1_v1_5.new(keyPub)
cipher_text = cipher.encrypt(msg.encode())
emsg = b64encode(cipher_text)
encryptedText = emsg.decode('utf-8')

n = keyPub.n
e = keyPub.e

def convergents_from_contfrac(frac):
    convs = [];
    for i in range(len(frac)):
        convs.append(contfrac_to_rational(frac[0:i]))
    return convs

def contfrac_to_rational (frac):
    if len(frac) == 0:
        return (0,1)
    num = frac[-1]
    denom = 1
    for _ in range(-2,-len(frac)-1,-1):
        num, denom = frac[_]*num+denom, num
    return (num,denom)

def is_perfect_square(n):
    h = n & 0xF; 
    
    if h > 9:
        return -1 

    
    if ( h != 2 and h != 3 and h != 5 and h != 6 and h != 7 and h != 8 ):
        # take square root if you must
        t = isqrt(n)
        if t*t == n:
            return t
        else:
            return -1
    
    return -1

def test_is_perfect_square():
    print("Testing is_perfect_square")
    testsuit = [4, 0, 15, 25, 18, 901, 1000, 1024]
    
    for n in testsuit:
        print("Is ", n, " a perfect square?")
        if is_perfect_square(n)!= -1:
            print("Yes!")
        else:
            print("Nope")
            
def isqrt(n):
    if n < 0:
        raise ValueError('square root not defined for negative numbers')
    
    if n == 0:
        return 0
    a, b = divmod(bitlength(n), 2)
    x = 2**(a+b)
    while True:
        y = (x + n//x)//2
        if y >= x:
            return x
        x = y

def bitlength(x):
    assert x >= 0
    n = 0
    while x > 0:
        n = n+1
        x = x>>1
    return n

def hack_RSA(e,n):
    
    # rational_to_contfrac ref
    x, y = e, n
    
    a = x//y
    pquotients = [a]
    while a * y != x:
        x,y = y,x-a*y
        a = x//y
        pquotients.append(a)
    frac = pquotients
    # rational_to_contfrac ref end


    convergents = convergents_from_contfrac(frac)
    
    for (k,d) in convergents:
        
        #check if d is actually the key
        if k!=0 and (e*d-1)%k == 0:
            phi = (e*d-1)//k
            s = n - phi + 1
            discr = s*s - 4*n
            if(discr>=0):
                t = is_perfect_square(discr)
                if t!=-1 and (s+t)%2==0:
                    print("Hacked!")
                    return d
 
d = hack_RSA(e,n) 
pt = pow(flag,d,n)
print(long_to_bytes(pt))

 

 

'Cryptography' 카테고리의 다른 글

BraekerCTF Write up - Thus spoke machine  (0) 2024.02.29
RSA 역원  (0) 2024.02.17
선택 암호문 공격(Chosen Ciphertext Attack) - testbook rsa  (0) 2024.02.14
RSA 수학적 원리 발표 / 세특  (1) 2024.01.03
Factordb 사용법  (0) 2024.01.03

 

testbook rsa 문제파일을 받아 열어보니 

#!/usr/bin/python3
from Crypto.Util.number import getStrongPrime, bytes_to_long, inverse


class RSA(object):
    def __init__(self):
        self.p = getStrongPrime(512)
        self.q = getStrongPrime(512)
        self.N = self.p * self.q
        self.e = 0x10001
        self.d = inverse(self.e, self.N - self.p - self.q + 1)

    def encrypt(self, pt):
        return pow(pt, self.e, self.N)

    def decrypt(self, ct):
        return pow(ct, self.d, self.N)


rsa = RSA()
FLAG = bytes_to_long(open("flag", "rb").read())
FLAG_enc = rsa.encrypt(FLAG)

print("Welcome to dream's RSA server")

while True:
    print("[1] Encrypt")
    print("[2] Decrypt")
    print("[3] Get info")

    choice = input()

    if choice == "1":
        print("Input plaintext (hex): ", end="")
        pt = bytes_to_long(bytes.fromhex(input()))
        print(rsa.encrypt(pt))

    elif choice == "2":
        print("Input ciphertext (hex): ", end="")      #2번을 누르고 플래그 값이나 암호문보다 값이 작은 N을 입력하면 치트를 쓰지말라고 한다 
        ct = bytes_to_long(bytes.fromhex(input()))
        if ct == FLAG_enc or ct > rsa.N:
            print("Do not cheat !")
        else:
            print(rsa.decrypt(ct))

    elif choice == "3":                       #3번을 누르면 공개키 (E,n)과 암호문을 준다.
        print(f"N: {rsa.N}")
        print(f"e: {rsa.e}")
        print(f"FLAG: {FLAG_enc}")

    else:
        print("Nope")

 

이런식으로 운영되는 방식이였다 



근데 공개키로 평문을 암호문으로 만들지 않나? 그럼 어떻게 공격하지..  싶었는데 찾아보니
선택 암호문 공격 (CCA) 를 알아야한다 



선택 암호문 공격은 임의로 선택된 암호문과 일치하는 평문으로부터 암호키를 알아내기 위해 시도하는 공격이다.
즉 원하는 암호문을 복호화해주는 경우 사용할 수 있는 공격 방법이다.
RSA에서 쓰이는 경우는 "곱셈에 대한 준동형사상(Homomorphism)의 성질"이라고 한다

곱셈에 대한 준동형사상은 다음 식으로 정리될 수 있으며, 이를 이용하면 다음과 같은 공격이 가능해진다.



암호화된 flag가 있고, 암/복호화 기능이 존재한다고 가정하면

1. 숫자 2를 암호화 한다.

2. 숫자 2를 암호화 한 값 *  flag를 암호화 한 값을 곱한다.

3. 결과 값을 숫자 2로 나누면 flag가 된다.





덧붙여, 이 방법을 막기 위해서 고안된 방법은 RSA-OAEP를 제안하였다.

RSA-OAEP는 암호화 단계에서 평문 해시값과 정해진 개수의 '0' 등으로 만들어진 "인증 정보"를 평문의 앞에 추가하고 RSA로 암호화한다.

이후 복호화단계에서 이 "인증 정보"가 보이지 않을 경우 평문을 알고 있는 사람이 만든 암호문이 아니라고 판단하여 복호화를 진행하지 않는다.

실제로 RSA-OAEP에서는 난수를 이용하는 등 암호문이 매번 다른 패턴이 되도록 하여 안전성을 높였다





즉, 이 문제에서는 

2^e * flag_enc 를 [2] Decrypt에 넣어 1/2 해주면 된다.



내가 참고한 blog에서는 pwn 툴을 사용했는데 처음 써봐서 베끼는 수준 이였지만..

이 문제를 통해 pwn툴의 이해와 CCA의 개념을 이해했다

 

from pwn import *
from Crypto.Util.number import *

p = remote('host3.dreamhack.games', 21275) # 서버랑 연결 

p.sendlineafter('info\n', '3') #기다렸다가, 3번째 메뉴 선택

p.recvuntil('N: ')             # N값 받아오기(개행문자 제거해 정수로 변환한 값을 n에 저장)
n = int(p.recvline()[:-1])

p.recvuntil('e: ')            # e값 받아오기 (개행문자 제거해 정수로 변환한 값을 e에 저장)
e = int(p.recvline()[:-1])

p.recvuntil('FLAG: ')        # FLAG값 받아오기(개행문자 제거해 정수로 변환한 값을 flag_enc에 저장)
flag_enc = int(p.recvline()[:-1])

exploit_flag = (pow(2,e) * flag_enc) % n  # exploit_flag에 2^e * flag_enc % n 값을 저장

p.sendlineafter('info\n', '2')                  # 2번째 메뉴 선택
p.sendlineafter('hex): ', hex(exploit_flag)[2:])# exploit_flag값을 16진수로 변환해 전송 16진수 변환시 0x가 붙으므로 [2:]로 0x를 제거

verflag = int(p.recvline()[:-1])  # verflag에 받아온 값을 정수로 변환해 저장
flag  = verflag // 2      # verflag값을 2로 나눈 몫을 flag에 저장
log.info("REAL FLAG: " + str(long_to_bytes(flag))) # flag값을 바이트로 변환해 출력

 

 

참고 / 인용 블로그 출처

https://m.blog.naver.com/PostView.naver?blogId=apple8718&logNo=222256582723&categoryNo=0&proxyReferer=

 

DreamHack - Textbook-RSA

문제에 주어진 코드는 다음과 같다. 임의로 p와 q를 생성한 후, 공개키 값으로 65537을 사용하여 flag 값을...

blog.naver.com

https://dokhakdubini.tistory.com/289

'Cryptography' 카테고리의 다른 글

RSA 역원  (0) 2024.02.17
RSA Wiener attack code  (0) 2024.02.17
RSA 수학적 원리 발표 / 세특  (1) 2024.01.03
Factordb 사용법  (0) 2024.01.03
[Python] Crypto 모듈 다운로드 명령어  (0) 2024.01.02

ec2 - 로드밸런서- 로드밸런서선택 - Application Load Balancer 생성  - vpc , 매핑 

로드밸런서 만들때는 필요한 보안그룹을 만들어야해서 설정해줄거임.

 

인바운드 규칙 설정 

보안그룹 설정하고 다시 로드밸런서 설정으로 돌아와서 선택 

* 보안그룹이 안뜬다면 보안그룹 옆에있는 새로고침 누르기 

 

 

리스너 및 라우팅 설정

그룹을 설정해줘야하는데 이때 그룹이란, 누구누구한테 로드밸런싱을 할지 묶어주는게 그룹 

 

대상 그룹 생성 클릭 해서 vpc 확인후 선택 

아래에 보류중인것으로 포함 클릭 -  대상그룹 생성하면됨 

 

다시 돌아와서 새로고침 한번하고 대상그룹 선택 후 로드밸런서 생성 

* vpc 들어가서 작업 누르고 DNS 설정 둘다 켜져있는지 확인 

 

로드밸런서가 활성화 됐으면 원래 쓰던 myvpc-sg 클릭

인바운드 규칙 편집 - 새 규칙추가 -

새로 만든 보안규칙 선택 

- 이 보안규칙대로만 접속을 받겠다는것. 

 

로드밸런서 DAN  복사해서 웹 브라우저에 붙여넣고 새로고침 할때마다 

web01, web02, mydb에 접속이 되는걸 볼수있다. 

이제 cpu부하테스트 할거임 

stress 라고하는 패키지를 깔아서 테스트 할거니까

- web02에서 stress 깔아주기 

yum -y install stress

 

-stress 버전 확인 

stress --version

 

이미지 만들거니까  인스턴스로 가서 web02 중지하고 이미지 생성

 

이제 추가 설정을 할것이다.

 

  Amazon Simple Notification Service - 주제 - 주제생성 

 구독생성 - 프로토콜 (이메일) - 이메일 입력후 구독생성

이메일 들어가보면 메일이 와있을건데 confirm subscription 클릭 

 

이미지 다 만들었으니까 ec2에서 web02 인스턴스 시작 누르기 

 

알람받기 설정하기.

web02 작업 - cloudwatch 경보관리 - 경보생성 - 경보알림에서 위에서 만든 주제 선택 

 

 

5분마다 알람주겠다라는거임 cpu 부하테스트 할거니까 유형도 cpu 선택하고 생성 

 

 

다시 터미널로 접속할건데,

중지했다가 다시 시작했으니까 ip 바뀌었을거니까 다시 접속

- stress가 5분 안팍이면 알람이 안오니까 timeout을 500초로 해서 stress 주기 

stress --cpu 1 --timeout 500

 

 

좀 시간 지나서 cloudwatch 가면 ec2가 화나있음

 

Auto Scaling을 해주면 부하분산을 해주는데 안해줬으니까 지 혼자 견디고 있는것..

견디다 견디다 죽을수도있음 

그래서 Auto Scaling을 해볼거임.

 

템플릿 만들기 

ec2 페이지 - 시작 템플릿 

템플릿 : 설정정보를 저장

이미지 : 모든것을 저장

차이가 있음 

 

시작 템플릿 생성 - Auto Scaling 지침 체크 

내가 서버를 만드는게 아니라 얘가 서버를 만들어줄거기때문에 이미지를 만들어줘야함 AWS에서 주는거 써도 되긴하는데

아무것도 안되어있으니까 내가 세팅해준 이미지 선택 

 

인스턴스 유형 선택 - 키페어 선택 (ssh 접속해서 부하줄거니까) -보안그룹 선택 후 템플릿 생성 

 

ec2 로드밸런싱 메뉴 - 대상그룹 클릭 - 대상에서 아까 만든 인스턴스 3개 등록 취소 

 

vpc - 서브넷 들어가서 web01,web02 둘다 퍼블릭 IPv4 주소자동할당 되있는지 확인 -안되어있으면 편집해서 선택 

퍼블릭 ip를 안주면 외부에서 못들어옴 (고립) 

 

7단계라 번호로 정리하겠음 

1. ec2 - Auto Scaling 그룹 - 그룹생성 - 아까 만든 템플릿 선택 

2. vpc 선택 - 가용영역 2개 다 선택 (가상서버들이 확장되는 영역 ) 

3. 기존 로드밸런서 연결 선택 - 대상그룹선택에서 아까 만든 로드밸런서 선택 - 상태확인 시간을 100초로 수정 ( 부하확인 시간 100초가 넘었는데도 부하다? 그럼 그때 서버증설 즉 테스트 하려고 하는거임 진짜 부하인지 잠깐인지 하는거 보는거임 ) 

cloudwatch 내에서 그룹지표 수집 활성화 해야지 cloudwatch에서 모니터링 가능하니까 선택 

4. 그룹크기 (가상서버의 숫자) 원하는 용량 2로 설정 - 최소용량 2, 최대용량 6으로 설정 (아무리 부하가 와도 6개 이상 증설 불가능)

Auto Scaling 종류

이벤트 기반 : cpu가 얼마이상 되면 서버 증설 

시간기반 : 일정을 딱 정해줌 ex) 교육서버같은거는 개강일에 부하가 패턴처럼 진행되니까 그때만 오토스케일링 켜지도록 설정하는거 

대상 추적 크기 조정 정책 선택 - 인스턴스 워밍업 100초로 설정 

5. 알림추가 - 아까 만든거 클릭 

6. 태그추가 (이름) 

이건 사실 알아서 ㅎㅎ

7. 이건 그냥 검토라 생성하면 된다.

 

생성후에 ec2 인스턴스 클릭해서 보면 서버가 자동으로 생성되는걸 볼수있음 

 

인스턴스 - Auto Scaling서버 중에 하나를 종료하고 조금 기다리면 또 다시 생겨남

아까 최소설정한게 2여서 하나가 장애가 생겨도 다시 생겨나는것. ( 컨테이너도 같음 ) 

 

 

이제 부하를 줘서 자동으로 늘어나는걸 볼거임

만들어진 서버 ssh 접속하기 

 

얘네는 stress 깔려있는 이미지 따서 만든거라 깔려있음 이미 

stress --cpu 1 --timeout 500

 둘다 스트레스 주고 기다려보면 

 

 

원래 두개 말고 더 늘어나는걸 볼수있음 최대 6개까지만 늘어나고 이메일도 온다 

좀 더 기다리면 줄어들기도 함 

개별서버를 닫으면 증식 되는데 그룹을 삭제하면 아예 삭제됨

 

 

모니터링해보기 ~-~

+ Recent posts