N = int(input())
p = []
for _ in range(N):
a, b, c = map(int, input().split())
d = 0
if a == b == c :
d = 10000 + a*1000
elif a == b :
d = 1000 + a*100
elif b == c :
d = 1000 + b*100
elif c == a :
d = 1000 + c*100
else :
d = 100 * max(a, b, c)
p.append(d)
print(max(p))
평문 Plaintext : 암호화되지 않은 메시지 암호문 Cypertext : 암호화된 메시지
암호화 Encryption : 평문을 암호문으로 만드는 것 복호화 Decryption : 암호문으로부터 평문을 복원하는 것
키 Key : 평문/암호문을 암호화/복호화시키는 암호 알고리즘에 필요한 핵심 가변정보 값
모듈러 연산 : 어떤 숫자를 다른 숫자로 나눈 나머지를 구하는 연산 ex) a ≡ b (mod n) : a와 b는 n으로 나눈 나머지가 같다 합동 : 어떤 숫자를 다른 숫자로 나눈 나머지가 같은 경우, 이를 합동이라고 함
인코딩 : 데이터를 코드화하고 압축하는 등 다른 형태로 변환하는 것
인코딩은 암호화와 달리 데이터의 기밀성을 고려하지 않고 누구나 디코딩하여 원문을 구할 수 있다. 파일의 크기를 줄이거나 컴퓨터가 알아들을 수 있는 형식으로 변환하기 위해 사용한다.
Base64 : 8비트 이진 데이터(실행 파일, ZIP 파일 등)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식을 가리키는 개념.
총 64개로 이루어지며, =은 끝을 알리는 코드로 사용.
24비트 버퍼에 3바이트씩 집어넣고, 6비트식 끊어서 해당하는 문자로 변환
대칭키 암호 (=비밀키 암호)
암호화와 복호화에 같은 암호 키를 쓰는 알고리즘. (ex. DES, AES)
고대 치환 암호 : 평문을 이루는 각각의 문자를 다른 문자로 바꿔 정보를 숨기는 것 카이사르 암호(시저 암호) : 암호화하고자 하는 내용을 알파벳별로 일정한 거리만큼 밀어서 다른 알파벳으로 치환하는 암호 방식 비제네르 암호 : 여러 개의 수를 암호키로 사용하여 카이사르 암호보다 한 층 더 복잡한 다중 치환 암호
블록 암호 : 평문을 정해진 블록 단위로 암호화하는 알고리즘 (ex. AES, DES) 스트림 암호 : 이진 수열로 변환된 평문을 비트 단위로 암호화하는 알고리즘으로, 평문을 키와 배타적 논리합(XOR) 연산을 수행하여 암호문 생성.
비대칭키 암호 (=공개키 암호)
암호화와 복호화에 다른 암호 키를 쓰는 알고리즘으로, 전자서명에 사용됨 (ex. RSA, 타원곡선암호)
공개키 : 평문을 암호문으로 만드는 키로, 누구나 암호화 가능 비밀키(개인키) : 암호문을 복호화하는 키로, 키를 알고 있는 사람만 복호화 가능
일방향 함수 : 계산은 쉾지만 역을 구하는 것은 어려운 함수로, 대부분의 비대칭키 암호화 방식은 이것으로부터 구안 RSA 알고리즘 : 두 개의 큰 소수를 곱한 합성수는 소인수분해가 어렵다는 것을 기반으로 만들어진 암호 알고리즘
해시
데이터를 고정된 길이의 데이터로 매핑하는 함수로, N:1 일방향 함수 (ex. CRC, MD5, SHA1)
키key : 매핑 전 데이터의 값(평문) 해시 값 Hash Value : 매핑 후 데이터의 값(암호문) 해시 테이블 Hash Table : 키와 데이터를 저장하는 자료구조 해싱 Hashing : 매핑하는 과정
해시 충돌 : 서로 다른 두 개의 입력값에 대해 동일한 해시 값을 출력하는 상황. 해시 충돌이 발생하지 않을수록 좋은 해시 함수. 눈사태 효과 : 입력 값의 일부만 변경되어도 해시 값이 매우 크게 변함
사용 예시 : 무결성 검증, 비밀번호 저장
스테가노그래피
데이터 은폐 기술 중 하나로, 데이터를 다른 데이터에 삽입해 그 데이터의 존재 자체를 숨기는 것. 오늘날 디지털 스테가노그래피는 이미지, 오디오 파일, 동영상 클립, 텍스트 파일 등 무해해 보이는 객체 안에 비밀 메시지를 감춰두는 방식으로 활용됨.
2, 네트워크 해킹
네트워크 해킹 개요
네트워크 해킹 : 네트워크 상에서 발생되는 해킹을 의미 보안의 기본 요소에 따라 기밀성, 무결성, 가용성의 침해를 받음
(기밀성) 스니핑 sniffing : 네트워크 흐름의 중간에서 도청, 감시 등의 공격을 하는 행위 (무결성) 스푸핑 Spoofing : 사용자가 원하는 행위를 속여 비정상적인 행동을 하는 행위 (가용성) Dos 공격 : 서비스 거부 공격을 수행하여 서버나 시스템이 동작하지 못하도록 공격하는 행위
네트워크 용어 정리
시스템
노드 : 인터넷에 연결된 시스템의 가장 기본적인 용어
호스트 ; 컴퓨팅 기능이 있는 시스템. 양 끝단에 있는 송수신기를 뜻 (ex. PC)
클라이언트 : 서비스를 요청하는 시스템 (호스트가 송신을 할 때)
서버 : 서비스를 제공하는 시스템 (호스트가 수신을 할 때)
프로토콜 : 컴퓨터 간에 정보를 주고받을 때의 통신 방법에 대한 규칙이나 표준
게이트웨이 : 한 네트워크에서 다른 네트워크로 이동하기 위하여 거쳐야 하는 지점
1계층 리피터(repeater)
2계층 브리지(bridge)
3계층 라우터(router)
프로토콜
기본 요소
구문 Syntax : 전송하고자 하는 데이터의 형식(Format), 부호화(Coding), 신호 레벨(Signal Level) 등을 규정
의미 Semantics : 두 기기 간의 효율적이고 정확한 정보 전송을 위한 협조 사항과 오류 관리를 위한 제어 정보를 규정
시간 Timing : 두 기기 간의 통신 속도, 메시지의 순서 제어 등을 규정
OSI 7계층 (OSI 7 Layer)
국제 표준화기구 ISO에서 1984년에 네트워크 통신의 구조를 7계층으로 구분하여 각 계층 간 상호 작동하는 방식을 정의해놓은 것
송신자 측 : 원본 데이터를 상위 계층 → 하위 계층으로 전달하며 각 계층마다 헤더 추가
수신자 측 : 전달받은 데이터를 하위 계층 → 상위 계층으로 전달하며 원본 데이터 전달 받음
1계층 - 물리 계층 : 최하층 계층. 2진법의 바이너리 정보를 전기적, 물리적 신호로 수신자에게 정보 전달 (전송 단위 : Bit)
2계층 - 데이터 링크 계층 : 물리 계층에서 일어날 수 있는 오류들을 찾아내고 수정하여 하위 계층으로 데이터 전달 (전송 단위 : Frame)
3계층 -네트워크 계층 : 양 끝단의 사용자들의 IP를 확인하여 최적의 정보 전달이 가능한 루트를 찾는 라우팅을 진행 (전송 단위 : Packet)
4계층 -전송 계층 : 양 끝단의 사용자들이 신뢰성 있는 데이터를 주고받기 위해 프로토콜 정의, 하위 계층으로 데이터 전달 (전송 단위 : Segment)
5계층 -세션 계층 : 양 끝단의 사용자들의 통신을 관리하기 위한 방법을 정의하고 하위 계층으로 데이터 전달
6계층 -표현 계층 : 원본 데이터를 부호화, 변화, 암호화, 복호화, 압축 등을 진행하여 하위 계층으로 데이터 전달
7계층 -응용 계층 : 응용 소프트웨어에서 데이터를 생성하고 하위 계층으로 데이터 전달
패킷
네트워크에서 출발지와 목적지 간에 라우팅 되는 데이터 단위
네트워크 패킷은 사용자 데이터와 제어정보로 이루어지며, 사용자 데이터는 페이로드라고 함 (제어정보 : 페이로드를 전달하기 위한 정보)
구성요소
헤더 : 소스 주소, 대상 주소, 프로토콜 및 패킷 번호 포함. 전송 중인 패킷 유형을 식별하는 데 도움이 됨.
페이로드 : 패킷에 의해 전송되는 실제 데이털르 나타낸 것, 데이터라고도 함. 헤더 정보가 목적지에 도달할 때 제거됨.
트레일러 : 패킷 트레일러의 내용은 각 네트워크 유형에 따라 다름. 비트와 CRC 포함.
Wireshark
네트워크 패킷을 캡쳐하고 분석하는 오픈 소스 패킷 분석 프로그램
강력하고 쉬운 사용법 때문에 해킹 뿐만 아니라 보안 취약점 분석, 보안 컨설팅, 개인정보 영향평가 등 여러 분야에서 폭넓게 사용됨
호출자 : 프로그래밍에서 다른 함수 또는 메서드를 호출하는 주체. 쉽게 말해, 호출자는 특정 함수 또는 메서드를 실행하도록 명령한 코드 부분을 가리킴.
함수를 호출할 때는 반환된 이후를 위해 호출자의 상태 및 반환 주소를 저장해야함 또한, 호출자는 피호출자가 요구하는 인자를 전달해줘야하고, 피호출자의 실행이 종료될 때는 반환값을 전달받아야 함
함수 호출 규약의 종류
컴파일러는 지원하는 호출 규약 중에서 CPU의 아키텍처에 적합한 것을 선택
x86(32bit) 아키텍처 -> 레지스터 수 적음 -> 스택으로 인자 전달하는 규약 사용 x86-64 아키텍처 -> 레지스터 수 많음 -> 적은 인자는 레지스터만, 많은 인자는 스택 사용
CPU의 아키텍처가 같아도, 컴파일러가 다르면 적용하는 호출 규약이 다름 ex) C 컴파일, x86-64 아키텍처 윈도우 -> MSVC -> MS x64 호출 규약 리눅스 -> gcc -> SYSTEM V 호출 규약
SYSV
리눅스 gcc, x86-64 바이너리 컴파일 시 사용 리눅스 SYSTEM V(SYSV) Application Binary Interface(ABI) 기반, SYSV ABI는 ELF 포맷, 링킹 방법, 함수 호출 규약 등의 내용 포함
함수 호출 규약
6개의 인자를 RDI, RSI, RDX, RCX, R8, R9에 순서대로 저장하여 전달. 더 많은 인자를 사용해야 할 때는 스택을 추가로 이용.
Caller에서 인자 전달에 사용된 스택을 정리.
함수의 반환 값은 RAX로 전달.
cdecl
리눅스 gcc, x86 바이너리 컴파일 시 사용 스택을 통해 인자 전달, 인자 전달 위해 사용한 스택을 호출자가 정리 인자 전달시, 거꾸로 스택에 push
* push 횟수 x 4byte 만큼 esp가 증가됨
2. Stack Buffer Overflow
버퍼 오버플로우
버퍼
데이터가 목적지로 이동되기 전에 보관되는 임시 저장소
데이터가 안정적으로 목적지에 도달할 수 있도록 완충 작용을 함
스택에 있는 지역 변수는 '스택 버퍼', 힙에 할당된 메모리 영역은 '힙 버퍼'라고 불림
오버플로우
버퍼가 넘치는 것
int로 선언한 지역 변수는 4바이트 크기, 10개의 원소를 갖는 char배열은 10바이트 크기
일반적으로 버퍼는 메모리상 연속 할당됨 -> 특정 버퍼에서 오버플로우 발생하면 뒤에 있는 버퍼들의 값이 조작될 위험이 있음
스택 버퍼 오버플로우 : 스택의 버퍼에서 발생하는 오버플로우
주요데이터 변조 버퍼 오버플로우가 발생하는 버퍼 뒤에 중요한 데이터가 있다면, 해당 데이터가 변조됨으로써 문제가 발생할 수 있습니다.
*C 언어에서 if는 0일 때 거짓, 0이 아닐 때 참으로 동작
데이터 유출 C언어에서 정상적인 문자열은 널바이트로 종결되며, 표준 문자열 출력 함수들은 널바이트를 문자열의 끝으로 인식합니다. 만약 어떤 버퍼에 오버플로우를 발생시켜서 다른 버퍼와의 사이에 있는 널바이트를 모두 제거하면, 해당 버퍼를 출력시켜서 다른 버퍼의 데이터를 읽을 수 있습니다. 획득한 데이터는 각종 보호기법을 우회하는데 사용될 수 있으며, 해당 데이터 자체가 중요한 정보일 수도 있습니다.
// 문자열이 "I.Sly"가 아닌 경우 다음 단계로 분기 <+130>: jmp 0x1264 <main+155>
// 입력 값이 비어 있지 않은 경우 "You're doing it right!" 메시지를 출력 <+132>: movzx eax,BYTE PTR [rbp-0x10] <+136>: movzx eax,al <+139>: test eax,eax <+141>: je 0x1264 <main+155> <+143>: lea rdi,[rip+0xdfb] # 0x205a <+150>: call 0x1090 <puts@plt>
// 함수가 정상적으로 종료되는지 확인하고 스택 프레임을 정리, 스택 보호 검사 후 함수에서 반환 <+155>: mov eax,0x0 <+160>: mov rdx,QWORD PTR [rbp-0x8] <+164>: xor rdx,QWORD PTR fs:0x28 <+173>: je 0x127d <main+180> <+175>: call 0x10a0 <__stack_chk_fail@plt> <+180>: leave <+181>: ret
스택 프레임 구조를 그려보면 위와 같다.
문자열 길이인 8을 넘기게 되면 B에 데이터가 덮어써진다는 점을 이용하여 I.Sly 앞에 A 8개을 붙여 입력해주었다. [check] 뒤에 출력된 결과를 보아 변수 B에 I.Sly가 저장된 것을 확인할 수 있다. 필요한 조건을 충족하여 flag가 출력된 것을 볼 수 있다.