找到之前写的个类,ring3实现DLL注入进程,Inject()注入,Uninject()卸载

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
251
252
253
/************************************************************************/
/*
Yufan
CInjectDLL a class for DLL injection
to inject use Inject()
to uninject use Uninject()
*/
/************************************************************************/
#pragma once
#include "stdafx.h"
class CInjectDLL
{
public:
CInjectDLL(void);
BOOL Inject(const DWORD dwRemoteProcessID, const LPCTSTR& lpwszRemoteDllFullPath);
BOOL Inject(const LPCWSTR wszProcessName, const LPCTSTR& lpwszRemoteDllFullPath);
BOOL Uninject(const DWORD dwRemoteProcessID, const LPCTSTR& lpwszRemoteDllFullPath);
BOOL Uninject(const LPCWSTR wszProcessName, const LPCTSTR& lpwszRemoteDllFullPath);
~CInjectDLL(void);
private:
BOOL AdjustProcessTokenPrivilege();
BOOL GetProcessID(const wchar_t* wszProcessName, DWORD& dwProcID);
};
/************************************************************************/
/*
Yufan
CInjectDLL a class for DLL injection
to inject use Inject()
to uninject use Uninject()
*/
/************************************************************************/
#pragma once
#include "StdAfx.h"
#include "InjectDLL.h"
#include <Windows.h>
#include <string>
#include "tlhelp32.h"
CInjectDLL::CInjectDLL(void)
{
}
CInjectDLL::~CInjectDLL(void)
{
}
BOOL CInjectDLL::Inject(const DWORD dwRemoteProcessID, const LPCTSTR& lpwszRemoteDllFullPath)
{
std::wstring wstrRemoteDllFullPath = lpwszRemoteDllFullPath;
BOOL bRet;
if (!AdjustProcessTokenPrivilege())
{
OutputDebugString(_T("AdjustProcessTokenPrivilege failn"));
}
HANDLE hRemoteProgress = ::OpenProcess(PROCESS\_ALL\_ACCESS, FALSE, dwRemoteProcessID);
if (hRemoteProgress == NULL)
{
OutputDebugString(_T("OpenProcess failn"));
return FALSE;
}
// Allocate remote memory
DWORD dwMemSize = sizeof(wchar_t)*wstrRemoteDllFullPath.length()+1;
wchar\_t* wszDllPath = reinterpret\_cast<wchar\_t*>(::VirtualAllocEx(hRemoteProgress, NULL, dwMemSize, MEM\_COMMIT, PAGE_READWRITE));
if (wszDllPath == NULL)
{
OutputDebugString(_T("VirtualAllocEx failn"));
::CloseHandle(hRemoteProgress);
return FALSE;
}
// Write remote Memory
bRet = ::WriteProcessMemory(hRemoteProgress, wszDllPath, wstrRemoteDllFullPath.c_str(), dwMemSize, NULL);
if (!bRet)
{
OutputDebugString(_T("WriteProcessMemory failn"));
::CloseHandle(hRemoteProgress);
return FALSE;
}
// Create remote thread
FARPROC pfnFunAddr = ::GetProcAddress(::GetModuleHandle(_T("Kernel32")),"LoadLibraryW");
if (pfnFunAddr == NULL)
{
OutputDebugString(_T("GetProcAddress failn"));
::CloseHandle(hRemoteProgress);
return FALSE;
}
HANDLE hCreateThread;
hCreateThread = ::CreateRemoteThread(hRemoteProgress, NULL, 0, (LPTHREAD\_START\_ROUTINE) pfnFunAddr, wszDllPath, 0, NULL);
if (hCreateThread == NULL)
{
OutputDebugString(_T("CreateRemoteThread failn"));
::CloseHandle(hRemoteProgress);
::CloseHandle(hCreateThread);
return FALSE;
}
// Wait for thread return
// DWORD hLibModule;
// WaitForSingleObject(hCreateThread, INFINITE);
// GetExitCodeThread(hCreateThread, &hLibModule);
::VirtualFreeEx(hRemoteProgress, reinterpret\_cast<LPVOID>(wszDllPath), dwMemSize, MEM\_COMMIT);
::CloseHandle(hCreateThread);
::CloseHandle(hRemoteProgress);
return TRUE;
}
BOOL CInjectDLL::Inject(const wchar_t* wszProcessName, const LPCTSTR& lpwszRemoteDllFullPath)
{
DWORD dwProcID;
GetProcessID(wszProcessName,dwProcID);
if (Inject(dwProcID, lpwszRemoteDllFullPath))
return TRUE;
else
return FALSE;
}
BOOL CInjectDLL::Uninject(const DWORD dwRemoteProcessID, const LPCTSTR& lpwszRemoteDllFullPath)
{
std::wstring wstrRemoteDllFullPath = lpwszRemoteDllFullPath;
// Find injected DLL handle
HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwRemoteProcessID);
MODULEENTRY32 Me32 = {0};
Me32.dwSize = sizeof(MODULEENTRY32);
BOOL bRet = ::Module32First(hSnap, &Me32);
while (bRet)
{
if (wcscmp(Me32.szExePath, wstrRemoteDllFullPath.c_str()) == 0)
{
break;
}
bRet = ::Module32Next(hSnap, &Me32);
}
::CloseHandle(hSnap);
HANDLE hRemoteProgress = ::OpenProcess(PROCESS\_ALL\_ACCESS, FALSE, dwRemoteProcessID);
if (hRemoteProgress == NULL)
{
OutputDebugString(_T("OpenProcess failn"));
return FALSE;
}
// Create remote thread
FARPROC pfnFunAddr = ::GetProcAddress(::GetModuleHandle(_T("Kernel32")),"FreeLibrary");
if (pfnFunAddr == NULL)
{
OutputDebugString(_T("GetProcAddress failn"));
::CloseHandle(hRemoteProgress);
return FALSE;
}
HANDLE hCreateThread;
hCreateThread = ::CreateRemoteThread(hRemoteProgress, NULL, 0, (LPTHREAD\_START\_ROUTINE)pfnFunAddr, Me32.hModule, 0, NULL);
if (hCreateThread == NULL)
{
OutputDebugString(_T("CreateRemoteThread failn"));
::CloseHandle(hRemoteProgress);
::CloseHandle(hCreateThread);
return FALSE;
}
// Wait for thread return
//DWORD hLibModule;
//WaitForSingleObject(hCreateThread, INFINITE);
//GetExitCodeThread(hCreateThread, &hLibModule);
::CloseHandle(hCreateThread);
::CloseHandle(hRemoteProgress);
return TRUE;
}
BOOL CInjectDLL::Uninject(const wchar_t* wszProcessName, const LPCTSTR& lpwszRemoteDllFullPath)
{
DWORD dwProcID;
GetProcessID(wszProcessName,dwProcID);
if (Uninject(dwProcID, lpwszRemoteDllFullPath))
return TRUE;
else
return FALSE;
}
BOOL CInjectDLL::AdjustProcessTokenPrivilege()
{
LUID luidTmp;
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN\_ADJUST\_PRIVILEGES | TOKEN_QUERY, &hToken))
{
OutputDebugString(_T("AdjustProcessTokenPrivilege OpenProcessToken Failed ! n"));
return FALSE;
}
if(!LookupPrivilegeValue(NULL, SE\_DEBUG\_NAME, &luidTmp))
{
OutputDebugString(_T("AdjustProcessTokenPrivilege LookupPrivilegeValue Failed ! n"));
CloseHandle(hToken);
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges\[0\].Luid = luidTmp;
tkp.Privileges\[0\].Attributes = SE\_PRIVILEGE\_ENABLED;
if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
OutputDebugString(_T("AdjustProcessTokenPrivilege AdjustTokenPrivileges Failed ! n"));
CloseHandle(hToken);
return FALSE;
}
return TRUE;
}
BOOL CInjectDLL::GetProcessID(const wchar_t* wszProcessName, DWORD& dwProcID)
{
HANDLE hSnapShot = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, dwProcID );
PROCESSENTRY32 pe = {sizeof(pe)};
BOOL bOk = ::Process32First( hSnapShot, &pe );
while( bOk )
{
//wprintf(TEXT("ProcessID : %d, Name : %sn"), pe.th32ProcessID, pe.szExeFile);
if (wcsstr(pe.szExeFile, wszProcessName)!=NULL)
{
dwProcID = pe.th32ProcessID;
return TRUE;
}
bOk = ::Process32Next( hSnapShot, &pe );
}
::CloseHandle(hSnapShot);
return FALSE;
}

