1
2
3
4
5
6
7
8
OpenClipboard(0);
if(IsClipboardFormatAvailable(CF_UNICODETEXT)||IsClipboardFormatAvailable(CF_OEMTEXT)){
    HANDLE hClipboard;
    hClipboard = GetClipboardData(CF_UNICODETEXT);
    wchar_t* data = (wchar_t*)GlobalLock(hClipboard);
    MessageBoxW(0,data,L"MessageBox",MB_OK);
}
CloseClipboard();
cs


'C&C++' 카테고리의 다른 글

"" , L"" , TEXT("") , _T("")  (0) 2018.06.15
Using scanf() As gets()  (0) 2018.06.15
Parameter Split in WinMain (Argc, Argv)  (0) 2018.05.10
C++ WinSock Sample Code  (0) 2018.04.09
[MinGW] Using DLL and Compile Options  (0) 2018.04.09
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<windows.h>
#include<tchar.h>
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdPram, int nCmdShow){
    TCHAR cmdline[4096] ;
    TCHAR* argv[4096] ;
    int argc = 0 ;
    _tcscpy( cmdline, GetCommandLine() ) ;
    argv[argc] = _tcstok( cmdline, TEXT(" \t") ) ;
    while( argv[argc] != 0 )
        argv[++argc] = _tcstok( 0, TEXT(" \t") ) ;
    for(int i=0;i<argc;i++)
        MessageBox(NULL, argv[i], "MessageBox caption", MB_OK);
}
cs

 

'C&C++' 카테고리의 다른 글

Using scanf() As gets()  (0) 2018.06.15
WINAPI GetClipboardData()  (0) 2018.05.17
C++ WinSock Sample Code  (0) 2018.04.09
[MinGW] Using DLL and Compile Options  (0) 2018.04.09
swap using exclusive-or  (0) 2017.02.15

 

index.php 에서 LFI 취약점이 발생해서 index.php의 코드를 가져와본다.

 

 

81~83번째 줄에서 LFI 취약점이 발생하고 .php가 붙어서 php 파일 말고는 실행할 수 없다.

위 코드가 index.php의 핵심이 되는 코드인데 debug_mode라는게 존재해서 이를 통해 변수들을 출력할 수 있다.

이외에도 주석으로 phpinfo.php라는 페이지가 있는데 phpinfo() 함수를 통해 웹서버의 서버 설정들을 보여준다.

설정중에 파일 업로드 기능이 활성화 되어있어 php 페이지로 파일을 던지면 http 통신이 끊어지기 전까지

/tmp 디렉토리에 php[A-Za-z0-9]{6}의 형식으로 난수파일명으로 변환되어 일시적으로 파일이 저장된다.

(실제로 테스트 해본결과 http 통신이 끊어져도 바로 삭제되지는 않는다.)

아무튼 좋다. 일단 서버에 파일업로드를 하는것 까지는 했는데 문제는 서버에 올라간 코드를 어떻게 실행할것이냐?

문제는 파일명이 난수화 되어 업로드 되서 확장자가 날라간다는 점이다.

이를 해결할 수 있는 방법은 zip wrapper를 통해 압축 파일을 서버에 올려 실행하는 방법이다.

zip wrapper는 압축파일 속에 있는 파일을 띄워주는 역할을 하는데

LFI 취약점이 존재하므로 zip안에 php 코드가 있다면 LFI 취약점을 통해 내가 올린 파일을 실행할 수 있다.

 

 

위 코드를 압축해서 zip 파일로 만든다.

 

 

이렇게 만든 파일을 index.php?page=index&debug_mode=31337로 던지면 debug_mode 덕분에

내가 던진 파일이 /tmp 디렉토리에 어떠한 난수값으로 업로드 되었는지 알 수 있고 include 하는 페이지가

index.php이기 때문에 무한루프에 빠져 http 통신이 안끊어지도록 하여 레이스컨디션 공격이 가능하다.

 

 

이러한 방식으로 무한루프에 빠져 변수정보가 계속 출력이 되고 여기서 /tmp/php5HKDtk라는 파일명을 뽑을수있다.

 

