728x90

import re

import os


for root, dirs, files in os.walk('C:test\testFolder'):

    for fname in files:

        print(fname)

        match = re.findall("^[0-9]+ ",fname)

        fname_new = re.sub("^[0-9]+ ",match[0][:-1]+".",fname)

        os.rename(fname,fname_new)

        print(fname_new)



728x90

'프로그래밍 > Python' 카테고리의 다른 글

flask-admin 에서 pk, fk 등이 보이지 않고, 수정, 추가 안될때 해결 방법  (0) 2023.05.01
lof  (0) 2019.08.26
ball tree  (0) 2019.08.01
kd tree  (1) 2019.07.04
keras를 활용한 다중선형회귀분석  (2) 2019.05.30
728x90

Daddy told me about cool MD5 hash collision today.

I wanna do something like that too!


ssh col@pwnable.kr -p2222 (pw:guest)


--------------------------------------------------------------------------------------------------

접속



20바이트의 프로그램 파라미터를


check_password() 함수의 파라미터로 넘기고


check_password() 함수의 리턴값이 hashcode값과 같을 때 풀리는 문제이다.



check_password() 함수 내용을 보면


20바이트 문자열을 int형 포인터로 캐스팅하여 정수값으로 res에 더한다.


res값이 0x21DD09EC 값과 같게 해야 한다.


4바이트씩 총 20바이트 즉 5번을 더하므로 5로 나눈다.



0x21DD09EC - 0x6C5CEC8 * 5 = 4이므로


마지막 4바이트는 0x6C5CEC8 보다 4가 큰 0x6C5CECC를 입력한다.



 

python을 이용해서 값을 주었다.


리틀엔디안( Little Endian ) 이기 때문에 각 4바이트를 뒤집어서 입력해주어야 한다.

728x90

'ctf + wargame > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] - fd  (0) 2015.07.12
728x90

Mommy! what is a file descriptor in Linux?


ssh fd@pwnable.kr -p2222 (pw:guest)


--------------------------------------------------------------------------------------------------

접속 해 보자.



소스 파일을 열어보자



위 소스를 보면


메인함수의 매개변수를 정수로 변환하여 { atoi() - 아스키값을 정수로 }


0x1234를 뺀값을 파일디스크립터로 취하여 buf에 값을 읽어드린다.


그리고 "LETMEWIN\n"와 문자열을 비교하여 flag파일 내용을 출력한다.



- 파일 디스크립터(File Descriptor) : 시스템이 할당하여 준 파일이나 소켓을 대표하는 정수

   이 정수를 이용하여 파일에 접근하거나 제어할 수 있다. (윈도우에서의 HANDLE과 같다.)


항상 미리 예약되어 있는 값이 있는데

      ㄴ  표준 입력 : 0

          표준 출력 : 1

          표준 에러 출력 : 2

이다. 



해서 위 fd값을 표준 입력의 fd인 0으로 값을 주면 buf에 원하는 값을 넣을 수 있다.


0x1234는 십진수로 4660이므로




성공.

728x90

'ctf + wargame > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] - collision  (0) 2015.07.12
728x90

벡터곱


두 벡터 \mathbf{a} 와 \mathbf{b}의 벡터곱은 \mathbf{a} \times \mathbf{b}라 쓰고, 다음과 같이 정의된다. (위키백과)


\mathbf{a} \times \mathbf{b} = \hat{\mathbf n} \left| \mathbf{a} \right| \left| \mathbf{b} \right| \sin \theta



단위벡터 n은 벡터a와 벡터b에 공통수직으로 아래 그림과 같이 두개가 나온다.


 


해서 좌표계에 따라 정한다. (위 그림은 오른손 좌표계. 나사 돌리듯 벡터a에서 벡터b로 회전한다고 생각하면 된다.)


Left-handed and right-handed coordinate systems. Source: http://viz.aset.psu.edu/gho/sem_notes/3d_fundamentals/html/3d_coordinates.html

Left-handed and right-handed coordinate systems. Source: http://viz.aset.psu.edu/gho/sem_notes/3d_fundamentals/html/3d_coordinates.html

opengl(오른손좌표계), directx(왼손좌표계)



벡터a와 벡터b사이의 각을 계산할 필요없이 행렬식을 이용하여

아래 행렬의 1행에 대한 "여인수(cofactor)"를 전개하면 벡터의 좌표를 구할 수 있다.

(i x j = k, j x k = i, k x i = j 인 단위벡터)


\mathbf{a}\times\mathbf{b}=\det \begin{bmatrix} 
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
a_1 & a_2 & a_3 \\
b_1 & b_2 & b_3 \\
\end{bmatrix}



\mathbf a \times \mathbf b = [a_2 b_3 - a_3 b_2, a_3 b_1 - a_1 b_3, a_1 b_2 - a_2 b_1] 이 된다.



#############################################################################################

                                                             외적의 크기

#############################################################################################



벡터 삼중곱


(라그랑주 공식)

증명:

--------------------------------------------------------------------------------------------------