Comment and share

题目 买不到TI4的门票觉得人生好灰暗。。ACTF2014crypto200.tar ————割———— 解压以后是一个加密脚本,注意key是未知的,所以先研究算法想办法推出加密的key。 已知明文msg01和密文msg01.enc。 研究算法发现对明文加密时只用到上一位的密文以及key[i%len(key)]即key中的一个字符,并且是按位加密。 于是可以从msg01第一位开始遍历0-9a-zA-Z,与msg01.enc匹配就可以得到key的第一位,然后以此类推就能推出全部的key 代码如下

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
g2 = open('msg01.enc.ord', 'rb')
key = ''
c = ''
str = ''
t = chr(0)
i = 0
find = 0
ckey = g2.read(1)
realkey=''
for p in f:
for k1 in range(0, 256):
k1 = chr(k1)
find=0
c = chr(( ord(p) + (ord(k1) ^ ord(t)) + i**i ) & 0xff)
if c == ckey:
print 'get %d is %c' % (i, k1)
realkey += k1
find = 1
break
if find ==0:
print 'cant find NO.', i
break
t = p
i += 1
ckey = g2.read(1)
print repr(realkey)
g.close()
运行得到key ![](data:image/png;base64,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) 因为key是循环取的,所以key='DoNotTryToGuessWhatDoesD3AdCa7ThinkOf' 之后写一个解密脚本解密msg02.enc即可
g = open('msg02.enc', 'rb').read()
f = open('msgtest02', 'wb')
key = 'DoNotTryToGuessWhatDoesD3AdCa7ThinkOf'
i = 0
t = chr(0)
p = ''
str = ''
for c in g:
p =chr( (ord(c) - i**i - (ord(key\[i % len(key)\]) ^ ord(t)) ) & 0xff )
t = p
i += 1
str += p
f.write(p)
print str
f.close()

Comment and share

ACTF清明放假回家。。所以就不做了,抽空做了两个简单的密码的。 题目 本题flag不在ACTF{}中。 oivqmqgn, yja vibem naarn yi yxbo sqnyab yjqo q zixuea is gaqbn qdi. ykra jqn zira yi baseazy yjqy qeni ko yja ujbqzw rqdqhkoa. yjkn kn vjqy yja uquab saam kn qpixy: gix nxprky q uquab, va backav ky qom ky dayn uxpeknjam. oi oaam yi vqky q rioyj ib yvi xoyke gix naa gixb qbykzea ko yja oafy ujbqzw knnxa, vjao yja ykra jqn zira, va’ee mazkma yi zirukea q oav knnxa sbir yja qbykzean yjqy jqca paao nxprkyyam. yjqy’n pqnkzqeeg ky. qom dbqp gix seqd jaba, zbguyiiiniziieqrkbkdjy? ————割———— 很像单表代换的,参考辅助处理单表替换密码 yja很明显应该是the,剩下的慢慢试试。 下面的就转出部分没有转全 nowadays, the world seems to turn faster than a couple of years ago. time has come to reflect that also in the phracw magahine. this is what the paper feed is about: you submit a paper, we review it and it gets published. no need to wait a month or two until you see your article in the neft phracw issue, when the time has come, we’ll decide to compile a new issue from the articles that have been submitted. that’s basically it. and grab you flag here, cryptooosocoolamiright? key在最后一句cryptooosocoolamiright

Comment and share