index.php?page=zip:///tmp/php5HKDtk%23a 로 접속을 시도하면 실질적으로

index.php?page=zip:///tmp/php5HKDtk#a.php 로 접속하는 꼴이 되어 /tmp/php5HKDtk 파일의 압축을 해제하여

그 안에 있는 a.php를 include 한다 라는 뜻이 된다.

이러한 방식으로 remote code execution을 성공했고 마찬가지 방식으로 flag를 출력할 수 있다.

 

'문제 > CTF' 카테고리의 다른 글

CODEGATE 2017 Prequals RamG-thunder  (0) 2017.02.15

Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<iostream>
#include<Windows.h>
 
using namespace std;
 
void ErrorHandling(char* msg);
  
int main(int argc,char* argv[]){
    WSADATA wsaData;
    SOCKET serverSock,clientSock;
    SOCKADDR_IN serverAddr,clientAddr;
    int clientAddrSize;
    if(argc!=2){
        cout<<"Usage : "<<argv[0]<<" <port>"<<endl;
        exit(1);
    }
    if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
        ErrorHandling("WSAStartup() error!");
    
    serverSock=socket(PF_INET,SOCK_STREAM,0); 
    
    memset(&serverAddr,0,sizeof(serverAddr));
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    serverAddr.sin_port=htons(atoi(argv[1]));
    
    if(bind(serverSock,(SOCKADDR*)&serverAddr,sizeof(serverAddr))==SOCKET_ERROR) 
        ErrorHandling("bind() error");
    if(listen(serverSock,5)==SOCKET_ERROR)
        ErrorHandling("listen() error");
    
    clientAddrSize=sizeof(clientAddr);
    clientSock=accept(serverSock,(SOCKADDR*)&clientAddr,&clientAddrSize);
    cout<<"Connected Client IP : "<<inet_ntoa(clientAddr.sin_addr)<<endl;
    closesocket(serverSock);
    WSACleanup();
    return 0;
}
 
void ErrorHandling(char* msg){
    fputs(msg,stderr);
    fputc('\n',stderr);
    exit(1);
}
cs

 

Client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<Windows.h>
 
 using namespace std;
 
void ErrorHandling(char* msg);
 
int main(int argc,char* argv[]){
    WSADATA wsaData;
    SOCKET sock;
    SOCKADDR_IN serverAddr;
    if(argc!=3){
        cout<<"Usage : "<<argv[0]<<" <IP> <port> "<<endl;
        exit(1);
    }
    if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
        ErrorHandling("WSAStartup() error!");
 
    sock=socket(PF_INET,SOCK_STREAM,0);
 
    memset(&serverAddr,0,sizeof(serverAddr));
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_addr.s_addr=inet_addr(argv[1]);
    serverAddr.sin_port=htons(atoi(argv[2]));
 
    if(connect(sock,(SOCKADDR*)&serverAddr,sizeof(serverAddr))==SOCKET_ERROR)
        ErrorHandling("connect() error");
 
    closesocket(sock);
    WSACleanup();
    return 0;
}
 
void ErrorHandling(char* msg){
    fputs(msg,stderr);
    fputc('\n',stderr);
    exit(1);
}
cs

'C&C++' 카테고리의 다른 글

WINAPI GetClipboardData()  (0) 2018.05.17
Parameter Split in WinMain (Argc, Argv)  (0) 2018.05.10
[MinGW] Using DLL and Compile Options  (0) 2018.04.09
swap using exclusive-or  (0) 2017.02.15
2048 게임만들기  (0) 2017.02.08

 

Create and Use DLL

 

- Create

 

1
2
3
4
5
6
7
8
9
//mydll.h
 
#ifdef BUILD_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif
 
extern "C" int DLLEXPORT print();
cs

 

1
2
3
4
5
6
7
8
9
//mydll.cpp
 
#include<iostream>
#include "mydll.h"
 
 
extern "C" int DLLEXPORT print(){
    std::cout<<"This is My Dll"<<std::endl;
}
cs

 