그림출처 : http://ko.wikipedia.org/wiki/벡터곱

728x90
728x90

이번에는 DLL도 Injection 하여 코드 후킹을 해보았다.

아래 코드는 DLL의 일부이다.

void HookCode(void)
{
	HMODULE hMod;
	HANDLE hProc = NULL;
	//Destination Function Address
	LPVOID pDestFuncAddr;
	DWORD pGapOfAddress;
	DWORD dwOldProtect;
	BYTE NewBytes[5]={0xE9,0,};
	
	// dll의 handle을 구한 뒤 목적함수의 주소를 구함 
	hMod = GetModuleHandle("KERNEL32.dll");
    	pDestFuncAddr = (LPVOID)GetProcAddress(hMod,"CreateFileW");
	
	/*
	      JMP 주소 계산 = (이동할 주소) - (현재 주소) - 5(명령어 길이)
	*/ 
	pGapOfAddress = (DWORD)&MyHookFunc - (DWORD)pDestFuncAddr - 5;
 	
 	// 목적지 주소의 원래 5바이트값을 백업 
	memcpy(g_pOrgBytes, pDestFuncAddr, 5);
	
	// 새로 덮어씌울 5바이트값 
	memcpy(&NewBytes[1], &pGapOfAddress, 4);
	
	//  목적지 주소의 가상메모리 권한 변경 
	/*
		VirtualProtect(변경할 시작 주소, 변경할 크기(BYTE), 새로 부여할 권한, 기존 권한을 저장할 공간) 
	*/
	VirtualProtect(pDestFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
	
	// 새 Opcode 덮어씌움 
	memcpy(pDestFuncAddr, NewBytes, 5);
	
	// 가상메모리 권한 복원 
	VirtualProtect(pDestFuncAddr, 5, dwOldProtect, &dwOldProtect);
}

void MyHookFunc(void)
{
	UnHookCode();
	MessageBox(NULL,"you are hacked!","알림",MB_OK);
}

VirtualProtect() 함수를 이용하여 후킹할 함수의 시작주소로부터 5바이트의 영역을 쓰기권한을 주어


원하는 코드를 삽입할 수 있게 했다.


이번에 후킹한 함수는 CreateFileW()함수로 파일을 저장하기위해 주로 이 함수를 이용한다.





아래 코드는 위 DLL을 원하는 프로세스로 삽입시키는 Injector의 일부이다.


DWORD dwPID = 0xFFFFFFFF;
    
    if(argc != 2)
	{
		printf("Injector.exe [ProcessName]");
		return 1;
	}
	
    //find process
    dwPID = FindProcessID(argv[1]);
    if(dwPID == 0xFFFFFFFF)
    {
        printf("There is no <%s> process!\n",argv[1]);
        return 1;         
    }
    
    //nject dll
    InjectDll(dwPID, DEF_DLL_PATH);

매개변수로 프로세스의 이름을 받아서 PID를 구한 후 InjectDll을 호출한다.


BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName)
{
    int ForError=0; 
    HANDLE hProcess, hThread;
    HMODULE hMod;
    LPVOID pRemoteBuf;
    DWORD dwBufSize = lstrlen(szDllName) + 1;
    LPTHREAD_START_ROUTINE pThreadProc;
     
    // dwPID 를 이용하여 대상 프로세스의 HANDLE을 구함
    if( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )  //실패시 NULL 성공시 프로세스핸들 
        return FALSE;
        
    // 대상 프로세스메모리에 szDllName(dwBufSize) 크기만큼 메모리를 할당 
	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); //성공시 할당된 메모리 주소(대상 프로세스 가상메모리) 
     
    // 할당 받은 메모리에 myhack.dll 경로를 씀
    ForError = WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);
    if( !ForError )
        return FALSE;
     
     
    // LoadLibraryA() API 주소를 구함 
	hMod = GetModuleHandle("kernel32.dll");
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryA");
     
    // 대상프로세스에 스레드를 실행 
	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);
     
    CloseHandle(hThread);
    CloseHandle(hProcess);
     
    printf("모두 끝남"); 
     
    return TRUE; 
}

PID값을 이용하여 대상 프로세스에 대한 HANDLE을 구함


VirtualAllocEx() 함수를 이용하여 대상 프로세스의 가상메모리에 메모리를 할당


WriteProcessMemory() 함수를 이용하여 dll의 경로를 할당 받은 메모리에 씀

CreateRemoteThread() 함수를 이용하여 대상프로세스에 스레드 실행





이것을 이용하여 메모장을 후킹해 보았다.



먼저 Injector를 실행했다.



ProcessExplorer로 확인해 보니 삽입이 잘 되어 있다.


이제 "저장"버튼을 눌러서 CreateFileW()을 호출할 수 있게끔 했다.



버튼을 누르자


메시지박스를 띄우며 종료된다.


[소스 코드] :

https://github.com/khycan/API-Hooking/blob/master/API%20Hooking%20+%20DLL%20Injection/Injector/InjectorMain.cpp


