Tag Archive

#static-analysis

이 태그가 포함된 글을 최신순으로 모아봤어요.

14
posts
BLOG2026-08-19
[🥉 Bronze 1] 31줄 발췌본이 base64 인코더라는 걸 증명하기 — DreamHack [CodeEngn] Malware L05 풀이
blog

[🥉 Bronze 1] 31줄 발췌본이 base64 인코더라는 걸 증명하기 — DreamHack [CodeEngn] Malware L05 풀이

악성코드 소스 31줄만 주고 "무엇을 하는 함수인가"를 묻는다. 표준 알파벳 64자와 6비트 마스크가 보이니 base64 같은데, 눈으로 찍는 대신 가려진 두 줄을 채워 컴파일하고 입력 304종을 표준과 바이트 단위로 맞춰 봤다. 덤으로 이 구현이 3의 배수 아닌 길이에서 터지고 76열 규격도 어긴다는 것까지 실측했다.
#dreamhack#ctf#misc+6
 
BLOG2026-07-20
[🥉 Bronze 1] 64바이트를 6개 함수가 나눠 검증하는 crackme — DreamHack mix-compare 풀이
blog

[🥉 Bronze 1] 64바이트를 6개 함수가 나눠 검증하는 crackme — DreamHack mix-compare 풀이

64바이트 입력을 check → check_not → check_add → check_dec → check_mul → check_la 여섯 함수가 10바이트 안팎씩 나눠 맡아 각자 다른 산술 변환(NOT·덧셈·뺄셈·곱셈·역방향 덧셈)으로 검증한다. 비교 대상 배열은 .data에 평문 정수로 그대로 박혀 있어서, 각 구간의 변환을 거꾸로 풀기만 하면 64바이트 전체가 그대로 복원된다.
#dreamhack#ctf#reversing+3
 
BLOG2026-07-19
[🥈 Bronze 2] 함수 주소일까, 호출 지점일까 — DreamHack [CodeEngn] Malware L08 풀이
blog

[🥈 Bronze 2] 함수 주소일까, 호출 지점일까 — DreamHack [CodeEngn] Malware L08 풀이

다른 악성코드를 실행해 추가 감염을 일으키는 함수의 주소를 찾으라는 문제. 그래프 전체가 ShellExecuteExA로 대상 파일을 실행하는 하나의 함수인데, 그 함수 자체의 시작 주소를 냈다가 오답을 받았다. 함수 안에 ShellExecuteExA 호출이 두 곳이라는 걸 알고도 어느 쪽인지 헷갈렸는데, 결국 "함수의 주소"가 가리키는 건 실행 API를 호출하는 그 지점이었다.
#dreamhack#ctf#reversing+5
 
BLOG2026-07-19
[🥈 Bronze 2] 미끼인 줄 알았던 디코드가 사실 정답이었다 — DreamHack 아 문제 이름 뭘로하지 풀이
blog

[🥈 Bronze 2] 미끼인 줄 알았던 디코드가 사실 정답이었다 — DreamHack 아 문제 이름 뭘로하지 풀이

39바이트 암호문을 XOR 0xAA로 풀면 그럴듯한 DH{} 문자열이 바로 나온다. 너무 쉬워서 미끼라고 판단하고, 사용자 입력을 변형하는 복잡한 커스텀 인코딩 함수를 통째로 역산했다. GDB로 대조하다 32비트 시프트 카운트 마스킹 때문에 특정 자리가 항상 0이 되는 버그를 발견했고, 그 버그를 쫓아가다 결국 처음 봤던 그 디코드 문자열이 진짜 정답이었다는 걸 알게 됐다.
#dreamhack#ctf#reversing+4
 
BLOG2026-07-19
[🥈 Bronze 2] 난독화된 전역 변수를 GDB로 그대로 읽어내기 — DreamHack Stop before stops! 풀이
blog

[🥈 Bronze 2] 난독화된 전역 변수를 GDB로 그대로 읽어내기 — DreamHack Stop before stops! 풀이

