地铁难挤: 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