1
2
g++ --DBUILD_DLL mydll.cpp
g++ -shared -o mydll.dll mydll.o
cs

 

- Use

 

1
2
3
4
5
6
7
8
9
10
11
12
//main.cpp
 
#include<windows.h>
#include<iostream>
 
int main(){
    typedef int(*func)();
    HMODULE hmodule=LoadLibrary("mydll.dll");
    func print=(func)GetProcAddress(hmodule,"print");
    print();
    return 0;
}
cs

 

1
g++ -o main.exe main.cpp
cs

 

Windows Programming

 

1
g++ -o WinMain.exe WinMain.cpp -mwindows
cs


Using wWinMain


1
g++ -o WinMain.exe WinMain.cpp -municode
cs

 

Using library (ex. ws2_32.lib)

 

1
g++ -o server.exe server.cpp -lws2_32
cs

 

Compile Multiple Source files

 

1
g++ -o main.exe main.cpp temp.cpp
cs
 

 

'C&C++' 카테고리의 다른 글

WINAPI GetClipboardData()  (0) 2018.05.17
Parameter Split in WinMain (Argc, Argv)  (0) 2018.05.10
C++ WinSock Sample Code  (0) 2018.04.09
swap using exclusive-or  (0) 2017.02.15
2048 게임만들기  (0) 2017.02.08

pe 파일을 받았다. 실행시켜보니 암호화 문제같았다.


암호화 알고리즘을 분석해 복호화 알고리즘을 구현하는 문제같아서 IDA를 통해 분석해보았다.



string 검색을 통해보니 hidden menu라는 문자열이 보인다.



입력 받는 부분에서 4를 입력하면 hidden menu가 나온다. 암호화 알고리즘은 fake인가보다.



hidden menu를 보니 숨겨진 flag를 찾는 게임이라고 하고 각 단계별로 stage5까지 있다.



먼저 입력을 받으면 바이트 단위로 XOR연산을 하는데 


input값과 메모리의 값을 xor해서 특정 값(v40)과 비교를 한다. 




v50="MVYLXYUARJ" 이므로 v50과 메모리의값을 XOR연산하면 stage1의 input값이 나온다.


후에 안티디버깅을 해주는데 레지스터값 수정을통해 우회한다.



stage2는 특정 구조체에 있는 값을 비교해주는데 디버깅을 통해 메모리 값을 변조하여 우회하였다.



stage3는 레지스트리값을 검증하는데 HKEY_CURRENT_USER -> Hellow -> hellow_FishWorld 라는 레지스트리가 있기만 하면 통과된다.



regedit을 통해 레지스트리를 생성해주었다.



stage4는 stage2와 마찬가지로 특정 구조체의 값을 디버깅을 통해 변조하고 


간단한 안티디버깅을 하는데 마찬가지로 레지스터값을 변조해 우회하면 된다.



stage5는 stage1과 마찬가지로 input값을 특정값과 XOR연산해서 비교한다.



이번에는 v36과 비교를 하는데 간단한 코딩을 통해 stage5의 input값을 알아내었다.



최종적으로 v42에 위에서 단계별로 통과하며 얻은 값을 붙여주는데 v42를 통해 연산을 해서 c라는 파일을 생성한다.



파일 시그니쳐를 보니 png파일이다.




확장자를 붙여주니 올바르게 이미지가 보이고 클리어


'문제 > CTF' 카테고리의 다른 글

2016 WhiteHat Contest JB  (0) 2018.04.09




'C&C++' 카테고리의 다른 글

WINAPI GetClipboardData()  (0) 2018.05.17
Parameter Split in WinMain (Argc, Argv)  (0) 2018.05.10
C++ WinSock Sample Code  (0) 2018.04.09
[MinGW] Using DLL and Compile Options  (0) 2018.04.09
2048 게임만들기  (0) 2017.02.08

Options - General - Numbers of opcode bytes 


바이트 수를 보고싶은 만큼 입력해준다.