整理了一些东西,方便单表密码分析。 分析单表替换密码:http://www.counton.org/explorer/codebreaking/frequency-analysis.php 这网站上同时还有一些简单的密码分析 下面是一个替换后上下两行显示明密文通过颜色对比的shell

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
#!/bin/bash
#rois_yf
##################################################
cipher="oivqmqgn, yja vibem naarn yi yxbo sqnyab yjqo q zixuea is gaqbn qdi. ykra jqn zira yi baseazy yjqy qeni ko yja ujbqzw rqdqhkoa. yjkn kn vjqy yja uquab saam kn qpixy: gix nxprky q uquab, va backav ky qom ky dayn uxpeknjam. oi oaam yi vqky q rioyj ib yvi xoyke gix naa gixb qbykzea ko yja oafy ujbqzw knnxa, vjao yja ykra jqn zira, va'ee mazkma yi zirukea q oav knnxa sbir yja qbykzean yjqy jqca paao nxprkyyam. yjqy'n pqnkzqeeg ky. qom dbqp gix seqd jaba, zbguyiiiniziieqrkbkdjy?"
tranOrl='yjaqnarikevz'
tranRst='theasemoilwc'
##################################################
echoKnownPlain()
{
#white
echo -n -e "33\[0m$133\[0m"
}
echoCipher()
{
#red
echo -n -e "33\[31m$133\[0m"
}
echoUnknownPlain()
{
#blue
echo -n -e "33\[36m$133\[0m"
}
plain=\`echo $cipher | tr $tranOrl $tranRst\`
cols=\`tput cols\`
echo
echo
tput cuu 2
tput sc
for((i=0;i<${#plain};i++))
{
tput rc
echoCipher "${cipher:i:1}"
tput sc
tput cud 1
tput cub 1
if \[ "${plain:i:1}" != "${cipher:i:1}" \];
then
echoKnownPlain "${plain:i:1}"
else
echoUnknownPlain "${plain:i:1}"
fi
if (( $\[$cols-1\] == $\[$i%$cols\] ));
then
echo
echo
tput cuu 1
tput sc
fi
}
echo

效果如下 最后是个简单的替换脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python
#\-\*\- coding:utf-8 -*-
"""
rois_yf
"""
import sys
import os
import string
def main():
cipher = "oivqmqgn, yja vibem naarn yi yxbo sqnyab yjqo q zixuea is gaqbn qdi. ykra jqn zira yi baseazy yjqy qeni ko yja ujbqzw rqdqhkoa. yjkn kn vjqy yja uquab saam kn qpixy: gix nxprky q uquab, va backav ky qom ky dayn uxpeknjam. oi oaam yi vqky q rioyj ib yvi xoyke gix naa gixb qbykzea ko yja oafy ujbqzw knnxa, vjao yja ykra jqn zira, va'ee mazkma yi zirukea q oav knnxa sbir yja qbykzean yjqy jqca paao nxprkyyam. yjqy'n pqnkzqeeg ky. qom dbqp gix seqd jaba, zbguyiiiniziieqrkbkdjy?"
print
print (cipher)
translate_table = string.maketrans('yjaqnarikovbceszxupgmd', 'theasemoinwrvlfcupbydg')
print (cipher.translate(translate_table))
return
if \_\_name\_\_ == '\_\_main\_\_':
main()

Comment and share

福大锐捷更新了新版的。。。也有个linux版rjsupplicant rjsupplicant这个程序分x86和x64两个版本,启动时通过sh判断版本运行。 通过IDA加载x86的试试看,发现有带调试信息。。。一切就简单了。 先试试把多网卡处理掉,有调试信息的话先试试直接找函数看看。 尝试搜索字符串,多网卡就搜索multi试试,发现一个CAdapterDetectThread::MultipleAdaptesOrIPCheck函数 看下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
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
int __cdecl CAdapterDetectThread::MultipleAdaptesOrIPCheck(int a1)
{
int v1; // [email protected]
int v2; // [email protected]
int v3; // [email protected]
signed int v4; // [email protected]
char v5; // [email protected]
int v6; // [email protected]
int *v8; // [email protected]
int v9; // [email protected]
int v11; // \[sp+8h\] \[bp-60h\]@16
int v12; // \[sp+Ch\] \[bp-5Ch\]@16
const char *s1; // \[sp+24h\] \[bp-44h\]@2
void *ptr; // \[sp+28h\] \[bp-40h\]@1
char dest; // \[sp+30h\] \[bp-38h\]@19
int *v16; // \[sp+40h\] \[bp-28h\]@19
int v17; // \[sp+50h\] \[bp-18h\]@19
int v18; // \[sp+54h\] \[bp-14h\]@19
int v19; // \[sp+58h\] \[bp-10h\]@15
v1 = get\_nics\_info(0);
ptr = (void *)v1;
if ( !v1 )
return free\_nics\_info(ptr);
v2 = v1;
s1 = (const char *)(a1 + 360);
while ( !strcmp(s1, (const char *)v2) )
{
v3 = v2 + 16;
CLogFile::AppendText(g\_log\_Wireless, "nic name:%s", s1);
v4 = 6;
v5 = a1 == -884;
v6 = a1 + 884;
do
{
if ( !v4 )
break;
v5 = *(\_BYTE *)v3++ == *(\_BYTE *)v6++;
--v4;
}
while ( v5 );
if ( !v5 )
{
CLogFile::AppendText(g\_log\_Wireless, "mac chagedn");
v12 = 0;
v11 = 30;
goto FindMul;
}
CLogFile::AppendText(g\_log\_Wireless, "ipv4 count:%d", *(_DWORD *)(v2 + 48));
for ( i = *(\_DWORD *)(v2 + 52); i; i = *(\_DWORD *)(i + 8) )
CLogFile::AppendText(
g\_log\_Wireless,
(const char *)&unk_810ED8E,
*(_BYTE *)(i + 3),
*(_BYTE *)(i + 2),
*(_BYTE *)(i + 1),
*(_BYTE *)i);
if ( *(\_DWORD *)(v2 + 48) > 1 && *(\_BYTE *)(a1 + 890) )
{
CLogFile::AppendText(g\_log\_Wireless, "multiple ipsn");
v12 = 0;
v11 = 21;
goto FindMul;
}
v8 = *(int **)(v2 + 52);
if ( !v8 )
{
CLogFile::AppendText(g\_log\_Wireless, "ip chaged - no ipn");
v12 = 0;
v11 = 31;
goto FindMul;
}
v9 = *v8;
v19 = v9;
LOWORD(v9) = \_\_ROR\_\_(v9, 8);
v9 = \_\_ROR\_\_(v9, 16);
LOWORD(v9) = \_\_ROR\_\_(v9, 8);
v5 = *(_DWORD *)(a1 + 880) == v9;
v19 = v9;
if ( !v5 )
{
CLogFile::AppendText(g\_log\_Wireless, "ip chagedn");
v12 = 0;
v11 = 31;
goto FindMul;
}
LABEL_4:
v2 = *(_DWORD *)(v2 + 64);
if ( !v2 )
return free\_nics\_info(ptr);
}
if ( !*(_BYTE *)(a1 + 890) )
goto LABEL_4;
CLogFile::AppendText(g\_log\_Wireless, (const char *)&unk_810EDC9, v2);
memset(&dest, 0, 0x20u);
strncpy(&dest, (const char *)v2, 0xFu);
v16 = &v17;
v17 = 10;
v18 = 0;
if ( ioctl(*(_DWORD *)(a1 + 900), 0x8913u, &dest) < 0 )
{
if ( ioctl(*(_DWORD *)(a1 + 900), 0x8946u, &dest) >= 0 && v18 == 1 )
{
CLogFile::AppendText(g\_log\_Wireless, "multiple adaptersn");
v12 = 0;
v11 = 20;
goto FindMul;
}
goto LABEL_4;
}
if ( !((unsigned \_\_int8)v16 & 1) || !((unsigned \_\_int8)v16 & 0x40) )
{
CLogFile::AppendText(g\_log\_Wireless, "SIOCGIFFLAGS flags:%4x", (signed __int16)v16);
goto LABEL_4;
}
CLogFile::AppendText(g\_log\_Wireless, "multiple adapters flags:%4x", (signed __int16)v16);
v12 = 0;
v11 = 20;
FindMul:
PostThreadMessage(*(\_DWORD *)(a1 + 872), *(\_DWORD *)(a1 + 876), v11, v12);
return free\_nics\_info(ptr);
}

真好。。还有输出调试,可以看出如果发现多网卡多IP等情况会跳转到FindMul这个label然后PostMessage,应该是判断出多网卡之后向线程发送一个通知信息。把这个函数nop掉就Patch掉多网卡限制了。 ————割———— 之后是Network-manager服务 查找跟service有关的,找到一个stop_service函数

1
2
3
4
5
6
7
8
9
int \_\_cdecl service\_stop(int a1)
{
char s; // \[sp+10h\] \[bp-208h\]@1
memset(&s, 0, 0x200u);
sprintf(&s, "service %s stop 2>&-", a1);
system(&s);
return service_stop2(a1);
}

这个函数作用是通过传入的服务名调用system关闭服务。 查看xrefs引用

都是在EnvironmentCheck中引用。 查看下这个函数发现第一处的引用是关闭Network-Manager的。nop掉他,结束。 x64的也是类似的,就不重复了

Comment and share

人生真是寂寞如雪啊。。。

思路是找到棋盘位置->读取棋盘数据->计算可消除的格子->向窗口发送鼠标点击消息

Tip:可以点击练习来进行单人游戏。

找棋盘位置

找棋盘位置本来想下rand或者消息。。。结果断不了。。。只能用最简单的CE了。。。 跟金山游侠一样哦,选一个进程,然后搜索内存~ 预测棋盘应该是一个数组,就用棋盘最左上角的那个位置做参照,预测有东西应该是非0,没有应该大于0。
利用CE不断搜索,没搜一次再点练习更新一次棋盘 经过试验value type是byte哦 最后找到棋盘地址如下,这是x64的,x86的要再找下。。

读取棋盘数据

读棋盘数据首先要获得进程pid,可以通过Findwindow先找到窗口句柄,然后再GetWindowThreadProcessId找到pid。 最后ReadProcessMemory把棋盘数据读到数组里就好了。棋盘大小是11*19

1
2
3
4
5
6
7
8
9
10
11
hWnd = FindWindow(NULL, \_T(GAME\_CAPTION));
if (hWnd == NULL)
{
\_tprintf\_s(_T("Cant find windown"));
return FALSE;
}
GetWindowThreadProcessId(hWnd, &pid);
hGame = OpenProcess(PROCESS\_ALL\_ACCESS, FALSE, pid);
ReadProcessMemory(hGame, lpChess, chess, 11 * 19, NULL);
CloseHandle(hGame);

计算可消除的格子

棋盘数据已经存在11*19的数组里了,0代表空格,非零的情况对应的号码代表一个块,同号码代表同块 我是用一个深搜,先将棋盘外围填上一个边界值-1,代表到边界。

1
2
3
4
5
6
7
8
memset(chess2, -1, sizeof(chess2));
for (int i = 0; i < 11; i++)
{
for (int j = 0; j < 19; j++)
{
chess2\[i + 1\]\[j + 1\] = chess\[i\]\[j\];
}
}

之后从棋盘左上角开始遍历,判断每一个方块是否可以被消除。判断是否可以被消除的函数为bCheck()

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
int x1, x2, y1, y2;
for (x1 = 1; x1 <= 11; x1++)
{
for (y1 = 1; y1 <= 19; y1++)
{
if (chess2\[x1\]\[y1\] == 0)
continue;
for (x2 = 1; x2 <= 11; x2++)
{
for (y2 = 1; y2 <= 19; y2++)
{
if (!(x1 == x2 && y1 == y2) && chess2\[x1\]\[y1\] == chess2\[x2\]\[y2\])
{
if (bCheck(x1, y1, x2, y2, 0, DIRECT_BEGIN))
{
\_tprintf\_s(_T("GET:%d,%d and %d,%dn"), x1, y1, x2, y2);
CloseHandle(hWnd);
return TRUE;
}
}
}
}
}
}

下面是关键的bCheck,采用深搜。依次向上下左右递归搜索。

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
BOOL ClearLianliankan::bCheck(int x1, int y1, int x2, int y2, int cTurn, int eDirect)
{
if (cTurn > 3)
return FALSE;
if (x1 == x2 && y1 == y2)
return TRUE;
//UP
if ((chess2\[x1 - 1\]\[y1\] == 0 || chess2\[x1 - 1\]\[y1\] == chess2\[x2\]\[y2\]) && eDirect != DIRECT_DOWN)
{
if (eDirect != DIRECT_UP)
{
if (bCheck(x1 - 1, y1, x2, y2, cTurn + 1, DIRECT_UP))
return TRUE;
}
else
{
if (bCheck(x1 - 1, y1, x2, y2, cTurn, DIRECT_UP))
return TRUE;
}
}
//DOWN
if ((chess2\[x1 + 1\]\[y1\] == 0 || chess2\[x1 + 1\]\[y1\] == chess2\[x2\]\[y2\]) && eDirect != DIRECT_UP)
{
if (eDirect != DIRECT_DOWN)
{
if (bCheck(x1 + 1, y1, x2, y2, cTurn + 1, DIRECT_DOWN))
return TRUE;
}
else
{
if (bCheck(x1 + 1, y1, x2, y2, cTurn, DIRECT_DOWN))
return TRUE;
}
}
//LEFT
if ((chess2\[x1\]\[y1 - 1\] == 0 || chess2\[x1\]\[y1 - 1\] == chess2\[x2\]\[y2\]) && eDirect != DIRECT_RIGHT)
{
if (eDirect != DIRECT_LEFT)
{
if (bCheck(x1, y1 - 1, x2, y2, cTurn + 1, DIRECT_LEFT))
return TRUE;
}
else
{
if (bCheck(x1, y1 - 1, x2, y2, cTurn, DIRECT_LEFT))
return TRUE;
}
}
//RIGHT
if ((chess2\[x1\]\[y1 + 1\] == 0 || chess2\[x1\]\[y1 + 1\] == chess2\[x2\]\[y2\]) && eDirect != DIRECT_LEFT)
{
if (eDirect != DIRECT_RIGHT)
{
if (bCheck(x1, y1 + 1, x2, y2, cTurn + 1, DIRECT_RIGHT))
return TRUE;
}
else
{
if (bCheck(x1, y1 + 1, x2, y2, cTurn, DIRECT_RIGHT))
return TRUE;
}
}
return FALSE;
}

向窗口发送鼠标点击消息

用PostMessage就搞定啦。

1
2
3
4
PostMessage(hWnd, WM\_LBUTTONDOWN, 0, MAKELPARAM(25 + BLOCK\_WIDTH*(y1 - 1), 195 + BLOCK_HIGHT*(x1 - 1)));
PostMessage(hWnd, WM\_LBUTTONUP, 0, MAKELPARAM(25 + BLOCK\_WIDTH*(y1 - 1), 195 + BLOCK_HIGHT*(x1 - 1)));
PostMessage(hWnd, WM\_LBUTTONDOWN, 0, MAKELPARAM(25 + BLOCK\_WIDTH*(y2 - 1), 195 + BLOCK_HIGHT*(x2 - 1)));
PostMessage(hWnd, WM\_LBUTTONUP, 0, MAKELPARAM(25 + BLOCK\_WIDTH*(y2 - 1), 195 + BLOCK_HIGHT*(x2 - 1)));

这边要注意发送的坐标信息要我们自己去收集,可以用VS自带的Spy++,找到每个格子的长宽以及左上角格子的坐标。

完整代码

添加了热键什么的

https://github.com/yufanpi/lianliankan/

Comment and share

地铁难挤: 400 描述

米特尼克需要用社工办法 拿到THU安全专家的磁盘镜像以了解更多信息,于是他收买了THU专家的博士生,来到BJ市需要与博士生当面联系。但是,来到BJ市之后遇到的第一个问题 就是交通。BJ市人满为患,上下地铁时人们也不先下后上,而是互相挤。左边的人想挤到右边下车,右边的人也想挤到左边上车。你作为米特尼克在BJ的一位小 伙伴,能否帮他和所有乘客设计一个尽量少移动次数的方案,使得需要上车的人都上车,需要下车的人都下车。218.2.197.242:6000 or 218.2.197.243:6000

提示

此题是PPC 1. 地铁和车都是背景描述而已,和题目没关系,本题的目标就是让左边的人 L 都到 右边去,右边的人 R 都到左边来 2. 人的移动规则和游戏规则需要大家遍历出来,每次输入一个数字(20以内) 都不知道PPC什么意思。。反正先连接上去看看 要算一个sha1,先写了个python跑了一次X是三位的,但是发现每次连接字符串都会变。。。只能取得了再跑,后来发现用python写的会超时。。。然后尝试用hashcat来破 命令如下command = ‘cudaHashcat64 –custom-charset1 ?l?u?d -m 100 -a 3 “+result+” “+base+”?1?1?1?1”‘ 连上之后是一个什么游戏。。。 玩了半天,再根据题意。规则是空格分隔左右两边,最后要让L都到右边,R都到左边。 一次输入一个数字,代表这个字符串的第几个位置(空格也算一个位置),让这个位置上的人往另外一侧移动 一次最多只能移动两个人 如LRLRLRLRL R 输入9,,就变成LRLRLRLR LR 如LRLRLRLRL R 输入8,就变成LRLRLRL LRR,即两个人都到另一侧,并且互换位置 若输入不合法则返回wrong answer游戏失败。 下面就是游戏的算法啦 xin5739写的

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
//xin5739
#include <iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include "queue"
#define INF 100000000
using namespace std;
int sta\[1<<22\]\[22\];
int opp\[1<<22\]\[22\],ops\[1<<22\]\[22\],anss\[1<<22\]\[22\];
int len;
int judge(int s,int p)//判断是否达到目标,p是空格位置
{
for (int i=0;i<len;i++)
{
if(i<p&&(s&(1<<i))==0) return 0;
if(i>p&&(s&(1<<i))==1) return 0;
}
return 1;
}
int check(int s,int &p,int &now)//检查是否是合法移动,p是空格位置
{
int x,y;
x=p;y=now;
if(x==y) return -1;
int f0=0,f1=0;
if(x>y)
{
x--;
int t=x;x=y;y=t;
}
else x++;
for (int i=x;i<=y;i++)
{
if(s&(1<<i)) f1=1;
else f0=1;
}
if(f1==1&&f0==1)
{
if(y-x+1>2) return -1;
if(p<x)//pxy->yxp
{
if(s&(1<<y))
{
s|=(1<<p);
s^=(1<<y);
}
else if(s&(1<<p)) s^=(1<<p);
now=p;
p=y;
}
else //xyp->pyx
{
if(s&(1<<x))
{
s|=(1<<p);
s^=(1<<x);
}
else if(s&(1<<p)) s^=(1<<p);
now=p;
p=x;
}
return s;
}
else
{
if(p<x) //pxxxx->xxxxp
{
for (int j=p;j<y;j++)
{
if(s&(1<<(j+1)))
{
s|=(1<<j);
}
else if(s&(1<<j)) s^=(1<<j);
}
if(s&(1<<y)) s^=(1<<y);
now=p;
p=y;
}
else //xxxxp->pxxxx
{
// if(p!=y+1) printf("1111213123");
for (int j=p;j>x;j--)
{
if(s&(1<<(j-1)))
{
s|=(1<<j);
}
else if(s&(1<<j)) s^=(1<<j);
}
if(s&(1<<x)) s^=(1<<x);
now=p;
p=x;
}
return s;
}
return -1;
}
struct node
{
int s,p;
};
void bin2str(int s,int p)
{
for (int i=0;i<len;i++)
{
if(i==p) printf(" ");
else if(s&(1<<i)) printf("R");
else printf("L");
}
printf("n");
}
void bfs()
{
queue<node>q;
node z;
memset(sta,-1,sizeof(sta));
int i;
int s,p;
for (i=0;i<len;i++)
{
s=0;p=i;
int j;
for(j=0;j<p;j++) s|=(1<<j);
z.s=s;z.p=p;
q.push(z);
// bin2str(s,p);
sta\[s\]\[p\]=0;
}
while(!q.empty())
{
z=q.front();
q.pop();
for (i=0;i<len;i++)
{
int t=z.p,now=i;
int x=check(z.s,t,now);
if(sta\[x\]\[t\]==-1||sta\[z.s\]\[z.p\]+1<sta\[x\]\[t\])
{
node a;
sta\[x\]\[t\]=sta\[z.s\]\[z.p\]+1;
a.s=x;a.p=t;
opp\[x\]\[t\]=z.p; ops\[x\]\[t\]=z.s;anss\[x\]\[t\]=now;
q.push(a);
// bin2str(x,t);
// x=check(x,t,now);
// printf("%dn",now);
// bin2str(x,t);
}
}
}
}
void solve(int s,int p)
{
if(sta\[s\]\[p\]==0)
{
// bin2str(s,p);
// //if(judge(s,p))printf("11111n");
return;
}
// bin2str(s,p);
printf("%dn",anss\[s\]\[p\]+1);
solve(ops\[s\]\[p\],opp\[s\]\[p\]);
}
int main() {
// freopen("E:\\in.txt","r",stdin);
// freopen("E:\\out.txt","w",stdout);
char str\[22\];
gets(str);
//printf("%sn",str);
len=strlen(str);
int s=0,p;
for (int i=0;i<len;i++)
{
if(str\[i\]==' ') p=i;
else if(str\[i\]=='R') s|=(1<<i);
}
// printf("%d %dn",s,p);
// int now=8;
// s=check(s,p,now);
// bin2str(s,p);
bfs();
// printf("%dn",sta\[s\]\[p\]);
solve(s,p);
return 0;
}

后来我写的

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
//ROIS_yufan
//BCTF_crypto400
#include "stdio.h"
#include "string.h"
char czInput\[20\];
const int len = 16;
void PrintQueue()
{
//printf("%sn", czInput);
}
void PrintRst(int rst)
{
printf("%dn", rst + 1);
}
void ShiftSpace(int iWhere)
{
int iSpace;
for (iSpace = 0; iSpace < len; iSpace++)
{
if (czInput\[iSpace\] == ' ')
{
break;
}
}
if (iSpace < iWhere)
{
while (iSpace != iWhere)
{
iSpace++;
PrintRst(iSpace);
czInput\[iSpace - 1\] = czInput\[iSpace\];
czInput\[iSpace\] = ' ';
PrintQueue();
}
}
else if (iSpace > iWhere)
{
while (iSpace != iWhere)
{
iSpace--;
PrintRst(iSpace);
czInput\[iSpace + 1\] = czInput\[iSpace\];
czInput\[iSpace\] = ' ';
PrintQueue();
}
}
}
void RoolL(int curL)
{
if (curL > 0)
{
ShiftSpace(curL + 1);
}
//最左的L特例
else
{
ShiftSpace(curL + 2);
}
}
void SwapToRight(int iSpace)
{
//最左的L特例
if (iSpace == 1)
{
iSpace++;
}
PrintRst(iSpace - 2);
czInput\[iSpace\] = czInput\[iSpace - 2\];
czInput\[iSpace - 2\] = ' ';
PrintQueue();
}
void main()
{
gets(czInput);
int i;
for (i = len - 1; i >= 0; i--)
{
if (czInput\[i\] != 'L')
{
for (int j = i - 1; j >= 0; j--)
{
if (czInput\[j\] == 'L')
{
RoolL(j);
SwapToRight(j + 1);
i = len;
break;
}
}
}
}
for (i = 0; i < len; i++)
{
if (czInput\[i\] == ' ')
{
PrintRst(i + 1);
break;
}
}
}

然后写个脚本玩游戏就好啦。

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
#!/usr/bin/env python
#\-\*\- coding:utf-8 -*-
"""
BCTF_crypto300
ROIS_yufan
"""
import sys
import os
import base64,binascii,zlib
import hashlib
import re, socket
command = 'cudaHashcat64 --custom-charset1 ?l?u?d -m 100 -a 3 "+result+" "+base+"?1?1?1?1"'
def run(result, base):
f = os.popen("oclHashcat-1.01cudaHashcat64.exe --custom-charset1 ?l?u?d -m 100 -a 3 "+result+" "+base+"?1?1?1?1");
return f.read()
def getrst(str, result, base):
partten = re.compile(result + r':('+base+'....'+')')
return str\[str.find(result)+41:str.find(result)+61\]
def main():
HOST = '218.2.197.242' # The remote host
PORT = 6000 # The same port as used by the server
s = socket.socket(socket.AF\_INET, socket.SOCK\_STREAM)
s.connect((HOST, PORT))
print s.recv(1024)
strrecv = s.recv(1024)
print strrecv
\# strrecv = 'SHA1("5kEQPr0sul1aWUBb" + X).hexdigest() == "952792a53660aac0cc4d9eb1277f9b00d0ebf48c", X is a string of alphanumeric'
partten = re.compile(r'SHA1("(.*)" ')
base = partten.findall(strrecv)\[0\]
partten = re.compile(r'== "(.*)"')
result = partten.findall(strrecv)\[0\]
print base
print result
\# result = '848656a9e7f76052e8a73d42d17ec02400732e06'
\# base = 'rVYQ76B4IJdCzy8m'
rst = getrst(run(result, base), result, base)
print rst
s.sendall(rst\[-4:\]+'n')
print s.recv(1024)
while(1):
strrecv = s.recv(1024)
print repr(strrecv)
pattern = re.compile(r'\[LR \]+n')
if not pattern.search(strrecv):
strrecv = s.recv(1024)
strrecv = pattern.findall(strrecv)\[0\]
print strrecv
f = os.popen("c4.exe "+strrecv.replace(' ', '*'))
for line in f:
print repr(line)
s.sendall(line)
strrecv = s.recv(1024)
# pattern = re.compile(r'\[LR \]+n')
# strrecv = pattern.findall(strrecv)\[0\]
print strrecv
print s.recv(1024)
\# while len(strrecv):
\# input = raw_input()
\# s.sendall(input+'n')
\# strrecv = s.recv(1024)
\# pattern = re.compile(r'\[LR \]+n')
\# strrecv = pattern.findall(strrecv)\[0\]
\# print strrecv
return
if \_\_name\_\_ == '\_\_main\_\_':
main()

Comment and share

比特币钱包: 300 描述

来到中国后,米特尼克 身无分文了,怎样赚一大笔钱以备不时之需呢?比特币的爆发引起了他的注意。FBI 从丝绸之路缴获的大量比特币成了他的目标,他也想借此机会嘲笑一下 FBI。不费吹灰之力,他就搞定了这笔比特币巨款。你知道他是怎么搞定的吗?http://bctf.cn/files/downloads /robotum_9332cfdb5e503889e24e757d962a7454.html

提示

1. 机器人的眼睛是一个时钟,时钟是会走的阿,亲!2. 要做出此题,请先研究清楚比特币地址签名机制和 warpwallet 的用途3. 邮件发送格式说明,邮件内容那一行千万别写中文,verify 的部分不包含首尾的空格和回车(也就是 strip),下面的 signature 是 base64 串,可以使用 bitcoin-qt 客户端进行 sign 和 verify message 来验证 http://bctf.cn/files/downloads/robotum_9332cfdb5e503889e24e757d962a7454.html内容如下

嘿!你们好!

我是 FBI 的比特币守护机器人,我的地址是 [email protected], 我正在守护着 FBI 的一个重要比特币地址 1Atk95NnaQDiegEkqjJvg6c2KkJbSr2BEL (听说里面有很多钱!)。

你们知道吗?最近我学会了使用 Warpwallet,它既简单,又强大,还易于使用。哈哈!你们肯定没法猜到我的密钥是什么,不要偷窥哦。

好了,如果我的主人想取回存储在我这里的机密信息的话,只需要向我发送邮件就可以了。当然,邮件要使用这个重要比特币地址来签名,另外,你还要告诉我你想要取什么东西,只有让我验证通过了我才能告诉你。

为了避免忘记,我再重复一遍邮件的格式。

—–BEGIN BITCOIN SIGNED MESSAGE—–
这里写邮件的内容啦!
—–BEGIN SIGNATURE—–
这里是签名串
—–END BITCOIN SIGNED MESSAGE—–

祝你们好运!

这道题完全是靠第一个提示做出来的。。。 在那个网页中发现机器人用的是Warpwallet,于是先google下 https://keybase.io/warp/warp_1.0.6_SHA256_e68d4587b0e2ec34a7b554fbd1ed2d0fedfaeacf3e47fbb6c5403e252348cbfc.html 这个是通过Warpwallet用Passphrase和salt生产比特币地址(公钥)和private key 同时还有相关算法的说明 推 测salt应该就是那个机器人的email,那passphrase呢。。。看第一个提示,猜测是个时间然后就用这个算法找碰撞。。。一开始只从时钟上的 时间试到12点,没跑出来,后面把所有时间都跑了。。结果出了结果20:20,然后就能跑出他的private key啦 算法的代码是github上来的

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
#!/usr/bin/env python
#
#
\# Description: Implements the WarpWallet algorithm as descibed below:
#
\# s1 = scrypt(key=(passphrase||0x1), salt=(salt||0x1), N=2^18, r=8, p=1, dkLen=32)
\# s2 = pbkdf2(key=(passphrase||0x2), salt=(salt||0x2), c=2^16, dkLen=32, prf=HMAC_SHA256)
\# keypair = generate\_bitcoin\_keypair(s1 xor s2)
#
#modified by ROIS_yufan for BCTF2013 crypto300
import argparse
import binascii
import json
import scrypt
import sys
from passlib.utils import pbkdf2
from pycoin import ecdsa, encoding
from pycoin.ecdsa import secp256k1
class WarpWallet(object):
def \_\_init\_\_(self, pbkdf2\_count, derived\_key\_len, scrypt\_power, scrypt_p,
scrypt_r):
self.dklen = derived\_key\_len
self.pbkdf2\_count = pbkdf2\_count
self.scrypt\_power = scrypt\_power
self.scrypt\_r = scrypt\_r
self.scrypt\_p = scrypt\_p
def warp(self, passphrase, salt=""):
"""
Return dictionary of WarpWallet public and private keys corresponding to
the given passphrase and salt.
"""
s1 = binascii.hexlify(self._scrypt(passphrase, salt))
out = self._pbkdf2(passphrase, salt)
s2 = binascii.hexlify(out)
base = binascii.unhexlify(s1)
s3 = binascii.hexlify(self._sxor(base,out))
secret_exponent = int(s3, 16)
public\_pair = ecdsa.public\_pair\_for\_secret\_exponent(secp256k1.generator\_secp256k1, secret_exponent)
#private\_key = encoding.secret\_exponent\_to\_wif(secret_exponent, compressed=False)
public\_key = encoding.public\_pair\_to\_bitcoin\_address(public\_pair, compressed=False)
out = public_key
return out
def _scrypt(self, passphrase, salt=""):
scrypt_key = passphrase + "x01"
scrypt_salt = salt + "x01"
out = scrypt.hash(scrypt\_key, scrypt\_salt, N=2**self.scrypt_power,
r=self.scrypt\_r, p=self.scrypt\_p, buflen=self.dklen)
return out
def _pbkdf2(self, passphrase, salt=""):
hexlified_key = binascii.hexlify(passphrase) + "02"
pbkdf2\_key = binascii.unhexlify(hexlified\_key)
hexlified_salt = binascii.hexlify(salt) + "02"
pbkdf2\_salt = binascii.unhexlify(hexlified\_salt)
out = pbkdf2.pbkdf2(secret=pbkdf2\_key, salt=pbkdf2\_salt, keylen=self.dklen,
rounds=self.pbkdf2\_count, prf='hmac\_sha256')
return out
def _sxor (self, s1, s2):
# Convert strings to a list of character pair tuples,
# go through each tuple, converting them to ASCII code (ord),
# perform exclusive or on the ASCII code,
# then convert the result back to ASCII (chr),
# merge the resulting array of characters as a string.
return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2))
def parse_args():
parser = argparse.ArgumentParser()
parser.add\_argument("-c", "--pbkdf2\_count",
help="iteration count",
type=int,
default=2**16)
parser.add_argument("-d", "--dklen",
help="derived key length",
type=int,
default=32)
parser.add\_argument("-n", "--scrypt\_power",
help="2^n passed as the 'N' param to scrypt",
type=int,
default=18)
parser.add\_argument("-p", "--scrypt\_p",
help="'p' param to scrypt",
type=int,
default=1)
parser.add\_argument("-r", "--scrypt\_r",
help="'r' param to scrypt",
type=int,
default=8)
parser.add_argument("-P", "--passphrase" ,
help="passphrase",
type=str)
parser.add_argument("-S", "--salt" ,
help="salt",
type=str)
args = parser.parse_args()
if not args.passphrase:
print "Must provide passphrase (-P)"
sys.exit(1)
if not args.salt:
print "Must provide salt (-S)"
sys.exit(1)
return args
if \_\_name\_\_ == "\_\_main\_\_":
f = open("c300dict.txt", 'r')
for line in f:
strpass = line.strip()
wallet = WarpWallet(2**16, 32, 18,1, 8)
str = wallet.warp(strpass, salt)
if str == '1Atk95NnaQDiegEkqjJvg6c2KkJbSr2BEL':
print 'get!', strpass
break
print line

然后签名发邮件就ok啦,注意按题目要求的格式发。 http://p2pbucks.com/tools/brainwallet/index.html#sign

Comment and share

BCTF结束了。。。有点可惜吧。。。那个窃密木马因为一个小错误到手的300分就这样没了。。。不然还能进前十的- -

题目 混沌密码锁: 100 描述

据 传说,米特尼克进任何门都是不需要钥匙的,无论是金锁银锁还是密码锁。使用伪造身份在BAT安全部门工作的时候,有一扇带着密码锁的大门吸引了他的注意。 门后面到底藏着什么呢?米特尼克决定一探究竟。 http://bctf.cn/files/downloads/passcode_396331980c645d184ff793fdcbcb739b.py 218.2.197.242:9991 218.2.197.243:9991 passcode_396331980c645d184ff793fdcbcb739b.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
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
#!/usr/bin/env python2
#\-\*\- coding:utf-8 -*-
import base64,binascii,zlib
import os,random
base = \[str(x) for x in range(10)\] + \[ chr(x) for x in range(ord('A'),ord('A')+6)\]
def abc(str):
return sha.new(str).hexdigest()
def bin2dec(string_num):
return str(int(string_num, 2))
def hex2dec(string_num):
return str(int(string_num.upper(), 16))
def dec2bin(string_num):
num = int(string_num)
mid = \[\]
while True:
if num == 0: break
num,rem = divmod(num, 2)
mid.append(base\[rem\])
return ''.join(\[str(x) for x in mid\[::-1\]\])
def dec2hex(string_num):
num = int(string_num)
mid = \[\]
while True:
if num == 0: break
num,rem = divmod(num, 16)
mid.append(base\[rem\])
return ''.join(\[str(x) for x in mid\[::-1\]\])
def hex2bin(string_num):
return dec2bin(hex2dec(string_num.upper()))
def bin2hex(string_num):
return dec2hex(bin2dec(string_num))
def reverse(string):
return string\[::-1\]
def read_key():
os.system('cat flag')
def gb2312(string):
return string.decode('gb2312')
answer='78864179732635837913920409948348078659913609452869425042153399132863903834522365250250429645163517228356622776978637910679538418927909881502654275707069810737850807610916192563069593664094605159740448670132065615956224727012954218390602806577537456281222826375'
func_names = \['fun1', 'fun2', 'fun3', 'fun4', 'fun5', 'fun6', 'fun7', 'fun8', 'fun9'\]
f={}
f\['fun1'\]=reverse
f\['fun2'\]=base64.b64decode
f\['fun3'\]=zlib.decompress
f\['fun4'\]=dec2hex
f\['fun5'\]=binascii.unhexlify
f\['fun6'\]=gb2312
f\['fun7'\]=bin2dec
f\['fun8'\]=hex2bin
f\['fun9'\]=hex2dec
def check_equal(a, b):
if a == b:
return True
try:
if int(a) == int(b):
return True
except:
return False
return False
def main():
print "Welcome to Secure Passcode System"
print "First, please choose function combination:"
print "2"
for in1 in range(1,10):
for in2 in range(1,10):
for in3 in range(1,10):
for in4 in range(1,10):
in1=str(in1)
in2=str(in2)
in3=str(in3)
in4=str(in4)
f1='fun'+in1\[:1\]
f2='fun'+in2\[:1\]
f3='fun'+in3\[:1\]
f4='fun'+in4\[:1\]
if f1 not in func\_names or f2 not in func\_names or f3 not in func\_names or f4 not in func\_names:
print 'invalid function combination'
exit()
try:
answer_hash = f\['fun6'\](f\['fun2'\](f\[f1\](f\[f2\](f\[f3\](f\[f4\](answer))))))
except:
print "Wrong function combination, you bad guy!"
exit()
if len(answer_hash) == 0:
print 'You must be doing some little dirty trick! Stop it!'
exit()
usercode = raw_input('Your passcode: ')
try:
user_hash = f\['fun6'\](f\['fun2'\](f\[f1\](f\[f2\](f\[f3\](f\[f4\](usercode))))))
if user\_hash == answer\_hash:
if check_equal(answer, usercode):
print "This passcode has been locked, please use the new onen"
else:
print "Welcome back! The door always open for you, your majesty! "
read_key()
else:
print "Sorry, bad passcode.n"
except:
print "Sorry, bad passcode. Please try again."
if \_\_name\_\_ == '\_\_main\_\_':
main()

这个程序就是我们自选f1-f4四种函数answer=’78864179732635837913920409948348078659913609452869425042153399132863903834522365250250429645163517228356622776978637910679538418927909881502654275707069810737850807610916192563069593664094605159740448670132065615956224727012954218390602806577537456281222826375’ answer_hash = f[‘fun6’](f[‘fun2’](f[f1](f[f2](f[f3](f[f4](answer)))))) 然后将我们输入的usercode做同样变化 user_hash = f[‘fun6’](f[‘fun2’](f[f1](f[f2](f[f3](f[f4](usercode)))))) 相等即可通过(usercode不能与answer相同)。 如果输入的函数组合不符要求会”Wrong function combination, you bad guy!” 首先用暴力的方法求出函数的组合,只有唯一一种 f1=’fun3’ f2=’fun5’ f3=’fun1’ f4=’fun4’ 下面是关键

经过f[f1](ff2))之后是一个BASE64的串,然后用fun2进行base64解密,再通过fun6生成hash f[f1](ff2)) = ‘ztLU2s/rxOPU2s/rztLKssO0tcTTw7nIuOi3rdLrv8+2qNK7teOyu7rD08O7ucrHsfDTw8HLv7TV4r7ku7C+wL3hy8DE4771tcPE2A==’ 解 码后ff1“>’fun2’ = ‘xcexd2xd4xdaxcfxebxc4xe3xd4xdaxcfxebxcexd2xcaxb2xc3xb4xb5xc4xd3xc3xb9xc8xb8xe8xb7xadxd2xebxbfxcfxb6xa8xd2xbbxb5xe3xb2xbbxbaxc3xd3xc3xbbxb9xcaxc7xb1xf0xd3xc3xc1xcbxbfxb4xd5xe2xbexe4xbbxb0xbexc0xbdxe1xcbxc0xc4xe3xbexf5xb5xc3xc4xd8’ 参考http://zh.wikipedia.org/zh-cn/Base64 Base64是一种基于64个可打印字符来表示二进制数据的表示方法。 转 换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。 然后,每次取出6(因为2^6=64)个bit,按照其值选择 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码 后的输出。不断进行,直到全部输入数据转换完成。 当原数据长度不是3的整数倍时, 如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。 回到题中,最后四位是‘2A==’,对应为110110 000000 000000 000000(不足的填0了) 因为两个’=’所以三个比特中的后两个是没有数据的,只有前8个bit对应数据x90 那如果是’2B==’呢,对应为110110 000001 000000 000000 后面的数据是无用的,有用的依然是前8bit 对应x90 so……‘ztLU2s/rxOPU2s /rztLKssO0tcTTw7nIuOi3rdLrv8+2qNK7teOyu7rD08O7ucrHsfDTw8HLv7TV4r7ku7C+wL3hy8DE4771tcPE2B==’ 通 过base64解码的结果和 ‘ztLU2s/rxOPU2s /rztLKssO0tcTTw7nIuOi3rdLrv8+2qNK7teOyu7rD08O7ucrHsfDTw8HLv7TV4r7ku7C+wL3hy8DE4771tcPE2A==’ 是 相同的 后面就简单啦,逆回去求usercode就好啦。

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
#!/usr/bin/env python2
#\-\*\- coding:utf-8 -*-
#BCTF_Crypto100
#ROIS_yufan
import base64,binascii,zlib
import os,random
base = \[str(x) for x in range(10)\] + \[ chr(x) for x in range(ord('A'),ord('A')+6)\]
def abc(str):
return sha.new(str).hexdigest()
def bin2dec(string_num):
return str(int(string_num, 2))
def hex2dec(string_num):
return str(int(string_num.upper(), 16))
def dec2bin(string_num):
num = int(string_num)
mid = \[\]
while True:
if num == 0: break
num,rem = divmod(num, 2)
mid.append(base\[rem\])
return ''.join(\[str(x) for x in mid\[::-1\]\])
def dec2hex(string_num):
num = int(string_num)
mid = \[\]
while True:
if num == 0: break
num,rem = divmod(num, 16)
mid.append(base\[rem\])
return ''.join(\[str(x) for x in mid\[::-1\]\])
def hex2bin(string_num):
return dec2bin(hex2dec(string_num.upper()))
def bin2hex(string_num):
return dec2hex(bin2dec(string_num))
def reverse(string):
return string\[::-1\]
def read_key():
os.system('cat flag')
def gb2312(string):
return string.decode('gb2312')
answer='78864179732635837913920409948348078659913609452869425042153399132863903834522365250250429645163517228356622776978637910679538418927909881502654275707069810737850807610916192563069593664094605159740448670132065615956224727012954218390602806577537456281222826375'
func_names = \['fun1', 'fun2', 'fun3', 'fun4', 'fun5', 'fun6', 'fun7', 'fun8', 'fun9'\]
f={}
f\['fun1'\]=reverse
f\['fun2'\]=base64.b64decode
f\['fun3'\]=zlib.decompress
f\['fun4'\]=dec2hex
f\['fun5'\]=binascii.unhexlify
f\['fun6'\]=gb2312
f\['fun7'\]=bin2dec
f\['fun8'\]=hex2bin
f\['fun9'\]=hex2dec
def check_equal(a, b):
if a == b:
return True
try:
if int(a) == int(b):
return True
except:
return False
return False
def main():
print "Welcome to Secure Passcode System"
print "First, please choose function combination:"
\# in1=raw_input('f1: ')
f1='fun'+'3'
\# in2=raw_input('f2: ')
f2='fun'+'5'
\# in3=raw_input('f3: ')
f3='fun'+'1'
\# in4=raw_input('f4: ')
f4='fun'+'4'
print f1, f2, f3, f4
if f1 not in func\_names or f2 not in func\_names or f3 not in func\_names or f4 not in func\_names:
print 'invalid function combination'
exit()
try:
answer_hash = f\['fun6'\](f\['fun2'\](f\[f1\](f\[f2\](f\[f3\](f\[f4\](answer))))))
\# print f\[f4\](answer)
\# print f\[f3\](f\[f4\](answer))
\# print repr(f\[f2\](f\[f3\](f\[f4\](answer))))
print 'original base64', f\[f1\](f\[f2\](f\[f3\](f\[f4\](answer))))
print 'original decoded base64', repr(f\['fun2'\](f\[f1\](f\[f2\](f\[f3\](f\[f4\](answer))))))
print 'my base64 decoded', repr(base64.b64decode('ztLU2s/rxOPU2s/rztLKssO0tcTTw7nIuOi3rdLrv8+2qNK7teOyu7rD08O7ucrHsfDTw8HLv7TV4r7ku7C+wL3hy8DE4771tcPE2'+'B'+'=='))
except:
print "Wrong function combination, you bad guy!"
exit()
if len(answer_hash) == 0:
print 'You must be doing some little dirty trick! Stop it!'
exit()
for c in range(ord('A'), ord('Q')):
usercode = str (hex2dec(reverse(binascii.hexlify(zlib.compress('ztLU2s/rxOPU2s/rztLKssO0tcTTw7nIuOi3rdLrv8+2qNK7teOyu7rD08O7ucrHsfDTw8HLv7TV4r7ku7C+wL3hy8DE4771tcPE2'+chr(c)+'==')))))
print usercode
try:
\# print f\[f4\](usercode)
\# print f\[f3\](f\[f4\](usercode))
\# print repr(f\[f2\](f\[f3\](f\[f4\](usercode))))
\# print f\[f1\](f\[f2\](f\[f3\](f\[f4\](usercode))))
\# print repr(f\['fun2'\](f\[f1\](f\[f2\](f\[f3\](f\[f4\](usercode))))))
user_hash = f\['fun6'\](f\['fun2'\](f\[f1\](f\[f2\](f\[f3\](f\[f4\](usercode))))))
if user\_hash == answer\_hash:
if check_equal(answer, usercode):
print "This passcode has been locked, please use the new onen"
else:
print "Welcome back! The door always open for you, your majesty! "
else:
print "Sorry, bad passcode.n"
except:
print "Sorry, bad passcode. Please try again."
if \_\_name\_\_ == '\_\_main\_\_':
main()

Comment and share

Author's picture

Eadom

NO PWN NO FUN


@Alibaba


Hangzhou