- CodeEngn Basic RCE L11
<패킹 전의 프로그램 디버깅>
하지만 여기 nop은 무조건 점프라서 노상관
OEP를 묻길래 혹시나 해서 Dump를 떠봤더니, 역시나 UPX 패킹되어 있었다.
언패킹
<언패킹 후 디버깅>
우선 처음 보이는 이 부분(00401000)이 OEP 일것이고,
stolenbyte 여기여기 ^nop의 향연
12바이트나 훔쳐감..
한줄씩 실행해봤을 때 메시지 박스가 이상하게 출력됨
이는 메시지 박스 내용이 어디 도망간 것으로 추측
?
패킹하기 전에 프로그램을 실행해보면
이런 창이 나온다
이 문구를 불러와야하는데 그걸 훔쳐가서 문구가 깨진 것이다!
다시 언패킹하기 전의 디버깅,
여러 call을 bp 걸고 실행하다가 발견,
여기 push 0~ push 11.402012까지가 계산해보니까 딱 12바이트로, 이 부분을 복사해서 아까 훔쳐간 곳에 붙여 넣으면 정상실행 될 것이다!
- CodeEngn Basic RCE L12
해당 파일 실행화면
eax(내가 입력한 값)과 7A2896BF(10진수로 2049480383) 비교함key 창에 2049480383 입력하면 아마 congratulation 문구랑 함께 맞는 키를 찾았다고 알려줄것이다.
짠
문제는, 이제 hexdump를 수정해서 key가 그냥 뜨게 만들어야한다는데,
hex에 축하 출력 메세지 부분에 10진수 넣어주면 됨
이 곳의 Cong~ 부분을 위에 찾은 2049480383로 바꿔주고 실행하면,
위치는 여기!
- CodeEngn Basic RCE L13
-정답은 무엇인가
password를 찾는 문제인 것 같다!
입력으로 hello?를 넘겨줘봤는데 “Bad Luck! Try again!”라는 틀렸다는 의미의 메시지를 출력한다. 아마 패스워드 관련 알고리즘을 찾아서 패스워드를 구하라는 것 같다.
??????
근데 x64dbg로 열어보니 패스워드가 대놓고 나타나 있었다.
[참고] https://a6ly.dev/21 - 원래 푸는 법
디컴파일러 툴인 .Net Reflector를 사용해서 분석한다.
plaintext와 비교해서 같다면 성공 문자열을, 다르다면 실패 문자열을 출력한다.
코드를 보면 plaintext가 암호화 되어있는 것을 볼 수 있는데, 비교문 전에 plaintext를 복호화하니까 비교문 후에 실패문자열과 함께 복호화 된 plaintext가 출력되도록 코드를 수정한다.
이 후 프로그램을 실행시켜보면 실패문자열과 함께 password인 plaintext가 출력되는 것을 확인할 수 있다.
- CodeEngn Basic RCE L14
Name이 CodeEngn 일때 Serial을 구하시오
(이 문제는 정답이 여러개 나올 수 있는 문제이며 5개의 숫자로 되어있는 정답을 찾아야함, bruteforce 필요)
Ex) 11111
어셈블리어를 더 쉽게 살펴보기 위해서 실행 후 11111과 123123을 입력하였고,
올리디버거에 123123라는 부분이 에러/성공메세지 전에 띄워지는 것을 볼 수 있다.
즉 시리얼 넘버는 실행화면에 아랫줄이라는 것을 알 수 있었다.
이제 시리얼 넘버를 찾아야 하니 wrong seial 문구가 뜨는 지점을 기준으로 앞 뒤로 분석해 보자 !
0040133A CMP EAX,ESI
0040133C JNZ 00401353
이 부분을 해석해보면 EAX - ESI의 값이 0이 아니라면 00401353으로 이동해서
"YOU HAVE ENTER A WRONG SERIAL"이라는 에러메세지를 출력하도록 하고 있다.
그러면 JNZ에서 점프를 하지 않아야 "GOOD JOB. ~~~" 이라는 성공메세지를 출력할 수 있다.
즉 EAX - ESI = 0 이 되어야 하고, EAX와 ESI의 값이 같아야 한다.
레지스터 값에 각각 어떤것이 들어가는지 알아보기 위해서 CMP명령어에 F2를 눌러 BP를 걸고 실행시켰다.
우선 EAX에 들어가있는 값을 10진수로 변환 시켰더니 123123이 나온다.
즉 EAX와 ESI 중에서 EAX의 값이 사용자가 입력하는 시리얼 넘버라는 것을 알 수 있고,
ESI가 진짜 시리얼 넘버라는 것을 알 수 있다.
ESI를 10진수로 변환시키면 11880이고, 이를 다시 대입해 보겠다.
성공메세지가 뜬다.
근데 문제에서 이름이 CodeEngn일 때, 시리얼 넘버를 구하라고 했으므로 똑같은 방법으로 시리얼 넘버를 구하면
76193이 나오므로, 답은 76193이다 !
- CodeEngn Basic RCE L15
별다른 패킹 없다.
우클릭 -> Search For -> All Referenced Text Strings
성공시 출력하는 메시지와 실패시 출력하는 메시지가 비슷한 주소에 위치해 있는것을 보아 주위에 분기점이 있을것이라 생각
자세히 알아보기위해 일단 이동.
메시지가 있는 주소로 이동해보니 예상과 같이 분기점이 존재하는것을 확인.
나는 You craked the ~ 이부분 더블클릭함.
시리얼 값을 비교하는 듯한 CMP 문
분기점
성공메시지
코드를 살펴보니 EAX 값과 DS 값(45B844 주소의 4Byte 값)을 비교해서
다르면 00458854 (Try Again) 으로 점프하고
같으면 성공 메시지를 출력하는 것 확인
이제 우리는 비교하는 2개의 값을 알았으니
분기점 (00458837) 에 BP를 설정하고
두 개중 어떤것이 시리얼값이 저장된 것인지 확인하면
쉽게 시리얼값을 얻을수 있을 것
무작정 분기문과 비교문에 BP를 걸어주고 실행
BP 설정후 아래와 같이 CodeEngn 과 임의의 값을 입력한후 Check it 을 해주면 분기전에 멈추는것을 확인
일단 EAX 값을 먼저 확인하면
EAX 에 0000000A 가 저장되있는것을 확인!
즉 사용자 입력값 10의 16진수인 A가 저장된것을 보니
EAX 에는 사용자입력값이 저장된다는 것을 알수O
이제 시리얼이 45B844 주소에 위치해있다는 것을 확인했으니
Follow in Dump 를 이용해서 주소로 이동
이동해보면 아래의 그림처럼 저장되어 있는 값을 확인
00006160 즉 6160 을 10진수로 변환한 24928 이 시리얼 값이라는것
little endian이라서 거꾸로인듯~
확인을 위해 프로그램에 입력해보면 아래와 같이 인증에 성공한 모습
- 교재 4장 : 시스템 설정 변경 악성파일 분석
1.1 소개
지금 분석하려고 하는 Challenge 02.exe
- ?: 2009년도 악성파일
- 동작: 악성행위 (시스템 설정 변경, 키 설정 조작) - 그 과정에서 파일, 레지스트리 관련 코드 많이 사용
- 악성파일 동작 흐름도:
1.2 Challenge 02.exe 분석
1.2.1 기본 동작
Challenge 02.exe는 Stub code
지금까지 봤던 구성과 다름. Delphi(델파이)로 작성된 파일이라서.
악성행위 하기위한 조건: %WINDIR%drivers 경로에 위치해야
-> P118 (그림 4.3에서 진한부분): 실행경로 확인하는 코드
경로가 일치하면 -> 점프(0x0041D75C)해서 이동 -> 악성동작
일치하지 않으면 -> %WINDIR%drivers 경로에 service.exe란 복제파일 생성, 실행
1.2.2 동작중인 프로세스 확인
%WINDIR%drivers 경로에 service.exe란 복제파일 생성 전, 프로세스 검색코드 -> service.exe란 이름 유무 확인
if) 있으면 -> 이미 악성파일 존재 -> service.exe 파일 생성, 실행X
service.exe 유무 확인 법 = 실행 중인 프로세스 정보 얻는 방법)
CreateToolhelp32Snapshot() API: 동작 중인 프로세스 스냅샷 찍을 수 O
-> 스냅샷으로 프로세스 하나씩 검색 -> service.exe 찾기
-> Process32First() Process32Next() API: 검색된 프로세스 정보를 구조체에 담기
구조체 변수의 szExeFile[Max_Path] 멤버에 검색된 프로세스 이름 문자열 입력됨
* 구조체 원형) p119
service.exe 동작 확인 (=있었음!) -> BL 레지스터에 1 입력
즉, BL값이 1인지 아닌지 확인 -> service.exe 생성, 실행 결정
1.2.3 service.exe 생성, 실행
P121~123 :생성 후 숨기기
Challenge 02.exe 열기 (그림 4.12 CreateFileA)
-> %WINDIR%drivers 경로에 service.exe 파일 만들기
Challenge 02.exe 파일 뎉을 그대로 service.exe에 쓰기 (=service.exe는 Challenge 02.exe의 복제본) (그림 4.14~4.19)
=> service.exe 생성완료 (그림 4.20)
SetFileAttributesA() API 이용 -> service.exe를 숨긴파일로 변경 (그림 4.21)
p124~125: 자동 실행 레지스트리 등록 코드
service.exe 자동 실행 등록 -> 감염 Pc 부팅시 service.exe 동작
(그림 4.23~4.26: 자동 실행 등록 준비, 등록, 경로정보, 핸들반환)
ShellExecuteA() API로 service.exe 실행
1.3
Servise.exe = 실제 악성 행위를 하는 파일
CreateThread() API : 스레드 코드 호출 함수/스레드 코드가 악성 행위를 담고 있음
CreateThread 함수 : 00404A88 지점의 스레드 코드 호출
CreationFlags = > CREATE_SUSPENDED : 플래그 값
ResumeThread : 실제 호출 함수
문자열 비교 => 타깃 프로세스 찾음
프로세스) OpenProcess API / 윈도우) FindWindow API
: TerminateProcess에 들어가는 인자 값. PID 값 필요
TerminateProcess API : 강제 종료
'2. Reversing (리버싱) > 1) Write UP' 카테고리의 다른 글
[2021.05.15] reversing.kr , suninatas, xcz & 교재 6장(dll), 8장 (0) | 2021.05.15 |
---|---|
[2021.05.08] CodeEngn Basic 16~20 write-up / 교재 5,6장 (0) | 2021.05.08 |
[2021.03.27] CodeEngn Basic L08~L10 & 교재 3장 (0) | 2021.03.27 |
[2021.03.20] CodeEngn Basic L05-L07 & 교재 Chapter2 발표 (0) | 2021.03.20 |
[2021.03.13] CodeEngn Basic L01-L04 (0) | 2021.03.13 |