https://github.com/khycan/API-Hooking/blob/master/API%20Hooking%20%2B%20DLL%20Injection/dll/DllMain.cpp


728x90

'리버스엔지니어링 > API Hooking' 카테고리의 다른 글

Win32 API Hooking - Trampoline Code Hooking  (0) 2015.05.29
728x90

Trampoline Code Hooking은 후킹할 함수의 첫 5바이트를 수정하여 자신이 원하는 함수를 호출시키는 방법이다.


왜 하필 5바이트인가?

그 이유는 EIP의 흐름(실행 흐름)을 변화시키는 JMP문이 5바이트 이기 때문이다.


ex) JMP 00400000

   E9  xxxxxxxx -> 5byte


보통 이런 API Hooking은 DLL Injection과 함께 사용하여


타 프로세스의 기능을 개선시키거나 혹은 기능을 제거하는 등 폭넓게 사용할 수 있다.

(사용 소프트웨어에 하면 불법이라 한다.)


그러나 이번에는 DLL Injection 없이 API Hooking만 실시하였다.




위 코드에서는 새 바이트값을 WriteProcessMemory 함수를 이용해서 덮어씌웠지만


VirtualProtect 함수를 이용해서 해당 메모리의 속성(읽기, 쓰기 등)을 변경하여


memcpy(pFunction, NewBytes, 5); 이런 식으로도 할 수도 있다.




디버거로 확인해 보면


main 함수에서 HookCode()를 호출하기 전 printf의 바이트 값은


이랬지만 HookCode() 호출 후



이렇게 JMP Project1.00401500

        HookFunc함수로 jump하는 코드로 바뀐것을 확인할 수 있다.



실행 시켜보면


hooking 되어 메시지박스를 호출하는 것을 확인 할 수 있다.


[소스 코드] : 

https://github.com/khycan/API-Hooking/blob/master/API%20hooking%20without%20DLL%20Injection/HookingMain.c

728x90
728x90

USER32.DLL

안에 있고 키보드 이벤트를 발생시킨다. 대부분의 키보드기반의 매크로들이

이 함수를 이용하는 것 같다.


VOID WINAPI keybd_event(
  _In_ BYTE      bVk,
  _In_ BYTE      bScan,
  _In_ DWORD     dwFlags,
  _In_ ULONG_PTR dwExtraInfo
);


bVK : 가상 키코드 값 

                참고 : http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx


bScan : 하드웨어 키 스캔 코드 (사용하지 않으므로 " 0 " 으로 함)


dwFlags : 함수의 동작을 지정. 0x00의 경우 keyDown, 0x02의 경우 keyUp


dwExtraInfo : key 스트로크 관련 추가 정보 지정. 주로 0으로 지정

728x90
728x90

리눅스의 "파일 디스크립터"

                              ===========

                                       윈도우의 "핸들" 과 비슷하다.


파일 디스크립터---------- 0 : 표준 입력

                                        1 : 표준 출력

                                        2 : 표준 에러

728x90

'프로그래밍' 카테고리의 다른 글

Mark and Sweep  (3) 2020.11.16
워게임&알고리즘은행 사이트들  (0) 2015.01.09
728x90

깊이탐색을 기본으로 하는 알고리즘


모든 경우를 조사함으로 "가지치기"(필요없는 루프는 잘라내기)를


잘 해야 빠르게 결과값을 얻을 수 있다.



bool finished = false;     // 모든 풀이를 찾았는지 여부 //
backtrack(int a[], int k, data input)
{
        int c[MAXCANDIDATES]; // 다음 위치가 될 수 있는 후보 위치 //
        int ncandidates;          // 다음 위치가 될 수 있는 후보 개수 //
        int i;                         // 카운터 //

        if ( is_a_solution(a, k, input) )
                process_solution(a, k, inpit);
        else
        {
                k++;
                construct_candidates(a, k, input, c, &ncandidates);
                for(i=0; i<ncandidates; i++)
                {
                        a[k] = c[i];
                        backtrack(a, k, input);
                        if(finished) return;  // 일찍 종료함 //
                }
        }

}


728x90
728x90

공간상에서 여러개의 물체를 특정 좌표에 그릴때에 첫번째 물체를 그릴때에는 상관없지만


두번째부터는 첫번째 물체의 변환행렬(각도,이동 등등)이 남아있기에 원하는 위치에 그리기 위해서는


행렬을 단위행렬로 초기화가 필요하다. 그때 쓰는 것이 glLoadIdentity( ); 함수 이다.


그러나 glLoadIdentity로 행렬을 초기화하면 이전 행렬에 대한 값을 잃게 되므로 opengl에는


"행렬스택" 이라는 개념이 있어 스택에 이전 행렬들을 PUSH하여 집어넣고


POP하여 꺼낼 수 있다. glPushMatrix, glPopMatrix  두 함수를 사용하여 가능.



###단위행렬이란??

       -> "n차 정사각행렬에서 주 대각선이 위의 원소가 1이고 나머지 원소는 0인 행렬" 이다.

728x90

+ Recent posts