这回跟着个队伍跑,不过还是2X以后的成绩,前边太卷了。
自己会的部分,有些是别人已经提交了的。记录一下。
Crypto
crypto 1
给了一些数据,像这样就没有别的了
ct = [0, 1, 1, 2, 5, 10, 20, 40, 79, 159, 317, 635, 1269, 2538, 5077, 10154, 20307, 40615, 81229, 162458, 324916, 649832, 1299665, 2599330, 5198659, 10397319, 20794638, 41589276, 83178552, 166357103, 332714207, 665428414, 1330856827, 2661713655, 5323427309, 10646854619, 21293709237, 42587418474, 85174836949, 170349673898, 340699347795, 681398695591, 1362797391181, 2725594782363, 5451189564725, 10902379129451, 21804758258901, 43609516517803, 87219033035605, 174438066071211, 348876132142421, 697752264284843, 1395504528569685, 2791009057139370, 5582018114278740, 11164036228557480, 22328072457114960, 44656144914229920, 89312289828459841, 178624579656919682, 357249159313839363, 714498318627678726, 1428996637255357453, 2857993274510714906, 5715986549021429811, 11431973098042859623, 22863946196085719246, 45727892392171438492, 91455784784342876983, 182911569568685753966, 365823139137371507933, 731646278274743015865, 1463292556549486031730, ...]
看了会发现一个规律:
ct[i] = bit + sum(ct[:i])
把这些0,1弄出来就OK了。我来得早,这时候还没人上线,两个crypto都是1血,跟签到抢到1血一样。
#Alice and Bob decided to create their own super cryptosystem. However.. it has a super flaw
k = 0
f = ''
for i in range(1,len(ct)):
f += str(ct[i]-k)
k += ct[i]
print(f)
#前面的和+bit
f = '0'+f
for i in range(0, len(f),8):
print(chr(int(f[i:i+8],2)), end='')
#OSC{SUP3r!NCr3451NG_53QU3NC3}
crypto 2
一个e=3的RSA题
from Crypto.Util.number import bytes_to_long, getPrime
from secret import messages
def RSA_encrypt(message):
m = bytes_to_long(message)
p = getPrime(1024)
q = getPrime(1024)
N = p * q
e = 3
c = pow(m, e, N)
return N, e, c
for m in messages:
N, e, c = RSA_encrypt(m)
print(f"n = {N}")
print(f"e = {e}")
print(f"c = {c}")
给了好多的n,c显然,感觉如果flag不是很大可以爆破,不过只有第1行爆破出来了,正好是flag
from gmpy2 import iroot
from Crypto.Util.number import long_to_bytes
msg = open('output.txt').readlines()
for i in range(11):
n = int(msg[i*3][4:])
e = int(msg[i*3+1][4:])
c = int(msg[i*3+2][4:])
print(n)
print(e)
print(c)
while True:
a,b = iroot(c,3)
if b:
print(long_to_bytes(a))
break
c+=n
#OSC{C0N6r47U14710N5!_Y0U_UND3r574ND_H0W_70_U53_H4574D5_8r04DC457_4774CK_______0xL4ugh}
Rev
snake
python 字节码
2 0 LOAD_CONST 1 (0)
2 LOAD_CONST 0 (None)
4 IMPORT_NAME 0 (base64)
6 STORE_FAST 0 (base64)
3 8 LOAD_CONST 1 (0)
10 LOAD_CONST 2 (('Fernet',))
12 IMPORT_NAME 1 (cryptography.fernet)
14 IMPORT_FROM 2 (Fernet)
16 STORE_FAST 1 (Fernet)
18 POP_TOP
4 20 LOAD_CONST 3 (b'gAAAAABj7Xd90ySo11DSFyX8t-9QIQvAPmU40mWQfpq856jFl1rpwvm1kyE1w23fyyAAd9riXt-JJA9v6BEcsq6LNroZTnjExjFur_tEp0OLJv0c_8BD3bg=')
22 STORE_FAST 2 (encMessage)
5 24 LOAD_FAST 0 (base64)
26 LOAD_METHOD 3 (b64decode)
28 LOAD_CONST 4 (b'7PXy9PSZmf/r5pXB79LW1cj/7JT6ltPEmfjk8sHljfr6x/LyyfjymNXR5Z0=')
30 CALL_METHOD 1
32 STORE_FAST 3 (key_bytes)
6 34 BUILD_LIST 0
36 STORE_FAST 4 (key)
7 38 LOAD_FAST 3 (key_bytes)
40 GET_ITER
>> 42 FOR_ITER 9 (to 62)
44 STORE_FAST 5 (k_b)
8 46 LOAD_FAST 4 (key)
48 LOAD_METHOD 4 (append)
50 LOAD_FAST 5 (k_b)
52 LOAD_CONST 5 (160)
54 BINARY_XOR
56 CALL_METHOD 1
58 POP_TOP
60 JUMP_ABSOLUTE 21 (to 42)
10 >> 62 LOAD_GLOBAL 5 (bytes)
64 LOAD_FAST 4 (key)
66 CALL_FUNCTION 1
68 STORE_FAST 4 (key)
11 70 LOAD_FAST 1 (Fernet)
72 LOAD_FAST 4 (key)
74 CALL_FUNCTION 1
76 STORE_FAST 6 (fernet)
12 78 LOAD_FAST 6 (fernet)
80 LOAD_METHOD 6 (decrypt)
82 LOAD_FAST 2 (encMessage)
84 CALL_METHOD 1
86 LOAD_METHOD 7 (decode)
88 CALL_METHOD 0
90 STORE_FAST 7 (decMessage)
13 92 LOAD_GLOBAL 8 (print)
94 LOAD_FAST 7 (decMessage)
96 CALL_FUNCTION 1
98 POP_TOP
100 LOAD_CONST 0 (None)
102 RETURN_VALUE
None
手扣
import base64
from cryptography.fernet import Fernet
encMessage = b'gAAAAABj7Xd90ySo11DSFyX8t-9QIQvAPmU40mWQfpq856jFl1rpwvm1kyE1w23fyyAAd9riXt-JJA9v6BEcsq6LNroZTnjExjFur_tEp0OLJv0c_8BD3bg='
key_bytes = base64.b64decode(b'7PXy9PSZmf/r5pXB79LW1cj/7JT6ltPEmfjk8sHljfr6x/LyyfjymNXR5Z0=')
key = []
for k_b in key_bytes:
key.append(k_b^160)
key = bytes(key)
decMessage = Fernet(key).decrypt(encMessage)
print(decMessage)
#FLAG{FLY_L1k3_0xR4V3N}
#0xL4ugh{FLY_L1k3_0xR4V3N}
easy-Peasy
高低4位互换
v11[0] = 1947518052;
v11[1] = 84227255;
v11[2] = -181070859;
v11[3] = -972881100;
v11[4] = 1396909045;
v11[5] = 1396929315;
v12 = -10397;
v13 = 0;
v3 = 0i64;
v16 = 0i64;
v17 = 15i64;
LOBYTE(Block[0]) = 0;
sub_140001350(Block);
sub_1400015D0(std::cout, (__int64)"Enter The Flag: ");
sub_140001A50(std::cin, Block); // 读入Block
if ( v16 == 26 )
{
while ( 1 )
{
v4 = Block;
if ( v17 >= 0x10 )
v4 = (void **)Block[0];
v5 = Block;
if ( v17 >= 0x10 )
v5 = (void **)Block[0];
if ( *((unsigned __int8 *)v11 + v3) != ((*((char *)v4 + v3) >> 4) | (16 * (*((_BYTE *)v5 + v3) & 0xF))) )// 高低互换
break;
if ( ++v3 >= 26 )
{
v6 = sub_1400015D0(std::cout, (__int64)"The Flag is: ");
v7 = Block;
if ( v17 >= 0x10 )
v7 = (void **)Block[0];
sub_140001C50(v6, v7, v16);
goto LABEL_12;
}
}
}
解
va = [1947518052,84227255,-181070859,-972881100,1396909045,1396929315,-10397]
from pwn import p32
v11 = b''.join([p32(v&0xffffffff) for v in va])
f = ''
for v in v11:
f += chr(((v&0xf)<<4)+(v>>4))
print(f)
#FLAG{CPP_1S_C00l_24527456}
#0xL4ugh{CPP_1S_C00l_24527456}
lets go
代码看着很复杂,但明显能看出是字节变换
void __cdecl main_main()
{
__int64 v0; // r14
__int128 v1; // xmm15
__int64 *v2; // rax
__int64 v3; // r8
__int64 v4; // r9
__int64 v5; // rax
__int64 v6; // rcx
unsigned __int64 v7; // rbx
__int64 v8; // rsi
int v9; // r10d
__int64 v10; // r11
int v11; // r10d
__int64 v12; // rax
unsigned __int64 v13; // rcx
int v14; // r10d
__int64 v15; // rax
unsigned __int64 v16; // rcx
__int64 v17; // rax
unsigned __int64 v18; // rcx
__int64 v19; // rax
__int64 v20; // [rsp-46h] [rbp-D8h]
char v21; // [rsp+0h] [rbp-92h]
char v22; // [rsp+1h] [rbp-91h]
char v23; // [rsp+1h] [rbp-91h]
__int64 v24; // [rsp+2h] [rbp-90h]
__int64 v25; // [rsp+Ah] [rbp-88h]
__int64 v26; // [rsp+12h] [rbp-80h]
__int64 v27; // [rsp+3Ah] [rbp-58h] BYREF
__int64 *v28; // [rsp+42h] [rbp-50h]
void *v29; // [rsp+4Ah] [rbp-48h]
char **v30; // [rsp+52h] [rbp-40h]
__int128 v31; // [rsp+5Ah] [rbp-38h]
const char *v32; // [rsp+6Ah] [rbp-28h]
__int64 *v33; // [rsp+72h] [rbp-20h]
void *v34; // [rsp+7Ah] [rbp-18h]
char **v35; // [rsp+82h] [rbp-10h]
if ( (unsigned __int64)&v27 <= *(_QWORD *)(v0 + 16) )
runtime_morestack_noctxt_abi0();
v34 = &unk_494360;
v35 = &off_4C3F50;
fmt_Fprint();
runtime_newobject();
v28 = v2;
*v2 = 0LL;
v32 = "\b";
v33 = v2;
fmt_Fscanln();
v3 = *v28;
v27 = *v28;
v4 = v28[1];
v25 = v4;
v5 = 0LL;
v6 = 0LL;
v7 = 0LL;
v8 = 0LL;
while ( v5 < v4 )
{
v24 = v6;
v26 = v5;
v9 = *(unsigned __int8 *)(v3 + v5);
if ( (unsigned __int8)(v9 - 65) > 0x19u )
{
if ( (unsigned __int8)(v9 - 97) > 0x19u ) // 符号
{
v10 = v6 + 1;
if ( v7 < v6 + 1 )
{
v21 = *(_BYTE *)(v3 + v5);
runtime_growslice(v20);
v10 = v8 + 1;
v3 = v27;
v4 = v25;
LOBYTE(v9) = v21;
v8 = v17;
v7 = v18;
v5 = v26;
v6 = v24;
}
*(_BYTE *)(v8 + v6) = v9;
}
else
{
v10 = v6 + 1;
v14 = v9 - 26 * ((unsigned __int8)(v9 - 81) / 0x1Au);
if ( v7 < v6 + 1 )
{
v23 = v14;
runtime_growslice(v20);
v10 = v8 + 1;
v3 = v27;
v4 = v25;
LOBYTE(v14) = v23;
v8 = v15;
v7 = v16;
v5 = v26;
v6 = v24;
}
*(_BYTE *)(v8 + v6) = v14 + 16;
}
}
else
{
v10 = v6 + 1;
v11 = v9 - 26 * ((unsigned __int8)(v9 - 49) / 0x1Au);
if ( v7 < v6 + 1 )
{
v22 = v11;
runtime_growslice(v20);
v10 = v8 + 1;
v3 = v27;
v4 = v25;
LOBYTE(v11) = v22;
v8 = v12;
v7 = v13;
v5 = v26;
v6 = v24;
}
*(_BYTE *)(v8 + v6) = v11 + 16;
}
++v5;
v6 = v10;
}
runtime_slicebytetostring();
if ( v8 == 32 && (unsigned __int8)runtime_memequal() )
{
v31 = v1;
v19 = runtime_convTstring();
*(_QWORD *)&v31 = &unk_494360;
*((_QWORD *)&v31 + 1) = v19;
fmt_Fprintf();
}
else
{
v29 = &unk_494360;
v30 = &off_4C3F60;
fmt_Fprint();
}
}
这个只需要个码表就行,输入字母得到的就是码表,然后手工对应填一下
输入得到对应关系
abcdefghijklmnopqrstuvwxyz012345
qrstuvwxyzabcdefghijklmnop012345
ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
QRSTUVWXYZABCDEFGHIJKLMNOP012345
67890{_} 数字符号不变
c = b"u507rv78qr5t6q99941422uursv94464"
u507rv78qr5t6q99941422uursv94464
e507bf78ab5d6a99941422eebcf94464
手工输入得到flag
ef➤
Correct:)
FLAG{e507bf78ab5d6a99941422eebcf94464}
52 in example/user/hello/hello.go
换头
0xL4ugh{e507bf78ab5d6a99941422eebcf94464}
XPacker 未完成
看上去是运行时释放一个程序再找,但怎么运行都不释放,也许想错了
Misc
ATT-IP
流量题,wireShark打开一点点到结果
57包:
tcp://91.243.59.76:23927/
0xL4ugh{91.243.59.76_23927}
PVE
这个是别的提交的,只因为第1步没作出来后边的就没想弄。
给的一vmware的临时文件.vmem 一直想用什么软件找到。其实只有第1题用软件,其它都是在时差搜文本。
后来下了volatility 3才弄好这一步
┌──(kali㉿kali)-[~/volatility3]
└─$ py vol.py -f ~/ctf/PVE.vmem Banners
Volatility 3 Framework 2.4.1
Progress: 100.00 PDB scanning finished
Offset Banner
0x1a00180 Linux version 4.4.0-186-generic (buildd@lcy01-amd64-002) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) ) #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 (Ubuntu 4.4.0-186.216-generic 4.4.228)
0x211e6a4 Linux version 4.4.0-186-generic (buildd@lcy01-amd64-002) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) ) #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 (Ubuntu 4.4.0-186.216-generic 4.4.228)
0x1aaf7338 Linux version 4.4.0-186-generic (buildd@lcy01-amd64-002) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) ) #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 (Ubuntu 4.4.0-186.216-generic 4.4.228)
0x1fde00a8 Linux version 4.4.0-186-generic (buildd@lcy01-amd64-002) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) ) #216-Ubuntu SMP Wed Jul 1 05:34:05 UTC 2020 (Ubuntu 4.4.0-186.216-generic 4.4.228)
flag1:0xL4ugh{Ubuntu_4.4.0-186-generic}
第二步是Apache的版本,搜apache有很多,主要是两个版本,第2个=的是
0xL4ugh{2.2.14}
第三步找 flag 搜0xL4ugh
sudo echo "0xL4ugh{S4D_Y0U_G07_M3}" > flag.txt
0xL4ugh{S4D_Y0U_G07_M3}
第四个找程序里隐写的flag
int main(void){
char flag[] = "0xL4ugh{H1DD3N_1N_PR0CE$$}";
sleep(6969696969);
return 0;
}
0xL4ugh{H1DD3N_1N_PR0CE$$}
第五个找攻击求密码,没弄成,linux的密码存在shadow文件但这里没密码,再找passwd也没有,按密码的特征 $1$salt$enc_pass 搜$1$得到一个密码
Name: passwd/user-password-crypted
Template: passwd/user-password-crypted
Value: $1$JULXDu5H$c/QbtxOmwiX0rR7f0NXxj.
Owners: ubiquity
Flags: seen
从网站上解密得到 mrx 提交不正确。
队友还作了一些,刚开始已经狂飙到第2了,后来慢慢又多了1位成2x了