Level 1 — 프로그래밍과 컴퓨터 내부
-
Step 41. 파이썬 환경 세팅과 첫 코드 — 작업대를 세우는 날
Level 0에서는 명령어 한 줄에 컴퓨터가 한 번 대답하는 대화를 배웠습니다. 그 방식의 한계는 명확합니다. "천 개의 파일 이름을 바꿔 줘" 같은 일을 명령어로 하려면 손가락이 남아나지 않습니다. 그래서 컴퓨터에게 일과표를 미리…
-
Step 42. 자료형 심화 — 값을 담는 네 가지 바구니
지난 시간에는 값 하나에 이름표를 붙이는 법을 배웠습니다. name = "민수". 그런데 현실의 문제는 늘 "하나"가 아닙니다. 접속 로그에는 IP가 수천 개, 학생 명단에는 이름이 수십 개, 서버 설정에는 항목이 수십 개입니다.…
-
Step 43. 조건문과 반복문 — 판단하고 반복하는 코드
지금까지의 프로그램은 위에서 아래로 한 줄씩 곧장 흘렀습니다. 그런데 세상의 일은 곧장만 흐르지 않습니다. "비가 오면 우산을 챙기고, 아니면 그냥 나간다"(판단), "불이 꺼질 때까지 계속 두드린다"(반복). 프로그램이 진짜 일을 …
-
Step 44. 함수와 모듈 — 부품을 만들어 조립하다
지금까지는 코드를 "위에서 아래로 한 번 읽히는 글"로 썼습니다. 오늘부터는 "부품을 조립하는 공학"으로 씁니다. 자주 쓰는 코드 묶음에 이름을 붙여 보관하는 것이 함수(function)이고, 그 함수들을 정리한 파일이 모듈(modu…
-
Step 45. 파일 입출력 — 기억하는 프로그램 만들기
메모리(변수)는 휘발성입니다. 프로그램이 꺼지는 순간, 아무리 열심히 모은 데이터도 증발합니다. 그래서 남기고 싶은 것은 디스크, 즉 파일(file)에 적습니다. 파일 입출력은 지루한 기초처럼 보이지만, 실은 이 책에서 가장 재사용되는 기술입니다. 스캔 결과를 저장할…
-
Step 46. 예외처리와 디버깅 — 넘어져도 다시 일어나는 프로그램
지금까지 우리가 만든 프로그램에는 공통점이 있습니다. 착한 사용자만 상대한다는 것입니다. 숫자를 달라면 숫자를 주고, 파일이 있을 때만 엽니다. 그런데 현실의 사용자는 나이를 물었는데 "스무"라고 쓰고, 파일 이름을 틀리고, 빈 칸으로 엔터를 칩니다.…
-
Step 47. ★ 프로젝트: 가위바위보 — 설명서 없이 완성하는 첫 게임
레고 블록을 사면 설명서대로 한두 개는 따라 만듭니다. 그런데 진짜 실력은 설명서 없이 상상의 것을 만들 때 생깁니다. Step 41~46이 블록 설명서였다면, 오늘은 상상의 성을 쌓는 날입니다. 왜 하필 가위바위보일까요? 작지만 완전하기…
-
Step 48. 정규표현식 — 모양으로 찾는 자석
백만 줄짜리 로그에서 "IP 주소처럼 생긴 것"만 뽑고 싶다고 합시다. in으로는 못 합니다. "1.2.3.4"라는 정확한 문자열을 찾는 것이 아니라, "숫자.숫자.숫자.숫자 모양 전부"를 찾아야 하니까요. 모양으로…
-
Step 49. ★ 프로젝트: 비밀번호 도구 — 첫 번째 보안 도구를 만든다
"123456"과 "X9#mQ2$vL8&z"라는 비밀번호는 무엇이 다를까요? 대답은 "공격자가 알아내는 데 걸리는 시간"입니다. 전자는 전 세계 유출 비밀번호 순위 1위라 0.1초, 후자는 조합이 너무 많아 …
-
Step 50. 인코딩 탐구 — 글자와 숫자 사이의 다리
컴퓨터는 글자를 모릅니다. 아는 것은 숫자뿐입니다. 그러니 화면에 보이는 ‘A’도 ‘가’도, 내부에서는 전부 숫자입니다. 그럼 ‘A’는 몇 번일까요? 누가 정했을까요? 이 질문이 오늘의 출발점입니다. 글자가 숫자라는 것을 알면, 숫자를 다시 글자로 바꾸는…
-
Step 51. 표준 라이브러리 — 파이썬에 이미 들어 있는 도구 상자
파이썬을 설치한 순간, 여러분의 컴퓨터에는 이미 수백 개의 도구가 함께 깔렸습니다. 설치 없이 import 한 줄이면 바로 쓸 수 있는 이 기본 도구들을 표준 라이브러리(standard library)라고 부릅니다. 지금까지 쓴 random, re, datetime도…
-
Step 52. 클래스와 객체지향 — 데이터와 동작을 한 상자에
Step 33에서 네트워크의 컴퓨터들을 딕셔너리로 옮긴 적이 있습니다:
-
Step 53. pip와 가상환경 — 세계의 도구를 내 방에 들이는 법
Step 51에서 우리는 표준 라이브러리라는 기본 도구 상자를 썼습니다. 그런데 파이썬의 진짜 힘은 그 바깥에 있습니다. 전 세계 개발자들이 만들어 올린 수십만 개의 외부 도구 — 웹 요청을 두 줄로 해 주는…
-
Step 54. 알고리즘 훈련 1 — 문제를 코드로 번역하는 근육
지금까지 우리는 도구를 배웠습니다. 변수, 반복문, 함수, 파일. 그런데 도구를 아는 것과 문제를 푸는 것은 다릅니다. 요리 도구를 다 안다고 요리가 되지 않듯이, 문법을 안다고 프로그램이 나오지 않습니다. 사이에는 "문제를 코드로 번역하는…
-
Step 55. ★ 프로젝트: 로그 분석기 — 기록 더미에서 발자국을 골라내라
보안 분석가의 하루는 로그와 함께 시작됩니다. 서버는 누가, 언제, 어디서, 무엇을 했는지를 줄줄이 기록해 두는데, 그 기록 더미 어딘가에 공격의 발자국이 있습니다. 문제는 양입니다 — 하루 수만 줄을 사람이 눈으로 다 볼…
-
Step 56. C 시작 — 기계가 직접 아는 언어로
여기까지 파이썬으로 왔습니다. 그런데 보안의 깊은 곳 — 운영체제, 네트워크 장비, 유명한 취약점들 — 에는 다른 언어가 깔려 있습니다. C입니다. 운영체제 커널도, 파이썬 자체도, 대부분의 시스템 도구도 C로 만들어졌습니다. C는 입문자에게 어려운…
-
Step 57. C 제어문과 함수 — 같은 생각, 다른 표기
좋은 소식부터. C의 제어문(if, for, while)은 파이썬과 생각이 같습니다. 조건이 참이면 실행하고, 정한 횟수만큼 돌고, 조건이 유지되는 동안 돕니다. Step 43에서 배운 그 흐름입니다. 달라지는 것은 표기법뿐입니다 — 들여쓰기 대신 중괄호, range…
-
Step 58. 포인터 1 — 주소를 손에 쥐는 날
C 공부에서 "여기를 넘으면 C가 보인다"는 관문이 있습니다. 포인터(pointer)입니다. 어렵다는 소문이 자자하지만, 포인터는 어려운 개념이 아니라 낯선 개념입니다. 처음엔 헷갈립니다. 정상입니다. 이 파트를 배우는 모든 사람이 같은 어색함을 지나…
-
Step 59. 포인터 2: 배열 — 붙어 있는 칸들의 법칙
Step 58에서 우리는 변수 하나의 번지를 봤습니다. 오늘은 다섯 칸을 한꺼번에 봅니다. 배열(array) — 같은 종류의 변수 여러 개를 줄 세운 것 — 입니다. 파이썬의 리스트와 비슷해 보이지만, 속은 훨씬 단순하고 그래서…
-
Step 60. 메모리 구조 — 실행 중인 프로그램의 지도
지금까지 우리는 변수 하나하나의 번지를 봤습니다. 오늘은 지도 전체를 펼칩니다. 프로그램이 실행되면 운영체제는 그 프로그램에게 메모리라는 큰 땅을 내어 주는데, 그 땅은 무작정이 아니라 용도별로 구획이 나뉘어 있습니다. 기계어가 사는 구역, 오래…
-
Step 61. malloc과 free — 힙에서 빌리고 반납하라
int arr[100];은 만들 때 크기가 정해집니다. 그런데 실제 프로그램은 "실행해 보기 전에는 몇 개가 필요한지 모르는" 경우가 많습니다. 사용자가 입력하는 만큼, 파일에 들어 있는 만큼. 그래서 C에는 실행 중에 "이만큼 빌려 주세요&…
-
Step 62. 실험: 버퍼 오버플로우 — 넘친 입력의 행선지
해킹 역사상 가장 유명한 취약점, 버퍼 오버플로우(buffer overflow)를 직접 재현합니다. 지금까지의 C 수업이 사실 이 날을 위한 것이었습니다. 배열이 붙어 있다는 것(Step 59), C가 경계를 검사하지 않는다는 것(Step 59, 61), 스택에 지역…
-
Step 63. 컴파일 과정 — 네 명의 일꾼이 바톤을 넘긴다
우리는 지금까지 gcc hello.c -o hello 한 줄로 컴파일했습니다. 마법의 주문처럼요. 그런데 그 한 줄의 뒤에서는 네 명의 일꾼이 바톤을 넘기는 작업이 벌어집니다. 오늘은 그 작업대의 뚜껑을 엽니다. 오류 메시지를 읽는 눈이…
-
Step 64. 어셈블리 첫 만남 — 내 코드의 최종 실체
지난 시간 우리는 .s 파일을 잠깐 열어 봤습니다. mov, call 같은 이상한 단어들. 오늘은 그 파일을 정면으로 읽습니다. 어셈블리어(assembly language)는 기계어를 사람이 읽을 수 있게 기호로 옮긴, 가장 낮은 층의 언어입니다. 세상의…
-
Step 65. CPU와 레지스터 — 실행의 심장 박동을 보다
지난 시간 어셈블리에서 rax, rdi 같은 이름들이 계속 나왔습니다. 오늘 그 상자들을 정식으로 만납니다. 이 상자들을 레지스터(register)라고 하고, CPU의 모든 계산은 이 상자들 위에서 일어납니다. 그리고 오늘의 가장 중요한 등장인물은 rip라는 상자…
-
Step 66. 실행 파일의 구조 — 아이콘 속의 설계도
우리가 만든 실행 파일은 겉보기엔 그저 아이콘 하나입니다. 그런데 안을 열어 보면 정돈된 구조가 있습니다. 앞부분에 설명서, 그 뒤에 코드 구역, 데이터 구역이 차례로 붙은 모양새입니다. 이 구조를 배우는 이유는 하나입니다 —…
-
Step 67. 운영체제의 역할 — 모든 부탁은 커널에게
우리가 만든 프로그램들은 파일을 읽고, 화면에 글자를 찍고, 메모리를 빌렸습니다. 그런데 생각해 보세요. 디스크는 어떻게 읽는 걸까요? 화면에는 어떻게 그리는 걸까요? 우리 코드 어디에도 "디스크를 움직여라" 같은 명령은 없었습니다. 정답은, 우리 프…
-
Step 68. 프로세스의 실체 — fork 실험
지금까지 우리는 프로그램을 "디스크에 저장된 파일"과 "실행 중인 무언가"로 구분해 왔습니다. 실행 중인 그 무언가의 정식 이름이 프로세스(process)입니다. 그런데 이 프로세스는 도대체 어디서 올까요? 정답은 조금 기묘합니다. …
-
Step 69. 가상 메모리 — 모든 프로세스의 달콤한 착각
지난 시간에 우리는 fork로 프로세스를 복제하며 "각자 독립된 메모리를 갖는다"고 배웠습니다. 그런데 곰곰이 생각하면 이상한 점이 있습니다. 여러분이 만든 프로그램은 변수의 주소를 출력했고, 그 주소는 대략 0x7fff… 근처였습니다. 그런데 제…
-
Step 70. 프로젝트 — C로 메모리 관찰 도구 만들기
지금까지 우리는 메모리를 "배우는 대상"으로만 다뤘습니다. 오늘은 위치를 바꿉니다. 메모리를 관찰하는 도구를 직접 만드는 것입니다. 의사가 될 필요는 없지만, 적어도 청진기를 직접 만들어 본 사람이 환자의 소리를 다르게 듣습니다. 만들 것은 단순합니다…
-
Step 71. HTML/CSS 기초 — 웹페이지의 뼈대와 옷
지금까지 우리는 터미널이라는 검은 창에서 살았습니다. 오늘부터 무대는 브라우저입니다. 여러분이 매일 보는 웹페이지는 사실 전부 "텍스트 파일"입니다. 화려한 쇼핑몰도 뿌리를 따라가면 글자로 된 문서 하나이고, 브라우저가 그것을 예쁘게 그려 낸 것입니다…
-
Step 72. JavaScript 기초 — 웹페이지를 살아 있게 하는 언어
지난 시간에 만든 페이지는 예쁘지만 조용합니다. 버튼을 눌러도, 글자를 쳐도 반응이 없습니다. HTML과 CSS만으로는 "정적인 문서"가 한계이기 때문입니다. 여기에 생명을 불어넣는 것이 JavaScript(자바스크립트, JS)입니다. 보안 학습자에게…
-
Step 73. HTTP 완전 이해 — 웹의 대화 규칙
지난 두 챕터에서 우리는 페이지를 만들고 움직이게 했습니다. 그런데 그 페이지가 서버에서 우리 화면까지 어떻게 오는지는 아직 검은 상자입니다. 오늘 그 상자를 엽니다. 웹의 모든 통신은 단순한 규칙 하나로 돌아갑니다 — 클라이언트(손님)가…
-
Step 74. requests 라이브러리 — 파이썬으로 웹과 대화하기
지난 시간 우리는 curl로 서버와 대화했습니다. 명령 한 줄에 요청 하나. 훌륭하지만 한계가 있습니다 — 백 개의 페이지를 긁으려면 명령을 백 번 쳐야 하고, 응답에서 원하는 값만 뽑으려면 눈으로 찾아야 합니다. 자동화가…
-
Step 75. BeautifulSoup 크롤링 — HTML에서 원하는 것만 뽑기
지난 시간에 requests로 페이지를 통째로 가져오는 데 성공했습니다. 그런데 가져온 것을 보면 수천 글자짜리 HTML 문자열일 뿐입니다. 그 안에서 "명언 세 개"만 뽑으려면 어떻게 해야 할까요? 문자열 검색으로는 태그가 얽혀 있어 한계가…
-
Step 76. 크롤러와 자동화 — 매일 혼자 일하는 수집기
지금까지 우리의 스크립트는 "켜면 한 번 일하고 꺼지는" 장난감이었습니다. 진짜 도구는 다릅니다. 주인이 자는 동안에도 일하고, 어제 모은 것을 기억해서 같은 것을 두 번 가져오지 않고, 실패하면 조용히 기록을 남깁니다. 오늘의 프로젝트는…
-
Step 77. 소켓 통신 1 — TCP echo 서버와 클라이언트
지금까지 우리가 만든 프로그램은 혼자 일했습니다. 그런데 컴퓨터의 진짜 힘은 연결에서 나옵니다 — 웹, 게임, 메신저 전부 "두 프로그램이 네트워크로 대화하는 것"입니다. 그 대화의 전화기가 소켓(socket)입니다. 지난 챕터들의 requests가 …
-
Step 78. 소켓 통신 2 — 멀티 클라이언트 채팅 서버
지난 시간의 echo 서버에는 치명적인 제약이 있었습니다. 한 손님과 대화하는 동안 다른 손님은 문 밖에서 기다린다는 것. 진짜 서비스는 "직원을 접속마다 한 명씩 배치한다"는 발상으로 이를 풉니다. 프로그램 안의 그 직원이 스레드(thread,…
-
Step 79. 포트 스캐너 — 열린 문을 찾아내는 정찰기
Step 77에서 우리는 서버를 열었고, 클라이언트가 그 문을 두드렸습니다. 그런데 생각해 보세요 — 문을 두드리기만 하면 "열림/닫힘"을 알 수 있다면, 문을 하나씩 다 두드려 보면 그 건물의 지도가 그려지지 않을까요? 그것이 포트…
-
Step 80. Scapy 입문 — 패킷 수작업 공방
지금까지 우리는 소켓이라는 전화기로 대화했습니다. 편리했지만, 우리가 정할 수 있는 것은 "무슨 말을 할지"뿐 — 그 말을 담는 봉투(패킷)는 운영체제가 알아서 만들어 줬습니다. Scapy(스캐피)는 그 봉투를 우리 손으로 만드는 공방입니다. 패킷을 …
-
Step 81. nmap 완전 정복 — 정찰의 표준 도구
Step 79에서 우리는 포트 스캐너를 직접 만들었습니다. 잘 동작했지만, 세상에는 이 일을 25년 넘게 갈고닦아 온 도구가 있습니다. nmap(Network Mapper, 네트워크 지도 제작기)입니다. 침투 테스트 보고서의 첫 페이지에는 거의 항상 nmap의 출력이…
-
Step 82. 프로젝트 — 네트워크 지도와 위험도 평가
공격자가 네트워크에 들어와 제일 먼저 하는 일이 무엇인지 아십니까? "뭐가 있는지 지도를 그리는 것"입니다. 방어자의 첫 일도 정확히 같습니다 — 모르는 것은 지킬 수 없기 때문입니다. 오늘은 Step 81의 스캔 결과를 재료로,…
-
Step 83. Wireshark 1 — 캡처와 필터, 네트워크의 현미경
Step 80에서 우리는 패킷을 만들고 몇 개쯤 낚아채 봤습니다. 그런데 이 일을 전문으로 하는, 25년 된 현미경이 있습니다. Wireshark(와이어샤크)입니다. 네트워크 카드를 지나는 모든 패킷을 실시간으로 잡아, 계층별로 펼쳐 보여 주고, 대화 단위로…
-
Step 84. Wireshark 2 — 프로토콜 파헤치기와 이상 탐지
의사가 병을 알아보려면 먼저 건강한 몸을 알아야 합니다. 네트워크도 같습니다. "이상한 패킷"을 찾으려면 "정상적인 패킷"이 어떻게 생겼는지부터 알아야 합니다. 오늘은 TCP, DNS, HTTP의 정상적인 모습을 현미경으로 하나씩 파…
-
Step 85. 프로젝트 — HTTP vs HTTPS 비교 보고서
주소창의 자물쇠 — HTTPS입니다. 그런데 자물쇠가 있고 없고가 실제 전선 위에서 어떤 차이를 만드는지 직접 본 사람은 거의 없습니다. 이번 프로젝트의 목표는 단 하나입니다. 같은 내용을 HTTP(평문)로 한 번, HTTPS(암호문)로 한 번…
-
Step 86. Git 기초 — 코드의 타임머신
report_최종.docx, report_최종_진짜.docx, report_최종_진짜2_교수님피드백반영.docx — 파일 이름에 역사를 우겨 넣는 방식을 누구나 해 봤습니다. 코드는 문서보다 훨씬 자주 바뀌고, 한 줄만 잘못 고쳐도 전체가 멈춥니다. 그래서 프로그래머들…
-
Step 87. GitHub 원격 저장소와 포트폴리오 — 백업이자 전시장
어제 만든 타임머신은 내 컴퓨터 안에만 있습니다. 그런데 컴퓨터는 고장 나고, 노트북은 잃어버립니다. 타임머신 자체의 백업이 필요합니다. 그리고 또 하나 — 보안 업계에서 "실력을 증명해 보세요"라는 요구는 이력서 한 장보다 GitHub 프로필…
-
Step 88. 브랜치와 merge — 평행우주와 합치기
잘 돌아가던 스캐너에 새 기능을 붙이다가, 반쯤 만든 상태에서 "지금 버전으로 시연해 주세요"라는 요청을 받았다고 합시다. 되돌리자니 지금까지의 작업이 아깝고, 두자니 원본이 망가져 있습니다. Git의 답은 우주를 둘로 나누는 것입니다. 브랜치(bra…
-
Step 89. 마크다운 문서화 — 나만의 개인 위키
잔인한 사실 하나를 알려 드리겠습니다. 6개월 뒤의 여러분은 지금의 여러분을 기억하지 못합니다. 지금 당장 떠오르는 "그 에러 어떻게 고쳤지?"도 세 달 뒤에는 백지가 됩니다. 보안 공부는 쌓는 양이 방대해서 이 문제가 다른…
-
Step 90. 프로젝트 — XOR 파일 암호화/복호화 도구
암호라고 하면 첩보 영화의 검은 상자를 떠올리지만, 그 심장에는 놀랄 만큼 단순한 연산이 있습니다. 오늘의 주인공 XOR(배타적 논리합, 기호 ⊕) — 규칙은 단 한 줄, "같으면 0, 다르면 1." 이 연산에는 마법…
-
Step 91. 리눅스 복습 — OverTheWire Bandit 0~10
오늘 처음으로 밖에 있는 서버에 접속합니다. 단, 그 서버는 "여러분을 공격해 보라고 만들어 둔" 합법적인 연습장, OverTheWire Bandit입니다. 규칙은 단순합니다 — 각 레벨의 서버에 SSH로 접속해, 어딘가 숨겨진 "다음 레벨의…
-
Step 92. SQL 기초 1 — 데이터베이스와 대화하기 (CRUD)
웹 서비스의 겉모습은 HTML과 CSS지만, 그 속살 — 회원 목록, 게시글, 댓글, 그리고 비밀번호 — 은 거의 전부 데이터베이스(DB)라는 창고에 삽니다. 그리고 그 창고지기와 대화하는 언어가 SQL입니다. 보안을 공부하는 여러분에게 SQL이 중요한…
-
Step 93. SQL 기초 2 — JOIN과 파이썬 연동
실제 서비스는 데이터를 한 장의 표에 욱여넣지 않습니다. 회원은 회원 표에, 주문은 주문 표에 — 나눠 담습니다. 회원이 주소를 바꿀 때마다 그 사람의 주문 백 건을 전부 고치는 재앙을 피하기 위해서입니다. 그런데…
-
Step 94. Flask 맛보기 — 웹 서버를 직접 만든다
Step 73에서 우리는 HTTP 요청을 보내는 법을 배웠습니다. 그런데 한 가지가 빠져 있었습니다 — 요청을 받은 쪽에서는 무슨 일이 일어나는가? 오늘 그 블랙박스를 엽니다. 도구는 Flask(플라스크) — 파이썬 몇 줄로 웹 서버를…
-
Step 95. Level 1 종합 프로젝트 — 네트워크 감시 도구 완성하기
지금까지 50개가 넘는 스텝을 지나왔습니다. 파이썬, 웹, 네트워크, 데이터베이스, Git, 문서화. 그런데 진짜 실력은 "따라하기를 해냈다"가 아니라 여기서 드러납니다 — 요구사항만 듣고 완성품을 만드는 것, 그것이 실력입니다. 중간에 막히는 부분이…