'리버싱' 카테고리의 다른 글

Assembly Jump Relative Address (Intel x86)  (0) 2019.07.09
Z3 SMT Solver for windows using visual studio  (0) 2017.02.08
Remote Linux Debugging using IDA  (0) 2016.08.25

SMT(Satisfiability modulo theories) Solver란 수학의 방정식을 풀어주는 해석기이다.


z3는 SMT Solver의 한 종류로 마이크로 소프트에서 개발했다고 한다. 


나는 파이썬으로 비쥬얼 스튜디오에서 작업하였다.


https://z3.codeplex.com/releases 에서 다운을 받는다.




비쥬얼 스튜디오를 통해 파이썬 프로젝트를 생성한다.



search Path-add forder to search path 클릭한다.



z3홈페이지에서 다운받은 파일에 있는 bin 폴더로 경로를 지정해준다.




1
2
3
4
5
6
7
8
9
10
11
12
13
from z3 import * # z3모듈을 import
 
x=Int('x')         
y=Int('y')         # 방정식에 사용할 변수 x,y를 선언
 
s=Solver()       # solver를 생성
 
s.add(x+y>5, x>1, y>1# add함수를 통해 방정식을 추가
 
print(s.check())     # 방정식에 만족하는 값을 구한다.
                     # 올바르게 식이 풀렸다면 z3.sat를 반환한다 
 
print(s.model())     # 방정식을 통해 구한 값을 출력한다.
cs

참고 : https://github.com/Z3Prover/z3


'리버싱' 카테고리의 다른 글

Assembly Jump Relative Address (Intel x86)  (0) 2019.07.09
How To See opcode using IDA  (0) 2017.02.10
Remote Linux Debugging using IDA  (0) 2016.08.25




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
 
#define LEFT   75      
#define RIGHT  77      
#define UP     72      
#define DOWN   80
#define ESC    27
int num[4][4= { 0, };
int is_empty[4][4= { 0, };
int pre[4][4= { 0, };
int is_pre, score, pre_score;
 
void printd(int num) {
    if (num == 0)
        printf("%4c", num);
    else {
        if (num == 2)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
        else if (num == 4)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2);
        else if (num == 8)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
        else if (num == 16)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
        else if (num == 32)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 5);
        else if (num == 64)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6);
        else if (num == 128)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
        else if (num == 256)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 8);
        else if (num == 512)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);
        else if (num == 1024)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
        else if (num == 2048)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
        else if (num == 4096)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 1);
        printf("%4d", num);
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
    }
}
void print() {
    printf("\n\n\n\n\n");
    printf("\t\t+---------+---------+---------+---------+\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t| ");
    printd(num[0][0]);
    printf("    | ");
    printd(num[0][1]);
    printf("    | ");
    printd(num[0][2]);
    printf("    | ");
    printd(num[0][3]);
    printf("    |\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t+---------+---------+---------+---------+\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t| ");
    printd(num[1][0]);
    printf("    | ");
    printd(num[1][1]);
    printf("    | ");
    printd(num[1][2]);
    printf("    | ");
    printd(num[1][3]);
    printf("    |\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t+---------+---------+---------+---------+\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t| ");
    printd(num[2][0]);
    printf("    | ");
    printd(num[2][1]);
    printf("    | ");
    printd(num[2][2]);
    printf("    | ");
    printd(num[2][3]);
    printf("    |\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t+---------+---------+---------+---------+\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t| ");
    printd(num[3][0]);
    printf("    | ");
    printd(num[3][1]);
    printf("    | ");
    printd(num[3][2]);
    printf("    | ");
    printd(num[3][3]);
    printf("    |\n");
    printf("\t\t|         |         |         |         |\n");
    printf("\t\t+---------+---------+---------+---------+\n");
    printf("\n\t\tscore : %d", score);
    printf("\n\t\t esc : stop\t\tb :  before\n");
}
int rand_init() {
    int a = rand() % 10;
    if (a == 0 || a == 7 || a == 9)return 4;
    else return 2;
}
void game_start() {
    int i, j, a, b, c, d;
    score = 0;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            num[i][j] = 0;
            is_empty[i][j] = 0;
        }
    }
    a = rand() % 4;
    b = rand() % 4;
    num[a][b] = rand_init();
    while (1) {
        c = rand() % 4;
        d = rand() % 4;
        if (!(a == c&&== d)) {
            if (num[a][b] == 4) {
                num[c][d] = 2;
                break;
            }
            num[c][d] = rand_init();
            break;
        }
    }
    is_pre = 1;
}
void search_empty() {
    int i, j,a, b;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            if (num[i][j] == 0)
                is_empty[i][j] = 1;
            else
                is_empty[i][j] = 0;
        }
    }
    while (1) {
        a = rand() % 4;
        b = rand() % 4;
        if (is_empty[a][b] == 1) {
            num[a][b] = rand_init();
            return;
        }
    }
}
void move(int z) {
    int copy[4][4];
    int i, j,k;
    if (is_pre == 0)is_pre = 1;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            copy[i][j] = num[i][j];
            pre[i][j] = num[i][j];
        }
    }
    pre_score = score;
    for (k = 0; k < 4; k++) {
        int arra[4= { 0, };
        int arrb[4= { 0, };
        int arrc[4= { 0, };
        for (i = 0; i < 4; i++) {
            if (z == 1)arra[i] = num[k][i];
            else if (z == 2)arra[i] = num[k][3 - i];
            else if (z == 3)arra[i] = num[i][k];
            else if (z == 4)arra[i] = num[3 - i][k];
        }
        for (i = 0, j = 0; i < 4; i++) {
            if (arra[i] != 0) {
                arrb[j] = arra[i];
                j++;
            }
        }
        for (i = 0; i < 3; i++) {
            if (arrb[i] == arrb[i + 1]) {
                arrb[i] = arrb[i] * 2;
                score += arrb[i];
                arrb[i + 1= 0;
            }
        }
        for (i = 0, j = 0; i < 4; i++) {
            if (arrb[i] != 0) {
                arrc[j] = arrb[i];
                j++;
            }
        }
        for (i = 0; i < 4; i++) {
            if (z == 1)num[k][i] = arrc[i];
            else if (z == 2)num[k][3 - i] = arrc[i];
            else if (z == 3)num[i][k] = arrc[i];
            else if (z == 4)num[3 - i][k] = arrc[i];
        }
    }
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
            if (copy[i][j] != num[i][j]) {
                search_empty();
                return;
            }
        }
    }
}
int esc() {
    char input;
    system("cls");
    printf("\n\n\n\n\n\n\n\n\n\t\t\tAre you sure you want to quit?\n\n");
    printf("\t\t\t1. yes(y)   2. no(n)\n");
    input = getch();
    if (input == 'y' || input == 'Y'return 1;
    else return 0;
}
void previous() {
    int i, j;
    if (is_pre) {
        for (i = 0; i < 4; i++)
            for (j = 0; j < 4; j++)
                num[i][j] = pre[i][j];
        score = pre_score;
        is_pre = 0;
    }
}
void game() {
    while (1) {
        char input;
        system("cls");
        print();
        input = getch();
        switch (input) {
        case LEFT:
            move(1);
            break;
        case RIGHT:
            move(2);
            break;
        case UP:
            move(3);
            break;
        case DOWN:
            move(4);
            break;
        case 'b':
            previous();
            break;
        case ESC:
            if (esc())
                return;
        }
    }
 
}
int main(int argc, char *argv[]) {
    srand((unsigned)time(NULL));
    game_start();
    game();
    return 0;
}
cs


'C&C++' 카테고리의 다른 글

WINAPI GetClipboardData()  (0) 2018.05.17
Parameter Split in WinMain (Argc, Argv)  (0) 2018.05.10
C++ WinSock Sample Code  (0) 2018.04.09
[MinGW] Using DLL and Compile Options  (0) 2018.04.09
swap using exclusive-or  (0) 2017.02.15

+ Recent posts