2015 순천향대 YISF가 얼마 남지 않았네요.
푼지 오래 된거지만 파일 공유겸 좋은 성적 거두시라고 풀이 써봤습니다.
접기
- NotifyRoutine
- 2개의 이미지네임의 관계.
- dword_10C20 의 흐름 (pid와 의 관계)
- Shared Memory
- 3개의 스트링과 3개의 함수
- 약간의 브루트포싱
접기 접기
DriverEntry를 보니 윈도우 커널문제다.
NotifyRoutine 이 문제의 핵심이다.
PsSetLoadImageNotifyRoutine 은 이미지(바이너리 exe, dll 등)가 로드 될 때 콜백함수를 등록해주는 커널 함수이다.
void __stdcall NotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
원형은 이렇다.
1번째 인자 : 바이너리 파일 이름
2번째 인자 : 프로세스 ID
3번째 인자 : 이미지 정보
이런것들이 인자로 넘어온다.
들어가서
NotifyRoutine 을 살펴보다보면 이런게 보인다.
스트링을 초기화한다.
인자를 맞추고 확인해보니
ldldldlldlddlldl.dll 아마 이미지 네임 처럼 보인다.
음.. v5 뭔가 연산을 하는데.. 역시 확인을 해보자
c5022345c99c622d6018ed8fbcc27b18 md5 해시 같기도 하고..
wcstr로 이 문자열을 FullImageName에서 찾는걸보니 이것도 이미지 이름인것 같다.
밑을 보면 조건이 있다. dword_10C20에 pid를 저장하고 fd0에 4를 넣는다.
이 조건을 꼭 맞추어야한다. 그렇지 않으면 dword_10FD0값이 나중에 복호화 함수에 쓰이기 때문에 key가 제대로 구해지지 않는다.
일단 단서는 하나 건졌다. exe던 dll이던 c5022345c99c622d6018ed8fbcc27b18을 포함한 이름의 바이너리를 실행시켜야한다.
바로 밑을 보면.
FullImageName은 이미지 네임, DestinationString은 ldldldlldlddlldl.dll였다. RtlCompareUnicodeString는 유니코드 문자열을 비교하는 함수이다. load된 이미지 네임이 ldldldlldlddlldl.dll여야 하는 것 같다.
그리고 ProcessId 는 dword_10C20값과 같아야 하나보다.
여러 조건이 보인다. 여기서 조금 헷갈린다.
애초에 일반적으로 pid는 195430이 될수가 없다. dword_10C20은 처음부터 195430으로 초기화 되어있다.
그러면 ProcessId == (HANDLE)dword_10C20를 어떻게 맞출수 있을까?
한가지 까먹은 사실이 있다. 다시 위를 올려보면
c20에 c5022345c99c622d6018ed8fbcc27b18의 pid가 들어가있다.
그럼 ProcessId는 c5022345c99c622d6018ed8fbcc27b18의 pid여야 한다. 그리고 이미지네임은 ldldldlldlddlldl.dll여야 할것이다.
*즉, c5022345c99c622d6018ed8fbcc27b18.exe에서 ldldldlldlddlldl.dll 이미지를 load해야한다 .
이 가정대로라면 195430 조건을 성립시키면 안된다.
그러면 sub_104C8(unk_10C40, 15);
sub_10406(unk_10C00, 15);
sub_10540(unk_10C24, 13);
이 순서대로 실행 된다.
확인해보면
55 FF 01 FF 47 FF 14 FF 43 FF B8 FE 8A FF 6B FF 53 FF 6F FF 3D FF BF FE 8A FF 9D FE 6A FF 00 00 5A 05 9F E0 25 04 03 05 76 04 40 04 7E 05 5F 04 08 04 C4 E1 65 04 AA E0 51 05 5B 04 57 04 00 00 6D 31 E3 2F 57 31 69 CF 64 31 8A CF D0 2E 66 CF 57 31 DA 2F 6E 31 93 CF B2 2E 00 00
이런 값이 나왔는데 사이즈*2의 크기가 바뀐걸보아 유니코드 문자열인것 같다.
생긴걸보니 한번더 복호화 해야겠다..
밑에 sub_105EA 를 보니
FFDF0800? 하드 코딩 되어있다.
이상한 주소에 메모리 라이팅을 시도한다.
[Windows] Shared Memory 이다.
sub_10498은 뭔진 모르겠지만 또 확인해보면
55 8B EC 무슨 코드인 것같다. 유니코드처럼 2바이트 씩 떨어져있는데
s='55 00 8B 00 ..' o='' for i in range(0,len(s),6): o+=s[i:i+3] print o
간단하게 파이썬으로 예쁘게 시술 해주자.
55 8B EC 51 C7 45 FC 00 00 00 00 EB 09 8B 45 FC 83 C0 02 89 45 FC 8B 4D FC 3B 4D 0C 7D 32 8B 55 FC 8B 45 08 0F B7 0C 50 83 E9 14 8B 55 FC 8B 45 08 66 89 0C 50 8B 4D FC 8B 55 08 0F B7 04 4A 35 41 01 00 00 8B 4D FC 8B 55 08 66 89 04 4A EB BD C7 45 FC 00 00 00 00 EB 09 8B 45 FC 83 C0 01 89 45 FC 8B 4D FC 3B 4D 0C 7D 32 8B 55 FC 8B 45 08 0F B7 0C 50 83 C1 5A 8B 55 FC 8B 45 08 66 89 0C 50 8B 4D FC 8B 55 08 0F B7 04 4A 35 39 30 00 00 8B 4D FC 8B 55 08 66 89 04 4A EB BD 8B E5 5D C3 55 8B EC 51 C7 45 FC 00 00 00 00 EB 09 8B 45 FC 83 C0 01 89 45 FC 8B 4D FC 3B 4D 0C 7D 4A 8B 55 FC 8B 45 08 0F B7 0C 50 81 C1 EA 00 00 00 8B 55 FC 8B 45 08 66 89 0C 50 8B 4D FC 8B 55 08 0F B7 04 4A 83 F0 43 8B 4D FC 8B 55 08 66 89 04 4A 8B 45 FC 8B 4D 08 0F B7 14 41 83 F2 17 8B 45 FC 8B 4D 08 66 89 14 41 EB A5 8B E5 5D C3 55 8B EC 51 C7 45 FC 00 00 00 00 EB 09 8B 45 FC 83 C0 03 89 45 FC 8B 4D FC 3B 4D 0C 7D 1C 8B 55 FC 8B 45 08 0F B7 0C 50 81 F1 59 01 00 00 8B 55 FC 8B 45 08 66 89 0C 50 EB D3 C7 45 FC 00 00 00 00 EB 09 8B 4D FC 83 C1 01 89 4D FC 8B 55 FC 3B 55 0C 7D 36 8B 45 FC 8B 4D 08 0F B7 14 41 81 C2 80 0D 00 00 8B 45 FC 8B 4D 08 66 89 14 41 8B 55 FC 8B 45 08 0F B7 0C 50 81 F1 D7 11 00 00 8B 55 FC 8B 45 08 66 89 0C 50 EB B9 8B E5 5D C3
+0 +a0 +10c에 총 3개의 함수가 있다.
mov eax,[ebp+08] mov [eax+edx*2],cx 를 보니 1번째 인자는 어떤 값을 변경할 주소인것 같고, 2바이트 단위로 쓰는 cx를 보니 유니코드 문자열인 것같다.
또 cmp ecx,[ebp+0C] 2번째 인자는 사이즈 일것이다.
함수는 3개
그런데 전에 이상한 스트링을 3개 구한적이 있다.
55 FF 01 FF 47 FF 14 FF 43 FF B8 FE 8A FF 6B FF 53 FF 6F FF 3D FF BF FE 8A FF 9D FE 6A FF 00 00 5A 05 9F E0 25 04 03 05 76 04 40 04 7E 05 5F 04 08 04 C4 E1 65 04 AA E0 51 05 5B 04 57 04 00 00 6D 31 E3 2F 57 31 69 CF 64 31 8A CF D0 2E 66 CF 57 31 DA 2F 6E 31 93 CF B2 2E 00 00
이것들을 넣으면 되지 않을까?
뭘 넣어야 할진 모른다. 어차피 함수는 3개에 스트링은 3개 경우의수는 3*2*1이다.
스트링1에 0 a0 10c
스트링2에 0 10c
스트링3에 10c
이런식으로 막 넣어본다.
스크립트를 짜고. 돌리면
찾았다!
스트링1->+a0
스트링2->+10c
스트링3->+0
a0(스트링1,15);
10c(스트링2,15);
0(스트링3,13);
접기 파일은 문제가 된다면 삭제하겠습니다.
좋은 결과 있으시길 바랍니다.