C++ 바이너리인데 함수·전역변수 이름이 전부 무작위 문자열로 바뀌어 있다. 정적 분석으로 로직은 다 읽히는데(24자 비밀번호를 비교해 맞으면 flag를 출력), 실제 비교 대상 문자열은 실행 시점에 조용히 채워지는 전역 std::string이라 정적 디스어셈블리만으론 값을 알 수 없다. GDB로 static initializer가 끝난 직후 raw 메모리를 읽어 값을 그대로 꺼냈다.
#dreamhack#ctf#reversing+5
 
BLOG2026-07-19
[🥉 Bronze 3] 뮤텍스가 두 개인 악성코드에서 Thread Mutex 골라내기 — DreamHack [CodeEngn] Malware L06 풀이
blog

[🥉 Bronze 3] 뮤텍스가 두 개인 악성코드에서 Thread Mutex 골라내기 — DreamHack [CodeEngn] Malware L06 풀이

같은 악성코드(bagla downloader) 그래프를 다루는 CodeEngn 시리즈의 또 다른 문제. 이번엔 뮤텍스가 두 개 나온다 — 프로그램 시작 시 만드는 프로세스 단일실행 가드용, 그리고 CreateThread 직후 만드는 두 번째 뮤텍스. 문제가 묻는 "Thread Mutex"는 스레드 생성과 바로 붙어 있는 후자다.
#dreamhack#ctf#reversing+5
 
BLOG2026-07-19
[🥉 Bronze 4] 가짜 함수 199개 속에서 flag 찾기 — DreamHack please, please, please 풀이
blog

[🥉 Bronze 4] 가짜 함수 199개 속에서 flag 찾기 — DreamHack please, please, please 풀이

stripped PIE 바이너리 안에 거의 동일한 함수가 199개 박혀 있다. 전부 "please~"만 출력하는 죽은 코드고, 실제 main도 puts 한 줄만 부르고 끝난다. objdump로 199개 중 유일하게 다른 함수를 찾아내면 "Hhu,"라는 또 다른 미끼가 나오는데, 정작 flag는 strings 한 번이면 바로 보이는 DH{NOGADA}였다.
#dreamhack#ctf#reversing+5
 
BLOG2026-07-19
[🥉 Bronze 4] IDA 그래프 한 장으로 끝내는 악성코드 재접속 주기 — DreamHack [CodeEngn] Malware L07 풀이
blog

[🥉 Bronze 4] IDA 그래프 한 장으로 끝내는 악성코드 재접속 주기 — DreamHack [CodeEngn] Malware L07 풀이

실행 파일 대신 IDA 그래프 캡쳐 한 장(07.pdf)만 주어진다. 악성코드가 C2 서버 접속에 실패했을 때 몇 ms 간격으로 재시도하는지를 묻는데, 그래프 안의 재시도 루프를 따라가면 `push 96000h` → `call ds:Sleep`가 답이다. 16진수 0x96000을 10진수로 환산한 614400이 flag가 된다.
#dreamhack#ctf#reversing+5
 
BLOG2026-07-13
[🥉 브론즈 2] 입력할 수 없는 정답 — DreamHack My Favorite Fruit 풀이
blog

[🥉 브론즈 2] 입력할 수 없는 정답 — DreamHack My Favorite Fruit 풀이

과일 이름을 물어보는 챗봇 바이너리다. 다섯 과일을 다 맞히면 전역 버퍼를 flag 로 복원해 출력하는데, scanf 포맷이 %9s 라 열 글자짜리 strawberry 는 아홉 글자로 잘려 절대 매칭되지 않는다. 그래서 런타임으로는 flag 가 나오지 않는다. 하지만 버퍼를 만드는 연산이 XOR 라 순서와 무관하므로, 다섯 과일 키를 정적으로 한꺼번에 XOR 해 flag 를 복원했다.
#dreamhack#ctf#reversing+4