프로그래밍

 3204, 1/161 회원가입  로그인  
   nninni79
   http://https://blog.naver.com/nninni79
   리버싱의 세번쨰 꽃 - 역랑-

http://www.hackerschool.org/HS_Boards/zboard.php?id=QNA_programming&no=6625 [복사]



안녕하슈.



코드몽키인 엄이라고 합니다.



사진 삭제
삭제삭제
사진 설명을 입력하세요.

이번에 할 강의는 리버싱의 세 번쨰 꽃 역랑에 대해 말해봅니다.



역랑이란,라이브러리 복제 행위를 말합니다.



해당 기능중을 손쉽게 쓰려면 이전에 softwaredebuging이 필수인데, 알아서

해당 디버깅 기능을 손에 넣으십시오.

사용법 알려주기엔, 욕하러오는 치터님들이 있을거라 생각해서 안알려 드리겠습니다.

저것도 어찌보면 짬이라서, 알려주면 좀 그렇거든요...

그냥 이론만 말해드립니다.

하지만, 글 보고 베껴먹는 사람들도 많을거라고 봅니다.



여튼 해당 디버깅 기능을 쓰면

비추얼 스튜디오에 지원을 해주는 디버깅으로도 접근하기 힘든 상위 함수에 접근을 할 수 있습니다.



역랑을 사용하면 장점이 무엇인가...첫 번쨰로 핵쟁이들의 입장으로 본다면,

이젠crc란게 무의미해 진다고 말할 짓거리가 가능해집니다.

서브 시스템콜 함수를 가공하는것도 가능한데, 메인함수도 못복제 할까요?ㅋ



이건, 제가 만들다만 MD5어셈 역랑 사본인데요.

[ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat createThread(find2) label(goto1) label(goto2) define(find,00C00A20) Registersymbol(find) define(find2,00C00f20) Registersymbol(find2) label(loop) label(put1) 00BFFDC0: db 2A 00BFFDC0+40: dd 59742A13 00BFFDC0+48: dd 1 00BFFDC0+4C: dd 000A7325 find: repne jne find+5 repne ret push ebp mov ebp,esp sub esp,00 push eax find2: push ebp mov ebp,esp sub esp,00000218 push ebx push esi push edi lea edi,[ebp-00000218] mov ecx,00000086 mov eax,CCCCCCCC repe stosd mov eax,[00BFFDC0+40] xor eax,ebp mov [ebp-04],eax mov ecx,00BFFDC0+48 //1 call put1 mov eax,[ebp+08] push 00BFFDC0 //42 push 00000104 mov eax,[ebp+08] push eax call 00A7C710 //7ffff // mov esi,esp lea eax,[ebp-00000148] push eax mov ecx,[ebp+08] push ecx call dword ptr [MapleStory.exe+710054] mov esi,esp call find mov [ebp-00000154],eax cmp dword ptr [ebp-00000154],-01 jne loop mov esi,esp call dword ptr [kernel32.GetLastError] cmp esi,esp call find jmp fun2 loop: mov eax,[ebp-00000148] and eax,20 je loop2 lea eax,[ebp-0000011C] loop2: mov esi,esp lea eax,[ebp-00000148] push eax mov ecx,[ebp-00000154] push ecx call dword ptr [MapleStory.exe+710054]//filae cmp esi,esp call find test eax,eax jne loop mov esi,esp mov eax,[ebp-00000154] push eax call dword ptr [MapleStory.exe+710050] //close fun2: push edx mov ecx,ebp push eax lea edx,[ConsoleApplication11.exe+11CC4]//1 call fun3 pop eax pop edx pop edi pop esi pop ebx mov ecx,[ebp-04] xor ecx,ebp call ConsoleApplication11.exe+11154 add esp,00000218 cmp ebp,esp call ConsoleApplication11.exe+11253 mov esp,ebp pop ebp ret fun3: push ebp mov ebp,esp push ecx push ebx mov ebx,edx mov [ebp-04],ecx push esi xor esi,esi cmp [ebx],esi jle get push edi xor edi,edi mov ecx,[ebx+04] mov eax,[ebp-04] mov edx,[ecx+edi] cmp [edx+eax-04],CCCCCCCC jne get2 mov eax,[ecx+edi+04] add eax,edx mov edx,[ebp-04] cmp [eax+edx],CCCCCCCC je get3 push [ecx+edi+08] mov eax,[ebp+04] push eax call ConsoleApplication11.exe+11352 get2: add esp,08 get3: inc esi add edi,0C cmp esi,[ebx] jl ConsoleApplication11.exe+12174 pop edi get: pop esi pop ebx mov esp,ebp pop ebp ret 00BFFDC0+58: dd #19 scand: label(scand2) push ebp mov ebp,esp sub esp,00000404 { 1028 } mov eax,[00BFFDC0+58] { (19) } xor eax,ebp mov [ebp-04],eax push ebx mov ebx,[ebp+08] push esi mov esi,[ebp+0C] push edi mov edi,[00BFFDC0+48] { (1) } cmp edi,-01 { 255 } je scand2 cmp byte ptr [esi],00 { 0 } je ConsoleApplication11.exe+12A88 push esi call ConsoleApplication11.exe+12B70 add eax,2D { 45 } add esp,04 { 4 } cmp eax,00000400 { 1024 } ja ConsoleApplication11.exe+12A88 push ConsoleApplication11.exe+17BA4 { ("Stack around the variable '") } lea eax,[ebp-00000404] push 00000400 { 1024 } push eax call ConsoleApplication11.exe+11366 push esi lea eax,[ebp-00000404] push 00000400 { 1024 } push eax call ConsoleApplication11.exe+1134D push ConsoleApplication11.exe+17BC0 { ("' was corrupted.") } lea eax,[ebp-00000404] push 00000400 { 1024 } push eax call ConsoleApplication11.exe+1134D add esp,24 { 36 } lea eax,[ebp-00000404] jmp ConsoleApplication11.exe+12A8D mov eax,ConsoleApplication11.exe+18080 { ("Stack corrupted near unknown variable") } push eax push 02 { 2 } push edi push ebx call ConsoleApplication11.exe+12B90 add esp,10 { 16 } mov ecx,[ebp-04] pop edi pop esi xor ecx,ebp pop ebx call ConsoleApplication11.exe+11154 mov esp,ebp pop ebp ret scand2: mov ecx,[ebp-04] pop edi pop esi xor ecx,ebp pop ebx call ConsoleApplication11.exe+11154 mov esp,ebp pop ebp ret scand3: cmp ecx,[ConsoleApplication11.exe+1A004] { (19) } repne jne scand3+5 repne ret repne jmp scand4 scand4: push ebp mov ebp,esp sub esp,00000324 push 17 call ConsoleApplication11.exe+111D6 //76975135 test eax,eax je scand5 mov ecx,00000002 int 29 scand5: mov [ConsoleApplication11.exe+1A248],eax mov [ConsoleApplication11.exe+1A244],ecx mov [ConsoleApplication11.exe+1A240],edx mov [ConsoleApplication11.exe+1A23C],ebx mov [ConsoleApplication11.exe+1A238],esi mov [ConsoleApplication11.exe+1A234],edi mov [ConsoleApplication11.exe+1A260],ss mov [ConsoleApplication11.exe+1A254],cs mov [ConsoleApplication11.exe+1A230],ds mov [ConsoleApplication11.exe+1A22C],es mov [ConsoleApplication11.exe+1A228],fs mov [ConsoleApplication11.exe+1A224],gs pushfd pop [ConsoleApplication11.exe+1A258] mov eax,[ebp+00] mov [ConsoleApplication11.exe+1A24C],eax mov eax,[ebp+04] mov [ConsoleApplication11.exe+1A250],eax lea eax,[ebp+08] mov [ConsoleApplication11.exe+1A25C],eax mov eax,[ebp-00000324] mov [ConsoleApplication11.exe+1A198],00010001 mov eax,[ConsoleApplication11.exe+1A250] mov [ConsoleApplication11.exe+1A154],eax mov [ConsoleApplication11.exe+1A148],C0000409 mov [ConsoleApplication11.exe+1A14C],00000001 mov [ConsoleApplication11.exe+1A158],00000001 mov ecx,00000004 imul edx,ecx,00 mov [edx+ConsoleApplication11.exe+1A15C],00000002 mov eax,00000004 imul ecx,eax,00 mov edx,[ConsoleApplication11.exe+1A004] mov [ebp+ecx-08],edx mov eax,00000004 shl eax,00 mov ecx,[ConsoleApplication11.exe+1A000] mov [ebp+eax-08],ecx push ConsoleApplication11.exe+18230 call ConsoleApplication11.exe+113C5 mov esp,ebp pop ebp ret [DISABLE]





이런식으로 그냥 함수호출을 핟게된다면,sha-256,MD5로 암호화된 함수들도 별다른 저항없이

iat와,eip,crc우회 그딴거 필요없이 그냥 호출만 때리면

호출해낼수 있는 행위가 가능한 이유가 왜 가능한지 아십니까?

바로 재귀구조 떄문입니다.

이러한 재귀구조의 취약성을 이용하는게 바로 역랑입니다.



아,위에 올린거 함수호출 MD5에 쓰이는 역랑의 완성본을 자체적으로 전부 올리지 않은

혹시 이용해먹을지 모르니 몇군대 뺴버렸어요.(저것도 어찌보면 고유의 기술,짬이랍니다.)


저거 좀 잘응용하면, MD5속도 더 빠르게 변해지긴 하던데, 여튼 그런건 중요치 않죠?



crc?안티디버깅? 정수 스택 저장? 소용 없습니다.

저 함수들 그냥 복제한후에 저한테 쓰기 적절하게 가공을 해재낀 거라서, 의미가 정말 없거든요.



그래요. 눈치채셨겠지만,역랑이란 라이브러리 복제입니다.

복제하는 방법은 본인의 기량이지만, 디버깅 기능을 써서 해당 코드의 동적 역할을 알아내고

스택 저장 반환을 할 당시 무수히 많은 goto와,시스템 콜을 할 간접 함수들,예외처리를 감당해야 할 역할을 컴파일러가,운영체제가 감당을 하질 않고, 코더가 하나부터 열 까지 처리하는 행위를 하면서

간접적인 영향의 재귀구조의 함수를 상위 커널깽판함수로 엿바꿔먹는 행위를 말합니다.



즉, 역랑의 장점은, 권한이 없음에도 간접적인 재귀구조를 역이용하여, 권한깽판칠떄 쓰이는 함수들을 사용하게 만들때 용이하게 어느정도 제한이 있어도, 커널 권한 깽판치게 도와줍니다...

솔직히 커널권한 깽판치게 해주는 몇없는 기법중 하나라고 봅니다.



실제로 아르테일에 접목된 보안들은 역랑의 산물이라고 볼 수 있겠으며, 가상의 하드웨어 메모리에crc가 돌아가는 신기한 현상이 가능한 건 공으로 한게 아닌, 역랑이라는 시스템콜의 함수를 중도 메인 함수에서 가공을한후 시스템 함수로 올려서 가능한 짓거리라고 볼 수 있겠습니다.



즉, 드라이버 서명의 영역에 간접적인 재귀함수로 이곳저곳 지나다니며, 연산을 대신 해달라고

시스템콜을 한 상위 함수들한테 요청을 하는 과정을 중도에 내가 가공한,역산식을 집어넣고

시스템콜을 한다면,가상머신을 굳이 안올려놔도 cpu의 가상의 영역에서 crc를 구동시킬 수 있게 만드는 행위는 일종의 드라이버 서명의 영역에 가능하다고 알려진것과 달리, 기교로도 가능해진다는 말입니다.



본서버에 쓰이는 IAT라는 재귀구조를 이용한 해당 가로채는 기법도 이중 한 종류라고 보아야 합니다.

하지만IAT의 역산을 수십,수백,수천번 더 집어넣은 다중 역산IAT가 어찌보면 역랑이라 볼 수 있겠지요...



다만, 보통은 이와같은 행위를 다른 합법 종사자들은 당연하지만,안하며, 바보같다고 합니다.

드라이버 올리면 저런거 한큐에 해결되거든요.



그도 그럴게 합법 종사자가 보면, 굳이 쉽게 만들어진 ms사에 만들어둔,운영체제에 지원해주는 라이브러리 안쓰고,라이브러리 복제하는 행위를 무수히많은 삽질을 통하여 한다고 하면, 아마 이유를 물어볼 겁니다.



"권한 문제 생기면,사x코드마냥 그냥 커널드라이버 올려서 깽판 치면 대자낭?ㅎㅎㅎㅎ 너는 바보야."

같은 식으로요...

그런데, 님들이 백신회사의 직원이 아니라면, 역랑을 써야지 어느정도 호환성문제에 를 해소하며,

포퍼먼스 구현이 가능한 권한 깽판이 가능해집니다.



이런식으로 함수에 제한을 많이 걸어둔 이유는 XP세대떄 워낙에 해커들이 악성코드로 꺵판쳐서

서명이 안된 드라이브를 win7이후로부턴 서명을 안한 드라이버는 못올리게 막아놔서 그렇습니다.



그래서 xp세대떄가 아마,보안으로 걸레짝나고 그럤던걸거에요.



그래서 위와같은 함수의 재귀구조를 역으로 역산하여, 연산식을 바꾸는 역랑이라는 행위가 드라이버를 안올렸음에도 권한을 깽판치기 쉬운 몇없는 집대성이자,기술의 기교라고 봐야 합니다.

역랑의 장점은 아래와 같은데, 일종의 함수에 락을걸린 제한을 풀 수 있다는게 해당과같은 행위가 로우레벨 개발자들 사이에서 어느정도 영역에 다다르면 무식할 정도의 양들도 소화가 가능해지는데, 그것을 그냥 시스템콜 함수에다가 접목하는 행위가 바로 역랑이라고 볼 수 있겠습니다.



역랑의 장점을 비유 해본다면 시스템 콜 함수로 비유한건 아니지만,

가령 만에하나 %08X을 이용해 문자열 반환 함수를 16자정도 넘어가면,

기존에 지원해주는 라이브러리에선 시스템 콜을 하게된다면, 예외처리를 해주어서 튕기게 만들어줍니다.

아래는 그냥 제가 역랑으로 스니퍼만들때 만들다만 아래와같은 스크립트를

그냥 예시 자료좀 올려보겠습니다.





push ebp

mov ebp,esp

sub esp,000000D8

push ebx

push esi

push edi

lea edi,[ebp-000000D8]

mov ecx,00000036

mov eax,CCCCCCCC

repe stosd

mov ecx,Dll1.dll+2302D

call Dll1.dll+114F1

lea eax,[ebp+10]

mov [ebp-08],eax

mov eax,[ebp-08]

push eax

mov ecx,[ebp+0C]

push ecx

push F //<<16자 문자열에 제한을 거는 사이즈 제한 인자입니다.

mov edx,[ebp+08]

push edx

call Dll1.dll+16B9D

add esp,10

pop edi

pop esi

pop ebx

add esp,000000D8

cmp ebp,esp

call Dll1.dll+113AC

mov esp,ebp

pop ebp

ret



이대로 갓다쓰면, 컴파일러가 똑똑해서 예외처리의 일종으로 16자의 구문으로 해당 라이브러리에

16자이상의 문자열이 들어올경우 해당 문자열의 사이즈를 읽어오고, 16자가 넘어가면 오류로 처산하는 인자를 가변성이 아닌,고정 인자열로 분류해서 박아넣어주는 행위를 해줍니다.

만약 운영체제에 지원해주는 함수들도 그렇다면 골 떄리겠죠?



하지만 인자의 제한의 함수를 바꾸면 해당 제한을 풀 수 있겠죠.

다만, 시스템콜을 하는 함수들은 운영체제에 돌아가서 그딴거 못하잖아요?

해도 님컴에만 돌아가지, 다른 사용자 못돌아가니 실제로 상용화가 힘들어 지겠지요.



사진 삭제
사진 설명을 입력하세요.





하지만 역랑을 사용하게 된다면,



사진 삭제
사진 설명을 입력하세요.

이런식으로 시스템콜에 하는 함수의 나열해주는 역산식을

바꿔놓고 써서 바꿀 수 있습니다.

이로인해 시스템 콜을 하는 상위 함수들을 권한이 없음에도 접근 가능한게 역랑의 장점입니다.

까놓고 말해서 걍 커널꺵판 재귀점 가로채서, 인자 뱉어내라고 함수를 가공하는 행위인 터라

권한 ㅈ도없어도 커널깽판 치는게 가능해집니다.



근데, 아무리 논문,문헌을 찾아봐도 이러한 행위에 관한 언어와,어귀를 찾아볼수가 없었습니다.

보통 저딴짓 안하거든요.

시스템콜을 하는함수들을 볼수있는 디버거가 한정적이라 말이지요.



여튼 장점은 뚫기 어렵다는 대개의 온라인 게임의 보안을 걸레짝마냥 만들 수도 있으며,

높은권한을 가진 함수를 간접적이지만 일부분적으로 권한꺵판치는게 가능해지며,

혹은 해당 기능을 오히려 불필요한 부분을 떼버림으로써 운영체제에 MS사가 지원해주는 함수를 기존보다 더욱 빠른 속도를 내게 하는게 가능해 집니다.

실제로 제가복제한 sleepde가 운영체제에 지원해주는 sleepex보다 훨씬 속도 빠르던걸요?



alloc(sleepdefine,188)

alloc(sleepdefine2,900)

alloc(sleepdefine3,900)

Registersymbol(sleepdefine)







sleepdefine3:

push 38

push KERNELBASE.BemFreeContract+3FE

call KERNELBASE.IsNLSDefinedString+473

mov [ebp-48],00000024

mov [ebp-44],00000001

push 07

pop ecx

xor eax,eax

lea edi,[ebp-40]

repe stosd

xor edi,edi

mov [ebp-1C],edi

cmp [ebp+0C],edi

je sleepdefine3+39

xor edx,edx

lea ecx,[ebp-48]

call dword ptr [KERNELBASE.dll+1058]

mov [ebp-04],edi

push [ebp+08]

lea eax,[ebp-24]

push eax

call KERNELBASE.IsNLSDefinedString+C81

mov esi,eax

cmp esi,edi

jne sleepdefine3+5B

mov [ebp-24],edi

mov [ebp-20],80000000

lea esi,[ebp-24]

push esi

push [ebp+0C]

call dword ptr [KERNELBASE.dll+10FC]

mov [ebp-1C],eax

cmp [ebp+0C],edi

je KERNELBASE.SleepEx+74

cmp eax,00000101

je sleepdefine3+5B

mov [ebp-04],FFFFFFFE

call sleepdefine3+96

mov eax,000000C0

cmp [ebp-1C],eax

je sleepdefine3+8C

xor eax,eax

call KERNELBASE.IsNLSDefinedString+4B8

ret 0008

xor edi,edi

cmp [ebp+0C],edi

je sleepdefine3+A4

lea ecx,[ebp-48]

call dword ptr [KERNELBASE.dll+1050]

ret

int 3

int 3

int 3

int 3

int 3



sleepdefine2:

mov edi,edi

push ebp

mov ebp,esp

push 00

push [ebp+08]

call sleepdefine3

pop ebp

ret 0004

int 3

int 3

int 3

int 3

int 3



sleepDefine:

mov edi,edi

push ebp

mov ebp,esp

pop ebp

jmp sleepdefine2............

mv.....





즉 역랑은 그냥 함수 복제입니다.

말 그대로 권한이 없음에도 커널단에 쓰이는 함수들을 마음대로 복제 가능하며,

장악이 가능해지는 행위를 하는 걸 재귀점 구조를 이용한 함수호출의 취약성을 이용한,기술적

기예라고 보아야 합니다.



이와같은 간접 함수에대한 요청으로 제한을 걸어둔 시스템 콜을 바꿔처먹는 행위가 권한이 없음에도 꺵판치는게 가능한 이유는 함수의 재귀구조에 있습니다.



함수들은 한 번 쓰이면,다른 함수에 임폴트하며 인자를 요청에 하달해달라는 간접적인 요청을 합니다.

그리고 해당 함수란,비슷한 영역에 있으면 하나의 함수로 여러개의 요청을 할 수 있기에,

사실상 해당 함수를 쓰려면, 꽤나 많은 라이브러리와,권한의 문제에 쩔쩔매도,이러한 예외처리 과정에서 정보를 어느정도 가공해달라는 요청을 하는 단순한 함수를 역산을 통하여 더 상위함수의 시스템콜의 함수로 바꿔먹는게 가능해 집니다.







즉 간단합니다.

권한이 없음에도, 커널권한을 간접적인 영향으로 일부분이기는 하지만 변조, 락을 풀면서,

권한깽판, 괴물 굇수,무식한 라이브러리, 기능을 쓸 수 있게 가능한것이

위와같은 역랑이라는 행위를 통하여 가능해집니다.





  Hit : 228     Date : 2021/04/20 05:28
[불법/스팸글로 신고하기]



    
3204   c언어 segmentation fault:11 오류 질문드립니다![2]     leebk1124
05/21 91
3203   C++함수관련 질문이에용!![2]     1999dylee
05/11 117
3202   파이썬 지문 드립니다.[1]     kksh1107
04/24 154
  리버싱의 세번쨰 꽃 - 역랑-     nninni79
04/20 227
3200   어셈블리어에 관한 질문입니다.[3]     p0wermilk
03/31 290
3199   달고나 문서 쉘코드[1]     ghjk645
03/24 253
3198 비밀글입니다  c언어 소수 값     adwefq
04/29 0
3197   C언어 소스질문입니다![4]     an0088
01/05 1477
3196   C++ /// 빌드 에러 ㅠㅠ     guichanta
08/23 962
3195 비밀글입니다  c언어 도와주세요ㅠㅠ     su6339
04/06 0
3194   해킹을 배우려고하는데[3]     zoodem04
03/26 2464
3193   c언어를 배우고싶어요 ![7]     dwc07238
02/11 1746
3192   스택이 쌓이는 방향에 관해서!![1]     hackxx123
12/10 1331
3191   해킹툴에서 ip 없이 하드에 심는거에는 어떤게 있을까요?[2]     aowlrgmlals
11/27 1494
3190   C언어 하는데 double 실수를 넣은데 자꾸 0.0이 나와요[2]     fatou10336
11/20 1348
3189   dumpcode.h 이해좀 도와주세요 .[1]     cm6418
11/06 1163
3188   c언어 알고리즘 질문입니다.[3]     alstn8150
10/12 1407
3187     [re] c언어 알고리즘 질문입니다.     dafher
05/13 557
3186   c언어 소스 질문 뭐가 문제인지ㅜㅜㅜㅜ[2]     sjjh96
05/23 2434
3185   파이썬 클래스 공부중 질문[1]     wnsdud5534
04/12 1331
1 [2][3][4][5][6][7][8][9][10]..[161]

Copyright 1999-2021 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org & Wowhacker.com